From a9c8fa98abeb968cfecbe4feb95290ede977b146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Mon, 4 Dec 2023 17:09:58 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B2=D0=B8=D1=81=20=D0=A0?= =?UTF-8?q?=D0=A2=D0=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ProcessMaps/IProcessMapPlanService.cs | 21 ++++ AsbCloudApp/Services/ValidationResultDto.cs | 25 +++++ .../ProcessMaps/ProcessMapPlanService.cs | 64 +++++++++++++ .../ProcessMaps/ProcessMapPlanServiceTests.cs | 95 +++++++++++++++++++ 4 files changed, 205 insertions(+) create mode 100644 AsbCloudApp/Services/ProcessMaps/IProcessMapPlanService.cs create mode 100644 AsbCloudApp/Services/ValidationResultDto.cs create mode 100644 AsbCloudInfrastructure/Services/ProcessMaps/ProcessMapPlanService.cs create mode 100644 AsbCloudWebApi.Tests/UnitTests/Services/ProcessMaps/ProcessMapPlanServiceTests.cs diff --git a/AsbCloudApp/Services/ProcessMaps/IProcessMapPlanService.cs b/AsbCloudApp/Services/ProcessMaps/IProcessMapPlanService.cs new file mode 100644 index 00000000..17273321 --- /dev/null +++ b/AsbCloudApp/Services/ProcessMaps/IProcessMapPlanService.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.ProcessMaps; + +namespace AsbCloudApp.Services.ProcessMaps; + +/// +/// РТК +/// +public interface IProcessMapPlanService + where T : ProcessMapPlanBaseDto +{ + /// + /// Получение РТК по скважине + /// + /// + /// + /// + Task>> GetAsync(int idWell, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/AsbCloudApp/Services/ValidationResultDto.cs b/AsbCloudApp/Services/ValidationResultDto.cs new file mode 100644 index 00000000..a15ab9e5 --- /dev/null +++ b/AsbCloudApp/Services/ValidationResultDto.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Services; + +/// +/// Результат валидации объекта +/// +public class ValidationResultDto + where T : class +{ + /// + /// Флаг валидности + /// + public bool IsValid { get; set; } + + /// + /// Объект валидации + /// + public T Item { get; set; } = null!; + + /// + /// Предупреждения + /// + public IEnumerable? Warnings { get; set; } +} \ No newline at end of file diff --git a/AsbCloudInfrastructure/Services/ProcessMaps/ProcessMapPlanService.cs b/AsbCloudInfrastructure/Services/ProcessMaps/ProcessMapPlanService.cs new file mode 100644 index 00000000..58d101ed --- /dev/null +++ b/AsbCloudInfrastructure/Services/ProcessMaps/ProcessMapPlanService.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Data.WellSections; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using AsbCloudApp.Services.ProcessMaps; + +namespace AsbCloudInfrastructure.Services.ProcessMaps; + +public class ProcessMapPlanService : IProcessMapPlanService + where T : ProcessMapPlanBaseDto +{ + private readonly ICrudRepository wellSectionTypeRepository; + private readonly IProcessMapPlanRepository processMapPlanRepository; + private readonly IRepositoryWellRelated wellSectionPlanRepository; + + public ProcessMapPlanService(ICrudRepository wellSectionTypeRepository, + IProcessMapPlanRepository processMapPlanRepository, + IRepositoryWellRelated wellSectionPlanRepository) + { + this.wellSectionTypeRepository = wellSectionTypeRepository; + this.processMapPlanRepository = processMapPlanRepository; + this.wellSectionPlanRepository = wellSectionPlanRepository; + } + + public async Task>> GetAsync(int idWell, CancellationToken cancellationToken) + { + var wellSectionTypes = await wellSectionTypeRepository.GetAllAsync(cancellationToken); + + var planProcessMaps = await processMapPlanRepository.GetByIdWellAsync(idWell, cancellationToken); + + var planWellSections = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken); + + return planProcessMaps.Select(processMapPlan => + { + var planWellSection = planWellSections.SingleOrDefault(s => s.IdSectionType == processMapPlan.IdWellSectionType); + + var isValid = planWellSection is not null && planWellSection.DepthStart <= processMapPlan.DepthStart && + planWellSection.DepthEnd >= processMapPlan.DepthEnd; + + var validationResult = new ValidationResultDto + { + IsValid = isValid, + Item = processMapPlan + }; + + if (isValid) + return validationResult; + + var wellSectionType = wellSectionTypes.SingleOrDefault(s => s.Id == processMapPlan.IdWellSectionType); + + validationResult.Warnings = new[] + { + $"Конструкция секции: {wellSectionType?.Caption}; Интервал бурения от {processMapPlan.DepthStart} до {processMapPlan.DepthEnd} не совпадает с данными указанными на странице Конструкция скважины / План" + }; + + return validationResult; + }); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi.Tests/UnitTests/Services/ProcessMaps/ProcessMapPlanServiceTests.cs b/AsbCloudWebApi.Tests/UnitTests/Services/ProcessMaps/ProcessMapPlanServiceTests.cs new file mode 100644 index 00000000..0981e29f --- /dev/null +++ b/AsbCloudWebApi.Tests/UnitTests/Services/ProcessMaps/ProcessMapPlanServiceTests.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Data.WellSections; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using AsbCloudInfrastructure.Services.ProcessMaps; +using NSubstitute; +using Xunit; + +namespace AsbCloudWebApi.Tests.UnitTests.Services.ProcessMaps; + +public class ProcessMapPlanServiceTests +{ + private const int idWellSectionPlan = 1; + private const int idWell = 3; + private const int idWellSectionType = 54; + + private readonly IEnumerable fakeCollectionWellSectionPlan = new WellSectionPlanDto[] + { + new() + { + Id = idWellSectionPlan, + IdWell = idWell, + IdSectionType = idWellSectionType, + DepthStart = 80, + DepthEnd = 150 + } + }; + + private readonly IEnumerable fakeCollectionWellSectionTypes = new WellSectionTypeDto[] + { + new() + { + Id = idWellSectionType, + Caption = "Направление 1", + Order = 1 + } + }; + + private readonly ICrudRepository wellSectionTypeRepositoryMock = + Substitute.For>(); + + private readonly IProcessMapPlanRepository processMapPlanRepositoryMock = + Substitute.For>(); + + private readonly IRepositoryWellRelated wellSectionPlanRepositoryMock = + Substitute.For>(); + + private readonly ProcessMapPlanService processMapPlanService; + + public ProcessMapPlanServiceTests() + { + processMapPlanService = new ProcessMapPlanService(wellSectionTypeRepositoryMock, + processMapPlanRepositoryMock, wellSectionPlanRepositoryMock); + + wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(fakeCollectionWellSectionPlan); + + wellSectionTypeRepositoryMock.GetAllAsync(Arg.Any()) + .ReturnsForAnyArgs(fakeCollectionWellSectionTypes); + } + + [Theory] + [InlineData(80, 150, true)] + [InlineData(90, 140, true)] + [InlineData(0, 110, false)] + [InlineData(110, 200, false)] + public async Task GetAsync_ReturnsValidatedCollectionProcessMapPlanWellDrilling(int depthStart, int depthEnd, bool isValidCollection) + { + //arrange + var fakeCollectionProcessMapPlanWellDrilling = new ProcessMapPlanWellDrillingDto[] + { + new() + { + IdWellSectionType = idWellSectionType, + DepthStart = depthStart, + DepthEnd = depthEnd + } + }; + + processMapPlanRepositoryMock.GetByIdWellAsync(Arg.Any(), Arg.Any()) + .ReturnsForAnyArgs(fakeCollectionProcessMapPlanWellDrilling); + + //act + var result = (await processMapPlanService.GetAsync(idWell, CancellationToken.None)).ToArray(); + + //assert + Assert.Equal(isValidCollection, result.All(r => r.IsValid)); + Assert.Single(result); + } +} \ No newline at end of file