forked from ddrilling/AsbCloudServer
Merge branch 'CrudWellRelatedTest' into dev
This commit is contained in:
commit
adf19cf7f7
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
@ -6,7 +7,7 @@ namespace AsbCloudApp.Data
|
||||
/// <summary>
|
||||
/// Описание данных графика работ
|
||||
/// </summary>
|
||||
public class ScheduleDto : IId, IWellRelated
|
||||
public class ScheduleDto : IId, IWellRelated, IValidatableObject
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[Required]
|
||||
@ -50,5 +51,12 @@ namespace AsbCloudApp.Data
|
||||
/// Бурильщик
|
||||
/// </summary>
|
||||
public DrillerDto? Driller { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if(DrillStart >= DrillEnd)
|
||||
yield return new ValidationResult($"DrillStart > DrillEnd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,5 +43,4 @@ namespace AsbCloudInfrastructure.Repository
|
||||
return dtos;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
using AsbCloudApp.Data;
|
||||
using Refit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||
|
||||
public interface ICrudWellRelatedClient<TDto>
|
||||
where TDto : IId, IWellRelated
|
||||
{
|
||||
[Post("/")]
|
||||
Task<IApiResponse<int>> InsertAsync([Body] TDto dto);
|
||||
|
||||
[Post("/range")]
|
||||
Task<IApiResponse<int>> InsertRangeAsync([Body] IEnumerable<TDto> dtos);
|
||||
|
||||
[Get("/")]
|
||||
Task<IApiResponse<IEnumerable<TDto>>> GetAllAsync();
|
||||
|
||||
[Get("/well/{idWell}")]
|
||||
Task<IApiResponse<IEnumerable<TDto>>> GetByIdWellAsync(int idWell);
|
||||
|
||||
[Get("/{id}")]
|
||||
Task<IApiResponse<TDto>> GetOrDefaultAsync(int id);
|
||||
|
||||
[Put("/")]
|
||||
Task<IApiResponse<int>> UpdateAsync([Body] TDto dto);
|
||||
|
||||
[Delete("/{id}")]
|
||||
Task<IApiResponse<int>> DeleteAsync(int id);
|
||||
}
|
@ -26,7 +26,7 @@ public class AdminDepositControllerTest : BaseIntegrationTest
|
||||
public AdminDepositControllerTest(WebAppFactoryFixture factory)
|
||||
: base(factory)
|
||||
{
|
||||
client = factory.GetAuthorizedHttpClient<IAdminDepositClient>();
|
||||
client = factory.GetAuthorizedHttpClient<IAdminDepositClient>(string.Empty);
|
||||
|
||||
dbContext.CleanupDbSet<Deposit>();
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
||||
public ProcessMapPlanDrillingControllerTest(WebAppFactoryFixture factory) : base(factory)
|
||||
{
|
||||
dbContext.CleanupDbSet<ProcessMapPlanDrilling>();
|
||||
client = factory.GetAuthorizedHttpClient<IProcessMapPlanDrillingClient>();
|
||||
client = factory.GetAuthorizedHttpClient<IProcessMapPlanDrillingClient>(string.Empty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -0,0 +1,228 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers
|
||||
{
|
||||
public abstract class CrudWellRelatedClient<TDto, TEntity> : BaseIntegrationTest
|
||||
where TDto : AsbCloudApp.Data.IId, AsbCloudApp.Data.IWellRelated
|
||||
where TEntity : class, AsbCloudDb.Model.IId, AsbCloudDb.Model.IWellRelated
|
||||
{
|
||||
public abstract IEnumerable<TDto> ValidDtos { get; }
|
||||
public abstract IEnumerable<TDto> InvalidDtos { get; }
|
||||
public abstract IEnumerable<TDto> ForbiddenDtos { get; }
|
||||
protected List<string> ExcludeProps { get; set; } = new() { "Id" };
|
||||
|
||||
protected ICrudWellRelatedClient<TDto> client;
|
||||
|
||||
public CrudWellRelatedClient(WebAppFactoryFixture factory, string uriSuffix)
|
||||
: base(factory)
|
||||
{
|
||||
client = factory.GetAuthorizedHttpClient<ICrudWellRelatedClient<TDto>>(uriSuffix);
|
||||
}
|
||||
|
||||
protected async Task<DbSet<TEntity>> GetCleanDbSet()
|
||||
{
|
||||
var dbset = dbContext.Set<TEntity>();
|
||||
dbset.RemoveRange(dbset);
|
||||
await dbContext.SaveChangesAsync(CancellationToken.None);
|
||||
return dbset;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Insert_returns_success_for_validDtos()
|
||||
{
|
||||
foreach (var validDto in ValidDtos)
|
||||
await Insert_returns_success(validDto);
|
||||
}
|
||||
|
||||
private async Task Insert_returns_success(TDto validDto)
|
||||
{
|
||||
var dbset = await GetCleanDbSet();
|
||||
|
||||
//act
|
||||
var response = await client.InsertAsync(validDto);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.True(response.Content > 0);
|
||||
|
||||
var entity = dbset.First();
|
||||
var fromDbDto = Convert(entity);
|
||||
MatchHelper.Match(validDto, fromDbDto, ExcludeProps);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Insert_returns_badRequest_for_invalidDtos()
|
||||
{
|
||||
foreach (var inValidDto in InvalidDtos)
|
||||
await Insert_returns_badRequest(inValidDto);
|
||||
}
|
||||
|
||||
private async Task Insert_returns_badRequest(TDto invalidDto)
|
||||
{
|
||||
await GetCleanDbSet();
|
||||
|
||||
//act
|
||||
var response = await client.InsertAsync(invalidDto);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Insert_returns_forbidden_for_forbiddenDtos()
|
||||
{
|
||||
foreach (var forbiddenDto in ForbiddenDtos)
|
||||
await Insert_returns_forbidden(forbiddenDto);
|
||||
}
|
||||
|
||||
private async Task Insert_returns_forbidden(TDto forbiddenDto)
|
||||
{
|
||||
await GetCleanDbSet();
|
||||
|
||||
//act
|
||||
var response = await client.InsertAsync(forbiddenDto);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllAsync_returns_data()
|
||||
{
|
||||
//arrange
|
||||
var dbset = await GetCleanDbSet();
|
||||
var entries = new List<(EntityEntry<TEntity>, TDto)>();
|
||||
|
||||
foreach (var dto in ValidDtos)
|
||||
{
|
||||
var entity = Convert(dto);
|
||||
entity.Id = 0;
|
||||
var entry = dbset.Add(entity);
|
||||
entries.Add((entry, dto));
|
||||
}
|
||||
dbContext.SaveChanges();
|
||||
|
||||
//act
|
||||
var response = await client.GetAllAsync();
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.NotNull(response.Content);
|
||||
Assert.Equal(entries.Count, response.Content.Count());
|
||||
|
||||
foreach (var item in response.Content)
|
||||
{
|
||||
var entry = entries.First(e => e.Item1.Entity.Id == item.Id);
|
||||
MatchHelper.Match(entry.Item2, item, ExcludeProps);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual TDto Convert(TEntity entity)
|
||||
{
|
||||
var dto = entity.Adapt<TDto>();
|
||||
return dto;
|
||||
}
|
||||
|
||||
protected virtual TEntity Convert(TDto dto)
|
||||
{
|
||||
var entity = dto.Adapt<TEntity>();
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScheduleControllerTest : CrudWellRelatedClient<ScheduleDto, Schedule>
|
||||
{
|
||||
static Driller driller = Data.Defaults.Drillers.First();
|
||||
static DrillerDto drillerDto = driller.Adapt<DrillerDto>();
|
||||
|
||||
static Well well = Data.Defaults.Wells.First();
|
||||
|
||||
public override IEnumerable<ScheduleDto> ValidDtos { get; } = new ScheduleDto[]
|
||||
{
|
||||
new() {
|
||||
Id = 1,
|
||||
IdWell = well.Id,
|
||||
Driller = drillerDto,
|
||||
IdDriller = driller.Id,
|
||||
DrillStart = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
DrillEnd = new DateTime(2024, 1, 2, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
ShiftStart = new TimeDto(8, 0, 0),
|
||||
ShiftEnd = new TimeDto(20, 0, 0),
|
||||
},
|
||||
new() {
|
||||
Id = 1,
|
||||
IdWell = well.Id,
|
||||
Driller = drillerDto,
|
||||
IdDriller = driller.Id,
|
||||
DrillStart = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
DrillEnd = new DateTime(2024, 1, 2, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
ShiftStart = new TimeDto(20, 0, 0),
|
||||
ShiftEnd = new TimeDto(8, 0, 0),
|
||||
}
|
||||
};
|
||||
|
||||
public override IEnumerable<ScheduleDto> InvalidDtos { get; } = new ScheduleDto[]
|
||||
{
|
||||
new() {
|
||||
IdWell = well.Id,
|
||||
Driller = drillerDto,
|
||||
IdDriller = driller.Id,
|
||||
DrillStart = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
DrillEnd = new DateTime(2022, 1, 2, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
ShiftStart = new TimeDto(8, 0, 0),
|
||||
ShiftEnd = new TimeDto(20, 0, 0),
|
||||
},
|
||||
new() {
|
||||
IdWell = well.Id,
|
||||
Driller = drillerDto,
|
||||
IdDriller = int.MaxValue - 1,
|
||||
DrillStart = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
DrillEnd = new DateTime(2024, 1, 2, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
ShiftStart = new TimeDto(8, 0, 0),
|
||||
ShiftEnd = new TimeDto(20, 0, 0),
|
||||
}
|
||||
};
|
||||
|
||||
public override IEnumerable<ScheduleDto> ForbiddenDtos { get; } = new ScheduleDto[] {
|
||||
new() {
|
||||
IdWell = int.MaxValue - 1,
|
||||
Driller = drillerDto,
|
||||
IdDriller = driller.Id,
|
||||
DrillStart = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
DrillEnd = new DateTime(2022, 1, 2, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
ShiftStart = new TimeDto(8, 0, 0),
|
||||
ShiftEnd = new TimeDto(20, 0, 0),
|
||||
}
|
||||
};
|
||||
|
||||
public ScheduleControllerTest(WebAppFactoryFixture factory)
|
||||
: base(factory, "api/schedule")
|
||||
{
|
||||
ExcludeProps.Add(nameof(ScheduleDto.Driller));
|
||||
}
|
||||
|
||||
protected override ScheduleDto Convert(Schedule entity)
|
||||
{
|
||||
var dto = base.Convert(entity);
|
||||
dto.DrillStart = entity.DrillStart.ToRemoteDateTime(well.Timezone.Hours);
|
||||
dto.DrillEnd = entity.DrillEnd.ToRemoteDateTime(well.Timezone.Hours);
|
||||
return dto;
|
||||
}
|
||||
|
||||
protected override Schedule Convert(ScheduleDto dto)
|
||||
{
|
||||
var entity = base.Convert(dto);
|
||||
entity.DrillStart = dto.DrillStart.FromTimeZoneOffsetHours(well.Timezone.Hours);
|
||||
entity.DrillEnd = dto.DrillEnd.FromTimeZoneOffsetHours(well.Timezone.Hours);
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
}
|
@ -66,7 +66,7 @@ public class SlipsStatControllerTest : BaseIntegrationTest
|
||||
wellOperations.Add(factWellOperation);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
client = factory.GetAuthorizedHttpClient<ISlipsTimeClient>();
|
||||
client = factory.GetAuthorizedHttpClient<ISlipsTimeClient>(string.Empty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -44,7 +44,7 @@ public class WellOperationControllerTest : BaseIntegrationTest
|
||||
public WellOperationControllerTest(WebAppFactoryFixture factory)
|
||||
: base(factory)
|
||||
{
|
||||
client = factory.GetAuthorizedHttpClient<IWellOperationClient>();
|
||||
client = factory.GetAuthorizedHttpClient<IWellOperationClient>(string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -10,8 +10,16 @@ namespace AsbCloudWebApi.IntegrationTests.Data
|
||||
new()
|
||||
{
|
||||
Id = 1,
|
||||
Name = "test",
|
||||
Surname = "test"
|
||||
Name = "test1",
|
||||
Surname = "test1",
|
||||
Patronymic = "test1"
|
||||
},
|
||||
new()
|
||||
{
|
||||
Id = 2,
|
||||
Name = "test2",
|
||||
Surname = "test2",
|
||||
Patronymic = "test2"
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,10 +83,12 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>,
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public T GetAuthorizedHttpClient<T>()
|
||||
public T GetAuthorizedHttpClient<T>(string uriSuffix)
|
||||
{
|
||||
var httpClient = GetAuthorizedHttpClient();
|
||||
if (!string.IsNullOrEmpty(uriSuffix))
|
||||
if(httpClient.BaseAddress is not null)
|
||||
httpClient.BaseAddress = new Uri(httpClient.BaseAddress, uriSuffix);
|
||||
return RestService.For<T>(httpClient, refitSettings);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user