diff --git a/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs b/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs index c2b359db..2a728bd5 100644 --- a/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs +++ b/AsbCloudInfrastructure/Repository/SetpointsRequestRepository.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; using System.Linq; +using AsbCloudApp.Exceptions; namespace AsbCloudInfrastructure.Repository { @@ -23,28 +24,37 @@ namespace AsbCloudInfrastructure.Repository this.wellService = wellService; } + //TODO: заметка для рефакторинга. Использовать метод из базового репозитория public virtual async Task UpdateRangeAsync(IEnumerable dtos, CancellationToken token) { - var ids = dtos.Select(d => d.Id); - var existingEntities = await dbSet - .AsNoTracking() - .Where(d => ids.Contains(d.Id)) - .Select(d => d.Id) - .ToListAsync(token) - .ConfigureAwait(false); + if (!dtos.Any()) + return 0; + + var ids = dtos + .Select(o => o.Id) + .Distinct() + .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() + .Where(o => ids.Contains(o.Id)) + .CountAsync(token); + + if (ids.Length != existingEntitiesCount) + throw new ArgumentInvalidException(nameof(dtos), "Все записи должны существовать в БД"); - if (ids.Count() > existingEntities.Count) - return ICrudRepository.ErrorIdNotFound; - - foreach (var dto in dtos) - { - var entity = Convert(dto); - var entry = dbSet.Update(entity); - entry.State = EntityState.Detached; - } + var entities = dtos.Select(Convert); + var entries = entities.Select(entity => dbContext.Set().Update(entity)).ToList(); var affected = await dbContext.SaveChangesAsync(token); + entries.ForEach(entry => entry.State = EntityState.Detached); + if(affected > 0) DropCache(); diff --git a/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs b/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs index 383c587f..e68eeef3 100644 --- a/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/SetpointsService.cs @@ -62,15 +62,14 @@ namespace AsbCloudInfrastructure.Services.SAUB var filtered = all.Where(s => s.IdWell == idWell && s.IdState == 1 && - s.UploadDate.AddSeconds(s.ObsolescenceSec) > DateTime.UtcNow); + s.UploadDate.AddSeconds(s.ObsolescenceSec).UtcDateTime > DateTime.UtcNow) + .ToArray(); if (!filtered.Any()) return Enumerable.Empty(); foreach (var item in filtered) - { item.IdState = 2; - } await setpointsRepository.UpdateRangeAsync(filtered, token); diff --git a/AsbCloudWebApi.IntegrationTests/Clients/ISetpointsClient.cs b/AsbCloudWebApi.IntegrationTests/Clients/ISetpointsClient.cs new file mode 100644 index 00000000..c8e6e523 --- /dev/null +++ b/AsbCloudWebApi.IntegrationTests/Clients/ISetpointsClient.cs @@ -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>> GetByTelemetryUidAsync(string uid); +} \ No newline at end of file diff --git a/AsbCloudWebApi.IntegrationTests/Controllers/SetpointsControllerTest.cs b/AsbCloudWebApi.IntegrationTests/Controllers/SetpointsControllerTest.cs new file mode 100644 index 00000000..d73148de --- /dev/null +++ b/AsbCloudWebApi.IntegrationTests/Controllers/SetpointsControllerTest.cs @@ -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(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); + } +} \ No newline at end of file