forked from ddrilling/AsbCloudServer
Валидация вставки / обновления + интеграционные тесты (начало)
This commit is contained in:
parent
f9504aea21
commit
011a479a4b
@ -2,6 +2,7 @@
|
||||
using AsbCloudApp.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -120,7 +121,7 @@ namespace AsbCloudApp.Repositories
|
||||
/// </summary>
|
||||
/// <param name="wellOperations"></param>
|
||||
/// <returns></returns>
|
||||
bool Validate(IEnumerable<WellOperationDto> wellOperations);
|
||||
IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperations);
|
||||
|
||||
/// <summary>
|
||||
/// Валидация данных (проверка с базой)
|
||||
@ -128,6 +129,6 @@ namespace AsbCloudApp.Repositories
|
||||
/// <param name="wellOperations"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
|
||||
IEnumerable<ValidationResult> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperations, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -333,12 +334,12 @@ public class WellOperationRepository : IWellOperationRepository
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<bool> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
|
||||
public IEnumerable<ValidationResult> ValidateWithDbAsync(IEnumerable<WellOperationDto> wellOperationDtos, CancellationToken token)
|
||||
{
|
||||
var firstOperation = wellOperationDtos
|
||||
.FirstOrDefault();
|
||||
if (firstOperation is null)
|
||||
return false;
|
||||
return Enumerable.Empty<ValidationResult>();
|
||||
|
||||
var request = new WellOperationRequest()
|
||||
{
|
||||
@ -346,53 +347,51 @@ public class WellOperationRepository : IWellOperationRepository
|
||||
OperationType = firstOperation.IdType,
|
||||
};
|
||||
|
||||
var entities = await BuildQuery(request)
|
||||
var entities = BuildQuery(request)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
.ToArray();
|
||||
|
||||
if (!entities.Any())
|
||||
return Validate(wellOperationDtos);
|
||||
var wellOperationsUnion = entities.Union(wellOperationDtos).OrderBy(o => o.DateStart);
|
||||
|
||||
var wellOperationsUnion = entities.Union(wellOperationDtos).OrderBy(o => o.DateStart).ToArray();
|
||||
return Validate(wellOperationsUnion);
|
||||
}
|
||||
|
||||
for(var i = 1; i < wellOperationsUnion.Count(); i++)
|
||||
public IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperationDtos)
|
||||
{
|
||||
var firstOperation = wellOperationDtos
|
||||
.FirstOrDefault();
|
||||
if (firstOperation is null)
|
||||
return Enumerable.Empty<ValidationResult>();
|
||||
|
||||
var validationResults = new List<ValidationResult>();
|
||||
|
||||
var wellOperations = wellOperationDtos.ToArray();
|
||||
for (var i = wellOperations.Count() - 1; i >= 1; i--)
|
||||
{
|
||||
var prevOperation = wellOperationsUnion[i - 1];
|
||||
var currentOperation = wellOperationsUnion[i];
|
||||
var prevOperation = wellOperations[i - 1];
|
||||
var currentOperation = wellOperations[i];
|
||||
|
||||
var prevOperationDateStart = prevOperation.DateStart.ToUniversalTime();
|
||||
var currentOperationDateStart = currentOperation.DateStart.ToUniversalTime();
|
||||
|
||||
var prevOperationDateEnd = prevOperation.DateStart.AddHours(prevOperation.DurationHours).ToUniversalTime();
|
||||
var currrentOperationDateEnd = currentOperation.DateStart.AddHours(currentOperation.DurationHours).ToUniversalTime();
|
||||
|
||||
if (currentOperation.Id == 0 && ((prevOperationDateStart.AddDays(Gap) < currentOperationDateStart) || (prevOperationDateEnd >= currrentOperationDateEnd)))
|
||||
if (prevOperationDateStart.AddDays(Gap) < currentOperationDateStart)
|
||||
{
|
||||
return false;
|
||||
validationResults.Add(new ValidationResult(
|
||||
$"Разница дат между операциями не должна превышать 90 дней",
|
||||
new[] { nameof(wellOperations) }));
|
||||
}
|
||||
|
||||
if (prevOperationDateEnd > currentOperationDateStart)
|
||||
{
|
||||
validationResults.Add(new ValidationResult(
|
||||
$"Предыдущая операция не завершена",
|
||||
new[] { nameof(wellOperations) }));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Validate(IEnumerable<WellOperationDto> wellOperationDtos)
|
||||
{
|
||||
var firstOperation = wellOperationDtos
|
||||
.FirstOrDefault();
|
||||
if (firstOperation is null)
|
||||
return false;
|
||||
|
||||
var maxOperationDateStart = firstOperation.DateStart.ToUniversalTime();
|
||||
|
||||
foreach (var dto in wellOperationDtos)
|
||||
{
|
||||
var currentOperationDateStart = dto.DateStart.ToUniversalTime();
|
||||
if (maxOperationDateStart.AddDays(Gap) < currentOperationDateStart)
|
||||
return false;
|
||||
|
||||
maxOperationDateStart = currentOperationDateStart;
|
||||
}
|
||||
return true;
|
||||
return validationResults;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -0,0 +1,14 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMapPlan;
|
||||
using AsbCloudApp.Requests;
|
||||
using Refit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Clients;
|
||||
|
||||
public interface IWellOperationClient
|
||||
{
|
||||
private const string BaseRoute = "/api/wellOperation";
|
||||
|
||||
[Post(BaseRoute)]
|
||||
Task<IApiResponse<int>> InsertRange(int idWell, [Body] IEnumerable<WellOperationDto> dtos);
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.ProcessMapPlan;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.ProcessMaps;
|
||||
using AsbCloudWebApi.IntegrationTests.Clients;
|
||||
using System.Net;
|
||||
using Xunit;
|
||||
|
||||
namespace AsbCloudWebApi.IntegrationTests.Controllers;
|
||||
|
||||
|
||||
public class WellOperationControllerTest : BaseIntegrationTest
|
||||
{
|
||||
private readonly int idWell = 4;
|
||||
|
||||
private readonly WellOperationDto[] dtos = new WellOperationDto[]
|
||||
{
|
||||
new WellOperationDto()
|
||||
{
|
||||
|
||||
},
|
||||
new WellOperationDto()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
private IWellOperationClient wellOperationClient;
|
||||
|
||||
public WellOperationControllerTest(WebAppFactoryFixture factory)
|
||||
: base(factory)
|
||||
{
|
||||
wellOperationClient = factory.GetAuthorizedHttpClient<IWellOperationClient>();
|
||||
var rep = factory.Get
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Успешное добавление операции с предварительной очисткой
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task InsertRangeWithDeleteBefore_returns_success()
|
||||
{
|
||||
////arrange
|
||||
//dbContext.WellOperations.Add(wellOperation);
|
||||
//dbContext.SaveChanges();
|
||||
|
||||
//var request = new OperationStatRequest
|
||||
//{
|
||||
// DateStartUTC = schedule.DrillStart.DateTime,
|
||||
// DateEndUTC = schedule.DrillEnd.DateTime,
|
||||
// DurationMinutesMin = 0,
|
||||
// DurationMinutesMax = 5
|
||||
//};
|
||||
|
||||
//var dtoExpected = new SlipsStatDto
|
||||
//{
|
||||
// DrillerName = $"{Data.Defaults.Drillers[0].Surname} {Data.Defaults.Drillers[0].Name} {Data.Defaults.Drillers[0].Patronymic}",
|
||||
// WellCount = 1,
|
||||
// SectionCaption = "Пилотный ствол",
|
||||
// SlipsCount = 1,
|
||||
// SlipsTimeInMinutes = (detectedOperation.DateEnd - detectedOperation.DateStart).TotalMinutes,
|
||||
// SectionDepth = factWellOperation.DepthEnd - factWellOperation.DepthStart,
|
||||
//};
|
||||
|
||||
////act
|
||||
//var response = await slipsTimeClient.GetAll(request);
|
||||
|
||||
////assert
|
||||
//Assert.NotNull(response.Content);
|
||||
//Assert.Single(response.Content);
|
||||
|
||||
//var dtoActual = response.Content.First();
|
||||
//MatchHelper.Match(dtoExpected, dtoActual);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Успешное добавление операции без очистки
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_success() {
|
||||
//arrange
|
||||
var dbset = dbContext.Set<WellOperation>();
|
||||
dbset.RemoveRange(dbset);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
operationRepository.Validate(dtos);
|
||||
|
||||
//act
|
||||
var response = await wellOperationClient.InsertRange(idWell, dtos);
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Неуспешное добавление операции с предварительной очисткой
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task InsertRangeWithDeleteBefore_returns_error()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Неуспешное добавление операции без очистки
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_error()
|
||||
{
|
||||
}
|
||||
}
|
@ -237,7 +237,8 @@ namespace AsbCloudWebApi.Controllers
|
||||
wellOperation.IdUser = User.GetUserId();
|
||||
wellOperation.IdType = idType;
|
||||
|
||||
if (!await operationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken))
|
||||
var validationResult = operationRepository.ValidateWithDbAsync(new[] { wellOperation }, cancellationToken);
|
||||
if(validationResult.Any())
|
||||
return this.ValidationBadRequest(nameof(wellOperation), "The date difference between the operations is more than 3 months");
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(new[] { wellOperation }, cancellationToken);
|
||||
@ -291,7 +292,8 @@ namespace AsbCloudWebApi.Controllers
|
||||
}
|
||||
|
||||
|
||||
if (!await Validate(wellOperations, deleteBeforeInsert, cancellationToken))
|
||||
var validationResult = Validate(wellOperations, deleteBeforeInsert, cancellationToken);
|
||||
if (validationResult.Any())
|
||||
return this.ValidationBadRequest(nameof(wellOperations), "The date difference between the operations is more than 3 months");
|
||||
|
||||
var result = await operationRepository.InsertRangeAsync(wellOperations, cancellationToken);
|
||||
@ -307,12 +309,12 @@ namespace AsbCloudWebApi.Controllers
|
||||
/// <param name="deleteBeforeInsert"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> Validate(IEnumerable<WellOperationDto> wellOperations, bool deleteBeforeInsert, CancellationToken cancellationToken)
|
||||
private IEnumerable<ValidationResult> Validate(IEnumerable<WellOperationDto> wellOperations, bool deleteBeforeInsert, CancellationToken cancellationToken)
|
||||
{
|
||||
if (deleteBeforeInsert)
|
||||
return operationRepository.Validate(wellOperations);
|
||||
else
|
||||
return await operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
|
||||
return operationRepository.ValidateWithDbAsync(wellOperations, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -340,7 +342,8 @@ namespace AsbCloudWebApi.Controllers
|
||||
value.LastUpdateDate = DateTimeOffset.UtcNow;
|
||||
value.IdUser = User.GetUserId();
|
||||
|
||||
if (!await operationRepository.ValidateWithDbAsync(new[] { value }, token))
|
||||
var validationResult = operationRepository.ValidateWithDbAsync(new[] { value }, token);
|
||||
if (validationResult.Any())
|
||||
return this.ValidationBadRequest(nameof(value), "The date difference between the operations is more than 3 months");
|
||||
|
||||
var result = await operationRepository.UpdateAsync(value, token)
|
||||
|
Loading…
Reference in New Issue
Block a user