Merge branch 'dev' into fix/well-composite-duration-hours

This commit is contained in:
on.nemtina 2024-04-19 12:36:45 +05:00
commit 4ebb17b963
7 changed files with 121 additions and 40 deletions

View File

@ -52,6 +52,11 @@ namespace AsbCloudInfrastructure
{ {
public static void MapsterSetup() public static void MapsterSetup()
{ {
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<SetpointsRequestDto, SetpointsRequest>()
.Ignore(source => source.Author)
.Ignore(source => source.Well);
TypeAdapterConfig.GlobalSettings.Default.Config TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<DetectedOperationDto, DetectedOperation>() .ForType<DetectedOperationDto, DetectedOperation>()
.Ignore(source => source.OperationCategory); .Ignore(source => source.OperationCategory);

View File

@ -53,7 +53,7 @@ namespace AsbCloudInfrastructure.Repository
cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence; cacheEntry.AbsoluteExpirationRelativeToNow = CacheObsolescence;
cacheEntry.SlidingExpiration = CacheObsolescence; cacheEntry.SlidingExpiration = CacheObsolescence;
var entities = await this.GetQuery().ToArrayAsync(token); var entities = await GetQuery().AsNoTracking().ToArrayAsync(token);
cacheEntry.Value = entities; cacheEntry.Value = entities;
return entities.AsEnumerable(); return entities.AsEnumerable();
}); });

View File

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading; using System.Threading;
using System.Linq; using System.Linq;
using AsbCloudApp.Exceptions;
namespace AsbCloudInfrastructure.Repository namespace AsbCloudInfrastructure.Repository
{ {
@ -23,26 +24,40 @@ namespace AsbCloudInfrastructure.Repository
this.wellService = wellService; this.wellService = wellService;
} }
//TODO: заметка для рефакторинга. Использовать метод из базового репозитория
public virtual async Task<int> UpdateRangeAsync(IEnumerable<SetpointsRequestDto> dtos, CancellationToken token) public virtual async Task<int> UpdateRangeAsync(IEnumerable<SetpointsRequestDto> dtos, CancellationToken token)
{ {
var ids = dtos.Select(d => d.Id); if (!dtos.Any())
var existingEntities = await dbSet return 0;
.AsNoTracking()
.Where(d => ids.Contains(d.Id)) var ids = dtos
.Select(d => d.Id) .Select(o => o.Id)
.ToListAsync(token) .Distinct()
.ConfigureAwait(false); .ToArray();
if (ids.Any(id => id == default))
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь Id");
if (ids.Length != dtos.Count())
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны иметь уникальные Id");
var existingEntitiesCount = await dbContext.Set<SetpointsRequest>()
.Where(o => ids.Contains(o.Id))
.CountAsync(token);
if (ids.Length != existingEntitiesCount)
throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД");
if (ids.Count() > existingEntities.Count) var entities = dtos.Select(Convert);
return ICrudRepository<SetpointsRequestDto>.ErrorIdNotFound; var entries = entities.Select(entity => dbContext.Set<SetpointsRequest>().Update(entity)).ToList();
foreach (var dto in dtos)
{
var entity = Convert(dto);
var entry = dbSet.Update(entity);
}
var affected = await dbContext.SaveChangesAsync(token); var affected = await dbContext.SaveChangesAsync(token);
entries.ForEach(entry => entry.State = EntityState.Detached);
if(affected > 0)
DropCache();
return affected; return affected;
} }

View File

@ -2,7 +2,6 @@
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Repository;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -62,17 +61,15 @@ namespace AsbCloudInfrastructure.Services.SAUB
var all = await setpointsRepository.GetAllAsync(token); var all = await setpointsRepository.GetAllAsync(token);
var filtered = all.Where(s => var filtered = all.Where(s =>
s.IdWell == idWell && s.IdWell == idWell &&
s.IdState == 1 && s.IdState == 1 &&
s.UploadDate.AddSeconds(s.ObsolescenceSec) > DateTime.UtcNow) s.UploadDate.AddSeconds(s.ObsolescenceSec).UtcDateTime > DateTime.UtcNow)
.ToList(); .ToArray();
if (!filtered.Any()) if (!filtered.Any())
return Enumerable.Empty<SetpointsRequestDto>(); return Enumerable.Empty<SetpointsRequestDto>();
foreach (var item in filtered) foreach (var item in filtered)
{
item.IdState = 2; item.IdState = 2;
}
await setpointsRepository.UpdateRangeAsync(filtered, token); await setpointsRepository.UpdateRangeAsync(filtered, token);

View File

@ -0,0 +1,12 @@
using AsbCloudApp.Data.SAUB;
using Refit;
namespace AsbCloudWebApi.IntegrationTests.Clients;
public interface ISetpointsClient
{
private const string BaseRoute = "/api/telemetry/{uid}/Setpoints";
[Get(BaseRoute)]
Task<IApiResponse<IEnumerable<SetpointsRequestDto>>> GetByTelemetryUidAsync(string uid);
}

View File

