From f0dba347c5048fc77d93ab46158b019ad9eddef3 Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Mon, 17 Aug 2020 20:14:52 +0200 Subject: [PATCH] document mapping and validation --- src/InternshipSystem.Api/ApiProfile.cs | 14 ++++ .../Controllers/DocumentsController.cs | 70 ++++++++++--------- .../InternshipSystem.Api.csproj | 3 + .../Queries/DocumentPublishRequest.cs | 2 +- src/InternshipSystem.Api/Startup.cs | 2 + .../DocumentPublishRequestValidator.cs | 15 ++++ .../Entity/Internship/Internship.cs | 19 +++++ .../InternshipSystem.Core.csproj | 4 ++ 8 files changed, 95 insertions(+), 34 deletions(-) create mode 100644 src/InternshipSystem.Api/ApiProfile.cs create mode 100644 src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs diff --git a/src/InternshipSystem.Api/ApiProfile.cs b/src/InternshipSystem.Api/ApiProfile.cs new file mode 100644 index 0000000..a25d338 --- /dev/null +++ b/src/InternshipSystem.Api/ApiProfile.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using InternshipSystem.Api.Queries; +using InternshipSystem.Core; + +namespace InternshipSystem.Api +{ + public class ApiProfile : Profile + { + public ApiProfile() + { + CreateMap(); + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs index 00ef234..b601bc6 100644 --- a/src/InternshipSystem.Api/Controllers/DocumentsController.cs +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -1,6 +1,9 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; +using AutoMapper; using InternshipSystem.Api.Queries; +using InternshipSystem.Api.Validators; using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Http; @@ -14,16 +17,18 @@ namespace InternshipSystem.Api.Controllers public class DocumentsController : ControllerBase { private InternshipDbContext Context { get; } + private IMapper Mapper { get; } - public DocumentsController(InternshipDbContext context) + public DocumentsController(InternshipDbContext context, IMapper mapper) { Context = context; + Mapper = mapper; } /// /// Fill out required document, /// - /// Documents Scan and description, and Id of filled document + /// Documents Scan and description, and Id of filled document /// /// If change was successfully registered /// If the provided query was malformed @@ -34,52 +39,51 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest document) + public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest documentRequest) { - // TODO: - // if not authorised then - // return Unauthorized(); + var validator = new DocumentPublishRequestValidator(); + var validationResult = await validator.ValidateAsync(documentRequest); - // TODO: - // is request is valid?? - // if not then - // return BadRequest(); + if (!validationResult.IsValid) + { + return BadRequest(validationResult.ToString()); + } var studentInternship = await GetCurrentStudentInternship(); - if (document.Id != null) - { - var doc = studentInternship.Documentation - .Find(d => d.Id == document.Id); - if (doc == null) + + var document = Mapper.Map(documentRequest); + + if (documentRequest.Id.HasValue) + { + try + { + studentInternship.UpdateDocument(document); + } + catch (InvalidOperationException) + { return NotFound(); - doc.Description = document.Description; - doc.Scan = document.Scan; - doc.Type = document.Type; - doc.State = DocumentState.Submitted; + } } else { - studentInternship.Documentation.Add( - new Document() - { - Description = document.Description, - Scan = document.Scan, - Type = document.Type, - State = DocumentState.Submitted - }); + studentInternship.AddNewDocument(document); } await Context.SaveChangesAsync(); return Ok(); } - //TODO: rewrite when authentication will be implemented private async Task GetCurrentStudentInternship() { - return Context.Editions - .FirstAsync().Result - .Internships - .First(); + // TODO: rewrite when authentication will be implemented + var edition = await Context + .Editions + .FirstAsync(); + + return await Context.Entry(edition) + .Collection(e => e.Internships) + .Query() + .FirstAsync(); } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/InternshipSystem.Api.csproj b/src/InternshipSystem.Api/InternshipSystem.Api.csproj index 1252f96..d5c17c0 100644 --- a/src/InternshipSystem.Api/InternshipSystem.Api.csproj +++ b/src/InternshipSystem.Api/InternshipSystem.Api.csproj @@ -8,6 +8,9 @@ + + + diff --git a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs index fe6b5b2..c57bdfe 100644 --- a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs +++ b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs @@ -4,7 +4,7 @@ namespace InternshipSystem.Api.Queries { public class DocumentPublishRequest { - public long Id { get; set; } + public long? Id { get; set; } public string Description { get; set; } public byte[] Scan { get; set; } public DocumentType Type { get; set; } diff --git a/src/InternshipSystem.Api/Startup.cs b/src/InternshipSystem.Api/Startup.cs index aa5f0c8..1f46ea9 100644 --- a/src/InternshipSystem.Api/Startup.cs +++ b/src/InternshipSystem.Api/Startup.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using AutoMapper; using InternshipSystem.Repository; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -30,6 +31,7 @@ namespace InternshipSystem.Api options.IncludeXmlComments(xmlPath); }) .AddScoped() + .AddAutoMapper(cfg => cfg.AddProfile()) .AddControllers() ; diff --git a/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs b/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs new file mode 100644 index 0000000..1d1b270 --- /dev/null +++ b/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; +using InternshipSystem.Api.Queries; +using InternshipSystem.Core; + +namespace InternshipSystem.Api.Validators +{ + public class DocumentPublishRequestValidator : AbstractValidator + { + public DocumentPublishRequestValidator() + { + RuleFor(document => document.Scan).NotEmpty(); + RuleFor(document => document.Type).NotEmpty(); + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Internship/Internship.cs b/src/InternshipSystem.Core/Entity/Internship/Internship.cs index 61f0c2b..52aaf69 100644 --- a/src/InternshipSystem.Core/Entity/Internship/Internship.cs +++ b/src/InternshipSystem.Core/Entity/Internship/Internship.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Linq; +using InternshipSystem.Core.ValueObject; namespace InternshipSystem.Core { @@ -11,5 +13,22 @@ namespace InternshipSystem.Core public Report Report { get; set; } public List Approvals { get; set; } public List Documentation { get; set; } + + public void UpdateDocument(Document document) + { + var oldDocument = Documentation.First(d => d.Id == document.Id); + + oldDocument.Description = document.Description; + oldDocument.Scan = document.Scan; + oldDocument.Type = document.Type; + oldDocument.State = DocumentState.Submitted; + } + + public void AddNewDocument(Document document) + { + document.State = DocumentState.Submitted; + + Documentation.Add(document); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/InternshipSystem.Core.csproj b/src/InternshipSystem.Core/InternshipSystem.Core.csproj index 6de04cb..bd77dfa 100644 --- a/src/InternshipSystem.Core/InternshipSystem.Core.csproj +++ b/src/InternshipSystem.Core/InternshipSystem.Core.csproj @@ -5,4 +5,8 @@ latest + + + +