Добавить тесты для технологических сообщений

This commit is contained in:
Roman Efremov 2024-11-26 12:27:52 +05:00
parent 4990a39b3d
commit 7807e4aa1e
9 changed files with 227 additions and 33 deletions

View File

@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Persistence.Models; using Persistence.Models;
using Persistence.Repositories; using Persistence.Repositories;
namespace Persistence.API.Controllers namespace Persistence.API.Controllers
{ {
[ApiController] [ApiController]
[Authorize]
[Route("api/[controller]")] [Route("api/[controller]")]
public class TechMessagesController : ControllerBase, ITechMessages public class TechMessagesController : ControllerBase, ITechMessages
{ {
@ -44,7 +46,7 @@ namespace Persistence.API.Controllers
{ {
var result = await techMessagesRepository.InsertRange(dtos, token); var result = await techMessagesRepository.InsertRange(dtos, token);
return Ok(result); return CreatedAtAction(nameof(InsertRange), result);
} }
} }
} }

View File

@ -4,7 +4,7 @@ using Refit;
namespace Persistence.Client.Clients; namespace Persistence.Client.Clients;
/// <summary> /// <summary>
/// Интерфейс для тестирования API, предназначенного для работы с уставками /// Интерфейс клиента для работы с уставками
/// </summary> /// </summary>
public interface ISetpointClient public interface ISetpointClient
{ {

View File

@ -0,0 +1,25 @@
using Persistence.Models;
using Refit;
namespace Persistence.Client.Clients
{
/// <summary>
/// Интерфейс клиента для хранения технологических сообщений
/// </summary>
public interface ITechMessagesClient
{
private const string BaseRoute = "/api/techMessages";
[Get($"{BaseRoute}")]
Task<IApiResponse<PaginationContainer<TechMessageDto>>> GetPage([Query] RequestDto request, CancellationToken token);
[Post($"{BaseRoute}")]
Task<IApiResponse<int>> InsertRange([Body] IEnumerable<TechMessageDto> dtos, CancellationToken token);
[Get($"{BaseRoute}/systems")]
Task<IApiResponse<IEnumerable<string>>> GetSystems(CancellationToken token);
[Get($"{BaseRoute}/statistics")]
Task<IApiResponse<int>> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token);
}
}

View File

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Mvc; using Persistence.Models;
using Persistence.Models;
using Refit; using Refit;
namespace Persistence.Client.Clients; namespace Persistence.Client.Clients;

View File

@ -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<PersistenceClientFactory>();
techMessagesClient = persistenceClientFactory.GetClient<ITechMessagesClient>();
}
[Fact]
public async Task GetPage_returns_success()
{
//arrange
dbContext.CleanupDbSet<TechMessage>();
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<TechMessage>();
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<TechMessage>();
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<IEnumerable<TechMessageDto>> InsertRange()
{
//arrange
var dtos = new List<TechMessageDto>()
{
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;
}
}
}

View File

@ -0,0 +1,14 @@
using Persistence.Database.Model;
namespace Persistence.IntegrationTests.Extensions;
public static class EFCoreExtensions
{
public static void CleanupDbSet<T>(this PersistenceDbContext dbContext)
where T : class
{
var dbset = dbContext.Set<T>();
dbset.RemoveRange(dbset);
dbContext.SaveChanges();
}
}

View File

@ -1,28 +0,0 @@
namespace Persistence.Repository.Data
{
/// <summary>
/// Модель для работы с уставкой
/// </summary>
public class SetpointDto
{
/// <summary>
/// Идентификатор уставки
/// </summary>
public int Id { get; set; }
/// <summary>
/// Значение уставки
/// </summary>
public required object Value { get; set; }
/// <summary>
/// Дата сохранения уставки
/// </summary>
public DateTimeOffset Edit { get; set; }
/// <summary>
/// Ключ пользователя
/// </summary>
public int IdUser { get; set; }
}
}

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Persistence.Database.Entity; using Persistence.Database.Entity;
using Persistence.Models; using Persistence.Models;
using Persistence.Repositories; using Persistence.Repositories;
using Persistence.Repository.Extensions;
namespace Persistence.Repository.Repositories namespace Persistence.Repository.Repositories
{ {

View File

@ -1,5 +1,8 @@
namespace Persistence.Models namespace Persistence.Models
{ {
/// <summary>
/// Модель технологического сообщения
/// </summary>
public class TechMessageDto public class TechMessageDto
{ {
/// <summary> /// <summary>