From d746f85fe4c223dfac7689a875a1f8d5f452710f Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 18 Nov 2024 09:39:24 +0500 Subject: [PATCH 1/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20Setpoint=20API=20=D0=B8=20=D1=80=D0=B5=D0=BF=D0=BE?= =?UTF-8?q?=D0=B7=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/SetpointController.cs | 48 +++++++++++++ .../Model/IPersistenceDbContext.cs | 3 +- Persistence.Database/Model/ISetpointData.cs | 10 +++ .../Model/PersistenceDbContext.cs | 15 ++-- Persistence.Database/Model/Setpoint.cs | 22 ++++++ .../Model/SetpointDictionary.cs | 18 +++++ Persistence.Repository/Data/SetpointDto.cs | 10 +++ Persistence.Repository/DependencyInjection.cs | 3 +- .../Repositories/SetpointRepository.cs | 70 +++++++++++++++++++ Persistence/Models/SetpointLogDto.cs | 2 +- Persistence/Models/SetpointValueDto.cs | 4 +- .../Repositories/ISetpointRepository.cs | 18 ++--- 12 files changed, 198 insertions(+), 25 deletions(-) create mode 100644 Persistence.API/Controllers/SetpointController.cs create mode 100644 Persistence.Database/Model/ISetpointData.cs create mode 100644 Persistence.Database/Model/Setpoint.cs create mode 100644 Persistence.Database/Model/SetpointDictionary.cs create mode 100644 Persistence.Repository/Data/SetpointDto.cs create mode 100644 Persistence.Repository/Repositories/SetpointRepository.cs diff --git a/Persistence.API/Controllers/SetpointController.cs b/Persistence.API/Controllers/SetpointController.cs new file mode 100644 index 0000000..3e8e94c --- /dev/null +++ b/Persistence.API/Controllers/SetpointController.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Mvc; +using Persistence.Models; +using Persistence.Repositories; + +namespace Persistence.API.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class SetpointController : ControllerBase, ISetpointApi + { + private readonly ISetpointRepository setpointRepository; + + public SetpointController(ISetpointRepository setpointRepository) + { + this.setpointRepository = setpointRepository; + } + + [HttpPost("current")] + public Task>> GetCurrentAsync(IEnumerable setpointKeys, CancellationToken token) + { + throw new NotImplementedException(); + } + + [HttpPost("history")] + public async Task>> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + { + var result = await setpointRepository.GetHistoryAsync(setpointKeys, historyMoment, token); + + return Ok(result); + } + + [HttpPost("log")] + public async Task>>> GetLogAsync([FromBody] IEnumerable setpointKeys, CancellationToken token) + { + var result = await setpointRepository.GetLogAsync(setpointKeys, token); + + return Ok(result); + } + + [HttpPost("save")] + public async Task> SaveAsync(Guid setpointKey, object newValue, CancellationToken token) + { + var result = await setpointRepository.SaveAsync(setpointKey, newValue, token); + + return Ok(result); + } + } +} diff --git a/Persistence.Database/Model/IPersistenceDbContext.cs b/Persistence.Database/Model/IPersistenceDbContext.cs index af837d6..2c1aebb 100644 --- a/Persistence.Database/Model/IPersistenceDbContext.cs +++ b/Persistence.Database/Model/IPersistenceDbContext.cs @@ -11,6 +11,7 @@ namespace Persistence.Database.Model; public interface IPersistenceDbContext : IDisposable { DbSet DataSaub { get; } - DatabaseFacade Database { get; } + DbSet Setpoint { get; } + DatabaseFacade Database { get; } Task SaveChangesAsync(CancellationToken cancellationToken); } diff --git a/Persistence.Database/Model/ISetpointData.cs b/Persistence.Database/Model/ISetpointData.cs new file mode 100644 index 0000000..630af70 --- /dev/null +++ b/Persistence.Database/Model/ISetpointData.cs @@ -0,0 +1,10 @@ +namespace Persistence.Database.Model +{ + public interface ISetpointData + { + public Guid Key { get; set; } + public object Value { get; set; } + public DateTimeOffset Created { get; set; } + public int IdUser { get; set; } + } +} diff --git a/Persistence.Database/Model/PersistenceDbContext.cs b/Persistence.Database/Model/PersistenceDbContext.cs index 3baf334..5f4b965 100644 --- a/Persistence.Database/Model/PersistenceDbContext.cs +++ b/Persistence.Database/Model/PersistenceDbContext.cs @@ -1,17 +1,16 @@ -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Diagnostics.Metrics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; +using Microsoft.EntityFrameworkCore; namespace Persistence.Database.Model; public partial class PersistenceDbContext : DbContext, IPersistenceDbContext { public DbSet DataSaub => Set(); + public DbSet Setpoint => Set(); + + public PersistenceDbContext() + { + } + public PersistenceDbContext(DbContextOptions options) { } diff --git a/Persistence.Database/Model/Setpoint.cs b/Persistence.Database/Model/Setpoint.cs new file mode 100644 index 0000000..50d7f24 --- /dev/null +++ b/Persistence.Database/Model/Setpoint.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Persistence.Database.Model +{ + [PrimaryKey(nameof(Key), nameof(Created))] + public class Setpoint : ISetpointData + { + [Comment("Ключ")] + public Guid Key { get; set; } + + [Column(TypeName = "jsonb"), Comment("Значение уставки")] + public required object Value { get; set; } + + [Comment("Дата изменения уставки")] + public DateTimeOffset Created { get; set; } + + [Comment("Id автора последнего изменения")] + public int IdUser { get; set; } + } +} diff --git a/Persistence.Database/Model/SetpointDictionary.cs b/Persistence.Database/Model/SetpointDictionary.cs new file mode 100644 index 0000000..cd20624 --- /dev/null +++ b/Persistence.Database/Model/SetpointDictionary.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Persistence.Database.Model +{ + public class SetpointDictionary + { + [Key, Comment("Ключ")] + public Guid Key { get; set; } + + [Comment("Наименование")] + public required string Name { get; set; } + + [Comment("Описание")] + public string? Description { get; set; } + } +} diff --git a/Persistence.Repository/Data/SetpointDto.cs b/Persistence.Repository/Data/SetpointDto.cs new file mode 100644 index 0000000..261b1bc --- /dev/null +++ b/Persistence.Repository/Data/SetpointDto.cs @@ -0,0 +1,10 @@ +namespace Persistence.Repository.Data +{ + public class SetpointDto + { + public int Id { get; set; } + public required object Value { get; set; } + public DateTimeOffset Edit { get; set; } + public int IdUser { get; set; } + } +} diff --git a/Persistence.Repository/DependencyInjection.cs b/Persistence.Repository/DependencyInjection.cs index 17904c8..e77edd0 100644 --- a/Persistence.Repository/DependencyInjection.cs +++ b/Persistence.Repository/DependencyInjection.cs @@ -21,9 +21,10 @@ public static class DependencyInjection services.AddDbContext(options => options.UseNpgsql(configuration.GetConnectionString(connectionStringName))); - services.AddScoped(provider => provider.GetRequiredService()); + services.AddScoped(provider => provider.GetRequiredService()); services.AddTransient, TimeSeriesDataRepository>(); + services.AddTransient(); return services; } diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs new file mode 100644 index 0000000..04304ce --- /dev/null +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -0,0 +1,70 @@ +using Mapster; +using Microsoft.EntityFrameworkCore; +using Persistence.Database.Model; +using Persistence.Models; +using Persistence.Repositories; + +namespace Persistence.Repository.Repositories +{ + public class SetpointRepository : ISetpointRepository + { + private DbContext db; + public SetpointRepository(DbContext db) + { + this.db = db; + } + + protected virtual IQueryable GetQueryReadOnly() => db.Set(); + + public async Task> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + { + var query = GetQueryReadOnly(); + var entities = await query + .Where(e => setpointKeys.Contains(e.Key) && e.Created.Date == historyMoment.Date) + .ToArrayAsync(token); + var dtos = entities.Select(e => e.Adapt()); + + return dtos; + } + + public async Task>> GetLogAsync(IEnumerable setpointKeys, CancellationToken token) + { + var query = GetQueryReadOnly(); + var entities = await query + .Where(e => setpointKeys.Contains(e.Key)) + .ToArrayAsync(token); + var dtos = entities + .GroupBy(e => e.Key) + .Select(e => new KeyValuePair>( + e.Key, + e.Select(s => s.Adapt()) + )).ToDictionary(); + + return dtos; + } + + public async Task SaveAsync(Guid setpointKey, object newValue, CancellationToken token) + { + try + { + var entity = new Setpoint() + { + Key = setpointKey, + Value = newValue, + IdUser = 0, // ToDo: откуда тянуть? + Created = DateTimeOffset.Now.ToUniversalTime() + }; + + await db.Set().AddAsync(entity, token); + var result = await db.SaveChangesAsync(token); + + return result; + } + catch(Exception ex) + { + var t = ex.Message; + return 0; + } + } + } +} diff --git a/Persistence/Models/SetpointLogDto.cs b/Persistence/Models/SetpointLogDto.cs index 8c259ca..f825aae 100644 --- a/Persistence/Models/SetpointLogDto.cs +++ b/Persistence/Models/SetpointLogDto.cs @@ -7,6 +7,6 @@ using System.Threading.Tasks; namespace Persistence.Models; public class SetpointLogDto : SetpointValueDto { - public DateTimeOffset Edit { get; set; } + public DateTimeOffset Created { get; set; } public int IdUser { get; set; } } diff --git a/Persistence/Models/SetpointValueDto.cs b/Persistence/Models/SetpointValueDto.cs index 7b49143..ca43330 100644 --- a/Persistence/Models/SetpointValueDto.cs +++ b/Persistence/Models/SetpointValueDto.cs @@ -8,7 +8,7 @@ namespace Persistence.Models; public class SetpointValueDto { - public int Id { get; set; } - public object Value { get; set; } + public Guid Key { get; set; } + public required object Value { get; set; } } diff --git a/Persistence/Repositories/ISetpointRepository.cs b/Persistence/Repositories/ISetpointRepository.cs index 38bbbf4..d315725 100644 --- a/Persistence/Repositories/ISetpointRepository.cs +++ b/Persistence/Repositories/ISetpointRepository.cs @@ -1,10 +1,4 @@ -using Microsoft.AspNetCore.Mvc; -using Persistence.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Persistence.Models; namespace Persistence.Repositories; @@ -17,19 +11,19 @@ public interface ISetpointRepository /// /// Получить значения уставок за определенный момент времени /// - /// + /// /// дата, на которую получаем данные /// /// - Task> GetHistoryAsync(IEnumerable setpoitKeys, DateTimeOffset historyMoment, CancellationToken token); + Task> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token); /// /// Получить историю изменений значений уставок /// - /// + /// /// /// - Task>> GetLogAsync(IEnumerable setpoitKeys, CancellationToken token); + Task>> GetLogAsync(IEnumerable setpointKeys, CancellationToken token); /// /// Метод сохранения уставки @@ -41,5 +35,5 @@ public interface ISetpointRepository /// /// to do /// id User учесть в соответствующем методе репозитория - Task SaveAsync(Guid setpointKey, int idUser, object newValue, CancellationToken token); + Task SaveAsync(Guid setpointKey, object newValue, CancellationToken token); } From 90c62b9ede7a8799841fb7919ebc8e7e6d3c89d2 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 18 Nov 2024 11:32:57 +0500 Subject: [PATCH 2/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D1=82=D0=B5=D1=81=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20Setpoint=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BaseIntegrationTest.cs | 4 +- .../Clients/ISetpointClient.cs | 17 +++++ .../Controllers/SetpointControllerTest.cs | 75 +++++++++++++++++++ .../Persistence.IntegrationTests.csproj | 1 + .../WebAppFactoryFixture.cs | 3 +- .../Repositories/SetpointRepository.cs | 3 +- 6 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 Persistence.IntegrationTests/Clients/ISetpointClient.cs create mode 100644 Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs diff --git a/Persistence.IntegrationTests/BaseIntegrationTest.cs b/Persistence.IntegrationTests/BaseIntegrationTest.cs index a0edda9..8a8f764 100644 --- a/Persistence.IntegrationTests/BaseIntegrationTest.cs +++ b/Persistence.IntegrationTests/BaseIntegrationTest.cs @@ -17,9 +17,9 @@ public abstract class BaseIntegrationTest : IClassFixture, protected BaseIntegrationTest(WebAppFactoryFixture factory) { - //scope = factory.Services.CreateScope(); + scope = factory.Services.CreateScope(); - //dbContext = scope.ServiceProvider.GetRequiredService(); + dbContext = scope.ServiceProvider.GetRequiredService(); } public void Dispose() diff --git a/Persistence.IntegrationTests/Clients/ISetpointClient.cs b/Persistence.IntegrationTests/Clients/ISetpointClient.cs new file mode 100644 index 0000000..831f119 --- /dev/null +++ b/Persistence.IntegrationTests/Clients/ISetpointClient.cs @@ -0,0 +1,17 @@ +using Persistence.Models; +using Refit; + +namespace Persistence.IntegrationTests.Clients +{ + public interface ISetpointClient + { + [Post("/api/Setpoint/history")] + Task>> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment); + + [Post("/api/Setpoint/log")] + Task>>> GetLogAsync(IEnumerable setpoitKeys); + + [Post("/api/Setpoint/save")] + Task> SaveAsync(Guid setpointKey, object newValue); + } +} diff --git a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs new file mode 100644 index 0000000..b972c43 --- /dev/null +++ b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs @@ -0,0 +1,75 @@ +using System.Net; +using Persistence.IntegrationTests.Clients; +using Xunit; + +namespace Persistence.IntegrationTests.Controllers +{ + public class SetpointControllerTest : BaseIntegrationTest + { + private ISetpointClient client; + private class TestObject + { + public string? value1 { get; set; } + public int value2 { get; set; } + public double value3 { get; set; } + } + public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory) + { + client = factory.GetHttpClient(string.Empty); + } + + [Fact] + public async Task GetHistoryAsync_returns_success() + { + //arrange + var setpointKeys = new List() + { + Guid.NewGuid(), + Guid.NewGuid() + }; + var historyMoment = DateTimeOffset.Now.ToUniversalTime(); + + //act + var response = await client.GetHistoryAsync(setpointKeys, historyMoment); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Fact] + public async Task GetLogAsync_returns_success() + { + //arrange + var setpointKeys = new List() + { + Guid.NewGuid(), + Guid.NewGuid() + }; + + //act + var response = await client.GetLogAsync(setpointKeys); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Fact] + public async Task SaveAsync_returns_success() + { + //arrange + var setpointKey = Guid.NewGuid(); + var setpointValue = new TestObject() + { + value1 = "1", + value2 = 2, + value3 = 3.3 + }; + + //act + var response = await client.SaveAsync(setpointKey, setpointValue); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + } +} diff --git a/Persistence.IntegrationTests/Persistence.IntegrationTests.csproj b/Persistence.IntegrationTests/Persistence.IntegrationTests.csproj index 2b793de..912eeda 100644 --- a/Persistence.IntegrationTests/Persistence.IntegrationTests.csproj +++ b/Persistence.IntegrationTests/Persistence.IntegrationTests.csproj @@ -24,6 +24,7 @@ + diff --git a/Persistence.IntegrationTests/WebAppFactoryFixture.cs b/Persistence.IntegrationTests/WebAppFactoryFixture.cs index ea6016d..dd95ac0 100644 --- a/Persistence.IntegrationTests/WebAppFactoryFixture.cs +++ b/Persistence.IntegrationTests/WebAppFactoryFixture.cs @@ -8,6 +8,7 @@ using Persistence.API; using Refit; using System.Net.Http.Headers; using System.Text.Json; +using Persistence.Database.Postgres; namespace Persistence.IntegrationTests; public class WebAppFactoryFixture : WebApplicationFactory @@ -51,7 +52,7 @@ public class WebAppFactoryFixture : WebApplicationFactory var scopedServices = scope.ServiceProvider; var dbContext = scopedServices.GetRequiredService(); - //dbContext.Database.EnsureCreatedAndMigrated(); + dbContext.Database.EnsureCreatedAndMigrated(); //dbContext.Deposits.AddRange(Data.Defaults.Deposits); dbContext.SaveChanges(); }); diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs index 04304ce..ef346e6 100644 --- a/Persistence.Repository/Repositories/SetpointRepository.cs +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -60,9 +60,8 @@ namespace Persistence.Repository.Repositories return result; } - catch(Exception ex) + catch (Exception) { - var t = ex.Message; return 0; } } From 6fd79f6c4a56be9402eb88e46e626b6e6c14b353 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 18 Nov 2024 11:39:27 +0500 Subject: [PATCH 3/6] Fix --- .../Controllers/SetpointControllerTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs index b972c43..d82e5af 100644 --- a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs @@ -70,6 +70,7 @@ namespace Persistence.IntegrationTests.Controllers //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal(1, response.Content); } } } From 9e375b48319b642ee71f76d7b28949ebfe18d988 Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 18 Nov 2024 15:05:12 +0500 Subject: [PATCH 4/6] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/SetpointController.cs | 18 ++-- Persistence.Database/Entity/ISetpointData.cs | 10 -- Persistence.Database/Entity/Setpoint.cs | 2 +- .../Clients/ISetpointClient.cs | 15 +-- .../Controllers/SetpointControllerTest.cs | 91 +++++++++++++++++-- .../Repositories/SetpointRepository.cs | 19 +++- Persistence/API/ISetpointApi.cs | 8 +- .../Repositories/ISetpointRepository.cs | 29 +++--- 8 files changed, 138 insertions(+), 54 deletions(-) delete mode 100644 Persistence.Database/Entity/ISetpointData.cs diff --git a/Persistence.API/Controllers/SetpointController.cs b/Persistence.API/Controllers/SetpointController.cs index 3e8e94c..519dec9 100644 --- a/Persistence.API/Controllers/SetpointController.cs +++ b/Persistence.API/Controllers/SetpointController.cs @@ -16,31 +16,33 @@ namespace Persistence.API.Controllers } [HttpPost("current")] - public Task>> GetCurrentAsync(IEnumerable setpointKeys, CancellationToken token) + public async Task>> GetCurrent(IEnumerable setpointKeys, CancellationToken token) { - throw new NotImplementedException(); + var result = await setpointRepository.GetCurrent(setpointKeys, token); + + return Ok(result); } [HttpPost("history")] - public async Task>> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + public async Task>> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) { - var result = await setpointRepository.GetHistoryAsync(setpointKeys, historyMoment, token); + var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token); return Ok(result); } [HttpPost("log")] - public async Task>>> GetLogAsync([FromBody] IEnumerable setpointKeys, CancellationToken token) + public async Task>>> GetLog([FromBody] IEnumerable setpointKeys, CancellationToken token) { - var result = await setpointRepository.GetLogAsync(setpointKeys, token); + var result = await setpointRepository.GetLog(setpointKeys, token); return Ok(result); } [HttpPost("save")] - public async Task> SaveAsync(Guid setpointKey, object newValue, CancellationToken token) + public async Task> Save(Guid setpointKey, object newValue, CancellationToken token) { - var result = await setpointRepository.SaveAsync(setpointKey, newValue, token); + var result = await setpointRepository.Save(setpointKey, newValue, 0, token); return Ok(result); } diff --git a/Persistence.Database/Entity/ISetpointData.cs b/Persistence.Database/Entity/ISetpointData.cs deleted file mode 100644 index 630af70..0000000 --- a/Persistence.Database/Entity/ISetpointData.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Persistence.Database.Model -{ - public interface ISetpointData - { - public Guid Key { get; set; } - public object Value { get; set; } - public DateTimeOffset Created { get; set; } - public int IdUser { get; set; } - } -} diff --git a/Persistence.Database/Entity/Setpoint.cs b/Persistence.Database/Entity/Setpoint.cs index 50d7f24..c1b8037 100644 --- a/Persistence.Database/Entity/Setpoint.cs +++ b/Persistence.Database/Entity/Setpoint.cs @@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Persistence.Database.Model { [PrimaryKey(nameof(Key), nameof(Created))] - public class Setpoint : ISetpointData + public class Setpoint { [Comment("Ключ")] public Guid Key { get; set; } diff --git a/Persistence.IntegrationTests/Clients/ISetpointClient.cs b/Persistence.IntegrationTests/Clients/ISetpointClient.cs index 831f119..2a526f5 100644 --- a/Persistence.IntegrationTests/Clients/ISetpointClient.cs +++ b/Persistence.IntegrationTests/Clients/ISetpointClient.cs @@ -5,13 +5,16 @@ namespace Persistence.IntegrationTests.Clients { public interface ISetpointClient { - [Post("/api/Setpoint/history")] - Task>> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment); + [Post("/current")] + Task>> GetCurrent(IEnumerable setpointKeys); + + [Post("/history")] + Task>> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment); - [Post("/api/Setpoint/log")] - Task>>> GetLogAsync(IEnumerable setpoitKeys); + [Post("/log")] + Task>>> GetLog(IEnumerable setpoitKeys); - [Post("/api/Setpoint/save")] - Task> SaveAsync(Guid setpointKey, object newValue); + [Post("/save")] + Task> Save(Guid setpointKey, object newValue); } } diff --git a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs index d82e5af..0401575 100644 --- a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs @@ -1,4 +1,6 @@ using System.Net; +using System.Text.Json; +using Mapster; using Persistence.IntegrationTests.Clients; using Xunit; @@ -10,16 +12,36 @@ namespace Persistence.IntegrationTests.Controllers private class TestObject { public string? value1 { get; set; } - public int value2 { get; set; } - public double value3 { get; set; } + public int? value2 { get; set; } } public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory) { + factory.ClientOptions.BaseAddress = new Uri($"http://localhost/api/Setpoint"); + client = factory.GetHttpClient(string.Empty); } [Fact] - public async Task GetHistoryAsync_returns_success() + public async Task GetCurrent_returns_success() + { + //arrange + var setpointKeys = new List() + { + Guid.NewGuid(), + Guid.NewGuid() + }; + + //act + var response = await client.GetCurrent(setpointKeys); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.Empty(response.Content); + } + + [Fact] + public async Task GetHistory_returns_success() { //arrange var setpointKeys = new List() @@ -30,14 +52,16 @@ namespace Persistence.IntegrationTests.Controllers var historyMoment = DateTimeOffset.Now.ToUniversalTime(); //act - var response = await client.GetHistoryAsync(setpointKeys, historyMoment); + var response = await client.GetHistory(setpointKeys, historyMoment); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.Empty(response.Content); } [Fact] - public async Task GetLogAsync_returns_success() + public async Task GetLog_returns_success() { //arrange var setpointKeys = new List() @@ -47,30 +71,77 @@ namespace Persistence.IntegrationTests.Controllers }; //act - var response = await client.GetLogAsync(setpointKeys); + var response = await client.GetLog(setpointKeys); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.Empty(response.Content); } [Fact] - public async Task SaveAsync_returns_success() + public async Task Save_returns_success() { //arrange var setpointKey = Guid.NewGuid(); var setpointValue = new TestObject() { value1 = "1", - value2 = 2, - value3 = 3.3 + value2 = 2 }; //act - var response = await client.SaveAsync(setpointKey, setpointValue); + var response = await client.Save(setpointKey, setpointValue); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(1, response.Content); } + + [Fact] + public async Task General_test_success() + { + //save + var setpointKey = Guid.NewGuid(); + var setpointValue = new TestObject() + { + value1 = "1", + value2 = 2 + }; + + var saveResponse = await client.Save(setpointKey, setpointValue); + Assert.Equal(HttpStatusCode.OK, saveResponse.StatusCode); + Assert.Equal(1, saveResponse.Content); + + //current + var currentResponse = await client.GetCurrent([setpointKey]); + Assert.Equal(HttpStatusCode.OK, currentResponse.StatusCode); + + var currentContent = currentResponse.Content; + Assert.NotNull(currentContent); + Assert.NotEmpty(currentContent); + + var currentContentValue = currentContent.FirstOrDefault()?.Value?.ToString(); + Assert.NotNull(currentContentValue); + Assert.NotEmpty(currentContentValue); + + var testObjectValue = JsonSerializer.Deserialize(currentContentValue); + Assert.NotNull(testObjectValue); + Assert.Equal(setpointValue.value1, testObjectValue.value1); + Assert.Equal(setpointValue.value2, testObjectValue.value2); + + //history + var historyMoment = DateTimeOffset.Now.ToUniversalTime(); + var historyResponse = await client.GetHistory([setpointKey], historyMoment); + Assert.Equal(HttpStatusCode.OK, historyResponse.StatusCode); + Assert.NotNull(historyResponse.Content); + Assert.NotEmpty(historyResponse.Content); + + //log + var logResponse = await client.GetLog([setpointKey]); + Assert.Equal(HttpStatusCode.OK, logResponse.StatusCode); + Assert.NotNull(logResponse.Content); + Assert.NotEmpty(logResponse.Content); + } } } diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs index ef346e6..ada1c82 100644 --- a/Persistence.Repository/Repositories/SetpointRepository.cs +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -16,7 +16,18 @@ namespace Persistence.Repository.Repositories protected virtual IQueryable GetQueryReadOnly() => db.Set(); - public async Task> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + public async Task> GetCurrent(IEnumerable setpointKeys, CancellationToken token) + { + var query = GetQueryReadOnly(); + var entities = await query + .Where(e => setpointKeys.Contains(e.Key)) + .ToArrayAsync(token); + var dtos = entities.Select(e => e.Adapt()); + + return dtos; + } + + public async Task> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) { var query = GetQueryReadOnly(); var entities = await query @@ -27,7 +38,7 @@ namespace Persistence.Repository.Repositories return dtos; } - public async Task>> GetLogAsync(IEnumerable setpointKeys, CancellationToken token) + public async Task>> GetLog(IEnumerable setpointKeys, CancellationToken token) { var query = GetQueryReadOnly(); var entities = await query @@ -43,7 +54,7 @@ namespace Persistence.Repository.Repositories return dtos; } - public async Task SaveAsync(Guid setpointKey, object newValue, CancellationToken token) + public async Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token) { try { @@ -51,7 +62,7 @@ namespace Persistence.Repository.Repositories { Key = setpointKey, Value = newValue, - IdUser = 0, // ToDo: откуда тянуть? + IdUser = idUser, Created = DateTimeOffset.Now.ToUniversalTime() }; diff --git a/Persistence/API/ISetpointApi.cs b/Persistence/API/ISetpointApi.cs index d086557..7af0895 100644 --- a/Persistence/API/ISetpointApi.cs +++ b/Persistence/API/ISetpointApi.cs @@ -14,7 +14,7 @@ public interface ISetpointApi /// ключи уставок /// /// - Task>> GetCurrentAsync(IEnumerable setpoitKeys, CancellationToken token); + Task>> GetCurrent(IEnumerable setpoitKeys, CancellationToken token); /// /// Получить значения уставок за определенный момент времени @@ -23,7 +23,7 @@ public interface ISetpointApi /// дата, на которую получаем данные /// /// - Task>> GetHistoryAsync(IEnumerable setpoitKeys, DateTimeOffset historyMoment, CancellationToken token); + Task>> GetHistory(IEnumerable setpoitKeys, DateTimeOffset historyMoment, CancellationToken token); /// /// Получить историю изменений значений уставок @@ -31,7 +31,7 @@ public interface ISetpointApi /// ключи уставок /// /// - Task>>> GetLogAsync(IEnumerable setpoitKeys, CancellationToken token); + Task>>> GetLog(IEnumerable setpoitKeys, CancellationToken token); /// /// Метод сохранения уставки @@ -40,5 +40,5 @@ public interface ISetpointApi /// значение /// /// - Task> SaveAsync(Guid setpointKey, object newValue, CancellationToken token); + Task> Save(Guid setpointKey, object newValue, CancellationToken token); } diff --git a/Persistence/Repositories/ISetpointRepository.cs b/Persistence/Repositories/ISetpointRepository.cs index d315725..f7439fc 100644 --- a/Persistence/Repositories/ISetpointRepository.cs +++ b/Persistence/Repositories/ISetpointRepository.cs @@ -7,15 +7,22 @@ namespace Persistence.Repositories; /// public interface ISetpointRepository { - - /// - /// Получить значения уставок за определенный момент времени - /// - /// - /// дата, на которую получаем данные - /// - /// - Task> GetHistoryAsync(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token); + /// + /// Получить значения уставок по набору ключей + /// + /// + /// + /// + Task> GetCurrent(IEnumerable setpointKeys, CancellationToken token); + + /// + /// Получить значения уставок за определенный момент времени + /// + /// + /// дата, на которую получаем данные + /// + /// + Task> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token); /// /// Получить историю изменений значений уставок @@ -23,7 +30,7 @@ public interface ISetpointRepository /// /// /// - Task>> GetLogAsync(IEnumerable setpointKeys, CancellationToken token); + Task>> GetLog(IEnumerable setpointKeys, CancellationToken token); /// /// Метод сохранения уставки @@ -35,5 +42,5 @@ public interface ISetpointRepository /// /// to do /// id User учесть в соответствующем методе репозитория - Task SaveAsync(Guid setpointKey, object newValue, CancellationToken token); + Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token); } From 9e55d6791cdbad56db77a6cbd3e4b112a024b51d Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Wed, 20 Nov 2024 15:29:58 +0500 Subject: [PATCH 5/6] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D1=81=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82=D0=B0=D0=BC=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/SetpointController.cs | 19 +-- Persistence.Database/Entity/Setpoint.cs | 3 +- .../Entity/SetpointDictionary.cs | 18 --- .../Clients/ISetpointClient.cs | 21 ++-- .../Controllers/SetpointControllerTest.cs | 108 +++++++++--------- Persistence.Repository/Data/SetpointDto.cs | 18 +++ .../Repositories/SetpointRepository.cs | 40 +++---- .../Repositories/ISetpointRepository.cs | 2 +- 8 files changed, 116 insertions(+), 113 deletions(-) delete mode 100644 Persistence.Database/Entity/SetpointDictionary.cs diff --git a/Persistence.API/Controllers/SetpointController.cs b/Persistence.API/Controllers/SetpointController.cs index 519dec9..14f966c 100644 --- a/Persistence.API/Controllers/SetpointController.cs +++ b/Persistence.API/Controllers/SetpointController.cs @@ -15,36 +15,37 @@ namespace Persistence.API.Controllers this.setpointRepository = setpointRepository; } - [HttpPost("current")] - public async Task>> GetCurrent(IEnumerable setpointKeys, CancellationToken token) + [HttpGet("current")] + public async Task>> GetCurrent([FromQuery] IEnumerable setpointKeys, CancellationToken token) { var result = await setpointRepository.GetCurrent(setpointKeys, token); return Ok(result); } - [HttpPost("history")] - public async Task>> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment, CancellationToken token) + [HttpGet("history")] + public async Task>> GetHistory([FromQuery] IEnumerable setpointKeys, [FromQuery] DateTimeOffset historyMoment, CancellationToken token) { var result = await setpointRepository.GetHistory(setpointKeys, historyMoment, token); return Ok(result); } - [HttpPost("log")] - public async Task>>> GetLog([FromBody] IEnumerable setpointKeys, CancellationToken token) + [HttpGet("log")] + public async Task>>> GetLog([FromQuery] IEnumerable setpointKeys, CancellationToken token) { var result = await setpointRepository.GetLog(setpointKeys, token); return Ok(result); } - [HttpPost("save")] + [HttpPost] public async Task> Save(Guid setpointKey, object newValue, CancellationToken token) { - var result = await setpointRepository.Save(setpointKey, newValue, 0, token); + // ToDo: вычитка idUser + await setpointRepository.Save(setpointKey, newValue, 0, token); - return Ok(result); + return Ok(); } } } diff --git a/Persistence.Database/Entity/Setpoint.cs b/Persistence.Database/Entity/Setpoint.cs index c1b8037..ef6b5dc 100644 --- a/Persistence.Database/Entity/Setpoint.cs +++ b/Persistence.Database/Entity/Setpoint.cs @@ -1,6 +1,5 @@ using System.ComponentModel.DataAnnotations.Schema; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Persistence.Database.Model { @@ -13,7 +12,7 @@ namespace Persistence.Database.Model [Column(TypeName = "jsonb"), Comment("Значение уставки")] public required object Value { get; set; } - [Comment("Дата изменения уставки")] + [Comment("Дата создания уставки")] public DateTimeOffset Created { get; set; } [Comment("Id автора последнего изменения")] diff --git a/Persistence.Database/Entity/SetpointDictionary.cs b/Persistence.Database/Entity/SetpointDictionary.cs deleted file mode 100644 index cd20624..0000000 --- a/Persistence.Database/Entity/SetpointDictionary.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Internal; - -namespace Persistence.Database.Model -{ - public class SetpointDictionary - { - [Key, Comment("Ключ")] - public Guid Key { get; set; } - - [Comment("Наименование")] - public required string Name { get; set; } - - [Comment("Описание")] - public string? Description { get; set; } - } -} diff --git a/Persistence.IntegrationTests/Clients/ISetpointClient.cs b/Persistence.IntegrationTests/Clients/ISetpointClient.cs index 2a526f5..a4f79b5 100644 --- a/Persistence.IntegrationTests/Clients/ISetpointClient.cs +++ b/Persistence.IntegrationTests/Clients/ISetpointClient.cs @@ -3,18 +3,23 @@ using Refit; namespace Persistence.IntegrationTests.Clients { + /// + /// Интерфейс для тестирования API, предназначенного для работы с уставками + /// public interface ISetpointClient { - [Post("/current")] - Task>> GetCurrent(IEnumerable setpointKeys); + private const string BaseRoute = "/api/setpoint"; + + [Get($"{BaseRoute}/current")] + Task>> GetCurrent([Query(CollectionFormat.Multi)] IEnumerable setpointKeys); - [Post("/history")] - Task>> GetHistory(IEnumerable setpointKeys, DateTimeOffset historyMoment); + [Get($"{BaseRoute}/history")] + Task>> GetHistory([Query(CollectionFormat.Multi)] IEnumerable setpointKeys, [Query] DateTimeOffset historyMoment); - [Post("/log")] - Task>>> GetLog(IEnumerable setpoitKeys); + [Get($"{BaseRoute}/log")] + Task>>> GetLog([Query(CollectionFormat.Multi)] IEnumerable setpointKeys); - [Post("/save")] - Task> Save(Guid setpointKey, object newValue); + [Post($"{BaseRoute}/")] + Task Save(Guid setpointKey, object newValue); } } diff --git a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs index 0401575..2fcfc52 100644 --- a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs @@ -1,6 +1,4 @@ using System.Net; -using System.Text.Json; -using Mapster; using Persistence.IntegrationTests.Clients; using Xunit; @@ -16,8 +14,6 @@ namespace Persistence.IntegrationTests.Controllers } public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory) { - factory.ClientOptions.BaseAddress = new Uri($"http://localhost/api/Setpoint"); - client = factory.GetHttpClient(string.Empty); } @@ -40,6 +36,22 @@ namespace Persistence.IntegrationTests.Controllers Assert.Empty(response.Content); } + [Fact] + public async Task GetCurrent_AfterSave_returns_success() + { + //arrange + var setpointKey = await Save(); + + //act + var response = await client.GetCurrent([setpointKey]); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.NotEmpty(response.Content); + Assert.Equal(response.Content.FirstOrDefault()?.Key, setpointKey); + } + [Fact] public async Task GetHistory_returns_success() { @@ -49,7 +61,7 @@ namespace Persistence.IntegrationTests.Controllers Guid.NewGuid(), Guid.NewGuid() }; - var historyMoment = DateTimeOffset.Now.ToUniversalTime(); + var historyMoment = DateTimeOffset.UtcNow; //act var response = await client.GetHistory(setpointKeys, historyMoment); @@ -60,6 +72,24 @@ namespace Persistence.IntegrationTests.Controllers Assert.Empty(response.Content); } + [Fact] + public async Task GetHistory_AfterSave_returns_success() + { + //arrange + var setpointKey = await Save(); + var historyMoment = DateTimeOffset.UtcNow; + historyMoment = historyMoment.AddDays(1); + + //act + var response = await client.GetHistory([setpointKey], historyMoment); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.NotEmpty(response.Content); + Assert.Equal(response.Content.FirstOrDefault()?.Key, setpointKey); + } + [Fact] public async Task GetLog_returns_success() { @@ -79,8 +109,29 @@ namespace Persistence.IntegrationTests.Controllers Assert.Empty(response.Content); } + [Fact] + public async Task GetLog_AfterSave_returns_success() + { + //arrange + var setpointKey = await Save(); + + //act + var response = await client.GetLog([setpointKey]); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.NotEmpty(response.Content); + Assert.Equal(response.Content.FirstOrDefault().Value.FirstOrDefault()?.Key, setpointKey); + } + [Fact] public async Task Save_returns_success() + { + await Save(); + } + + private async Task Save() { //arrange var setpointKey = Guid.NewGuid(); @@ -95,53 +146,8 @@ namespace Persistence.IntegrationTests.Controllers //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.Equal(1, response.Content); - } - [Fact] - public async Task General_test_success() - { - //save - var setpointKey = Guid.NewGuid(); - var setpointValue = new TestObject() - { - value1 = "1", - value2 = 2 - }; - - var saveResponse = await client.Save(setpointKey, setpointValue); - Assert.Equal(HttpStatusCode.OK, saveResponse.StatusCode); - Assert.Equal(1, saveResponse.Content); - - //current - var currentResponse = await client.GetCurrent([setpointKey]); - Assert.Equal(HttpStatusCode.OK, currentResponse.StatusCode); - - var currentContent = currentResponse.Content; - Assert.NotNull(currentContent); - Assert.NotEmpty(currentContent); - - var currentContentValue = currentContent.FirstOrDefault()?.Value?.ToString(); - Assert.NotNull(currentContentValue); - Assert.NotEmpty(currentContentValue); - - var testObjectValue = JsonSerializer.Deserialize(currentContentValue); - Assert.NotNull(testObjectValue); - Assert.Equal(setpointValue.value1, testObjectValue.value1); - Assert.Equal(setpointValue.value2, testObjectValue.value2); - - //history - var historyMoment = DateTimeOffset.Now.ToUniversalTime(); - var historyResponse = await client.GetHistory([setpointKey], historyMoment); - Assert.Equal(HttpStatusCode.OK, historyResponse.StatusCode); - Assert.NotNull(historyResponse.Content); - Assert.NotEmpty(historyResponse.Content); - - //log - var logResponse = await client.GetLog([setpointKey]); - Assert.Equal(HttpStatusCode.OK, logResponse.StatusCode); - Assert.NotNull(logResponse.Content); - Assert.NotEmpty(logResponse.Content); + return setpointKey; } } } diff --git a/Persistence.Repository/Data/SetpointDto.cs b/Persistence.Repository/Data/SetpointDto.cs index 261b1bc..4a20aa4 100644 --- a/Persistence.Repository/Data/SetpointDto.cs +++ b/Persistence.Repository/Data/SetpointDto.cs @@ -1,10 +1,28 @@ namespace Persistence.Repository.Data { + /// + /// Модель для работы с уставкой + /// public class SetpointDto { + /// + /// Идентификатор уставки + /// public int Id { get; set; } + + /// + /// Значение уставки + /// public required object Value { get; set; } + + /// + /// Дата сохранения уставки + /// public DateTimeOffset Edit { get; set; } + + /// + /// Ключ пользователя + /// public int IdUser { get; set; } } } diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs index ada1c82..2c08e71 100644 --- a/Persistence.Repository/Repositories/SetpointRepository.cs +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -31,9 +31,13 @@ namespace Persistence.Repository.Repositories { var query = GetQueryReadOnly(); var entities = await query - .Where(e => setpointKeys.Contains(e.Key) && e.Created.Date == historyMoment.Date) + .Where(e => setpointKeys.Contains(e.Key)) .ToArrayAsync(token); - var dtos = entities.Select(e => e.Adapt()); + var filteredEntities = entities + .GroupBy(e => e.Key) + .Select(e => e.Where(e => e.Created <= historyMoment).Last()); + var dtos = filteredEntities + .Select(e => e.Adapt()); return dtos; } @@ -46,35 +50,23 @@ namespace Persistence.Repository.Repositories .ToArrayAsync(token); var dtos = entities .GroupBy(e => e.Key) - .Select(e => new KeyValuePair>( - e.Key, - e.Select(s => s.Adapt()) - )).ToDictionary(); + .ToDictionary(e => e.Key, v => v.Select(z => z.Adapt())); return dtos; } - public async Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token) + public async Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token) { - try + var entity = new Setpoint() { - var entity = new Setpoint() - { - Key = setpointKey, - Value = newValue, - IdUser = idUser, - Created = DateTimeOffset.Now.ToUniversalTime() - }; + Key = setpointKey, + Value = newValue, + IdUser = idUser, + Created = DateTimeOffset.UtcNow + }; - await db.Set().AddAsync(entity, token); - var result = await db.SaveChangesAsync(token); - - return result; - } - catch (Exception) - { - return 0; - } + await db.Set().AddAsync(entity, token); + await db.SaveChangesAsync(token); } } } diff --git a/Persistence/Repositories/ISetpointRepository.cs b/Persistence/Repositories/ISetpointRepository.cs index 6d2690e..1d82b16 100644 --- a/Persistence/Repositories/ISetpointRepository.cs +++ b/Persistence/Repositories/ISetpointRepository.cs @@ -42,5 +42,5 @@ public interface ISetpointRepository /// /// to do /// id User учесть в соответствующем методе репозитория - Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token); + Task Save(Guid setpointKey, object newValue, int idUser, CancellationToken token); } From 4fa00de88ee1c217a2461dbee6e813aad8e3755d Mon Sep 17 00:00:00 2001 From: Roman Efremov Date: Mon, 25 Nov 2024 10:30:37 +0500 Subject: [PATCH 6/6] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D1=81=D1=82=D0=B8=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82=D0=B0=D0=BC=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20#2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/SetpointControllerTest.cs | 6 +++--- Persistence.Repository/Repositories/SetpointRepository.cs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs index 2fcfc52..a33c15d 100644 --- a/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs +++ b/Persistence.IntegrationTests/Controllers/SetpointControllerTest.cs @@ -49,7 +49,7 @@ namespace Persistence.IntegrationTests.Controllers Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.NotEmpty(response.Content); - Assert.Equal(response.Content.FirstOrDefault()?.Key, setpointKey); + Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key); } [Fact] @@ -87,7 +87,7 @@ namespace Persistence.IntegrationTests.Controllers Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.NotEmpty(response.Content); - Assert.Equal(response.Content.FirstOrDefault()?.Key, setpointKey); + Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key); } [Fact] @@ -122,7 +122,7 @@ namespace Persistence.IntegrationTests.Controllers Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.NotEmpty(response.Content); - Assert.Equal(response.Content.FirstOrDefault().Value.FirstOrDefault()?.Key, setpointKey); + Assert.Equal(setpointKey, response.Content.FirstOrDefault()?.Key); } [Fact] diff --git a/Persistence.Repository/Repositories/SetpointRepository.cs b/Persistence.Repository/Repositories/SetpointRepository.cs index 2c08e71..7f81c29 100644 --- a/Persistence.Repository/Repositories/SetpointRepository.cs +++ b/Persistence.Repository/Repositories/SetpointRepository.cs @@ -35,6 +35,7 @@ namespace Persistence.Repository.Repositories .ToArrayAsync(token); var filteredEntities = entities .GroupBy(e => e.Key) + .Select(e => e.OrderBy(o => o.Created)) .Select(e => e.Where(e => e.Created <= historyMoment).Last()); var dtos = filteredEntities .Select(e => e.Adapt());