Юнит тест для проверки метода GetTvdAsync сервиса WellOperationService

This commit is contained in:
Olga Nemt 2024-08-16 18:02:12 +05:00
parent 0d91c39f24
commit fdb6dd3b65
4 changed files with 139 additions and 88 deletions

View File

@ -36,14 +36,6 @@ namespace AsbCloudApp.Services
/// <returns></returns> /// <returns></returns>
Task<StatWellDto?> GetOrDefaultWellStatAsync(int idWell, CancellationToken token); Task<StatWellDto?> GetOrDefaultWellStatAsync(int idWell, CancellationToken token);
/// <summary>
/// Получить данные для графика TVD
/// </summary>
/// <param name="idWell"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<PlanFactPredictBase<WellOperationDto>>> GetTvdAsync(int idWell, CancellationToken token);
/// <summary> /// <summary>
/// Получить статистику по набору скважин /// Получить статистику по набору скважин
/// </summary> /// </summary>

View File

@ -418,82 +418,6 @@ public class OperationsStatService : IOperationsStatService
return dDepth / (dHours + double.Epsilon); return dDepth / (dHours + double.Epsilon);
} }
public async Task<IEnumerable<PlanFactPredictBase<WellOperationDto>>> GetTvdAsync(int idWell, CancellationToken token)
{
var wellOperations = (await GetOperationsAsync(idWell, token)).ToArray();
if (!wellOperations.Any())
return Enumerable.Empty<PlanFactPredictBase<WellOperationDto>>();
var tzOffsetHours = wellService.GetTimezone(idWell).Hours;
var tvd = new List<PlanFactPredictBase<WellOperationDto>>(wellOperations.Length);
var (Plan, Fact) = wellOperations.FirstOrDefault();
var dateStart = Plan?.DateStart ?? Fact!.DateStart;
int? iLastMatch = null;
int iLastFact = 0;
var nptHours = 0d;
DateTimeOffset? firstDateStartFact = Fact!.DateStart;
DateTimeOffset? firstDateStartPlan = Plan?.DateStart;
for (int i = 0; i < wellOperations.Length; i++)
{
var item = wellOperations[i];
var plan = item.Plan;
var fact = item.Fact;
var planFactPredict = new PlanFactPredictBase<WellOperationDto>();
if (plan is not null)
{
planFactPredict.Plan = Convert(plan, tzOffsetHours);
if (!firstDateStartPlan.HasValue) {
firstDateStartPlan = planFactPredict.Plan.DateStart;
}
planFactPredict.Plan.Day = (planFactPredict.Plan.DateStart - firstDateStartPlan.Value).TotalDays;
if (fact is not null)
iLastMatch = i;
}
if (fact is not null)
{
if(WellOperationCategory.NonProductiveTimeSubIds.Contains(fact.IdCategory))
nptHours += fact.DurationHours;
planFactPredict.Fact = Convert(fact, tzOffsetHours);
planFactPredict.Fact.Day = (planFactPredict.Fact.DateStart - firstDateStartFact.Value).TotalDays;
planFactPredict.Fact.NptHours = nptHours;
iLastFact = i;
}
tvd.Add(planFactPredict);
}
if (iLastMatch is null || iLastMatch == wellOperations.Length - 1)
return tvd;
var lastMatchPlan = wellOperations[iLastMatch.Value].Plan!;
var lastMatchPlanOperationEnd = lastMatchPlan.DateStart.AddHours(lastMatchPlan.DurationHours);
var lastFact = wellOperations[iLastFact].Fact!;
var lastFactDateEnd = lastFact.DateStart.AddHours(lastFact.DurationHours);
var startOffset = lastFactDateEnd - lastMatchPlanOperationEnd;
for (int i = iLastMatch.Value + 1; i < wellOperations.Length; i++)
{
if (wellOperations[i].Plan is null)
continue;
var predict = Convert(wellOperations[i].Plan!, tzOffsetHours);
predict.IdType = 2;
predict.DateStart = predict.DateStart + startOffset;
predict.Day = (predict.DateStart - dateStart).TotalDays;
tvd[i].Predict = predict;
}
return tvd;
}
private async Task<IEnumerable<(WellOperation? Plan, WellOperation? Fact)>> GetOperationsAsync(int idWell, CancellationToken token) private async Task<IEnumerable<(WellOperation? Plan, WellOperation? Fact)>> GetOperationsAsync(int idWell, CancellationToken token)
{ {
var query = db.WellOperations var query = db.WellOperations

View File

@ -15,7 +15,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
{ {
public class ScheduleReportService : IScheduleReportService public class ScheduleReportService : IScheduleReportService
{ {
private readonly IOperationsStatService operationsStatService; private readonly IWellOperationService wellOperationService;
private readonly IWellService wellService; private readonly IWellService wellService;
const string sheetNameSchedule = "Сетевой график"; const string sheetNameSchedule = "Сетевой график";
const string sheetNameSchedulePlan = "План"; const string sheetNameSchedulePlan = "План";
@ -24,15 +24,15 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
const string sheetNameTvd = "ГГД"; const string sheetNameTvd = "ГГД";
const int maxChartsToWrap = 88; const int maxChartsToWrap = 88;
public ScheduleReportService(IOperationsStatService operationsStatService, IWellService wellService) public ScheduleReportService(IWellOperationService wellOperationService, IWellService wellService)
{ {
this.operationsStatService = operationsStatService; this.wellOperationService = wellOperationService;
this.wellService = wellService; this.wellService = wellService;
} }
public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token = default) public async Task<Stream> MakeReportAsync(int idWell, CancellationToken token = default)
{ {
var tvd = await operationsStatService.GetTvdAsync(idWell, token); var tvd = await wellOperationService.GetTvdAsync(idWell, token);
var well = await wellService.GetOrDefaultAsync(idWell, token) var well = await wellService.GetOrDefaultAsync(idWell, token)
?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist"); ?? throw new ArgumentInvalidException(nameof(idWell), "idWell doesn`t exist");

View File

@ -0,0 +1,135 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.WellOperation;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository;
using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.WellOperationService.WellOperationService;
using Mapster;
using NSubstitute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace AsbCloudWebApi.Tests.Services;
public class WellOperationServiceTest
{
private const int idWell = 1;
private readonly IWellOperationService wellOperationServiceMock = Substitute.For<IWellOperationService>();
private readonly IWellOperationRepository wellOperationRepositoryMock = Substitute.For<IWellOperationRepository>();
private readonly IWellService wellServiceMock = Substitute.For<IWellService>();
private readonly IWellOperationCategoryRepository wellOperationCategoryRepositoryMock = Substitute.For<IWellOperationCategoryRepository>();
private readonly SimpleTimezoneDto timeZone = new SimpleTimezoneDto()
{
Hours = 5,
};
private readonly WellOperationBaseDto wellOperation = new WellOperationBaseDto()
{
IdWell = idWell,
Id = 1,
IdType = WellOperation.IdOperationTypeFact,
DepthStart = 1,
DepthEnd = 2,
DateStart = DateTimeOffset.UtcNow,
DurationHours = 3,
IdCategory = WellOperationCategory.NonProductiveTimeSubIds.FirstOrDefault(),
IdWellSectionType = 1
};
private readonly List<WellOperationBaseDto> wellOperations = new List<WellOperationBaseDto>();
private readonly IEnumerable<PlanFactPredictBase<WellOperationDto>> tvds = new List<PlanFactPredictBase<WellOperationDto>>()
{
new PlanFactPredictBase<WellOperationDto>()
{
Fact = new WellOperationDto(),
Plan = new WellOperationDto(),
Predict = new WellOperationDto()
}
};
public WellOperationServiceTest()
{
//wellOperationServiceMock.GetTvdAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
// .Returns(tvds);
wellServiceMock
.GetTimezone(Arg.Any<int>())
.Returns(timeZone);
//фактическая операция, у которой нет плановой для сопоставления
var wellOperation1 = wellOperation.Adapt<WellOperationBaseDto>();
//фактическая операция, у которой есть плановая для сопоставления
var wellOperation2 = wellOperation1.Adapt<WellOperationBaseDto>();
wellOperation2.Id = wellOperation1.Id + 1;
wellOperation2.IdPlan = wellOperation1.Id;
wellOperation2.IdType = WellOperation.IdOperationTypeFact;
wellOperation2.DateStart = wellOperation1.DateStart.AddDays(1);
//плановая операция
var wellOperation3 = wellOperation1.Adapt<WellOperationBaseDto>();
wellOperation3.Id = wellOperation1.Id + 2;
wellOperation3.IdType = WellOperation.IdOperationTypePlan;
wellOperation3.DateStart = wellOperation1.DateStart.AddDays(2);
wellOperations.Add(wellOperation1);
wellOperations.Add(wellOperation2);
wellOperations.Add(wellOperation3);
wellOperationRepositoryMock.GetAll(Arg.Any<WellOperationRepositoryRequest>(), Arg.Any<CancellationToken>())
.Returns(wellOperations);
wellOperationServiceMock = new WellOperationService(wellServiceMock, wellOperationRepositoryMock, wellOperationCategoryRepositoryMock);
}
[Fact]
public async Task GetTvdAsync_ShouldReturn_Success()
{
var factOperations = wellOperations
.Where(o => o.IdType == WellOperation.IdOperationTypeFact);
//act
var data = await wellOperationServiceMock.GetTvdAsync(idWell, CancellationToken.None);
var actualFactNptHours = data
.Where(o => o.Fact != null)
.Select(o => o.Fact!.NptHours)
.ToArray();
var factOperationsWithNpt = factOperations
.Where(o => WellOperationCategory.NonProductiveTimeSubIds.Contains(o.IdCategory));
var expectedFactNptHours = factOperations
.Select(dto =>
{
var nptHours = factOperationsWithNpt
.Where(o => o.DateStart <= dto.DateStart)
.Sum(e => e.DurationHours);
return nptHours;
});
var actualFactDays = data
.Where(o => o.Fact != null)
.Select(o => o.Fact!.Day)
.ToArray();
var firstWellOperation = factOperations.MinBy(e => e.DateStart)!;
var expectedFactDays = factOperations
.Select(dto =>
{
var day = (dto.DateStart - firstWellOperation.DateStart).TotalDays;
return day;
});
//assert
Assert.Equal(expectedFactNptHours, actualFactNptHours);
Assert.Equal(expectedFactDays, actualFactDays);
}
}