diff --git a/Persistence.API/Controllers/TechMessagesController.cs b/Persistence.API/Controllers/TechMessagesController.cs
index 16db89c..47d79d5 100644
--- a/Persistence.API/Controllers/TechMessagesController.cs
+++ b/Persistence.API/Controllers/TechMessagesController.cs
@@ -1,10 +1,12 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
using Persistence.Models;
using Persistence.Repositories;
namespace Persistence.API.Controllers
{
[ApiController]
+ [Authorize]
[Route("api/[controller]")]
public class TechMessagesController : ControllerBase, ITechMessages
{
@@ -44,7 +46,7 @@ namespace Persistence.API.Controllers
{
var result = await techMessagesRepository.InsertRange(dtos, token);
- return Ok(result);
+ return CreatedAtAction(nameof(InsertRange), result);
}
}
}
diff --git a/Persistence.Client/Clients/ISetpointClient.cs b/Persistence.Client/Clients/ISetpointClient.cs
index 49733f0..72d76e1 100644
--- a/Persistence.Client/Clients/ISetpointClient.cs
+++ b/Persistence.Client/Clients/ISetpointClient.cs
@@ -4,7 +4,7 @@ using Refit;
namespace Persistence.Client.Clients;
///
-/// Интерфейс для тестирования API, предназначенного для работы с уставками
+/// Интерфейс клиента для работы с уставками
///
public interface ISetpointClient
{
diff --git a/Persistence.Client/Clients/ITechMessagesClient.cs b/Persistence.Client/Clients/ITechMessagesClient.cs
new file mode 100644
index 0000000..1426b54
--- /dev/null
+++ b/Persistence.Client/Clients/ITechMessagesClient.cs
@@ -0,0 +1,25 @@
+using Persistence.Models;
+using Refit;
+
+namespace Persistence.Client.Clients
+{
+ ///
+ /// Интерфейс клиента для хранения технологических сообщений
+ ///
+ public interface ITechMessagesClient
+ {
+ private const string BaseRoute = "/api/techMessages";
+
+ [Get($"{BaseRoute}")]
+ Task>> GetPage([Query] RequestDto request, CancellationToken token);
+
+ [Post($"{BaseRoute}")]
+ Task> InsertRange([Body] IEnumerable dtos, CancellationToken token);
+
+ [Get($"{BaseRoute}/systems")]
+ Task>> GetSystems(CancellationToken token);
+
+ [Get($"{BaseRoute}/statistics")]
+ Task> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token);
+ }
+}
diff --git a/Persistence.Client/Clients/ITimeSeriesClient.cs b/Persistence.Client/Clients/ITimeSeriesClient.cs
index 8f7ef0e..349337b 100644
--- a/Persistence.Client/Clients/ITimeSeriesClient.cs
+++ b/Persistence.Client/Clients/ITimeSeriesClient.cs
@@ -1,5 +1,4 @@
-using Microsoft.AspNetCore.Mvc;
-using Persistence.Models;
+using Persistence.Models;
using Refit;
namespace Persistence.Client.Clients;
diff --git a/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs
new file mode 100644
index 0000000..9eb0e9d
--- /dev/null
+++ b/Persistence.IntegrationTests/Controllers/TechMessagesControllerTest.cs
@@ -0,0 +1,178 @@
+using System.Net;
+using Microsoft.Extensions.DependencyInjection;
+using Persistence.Client;
+using Persistence.Client.Clients;
+using Persistence.Database.Entity;
+using Persistence.Models;
+using Xunit;
+
+namespace Persistence.IntegrationTests.Controllers
+{
+ public class TechMessagesControllerTest : BaseIntegrationTest
+ {
+ private readonly ITechMessagesClient techMessagesClient;
+ public TechMessagesControllerTest(WebAppFactoryFixture factory) : base(factory)
+ {
+ var scope = factory.Services.CreateScope();
+ var persistenceClientFactory = scope.ServiceProvider
+ .GetRequiredService();
+
+ techMessagesClient = persistenceClientFactory.GetClient();
+ }
+
+ [Fact]
+ public async Task GetPage_returns_success()
+ {
+ //arrange
+ dbContext.CleanupDbSet();
+ var requestDto = new RequestDto()
+ {
+ Skip = 1,
+ Take = 2,
+ SortSettings = nameof(TechMessageDto.ImportantId)
+ };
+
+ //act
+ var response = await techMessagesClient.GetPage(requestDto, new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.NotNull(response.Content);
+ Assert.Empty(response.Content.Items);
+ Assert.Equal(requestDto.Skip, response.Content.Skip);
+ Assert.Equal(requestDto.Take, response.Content.Take);
+ }
+
+ [Fact]
+ public async Task GetPage_AfterSave_returns_success()
+ {
+ //arrange
+ var dtos = await InsertRange();
+ var dtosCount = dtos.Count();
+ var requestDto = new RequestDto()
+ {
+ Skip = 0,
+ Take = 2,
+ SortSettings = nameof(TechMessageDto.ImportantId)
+ };
+
+ //act
+ var response = await techMessagesClient.GetPage(requestDto, new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.NotNull(response.Content);
+ Assert.Equal(dtosCount, response.Content.Count);
+ }
+
+ [Fact]
+ public async Task InsertRange_returns_success()
+ {
+ await InsertRange();
+ }
+
+ [Fact]
+ public async Task GetSystems_returns_success()
+ {
+ //act
+ dbContext.CleanupDbSet();
+ var response = await techMessagesClient.GetSystems(new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.NotNull(response.Content);
+ Assert.Empty(response.Content);
+ }
+
+ [Fact]
+ public async Task GetSystems_AfterSave_returns_success()
+ {
+ //arrange
+ var dtos = await InsertRange();
+ var systems = dtos
+ .Select(e => e.AutoDrillingSystem)
+ .Distinct()
+ .ToArray();
+
+ //act
+ var response = await techMessagesClient.GetSystems(new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.NotNull(response.Content);
+ string?[]? content = response.Content?.ToArray();
+ Assert.Equal(systems, content);
+ }
+
+ [Fact]
+ public async Task GetStatistics_returns_success()
+ {
+ //arrange
+ dbContext.CleanupDbSet();
+ var imortantId = 1;
+ var autoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem);
+
+ //act
+ var response = await techMessagesClient.GetStatistics(imortantId, autoDrillingSystem, new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Equal(0, response.Content);
+ }
+
+ [Fact]
+ public async Task GetStatistics_AfterSave_returns_success()
+ {
+ //arrange
+ var imortantId = 1;
+ var autoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem);
+ var dtos = await InsertRange();
+ var filteredDtos = dtos.Where(e => e.ImportantId == imortantId && e.AutoDrillingSystem == e.AutoDrillingSystem);
+
+ //act
+ var response = await techMessagesClient.GetStatistics(imortantId, autoDrillingSystem, new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Equal(filteredDtos.Count(), response.Content);
+ }
+
+ public async Task> InsertRange()
+ {
+ //arrange
+ var dtos = new List()
+ {
+ new TechMessageDto()
+ {
+ EventId = Guid.NewGuid(),
+ ImportantId = 1,
+ OccurrenceDate = DateTimeOffset.UtcNow,
+ Depth = 1.11,
+ MessageText = nameof(TechMessageDto.MessageText),
+ AutoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem),
+ UserId = Guid.NewGuid()
+ },
+ new TechMessageDto()
+ {
+ EventId = Guid.NewGuid(),
+ ImportantId = 2,
+ OccurrenceDate = DateTimeOffset.UtcNow,
+ Depth = 2.22,
+ MessageText = nameof(TechMessageDto.MessageText),
+ AutoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem),
+ UserId = Guid.NewGuid()
+ }
+ };
+
+
+ //act
+ var response = await techMessagesClient.InsertRange(dtos, new CancellationToken());
+
+ //assert
+ Assert.Equal(HttpStatusCode.Created, response.StatusCode);
+ Assert.Equal(dtos.Count, response.Content);
+
+ return dtos;
+ }
+ }
+}
diff --git a/Persistence.IntegrationTests/Extensions/EFCoreExtensions.cs b/Persistence.IntegrationTests/Extensions/EFCoreExtensions.cs
new file mode 100644
index 0000000..6b09587
--- /dev/null
+++ b/Persistence.IntegrationTests/Extensions/EFCoreExtensions.cs
@@ -0,0 +1,14 @@
+using Persistence.Database.Model;
+
+namespace Persistence.IntegrationTests.Extensions;
+
+public static class EFCoreExtensions
+{
+ public static void CleanupDbSet(this PersistenceDbContext dbContext)
+ where T : class
+ {
+ var dbset = dbContext.Set();
+ dbset.RemoveRange(dbset);
+ dbContext.SaveChanges();
+ }
+}
diff --git a/Persistence.Repository/Data/SetpointDto.cs b/Persistence.Repository/Data/SetpointDto.cs
deleted file mode 100644
index 4a20aa4..0000000
--- a/Persistence.Repository/Data/SetpointDto.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-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/TechMessagesRepository.cs b/Persistence.Repository/Repositories/TechMessagesRepository.cs
index f5ddb35..9abda86 100644
--- a/Persistence.Repository/Repositories/TechMessagesRepository.cs
+++ b/Persistence.Repository/Repositories/TechMessagesRepository.cs
@@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Persistence.Database.Entity;
using Persistence.Models;
using Persistence.Repositories;
+using Persistence.Repository.Extensions;
namespace Persistence.Repository.Repositories
{
diff --git a/Persistence/Models/TechMessageDto.cs b/Persistence/Models/TechMessageDto.cs
index 274a1d5..625b22f 100644
--- a/Persistence/Models/TechMessageDto.cs
+++ b/Persistence/Models/TechMessageDto.cs
@@ -1,5 +1,8 @@
namespace Persistence.Models
{
+ ///
+ /// Модель технологического сообщения
+ ///
public class TechMessageDto
{
///