@ -0,0 +1,53 @@
using System.Net;
using AsbCloudDb.Model;
using AsbCloudWebApi.IntegrationTests.Clients;
using Microsoft.EntityFrameworkCore;
using Xunit;
namespace AsbCloudWebApi.IntegrationTests.Controllers;
public class SetpointsControllerTest : BaseIntegrationTest
{
private readonly ISetpointsClient client;
public SetpointsControllerTest(WebAppFactoryFixture factory)
: base(factory)
{
client = factory.GetAuthorizedHttpClient<ISetpointsClient>(string.Empty);
}
[Fact]
public async Task GetByTelemetryUidAsync_returns_success()
{
//arrange
var well = await dbContext.Wells
.Include(w => w.Telemetry)
.FirstAsync();
var entity = new SetpointsRequest
{
IdWell = well.Id,
UploadDate = DateTimeOffset.UtcNow,
ObsolescenceSec = 15,
IdState = 1,
IdAuthor = 1
};
var entry = dbContext.SetpointsRequests.Add(entity);
await dbContext.SaveChangesAsync();
entry.State = EntityState.Detached;
//act
var response = await client.GetByTelemetryUidAsync(well.Telemetry!.RemoteUid);
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
Assert.Single(response.Content);
var setpoints = await dbContext.SetpointsRequests.ToArrayAsync();
foreach (var setpoint in setpoints)
Assert.Equal(2, setpoint.IdState);
}
}

View File

@ -26,9 +26,7 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
= Substitute.For<IWellOperationRepository>(); = Substitute.For<IWellOperationRepository>();
private IWellService wellService private IWellService wellService
= Substitute.For<IWellService>(); = Substitute.For<IWellService>();
private List<int> idsWells;
private readonly static IEnumerable<WellOperationCategoryDto> operationCategories = new List<WellOperationCategoryDto>() private readonly static IEnumerable<WellOperationCategoryDto> operationCategories = new List<WellOperationCategoryDto>()
{ {
new(){Id = 5096, Name = "Шаблонирование перед спуском"}, new(){Id = 5096, Name = "Шаблонирование перед спуском"},
@ -47,6 +45,12 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
new() {Id = 31, Caption = "Техническая колонна", Order = 2} new() {Id = 31, Caption = "Техническая колонна", Order = 2}
}; };
private readonly static IEnumerable<WellDto> wells = new List<WellDto>()
{
new() {Id = 55, Caption = "Скважина с ключом 55"},
new() {Id = 64, Caption = "Скважина с ключом 64"},
};
private readonly static IEnumerable<WellOperationDto> wellOperations1 = new List<WellOperationDto>() private readonly static IEnumerable<WellOperationDto> wellOperations1 = new List<WellOperationDto>()
{ {
new() new()
@ -162,6 +166,11 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
wellOperationCategoryRepository.Get(Arg.Any<bool>()) wellOperationCategoryRepository.Get(Arg.Any<bool>())
.Returns(operationCategories); .Returns(operationCategories);
idsWells = new List<int>() { 55, 64 };
wellService.GetAsync(Arg.Any<WellRequest>(), Arg.Any<CancellationToken>())
.Returns(wells);
service = new WellCompositeOperationService( service = new WellCompositeOperationService(
wellSectionTypeRepository, wellSectionTypeRepository,
wellOperationCategoryRepository, wellOperationCategoryRepository,
@ -182,10 +191,8 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>()) wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.Returns(wellOperations1); .Returns(wellOperations1);
var idsWell = new List<int>() { 55, 64 };
// act // act
var result = await service.GetAsync(idsWell, CancellationToken.None); var result = await service.GetAsync(idsWells, CancellationToken.None);
// assert // assert
var compositeWellOperations = result.WellOperationsComposite; var compositeWellOperations = result.WellOperationsComposite;
@ -211,10 +218,8 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>()) wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.Returns(wellOperations2); .Returns(wellOperations2);
var idsWell = new List<int>() { 55, 64 };
// act // act
var result = await service.GetAsync(idsWell, CancellationToken.None); var result = await service.GetAsync(idsWells, CancellationToken.None);
// assert // assert
var compositeWellOperations = result.WellOperationsComposite; var compositeWellOperations = result.WellOperationsComposite;
@ -237,10 +242,8 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>()) wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.Returns(wellOperations3); .Returns(wellOperations3);
var idsWell = new List<int>() { 55, 64 };
// act // act
var result = await service.GetAsync(idsWell, CancellationToken.None); var result = await service.GetAsync(idsWells, CancellationToken.None);
// assert // assert
var compositeWellOperations = result.WellOperationsComposite; var compositeWellOperations = result.WellOperationsComposite;
@ -265,10 +268,8 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>()) wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.Returns(wellOperations4); .Returns(wellOperations4);
var idsWell = new List<int>() { 55, 64 };
// act // act
var result = await service.GetAsync(idsWell, CancellationToken.None); var result = await service.GetAsync(idsWells, CancellationToken.None);
// assert // assert
var compositeWellOperations = result.WellOperationsComposite; var compositeWellOperations = result.WellOperationsComposite;
@ -297,10 +298,8 @@ namespace AsbCloudWebApi.Tests.Services.WellCompositeOperation
wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>()) wellOperationRepository.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.Returns(wellOperations); .Returns(wellOperations);
var idsWell = new List<int>() { 55, 64 };
// act // act
var result = await service.GetAsync(idsWell, CancellationToken.None); var result = await service.GetAsync(idsWells, CancellationToken.None);
// assert // assert
var wellOperationsCount = result.WellCompositeSourceOperations var wellOperationsCount = result.WellCompositeSourceOperations