Интеграционный тест для сопоставления категорий между шаблонами импорта/экспорта ГГД и записями в БД

This commit is contained in:
Olga Nemt 2024-04-23 14:43:17 +05:00
parent 0b4fbe34ce
commit dc96d03740
4 changed files with 208 additions and 160 deletions

View File

@ -29,4 +29,10 @@ public interface IWellOperationClient
[Get(BaseRoute + "/export")]
Task<IApiResponse<PhysicalFileResult>> ExportAsync(int idWell, int idType);
[Get(BaseRoute + "/template")]
Task<IApiResponse<Stream>> GetTemplate(int idWell, int idType);
[Get(BaseRoute + "/categories")]
Task<IApiResponse<IEnumerable<WellOperationCategoryDto>>> GetCategories(int idWell, bool includeParents, bool includeHidden);
}

View File

@ -1,208 +1,250 @@
using System.Net;
using System.Reflection;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Requests;
using AsbCloudDb.Model;
using AsbCloudInfrastructure;
using AsbCloudWebApi.IntegrationTests.Clients;
using AsbCloudWebApi.IntegrationTests.Data;
using ClosedXML.Excel;
using Mapster;
using Microsoft.EntityFrameworkCore;
using Refit;
using System.Net;
using System.Reflection;
using Xunit;
namespace AsbCloudWebApi.IntegrationTests.Controllers.WellOperations;
public class WellOperationControllerTest : BaseIntegrationTest
{
private IWellOperationClient client;
private IWellOperationClient client;
public WellOperationControllerTest(WebAppFactoryFixture factory)
: base(factory)
{
client = factory.GetAuthorizedHttpClient<IWellOperationClient>(string.Empty);
public WellOperationControllerTest(WebAppFactoryFixture factory)
: base(factory)
{
client = factory.GetAuthorizedHttpClient<IWellOperationClient>(string.Empty);
dbContext.CleanupDbSet<WellOperation>();
}
dbContext.CleanupDbSet<WellOperation>();
}
/// <summary>
/// Успешное добавление операций (без предварительной очистки данных)
/// </summary>
/// <returns></returns>
[Fact]
public async Task InsertRange_returns_success()
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
var dtos = new[] { entity.Adapt<WellOperationDto>() };
/// <summary>
/// Успешное добавление операций (без предварительной очистки данных)
/// </summary>
/// <returns></returns>
[Fact]
public async Task InsertRange_returns_success()
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
var dtos = new[] { entity.Adapt<WellOperationDto>() };
//act
var response = await client.InsertRangeAsync(well.Id, false, dtos);
//act
var response = await client.InsertRangeAsync(well.Id, false, dtos);
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
/// <summary>
/// Успешное добавление операций (с предварительной очисткой данных)
/// </summary>
/// <returns></returns>
[Fact]
public async Task InsertRangeWithDeleteBefore_returns_success()
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
var dtos = new[] { entity.Adapt<WellOperationDto>() };
/// <summary>
/// Успешное добавление операций (с предварительной очисткой данных)
/// </summary>
/// <returns></returns>
[Fact]
public async Task InsertRangeWithDeleteBefore_returns_success()
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
var dtos = new[] { entity.Adapt<WellOperationDto>() };
//act
var response = await client.InsertRangeAsync(well.Id, true, dtos);
//act
var response = await client.InsertRangeAsync(well.Id, true, dtos);
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
/// <summary>
/// Успешное обновление операций
/// </summary>
/// <returns></returns>
[Fact]
public async Task UpdateRangeAsync_returns_success()
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
dbContext.WellOperations.Add(entity);
await dbContext.SaveChangesAsync();
/// <summary>
/// Успешное обновление операций
/// </summary>
/// <returns></returns>
[Fact]
public async Task UpdateRangeAsync_returns_success()
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
dbContext.WellOperations.Add(entity);
await dbContext.SaveChangesAsync();
var dtos = new[] { entity.Adapt<WellOperationDto>() };
var dtos = new[] { entity.Adapt<WellOperationDto>() };
//act
var response = await client.UpdateRangeAsync(well.Id, dtos);
//act
var response = await client.UpdateRangeAsync(well.Id, dtos);
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
/// <summary>
/// Получение плановых операций
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetPageOperationsAsync_returns_first_page()
{
//arrange
const int pageSize = 10;
const int pageIndex = 0;
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
dbContext.WellOperations.Add(entity);
await dbContext.SaveChangesAsync();
/// <summary>
/// Получение плановых операций
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetPageOperationsAsync_returns_first_page()
{
//arrange
const int pageSize = 10;
const int pageIndex = 0;
var dto = entity.Adapt<WellOperationDto>();
var timezoneOffset = TimeSpan.FromHours(well.Timezone.Hours);
dto.DateStart = dto.DateStart.ToOffset(timezoneOffset);
dto.LastUpdateDate = dto.LastUpdateDate?.ToOffset(timezoneOffset);
var well = await dbContext.Wells.FirstAsync();
var entity = CreateWellOperation(well.Id);
dbContext.WellOperations.Add(entity);
await dbContext.SaveChangesAsync();
var request = new WellOperationRequestBase
{
OperationType = WellOperation.IdOperationTypePlan,
Skip = pageIndex,
Take = pageSize,
};
var dto = entity.Adapt<WellOperationDto>();
var timezoneOffset = TimeSpan.FromHours(well.Timezone.Hours);
dto.DateStart = dto.DateStart.ToOffset(timezoneOffset);
dto.LastUpdateDate = dto.LastUpdateDate?.ToOffset(timezoneOffset);
//act
var response = await client.GetPageOperationsAsync(well.Id, request);
var request = new WellOperationRequestBase
{
OperationType = WellOperation.IdOperationTypePlan,
Skip = pageIndex,
Take = pageSize,
};
//assert
Assert.Equal(response.StatusCode, HttpStatusCode.OK);
Assert.NotNull(response.Content);
//act
var response = await client.GetPageOperationsAsync(well.Id, request);
var totalExpected = response.Content.Count - pageSize * pageIndex;
Assert.Equal(totalExpected, response.Content.Items.Count());
//assert
Assert.Equal(response.StatusCode, HttpStatusCode.OK);
Assert.NotNull(response.Content);
Assert.Single(response.Content.Items);
var actualDto = response.Content.Items.First();
var totalExpected = response.Content.Count - pageSize * pageIndex;
Assert.Equal(totalExpected, response.Content.Items.Count());
MatchHelper.Match(dto, actualDto);
}
Assert.Single(response.Content.Items);
var actualDto = response.Content.Items.First();
[Theory]
[InlineData(WellOperation.IdOperationTypePlan, "PlanWellOperations.xlsx")]
[InlineData(WellOperation.IdOperationTypeFact, "FactWellOperations.xlsx")]
public async Task ParseAsync_returns_success(int idType, string fileName)
{
//arrange
var well = await dbContext.Wells.FirstAsync();
MatchHelper.Match(dto, actualDto);
}
var expectedDto = new WellOperationDto
{
IdWell = well.Id,
IdWellSectionType = 2,
IdCategory = WellOperationCategory.IdSlide,
IdPlan = null,
CategoryInfo = "Доп.инфо",
IdType = idType,
DepthStart = 10.0,
DepthEnd = 20.0,
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(well.Timezone.Hours)),
DurationHours = 1.0,
Comment = "123",
};
[Theory]
[InlineData(WellOperation.IdOperationTypePlan, "PlanWellOperations.xlsx")]
[InlineData(WellOperation.IdOperationTypeFact, "FactWellOperations.xlsx")]
public async Task ParseAsync_returns_success(int idType, string fileName)
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var stream = Assembly.GetExecutingAssembly().GetFileCopyStream(fileName);
var expectedDto = new WellOperationDto
{
IdWell = well.Id,
IdWellSectionType = 2,
IdCategory = WellOperationCategory.IdSlide,
IdPlan = null,
CategoryInfo = "Доп.инфо",
IdType = idType,
DepthStart = 10.0,
DepthEnd = 20.0,
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(well.Timezone.Hours)),
DurationHours = 1.0,
Comment = "123",
};
var streamPart = new StreamPart(stream, fileName, "application/octet-stream");
var stream = Assembly.GetExecutingAssembly().GetFileCopyStream(fileName);
//act
var response = await client.ParseAsync(well.Id, idType, streamPart);
var streamPart = new StreamPart(stream, fileName, "application/octet-stream");
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
//act
var response = await client.ParseAsync(well.Id, idType, streamPart);
var actualDto = response.Content.Item.First().Item;
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
MatchHelper.Match(expectedDto, actualDto);
}
var actualDto = response.Content.Item.First().Item;
[Theory]
[InlineData(WellOperation.IdOperationTypePlan)]
[InlineData(WellOperation.IdOperationTypeFact)]
public async Task ExportAsync_returns_success(int idType)
{
//arrange
var well = await dbContext.Wells.FirstAsync();
MatchHelper.Match(expectedDto, actualDto);
}
var entity = CreateWellOperation(well.Id, idType);
dbContext.WellOperations.Add(entity);
await dbContext.SaveChangesAsync();
[Theory]
[InlineData(WellOperation.IdOperationTypePlan)]
[InlineData(WellOperation.IdOperationTypeFact)]
public async Task ExportAsync_returns_success(int idType)
{
//arrange
var well = await dbContext.Wells.FirstAsync();
//act
var response = await client.ExportAsync(well.Id, idType);
var entity = CreateWellOperation(well.Id, idType);
dbContext.WellOperations.Add(entity);
await dbContext.SaveChangesAsync();
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("application/octet-stream", response.ContentHeaders?.ContentType?.MediaType);
Assert.True(response.ContentHeaders?.ContentLength > 0);
}
//act
var response = await client.ExportAsync(well.Id, idType);
private static WellOperation CreateWellOperation(int idWell, int idType = WellOperation.IdOperationTypePlan) =>
new()
{
IdWell = idWell,
IdWellSectionType = 2,
IdCategory = WellOperationCategory.IdSlide,
IdPlan = null,
CategoryInfo = "Доп.инфо",
LastUpdateDate = new DateTimeOffset(new DateTime(2023, 1, 10)).ToUniversalTime(),
IdType = idType,
DepthStart = 10.0,
DepthEnd = 20.0,
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(Defaults.Timezone.Hours)).ToUniversalTime(),
DurationHours = 1.0,
Comment = "1",
IdUser = 1,
};
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("application/octet-stream", response.ContentHeaders?.ContentType?.MediaType);
Assert.True(response.ContentHeaders?.ContentLength > 0);
}
[Theory]
[InlineData(WellOperation.IdOperationTypePlan)]
[InlineData(WellOperation.IdOperationTypeFact)]
public async Task MatchCategoriesFromTemplateAndDb_returns_success(int idType)
{
//arrange
var well = await dbContext.Wells.FirstAsync();
var responseTemplate = await client.GetTemplate(well.Id, idType);
var stream = responseTemplate.Content;
using var workbook = new XLWorkbook(stream);
var sheet = workbook.GetWorksheet("Справочники");
var count = sheet.RowsUsed().Count() - 1;
var categoryCaptionsInTemplate = new List<string>();
for (var i = 0; i < count; i++)
{
var xlRow = sheet.Row(i + 2);
var rowNumber = xlRow.RowNumber();
var xlCell = xlRow.Cell(1);
var cellValue = xlCell.GetText().Trim();
categoryCaptionsInTemplate.Add(cellValue);
}
var responseCategories = await client.GetCategories(well.Id, false, false);
var categories = responseCategories.Content;
var categoryCaptionsInDb = categories!.Select(c => c.Name.Trim());
var notExistedInTemplate = categoryCaptionsInDb.Except(categoryCaptionsInTemplate);
var notExistedInDb = categoryCaptionsInTemplate.Except(categoryCaptionsInDb);
//assert
Assert.True(categoryCaptionsInDb.Count() == categoryCaptionsInTemplate.Count());
Assert.True(notExistedInTemplate.Count() == 0);
Assert.True(notExistedInDb.Count() == 0);
}
private static WellOperation CreateWellOperation(int idWell, int idType = WellOperation.IdOperationTypePlan) =>
new()
{
IdWell = idWell,
IdWellSectionType = 2,
IdCategory = WellOperationCategory.IdSlide,
IdPlan = null,
CategoryInfo = "Доп.инфо",
LastUpdateDate = new DateTimeOffset(new DateTime(2023, 1, 10)).ToUniversalTime(),
IdType = idType,
DepthStart = 10.0,
DepthEnd = 20.0,
DateStart = new DateTimeOffset(new DateTime(2023, 1, 10), TimeSpan.FromHours(Defaults.Timezone.Hours)).ToUniversalTime(),
DurationHours = 1.0,
Comment = "1",
IdUser = 1,
};
}