Правки после ревью

This commit is contained in:
Степанов Дмитрий 2023-12-13 18:06:48 +05:00
parent f7ac9f0ccd
commit 38a852ace0
15 changed files with 158 additions and 328 deletions

View File

@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Data.WellSections; namespace AsbCloudApp.Data.ProcessMaps;
/// <summary> /// <summary>
/// Секция скважины - план /// Секция скважины - план
@ -28,26 +28,26 @@ public class WellSectionPlanDto : ItemInfoDto,
/// Начальная глубина бурения, м /// Начальная глубина бурения, м
/// </summary> /// </summary>
[Required(ErrorMessage = "Поле обязательно для заполнение")] [Required(ErrorMessage = "Поле обязательно для заполнение")]
[Range(0, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")] [Range(0, 10000, ErrorMessage = "Допустимое значение от 0 до 10000")]
public double DepthStart { get; set; } public double DepthStart { get; set; }
/// <summary> /// <summary>
/// Конечная глубина бурения, м /// Конечная глубина бурения, м
/// </summary> /// </summary>
[Required(ErrorMessage = "Поле обязательно для заполнение")] [Required(ErrorMessage = "Поле обязательно для заполнение")]
[Range(0, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")] [Range(0, 10000, ErrorMessage = "Допустимое значение от 0 до 10000")]
public double DepthEnd { get; set; } public double DepthEnd { get; set; }
/// <summary> /// <summary>
/// Внешний диаметр /// Внешний диаметр
/// </summary> /// </summary>
[Range(0, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")] [Range(1, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")]
public double? OuterDiameter { get; set; } public double? OuterDiameter { get; set; }
/// <summary> /// <summary>
/// Внутренний диаметр /// Внутренний диаметр
/// </summary> /// </summary>
[Range(0, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")] [Range(1, 10000, ErrorMessage = "Допустимое значение от 1 до 10000")]
public double? InnerDiameter { get; set; } public double? InnerDiameter { get; set; }
/// <inheritdoc /> /// <inheritdoc />
@ -65,9 +65,5 @@ public class WellSectionPlanDto : ItemInfoDto,
if (OuterDiameter <= InnerDiameter) if (OuterDiameter <= InnerDiameter)
yield return new ValidationResult("Внешний диаметр не должен быть больше или равен внутреннему", yield return new ValidationResult("Внешний диаметр не должен быть больше или равен внутреннему",
new[] { nameof(OuterDiameter) }); new[] { nameof(OuterDiameter) });
if (InnerDiameter >= OuterDiameter)
yield return new ValidationResult("Внутренний диаметр не должен больше или равен внутреннему",
new[] { nameof(InnerDiameter) });
} }
} }

View File

@ -1,6 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace AsbCloudApp.Services; namespace AsbCloudApp.Data;
/// <summary> /// <summary>
/// Результат валидации объекта /// Результат валидации объекта
@ -11,7 +13,7 @@ public class ValidationResultDto<T>
/// <summary> /// <summary>
/// Флаг валидности /// Флаг валидности
/// </summary> /// </summary>
public bool IsValid { get; set; } public bool IsValid => !Warnings.Any();
/// <summary> /// <summary>
/// Объект валидации /// Объект валидации
@ -21,5 +23,5 @@ public class ValidationResultDto<T>
/// <summary> /// <summary>
/// Предупреждения /// Предупреждения
/// </summary> /// </summary>
public IEnumerable<string>? Warnings { get; set; } public IEnumerable<ValidationResult> Warnings { get; set; } = Enumerable.Empty<ValidationResult>();
} }

View File

@ -0,0 +1,22 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Services;
namespace AsbCloudApp.Repositories;
/// <summary>
/// Секция скважины - план
/// </summary>
public interface IWellSectionPlanRepository : IRepositoryWellRelated<WellSectionPlanDto>
{
/// <summary>
/// Получить типы секций
/// </summary>
/// <param name="idWell"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<WellSectionTypeDto>> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken);
}

View File

@ -1,6 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
namespace AsbCloudApp.Services.ProcessMaps; namespace AsbCloudApp.Services.ProcessMaps;
@ -12,7 +13,7 @@ public interface IProcessMapPlanService<T>
where T : ProcessMapPlanBaseDto where T : ProcessMapPlanBaseDto
{ {
/// <summary> /// <summary>
/// Получение РТК по скважине /// Получение РТК план по скважине
/// </summary> /// </summary>
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="cancellationToken"></param> /// <param name="cancellationToken"></param>

View File

@ -1,37 +0,0 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellSections;
namespace AsbCloudApp.Services.WellSections;
/// <summary>
/// Секция скважины - план
/// </summary>
public interface IWellSectionPlanService
{
/// <summary>
/// Добавить секцию
/// </summary>
/// <param name="wellSectionPlan"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<int> InsertAsync(WellSectionPlanDto wellSectionPlan, CancellationToken cancellationToken);
/// <summary>
/// Обновить секцию
/// </summary>
/// <param name="wellSectionPlan"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<int> UpdateAsync(WellSectionPlanDto wellSectionPlan, CancellationToken cancellationToken);
/// <summary>
/// Получить типы секций
/// </summary>
/// <param name="idWell"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IEnumerable<WellSectionTypeDto>> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken);
}

View File

@ -64,6 +64,8 @@ namespace AsbCloudDb.Model
public virtual DbSet<TelemetryWirelineRunOut> TelemetryWirelineRunOut => Set<TelemetryWirelineRunOut>(); public virtual DbSet<TelemetryWirelineRunOut> TelemetryWirelineRunOut => Set<TelemetryWirelineRunOut>();
public virtual DbSet<TrajectoryFact> TrajectoriesFact => Set<TrajectoryFact>(); public virtual DbSet<TrajectoryFact> TrajectoriesFact => Set<TrajectoryFact>();
public virtual DbSet<WellSectionPlan> WellSectionsPlan => Set<WellSectionPlan>();
// GTR WITS // GTR WITS
public DbSet<WitsItemFloat> WitsItemFloat => Set<WitsItemFloat>(); public DbSet<WitsItemFloat> WitsItemFloat => Set<WitsItemFloat>();
public DbSet<WitsItemInt> WitsItemInt => Set<WitsItemInt>(); public DbSet<WitsItemInt> WitsItemInt => Set<WitsItemInt>();
@ -87,7 +89,7 @@ namespace AsbCloudDb.Model
public DbSet<Manual> Manuals => Set<Manual>(); public DbSet<Manual> Manuals => Set<Manual>();
public DbSet<ManualDirectory> ManualDirectories => Set<ManualDirectory>(); public DbSet<ManualDirectory> ManualDirectories => Set<ManualDirectory>();
public DbSet<Contact> Contacts => Set<Contact>(); public DbSet<Contact> Contacts => Set<Contact>();
public DbSet<WellSectionPlan> PlanWellSections => Set<WellSectionPlan>(); public DbSet<WellSectionPlan> WellSectionPlans => Set<WellSectionPlan>();
public DbSet<DrillTest> DrillTests => Set<DrillTest>(); public DbSet<DrillTest> DrillTests => Set<DrillTest>();
public AsbCloudDbContext() : base() public AsbCloudDbContext() : base()

View File

@ -81,7 +81,7 @@ namespace AsbCloudDb.Model
DbSet<Contact> Contacts { get; } DbSet<Contact> Contacts { get; }
DbSet<DrillTest> DrillTests { get; } DbSet<DrillTest> DrillTests { get; }
DbSet<TrajectoryFact> TrajectoriesFact { get; } DbSet<TrajectoryFact> TrajectoriesFact { get; }
DbSet<WellSectionPlan> PlanWellSections { get; } DbSet<WellSectionPlan> WellSectionsPlan { get; }
DatabaseFacade Database { get; } DatabaseFacade Database { get; }
Task<int> RefreshMaterializedViewAsync(string mwName, CancellationToken token); Task<int> RefreshMaterializedViewAsync(string mwName, CancellationToken token);

View File

@ -42,13 +42,10 @@ using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance; using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Data.WellSections;
using AsbCloudApp.Services.DailyReport; using AsbCloudApp.Services.DailyReport;
using AsbCloudApp.Services.WellSections;
using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance; using AsbCloudDb.Model.DailyReports.Blocks.TimeBalance;
using AsbCloudDb.Model.WellSections; using AsbCloudDb.Model.WellSections;
using AsbCloudInfrastructure.Services.ProcessMaps; using AsbCloudInfrastructure.Services.ProcessMaps;
using AsbCloudInfrastructure.Services.WellSections;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
@ -320,12 +317,13 @@ namespace AsbCloudInfrastructure
services.AddTransient<IDailyReportRepository, DailyReportRepository>(); services.AddTransient<IDailyReportRepository, DailyReportRepository>();
services.AddTransient<IDailyReportExportService, DailyReportExportService>(); services.AddTransient<IDailyReportExportService, DailyReportExportService>();
services.AddTransient<IWellSectionPlanService, WellSectionPlanService>();
services.AddTransient<IRepositoryWellRelated<WellSectionPlanDto>, CrudWellRelatedRepositoryBase<WellSectionPlanDto, WellSectionPlan>>(); services.AddTransient<IRepositoryWellRelated<WellSectionPlanDto>, CrudWellRelatedRepositoryBase<WellSectionPlanDto, WellSectionPlan>>();
services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellDrillingDto>, ProcessMapPlanService<ProcessMapPlanWellDrillingDto>>(); services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellDrillingDto>, ProcessMapPlanService<ProcessMapPlanWellDrillingDto>>();
services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellReamDto>, ProcessMapPlanService<ProcessMapPlanWellReamDto>>(); services.AddTransient<IProcessMapPlanService<ProcessMapPlanWellReamDto>, ProcessMapPlanService<ProcessMapPlanWellReamDto>>();
services.AddTransient<IWellSectionPlanRepository, WellSectionPlanRepository>();
return services; return services;
} }
} }

View File

@ -25,7 +25,7 @@ namespace AsbCloudInfrastructure.Repository
var entities = await GetQuery() var entities = await GetQuery()
.Where(e => e.IdWell == idWell) .Where(e => e.IdWell == idWell)
.AsNoTracking() .AsNoTracking()
.ToListAsync(token); .ToArrayAsync(token);
var dtos = entities.Select(Convert).ToList(); var dtos = entities.Select(Convert).ToList();
return dtos; return dtos;
} }
@ -38,7 +38,7 @@ namespace AsbCloudInfrastructure.Repository
var entities = await GetQuery() var entities = await GetQuery()
.Where(e => idsWells.Contains(e.IdWell)) .Where(e => idsWells.Contains(e.IdWell))
.AsNoTracking() .AsNoTracking()
.ToListAsync(token); .ToArrayAsync(token);
var dtos = entities.Select(Convert).ToList(); var dtos = entities.Select(Convert).ToList();
return dtos; return dtos;
} }

View File

@ -0,0 +1,85 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudDb.Model;
using AsbCloudDb.Model.WellSections;
using Mapster;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace AsbCloudInfrastructure.Repository;
public class WellSectionPlanRepository : CrudWellRelatedRepositoryBase<WellSectionPlanDto, WellSectionPlan>,
IWellSectionPlanRepository
{
public WellSectionPlanRepository(IAsbCloudDbContext context)
: base(context, query => query.Include(w => w.SectionType))
{
}
public override async Task<int> InsertAsync(WellSectionPlanDto item, CancellationToken token)
{
var id = 0;
try
{
id = await base.InsertAsync(item, token);
}
catch (DbUpdateException ex)
{
if (ex.InnerException is PostgresException pgException)
HandlePostgresException(pgException, item);
else
throw;
}
return id;
}
public override async Task<int> UpdateAsync(WellSectionPlanDto item, CancellationToken token)
{
var id = 0;
try
{
id = await base.UpdateAsync(item, token);
}
catch (DbUpdateException ex)
{
if (ex.InnerException is PostgresException pgException)
HandlePostgresException(pgException, item);
else
throw;
}
return id;
}
public async Task<IEnumerable<WellSectionTypeDto>> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken)
{
var query = from wellSectionType in dbContext.WellSectionTypes
join wellSectionPlan in dbContext.WellSectionsPlan on wellSectionType.Id equals wellSectionPlan.IdSectionType
orderby wellSectionType.Order
select wellSectionType;
IEnumerable<WellSectionType> entities = await query.ToArrayAsync(cancellationToken);
if (!entities.Any())
entities = await dbContext.WellSectionTypes.OrderBy(w => w.Order).ToArrayAsync(cancellationToken);
return entities.Select(w => w.Adapt<WellSectionTypeDto>());
}
private static void HandlePostgresException(PostgresException pgException, WellSectionPlanDto wellSectionPlan)
{
if (pgException.SqlState == PostgresErrorCodes.UniqueViolation)
throw new ArgumentInvalidException($"Секция уже добавлена в конструкцию скважины",
nameof(wellSectionPlan.IdSectionType));
}
}

View File

@ -1,10 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.WellSections;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps; using AsbCloudApp.Services.ProcessMaps;
@ -31,31 +31,32 @@ public class ProcessMapPlanService<T> : IProcessMapPlanService<T>
{ {
var wellSectionTypes = await wellSectionTypeRepository.GetAllAsync(cancellationToken); var wellSectionTypes = await wellSectionTypeRepository.GetAllAsync(cancellationToken);
var planProcessMaps = await processMapPlanRepository.GetByIdWellAsync(idWell, cancellationToken); var processMapsPlan = await processMapPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
var planWellSections = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken); var wellSectionsPlan = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
return planProcessMaps.Select(processMapPlan => return processMapsPlan.Select(processMapPlan =>
{ {
var planWellSection = planWellSections.SingleOrDefault(s => s.IdSectionType == processMapPlan.IdWellSectionType); var wellSectionPlan = wellSectionsPlan.FirstOrDefault(s => s.IdSectionType == processMapPlan.IdWellSectionType);
var isValid = planWellSection is not null && planWellSection.DepthStart <= processMapPlan.DepthStart && var isValid = wellSectionPlan is not null && wellSectionPlan.DepthStart <= processMapPlan.DepthStart &&
planWellSection.DepthEnd >= processMapPlan.DepthEnd; wellSectionPlan.DepthEnd >= processMapPlan.DepthEnd;
var validationResult = new ValidationResultDto<T> var validationResult = new ValidationResultDto<T>
{ {
IsValid = isValid,
Item = processMapPlan Item = processMapPlan
}; };
if (isValid) if (isValid)
return validationResult; return validationResult;
var wellSectionType = wellSectionTypes.SingleOrDefault(s => s.Id == processMapPlan.IdWellSectionType); var wellSectionType = wellSectionTypes.FirstOrDefault(s => s.Id == processMapPlan.IdWellSectionType);
validationResult.Warnings = new[] validationResult.Warnings = new ValidationResult[]
{ {
$"Конструкция секции: {wellSectionType?.Caption}; Интервал бурения от {processMapPlan.DepthStart} до {processMapPlan.DepthEnd} не совпадает с данными указанными на странице Конструкция скважины / План" new($"Конструкция секции: {wellSectionType?.Caption}; " +
$"Интервал бурения от {processMapPlan.DepthStart} до {processMapPlan.DepthEnd} не совпадает с данными указанными на странице " +
$"Конструкция скважины / План")
}; };
return validationResult; return validationResult;

View File

@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellSections;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services;
using AsbCloudApp.Services.WellSections;
namespace AsbCloudInfrastructure.Services.WellSections;
public class WellSectionPlanService : IWellSectionPlanService
{
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository;
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository;
public WellSectionPlanService(IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository,
ICrudRepository<WellSectionTypeDto> wellSectionTypeRepository)
{
this.wellSectionPlanRepository = wellSectionPlanRepository;
this.wellSectionTypeRepository = wellSectionTypeRepository;
}
public async Task<int> InsertAsync(WellSectionPlanDto wellSectionPlan, CancellationToken cancellationToken)
{
await EnsureUniqueSectionTypeInWellAsync(wellSectionPlan, cancellationToken);
return await wellSectionPlanRepository.InsertAsync(wellSectionPlan, cancellationToken);
}
public async Task<int> UpdateAsync(WellSectionPlanDto wellSectionPlan, CancellationToken cancellationToken)
{
await EnsureUniqueSectionTypeInWellAsync(wellSectionPlan, cancellationToken);
wellSectionPlan.LastUpdateDate = DateTime.UtcNow;
return await wellSectionPlanRepository.UpdateAsync(wellSectionPlan, cancellationToken);
}
public async Task<IEnumerable<WellSectionTypeDto>> GetWellSectionTypesAsync(int idWell, CancellationToken cancellationToken)
{
var wellSectionTypes = (await wellSectionTypeRepository.GetAllAsync(cancellationToken))
.OrderBy(w => w.Order);
var planWellSections = await wellSectionPlanRepository.GetByIdWellAsync(idWell, cancellationToken);
if (!planWellSections.Any())
return wellSectionTypes;
return wellSectionTypes.Where(w => planWellSections.Any(s => s.IdSectionType == w.Id));
}
private async Task EnsureUniqueSectionTypeInWellAsync(WellSectionPlanDto section, CancellationToken cancellationToken)
{
var existingWellSectionPlan = (await wellSectionPlanRepository.GetByIdWellAsync(section.IdWell, cancellationToken))
.SingleOrDefault(s => s.IdSectionType == section.IdSectionType);
if (existingWellSectionPlan is not null && existingWellSectionPlan.Id != section.Id)
{
var sectionType = await wellSectionTypeRepository.GetOrDefaultAsync(section.IdSectionType, cancellationToken);
throw new ArgumentInvalidException($"Секция '{sectionType?.Caption}' уже добавлена в конструкцию скважины",
nameof(section.IdSectionType));
}
}
}

View File

@ -4,7 +4,6 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.WellSections;
using AsbCloudApp.Repositories; using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.ProcessMaps; using AsbCloudInfrastructure.Services.ProcessMaps;

View File

@ -1,169 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellSections;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services;
using AsbCloudInfrastructure.Services.WellSections;
using NSubstitute;
using Xunit;
namespace AsbCloudWebApi.Tests.UnitTests.Services.WellSections;
public class WellSectionPlanServiceTests
{
private const int idWellSectionPlan = 1;
private const int idWell = 3;
private const int idWellSectionType = 54;
private readonly IEnumerable<WellSectionPlanDto> fakePlanWellSections = new WellSectionPlanDto[]
{
new()
{
Id = idWellSectionPlan,
IdWell = idWell,
IdSectionType = idWellSectionType
}
};
private readonly IEnumerable<WellSectionTypeDto> fakeWellSectionTypes = new WellSectionTypeDto[]
{
new()
{
Id = idWellSectionType
}
};
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepositoryMock =
Substitute.For<IRepositoryWellRelated<WellSectionPlanDto>>();
private readonly ICrudRepository<WellSectionTypeDto> wellSectionTypeRepositoryMock =
Substitute.For<ICrudRepository<WellSectionTypeDto>>();
private readonly WellSectionPlanService wellSectionPlanService;
public WellSectionPlanServiceTests()
{
wellSectionPlanService = new WellSectionPlanService(wellSectionPlanRepositoryMock, wellSectionTypeRepositoryMock);
wellSectionTypeRepositoryMock.GetAllAsync(Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeWellSectionTypes);
}
[Fact]
public async Task InsertAsync_InsertNewWellSectionTypeWithUniqueSectionTypeInWell_InvokesWellSectionPlanRepositoryInsertAsync()
{
//arrange
var insertedWellSection = new WellSectionPlanDto();
//act
await wellSectionPlanService.InsertAsync(insertedWellSection, CancellationToken.None);
//assert
await wellSectionPlanRepositoryMock.Received().InsertAsync(Arg.Any<WellSectionPlanDto>(), Arg.Any<CancellationToken>());
}
[Fact]
public async Task InsertAsync_InsertNewWellSectionTypeWithNotUniqueSectionTypeInWell_ReturnsDuplicateException()
{
//arrange
var insertedWellSection = new WellSectionPlanDto
{
Id = 2,
IdSectionType = idWellSectionType
};
wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakePlanWellSections);
//act
Task Result() => wellSectionPlanService.InsertAsync(insertedWellSection, CancellationToken.None);
//assert
await Assert.ThrowsAsync<ArgumentInvalidException>(Result);
}
[Fact]
public async Task UpdateAsync_UpdateExistingWellSectionTypeWithUniqueSectionTypeInWell_InvokesWellSectionPlanRepositoryUpdateAsync()
{
//arrange
var updatedWellSection = new WellSectionPlanDto
{
Id = idWellSectionPlan,
IdSectionType = idWellSectionType
};
//act
await wellSectionPlanService.UpdateAsync(updatedWellSection, CancellationToken.None);
//assert
await wellSectionPlanRepositoryMock.Received().UpdateAsync(Arg.Any<WellSectionPlanDto>(), Arg.Any<CancellationToken>());
}
[Fact]
public async Task UpdateAsync_ReturnsLastUpdateDateNotNull()
{
//arrange
var updatedWellSection = new WellSectionPlanDto
{
Id = idWellSectionPlan,
IdSectionType = idWellSectionType
};
//act
await wellSectionPlanService.UpdateAsync(updatedWellSection, CancellationToken.None);
//assert
Assert.NotNull(updatedWellSection.LastUpdateDate);
}
[Fact]
public async Task UpdateAsync_UpdateExistingWellSectionTypeWithNotUniqueSectionTypeInWell_ReturnsDuplicateException()
{
//arrange
var updatedWellSection = new WellSectionPlanDto
{
Id = 2,
IdSectionType = idWellSectionType
};
wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakePlanWellSections);
//act
Task Result() => wellSectionPlanService.UpdateAsync(updatedWellSection, CancellationToken.None);
//assert
await Assert.ThrowsAsync<ArgumentInvalidException>(Result);
}
[Fact]
public async Task GetWellSectionTypesAsync_EmptyCollectionWellSectionPlan_ReturnsCollectionWellSectionType()
{
//arrange
wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(Enumerable.Empty<WellSectionPlanDto>());
//act
var result = await wellSectionPlanService.GetWellSectionTypesAsync(idWell, CancellationToken.None);
//assert
Assert.Single(result);
}
[Fact]
public async Task GetWellSectionTypesAsync_NotEmptyCollectionWellSectionPlan_ReturnsCollectionWellSectionType()
{
//arrange
wellSectionPlanRepositoryMock.GetByIdWellAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakePlanWellSections);
//act
var result = await wellSectionPlanService.GetWellSectionTypesAsync(idWell, CancellationToken.None);
//assert
Assert.Single(result);
}
}

View File

@ -1,18 +1,18 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.ProcessMaps;
using AsbCloudApp.Data.WellSections;
using AsbCloudApp.Exceptions; using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudApp.Services.WellSections;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace AsbCloudWebApi.Controllers.WellSections; namespace AsbCloudWebApi.Controllers.ProcessMaps;
/// <summary> /// <summary>
/// Конструкция скважины - план /// Конструкция скважины - план
@ -22,20 +22,17 @@ namespace AsbCloudWebApi.Controllers.WellSections;
[Authorize] [Authorize]
public class WellSectionPlanController : ControllerBase public class WellSectionPlanController : ControllerBase
{ {
private readonly IWellSectionPlanService wellSectionPlanService;
private readonly IWellService wellService; private readonly IWellService wellService;
private readonly IWellSectionPlanRepository wellSectionPlanRepository;
private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository; private readonly ICrudRepository<WellSectionTypeDto> wellSectionRepository;
private readonly IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository;
public WellSectionPlanController(IWellSectionPlanService wellSectionPlanService, public WellSectionPlanController(IWellService wellService,
IWellService wellService, IWellSectionPlanRepository wellSectionPlanRepository,
ICrudRepository<WellSectionTypeDto> wellSectionRepository, ICrudRepository<WellSectionTypeDto> wellSectionRepository)
IRepositoryWellRelated<WellSectionPlanDto> wellSectionPlanRepository)
{ {
this.wellSectionPlanService = wellSectionPlanService;
this.wellService = wellService; this.wellService = wellService;
this.wellSectionRepository = wellSectionRepository;
this.wellSectionPlanRepository = wellSectionPlanRepository; this.wellSectionPlanRepository = wellSectionPlanRepository;
this.wellSectionRepository = wellSectionRepository;
} }
//TODO: так же следует вынести в базовый контроллер //TODO: так же следует вынести в базовый контроллер
@ -73,7 +70,7 @@ public class WellSectionPlanController : ControllerBase
await AssertUserAccessToWell(idWell, cancellationToken); await AssertUserAccessToWell(idWell, cancellationToken);
var wellSectionId = await wellSectionPlanService.InsertAsync(wellSection, cancellationToken); var wellSectionId = await wellSectionPlanRepository.InsertAsync(wellSection, cancellationToken);
return Ok(wellSectionId); return Ok(wellSectionId);
} }
@ -94,12 +91,13 @@ public class WellSectionPlanController : ControllerBase
{ {
wellSection.IdWell = idWell; wellSection.IdWell = idWell;
wellSection.IdUser = IdUser; wellSection.IdUser = IdUser;
wellSection.LastUpdateDate = DateTimeOffset.UtcNow;
await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken); await CheckIsExistsWellSectionTypeAsync(wellSection.IdSectionType, cancellationToken);
await AssertUserAccessToWell(idWell, cancellationToken); await AssertUserAccessToWell(idWell, cancellationToken);
var wellSectionId = await wellSectionPlanService.UpdateAsync(wellSection, cancellationToken); var wellSectionId = await wellSectionPlanRepository.UpdateAsync(wellSection, cancellationToken);
if (wellSectionId == ICrudRepository<WellSectionPlanDto>.ErrorIdNotFound) if (wellSectionId == ICrudRepository<WellSectionPlanDto>.ErrorIdNotFound)
return this.ValidationBadRequest(nameof(wellSection.Id), $"Секции скважины с Id: {wellSection.Id} не существует"); return this.ValidationBadRequest(nameof(wellSection.Id), $"Секции скважины с Id: {wellSection.Id} не существует");
@ -121,7 +119,7 @@ public class WellSectionPlanController : ControllerBase
{ {
await AssertUserAccessToWell(idWell, cancellationToken); await AssertUserAccessToWell(idWell, cancellationToken);
var wellSectionTypes = await wellSectionPlanService.GetWellSectionTypesAsync(idWell, cancellationToken); var wellSectionTypes = await wellSectionPlanRepository.GetWellSectionTypesAsync(idWell, cancellationToken);
if (!wellSectionTypes.Any()) if (!wellSectionTypes.Any())
return NoContent(); return NoContent();