DD.WellWorkover.Cloud/AsbCloudWebApi.Tests/Services/DailyReportServiceTest.cs

584 lines
21 KiB
C#
Raw Normal View History

using AsbCloudApp.Data;
using AsbCloudApp.Data.DailyReport;
using AsbCloudApp.Data.DailyReport.Blocks.Sign;
using AsbCloudApp.Data.DailyReport.Blocks.Subsystems;
using AsbCloudApp.Data.DailyReport.Blocks.TimeBalance;
using AsbCloudApp.Data.DetectedOperation;
using AsbCloudApp.Data.ProcessMaps.Report;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Data.Trajectory;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.ProcessMaps.WellDrilling;
using AsbCloudInfrastructure.Services.DailyReport;
using NSubstitute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace AsbCloudWebApi.Tests.Services;
public class DailyReportServiceTest
{
private const int idDailyReport = 1;
private const int idUser = 3;
private const int idWell = 2;
private readonly SubsystemBlockDto fakeSubsystemBlock = new()
{
IdUser = idUser,
Wellbore = 999,
MeasurementsPerDay = 999,
TotalRopPlan = 999,
Comment = "Увеличить обороты",
Subsystems = new[]
{
new SubsystemRecordDto
{
Name = "АвтоСПО",
UsagePerDay = new SubsystemParametersDto
{
UsedTimeHours = 24,
SumDepthInterval = 1500,
KUsage = 15
},
UsagePerWell = new SubsystemParametersDto
{
UsedTimeHours = 500,
SumDepthInterval = 3000,
KUsage = 100
}
}
}
};
private readonly SignBlockDto fakeSignBlock = new()
{
IdUser = idUser,
DrillingMaster = new SignRecordDto
{
Name = "Иван",
Patronymic = "Иванович",
Surname = "Иванов"
},
Supervisor = new SignRecordDto()
{
Name = "Илья",
Patronymic = "Ильич",
Surname = "Бурилов"
}
};
private readonly TimeBalanceBlockDto fakeTimeBalanceBlock = new()
{
IdUser = idUser,
IdSection = 1,
WellDepth = new PlanFactDto<double?>
{
Plan = 2000
},
WellOperations = new[]
{
new TimeBalanceRecordDto
{
IdWellOperation = 1,
DurationHours = new PlanFactDto<double?>
{
Fact = 100,
Plan = 150,
},
DrillingDeviationPerSection = 90,
DrillingDeviationPerDay = 100,
ReasonDeviation = "Отклонение"
}
}
};
private readonly DetectedOperationListDto fakeWellOperationSlipsTime = new()
{
Stats = new[]
{
new DetectedOperationDrillersStatDto
{
Count = 40
}
}
};
private readonly ProcessMapReportDataSaubStatDto fakeProcessMapReportWellDrilling = new()
{
DrillingMode = "Ротор",
DateStart = new DateTimeOffset(2023, 10, 26, 0, 0, 0, TimeSpan.Zero),
DeltaDepth = 500,
Rop = new PlanFactDto<double?>
{
Plan = 300,
Fact = 500
},
DrilledTime = 100
};
private readonly WellSectionTypeDto fakeSectionType = new()
{
Id = 1,
Caption = "Пилотный ствол",
};
private readonly TrajectoryGeoFactDto fakeLastFactTrajectory = new()
{
WellboreDepth = 100,
VerticalDepth = 150,
ZenithAngle = 3,
AzimuthGeo = 5
};
private readonly CompanyDto fakeCustomer = new()
{
Caption = "Тестовый заказчик",
IdCompanyType = 1
};
private readonly CompanyDto fakeContractor = new()
{
Caption = "Тестовый подрядчик",
IdCompanyType = 2
};
private readonly WellOperationDto fakeFirstFactWellOperation = new()
{
IdWell = idWell,
IdParentCategory = 4001,
IdWellSectionType = 1,
CategoryName = "Механическое. бурение",
DateStart = new DateTime(2023, 10, 26),
DepthStart = 80,
DepthEnd = 150,
DurationHours = 8,
};
private readonly WellOperationDto fakeLastFactWellOperation = new()
{
IdWell = idWell,
CategoryName = "Механическое. бурение",
IdWellSectionType = 1,
IdParentCategory = 4001,
DateStart = new DateTime(2023, 10, 26),
DepthStart = 150,
DepthEnd = 200,
DurationHours = 8,
};
private readonly ScheduleDto fakeShedule = new()
{
IdWell = idWell,
ShiftStart = new TimeDto(1),
ShiftEnd = new TimeDto(5),
DrillStart = new DateTimeOffset(2023, 01, 26, 0, 0, 0, TimeSpan.Zero),
DrillEnd = new DateTimeOffset(2023, 12, 26, 0, 0, 0, TimeSpan.Zero),
Driller = new()
{
Name = "Иван",
Surname = "Иванов",
Patronymic = "Бурила"
}
};
private readonly SubsystemStatDto fakeSubsystemsStat = new()
{
SubsystemName = "АПД",
SumDepthInterval = 250,
UsedTimeHours = 200,
KUsage = 30
};
private readonly SimpleTimezoneDto fakeWellTimezone = new()
{
Hours = 5,
};
private readonly IWellService wellServiceMock = Substitute.For<IWellService>();
private readonly ITrajectoryNnbRepository trajectoryFactNnbRepositoryMock = Substitute.For<ITrajectoryNnbRepository>();
private readonly IDailyReportRepository dailyReportRepositoryMock = Substitute.For<IDailyReportRepository>();
private readonly IScheduleRepository scheduleRepositoryMock = Substitute.For<IScheduleRepository>();
private readonly IWellOperationRepository wellOperationRepositoryMock = Substitute.For<IWellOperationRepository>();
private readonly ISubsystemService subsystemServiceMock = Substitute.For<ISubsystemService>();
2024-02-21 15:08:51 +05:00
private readonly IProcessMapReportDrillingService processMapReportWellDrillingServiceMock = Substitute.For<IProcessMapReportDrillingService>();
private readonly IDetectedOperationService detectedOperationServiceMock = Substitute.For<IDetectedOperationService>();
private readonly DailyReportService dailyReportService;
private readonly DailyReportDto fakeDailyReport;
private readonly WellDto fakeWell;
private readonly DatesRangeDto fakeDatesRange;
private readonly DataSaubStatRequest fakeRequest = new DataSaubStatRequest();
public DailyReportServiceTest()
{
fakeDailyReport = new DailyReportDto
{
Id = idDailyReport,
IdWell = idWell,
Date = new(2023, 10, 26),
DateLastUpdate = null
};
fakeWell = new WellDto
{
Id = idWell,
Caption = "Тестовое название",
WellType = "Горизонтальная",
Cluster = "Тестовый куст",
Deposit = "Тестовое месторождение",
Companies = new[] { fakeCustomer, fakeContractor }
};
fakeDatesRange = new DatesRangeDto
{
From = fakeFirstFactWellOperation.DateStart.DateTime,
To = fakeLastFactWellOperation.DateStart.DateTime
};
dailyReportService = new DailyReportService(wellServiceMock,
trajectoryFactNnbRepositoryMock,
dailyReportRepositoryMock,
scheduleRepositoryMock,
wellOperationRepositoryMock,
subsystemServiceMock,
processMapReportWellDrillingServiceMock,
detectedOperationServiceMock);
dailyReportRepositoryMock.InsertAsync(Arg.Any<DailyReportDto>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(idDailyReport);
dailyReportRepositoryMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<DateOnly>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeDailyReport);
dailyReportRepositoryMock.UpdateAsync(Arg.Any<DailyReportDto>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(idDailyReport);
wellServiceMock.GetOrDefaultAsync(Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeWell);
trajectoryFactNnbRepositoryMock.GetByRequestAsync(Arg.Any<TrajectoryRequest>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeLastFactTrajectory });
wellOperationRepositoryMock.GetAsync(Arg.Any<WellOperationRequest>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeFirstFactWellOperation, fakeLastFactWellOperation });
wellOperationRepositoryMock.GetDatesRangeAsync(Arg.Any<int>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeDatesRange);
wellOperationRepositoryMock.GetSectionTypes()
.ReturnsForAnyArgs(new[] { fakeSectionType });
detectedOperationServiceMock.GetAsync(Arg.Any<DetectedOperationByWellRequest>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(fakeWellOperationSlipsTime);
subsystemServiceMock.GetStatAsync(Arg.Any<SubsystemRequest>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeSubsystemsStat });
scheduleRepositoryMock.GetAsync(Arg.Any<int>(), Arg.Any<DateTime>(), Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeShedule });
processMapReportWellDrillingServiceMock.GetAsync(Arg.Any<int>(), fakeRequest, Arg.Any<CancellationToken>())
.ReturnsForAnyArgs(new[] { fakeProcessMapReportWellDrilling });
wellServiceMock.GetTimezone(Arg.Any<int>())
.ReturnsForAnyArgs(fakeWellTimezone);
}
[Fact]
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSubsystemBlock()
{
//act
var result = await dailyReportService.UpdateOrInsertAsync(idWell, fakeDailyReport.Date, idUser, fakeSubsystemBlock, CancellationToken.None);
//assert
Assert.NotNull(fakeSubsystemBlock.LastUpdateDate);
Assert.NotNull(fakeDailyReport.DateLastUpdate);
Assert.Equal(fakeSubsystemBlock.IdUser, idUser);
Assert.Equal(fakeDailyReport.SubsystemBlock, fakeSubsystemBlock);
Assert.Equal(idDailyReport, result);
}
[Theory]
[MemberData(nameof(DateDailyReport))]
public async Task UpdateOrInsertAsync_ShouldReturn_UnableToUpdateDailyReport(DateOnly dateDailyReport)
{
//act
var result = await Assert.ThrowsAsync<ArgumentInvalidException>(() => dailyReportService.UpdateOrInsertAsync(
idWell,
dateDailyReport,
idUser,
fakeSignBlock,
CancellationToken.None));
//assert
Assert.Contains("Невозможно обновить суточный отчёт", result.Message);
}
[Fact]
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedSignBlock()
{
//act
var result = await dailyReportService.UpdateOrInsertAsync(idWell, fakeDailyReport.Date, idUser, fakeSignBlock, CancellationToken.None);
//assert
Assert.NotNull(fakeSignBlock.LastUpdateDate);
Assert.NotNull(fakeDailyReport.DateLastUpdate);
Assert.Equal(fakeSignBlock.IdUser, idUser);
Assert.Equal(fakeDailyReport.SignBlock, fakeSignBlock);
Assert.Equal(idDailyReport, result);
}
[Fact]
public async Task UpdateOrInsertAsync_ShouldReturn_UpdatedTimeBalanceBlock()
{
//act
var result = await dailyReportService.UpdateOrInsertAsync(idWell, fakeDailyReport.Date, idUser, fakeTimeBalanceBlock,
CancellationToken.None);
//assert
Assert.NotNull(fakeTimeBalanceBlock.LastUpdateDate);
Assert.NotNull(fakeDailyReport.DateLastUpdate);
Assert.Equal(fakeTimeBalanceBlock.IdUser, idUser);
Assert.Equal(fakeDailyReport.TimeBalanceBlock, fakeTimeBalanceBlock);
Assert.Equal(idDailyReport, result);
}
[Theory]
[MemberData(nameof(DateDailyReport))]
public async Task GetAsync_ShouldReturn_UnableToGetDailyReport(DateOnly dateDailyReport)
{
//act
var result = await Assert.ThrowsAsync<ArgumentInvalidException>(() => dailyReportService.GetAsync(idWell,
dateDailyReport,
CancellationToken.None));
//assert
Assert.Contains("Невозможно получить суточный отчёт", result.Message);
}
[Fact]
public async Task GetAsync_ShouldReturn_AddedWellInfo()
{
//act
var result = await dailyReportService.GetAsync(idWell, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.Equal(result.IdWell, fakeWell.Id);
Assert.Equal(result.WellCaption, fakeWell.Caption);
Assert.Equal(result.WellType, fakeWell.WellType);
Assert.Equal(result.Cluster, fakeWell.Cluster);
Assert.Equal(result.Deposit, fakeWell.Deposit);
Assert.Equal(result.Customer, fakeCustomer.Caption);
Assert.Equal(result.Contractor, fakeContractor.Caption);
Assert.Equal(result.DepthStart, fakeFirstFactWellOperation.DepthStart);
Assert.Equal(result.DepthEnd, fakeLastFactWellOperation.DepthEnd);
}
[Fact]
public async Task GetAsync_ShouldReturn_AddedTrajectoryBlock()
{
//act
var result = await dailyReportService.GetAsync(idWell, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.Equal(fakeLastFactTrajectory.WellboreDepth, result.TrajectoryBlock.WellboreDepth);
Assert.Equal(fakeLastFactTrajectory.VerticalDepth, result.TrajectoryBlock.VerticalDepth);
Assert.Equal(fakeLastFactTrajectory.ZenithAngle, result.TrajectoryBlock.ZenithAngle);
Assert.Equal(fakeLastFactTrajectory.AzimuthGeo, result.TrajectoryBlock.AzimuthGeo);
}
[Fact]
public async Task GetAsync_ShouldReturn_AddedFactWellOperationBlock()
{
//act
var result = await dailyReportService.GetAsync(idWell, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.Equal(16, result.FactWellOperationBlock.SectionDrillingHours);
Assert.Single(result.FactWellOperationBlock.WellOperations);
var wellOperation = result.FactWellOperationBlock.WellOperations.Single();
Assert.Equal("Механическое. бурение", wellOperation.CategoryName);
Assert.Equal(16, wellOperation.DurationHours);
}
[Fact]
public async Task GetAsync_ShouldReturn_AddedScheduleBlock()
{
//act
var result = await dailyReportService.GetAsync(idWell, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.Single(result.ScheduleBlock);
var sheduleRecord = result.ScheduleBlock.Single();
Assert.Equal(fakeShedule.ShiftStart, sheduleRecord.ShiftStart);
Assert.Equal(fakeShedule.ShiftEnd, sheduleRecord.ShiftEnd);
Assert.Equal(fakeShedule.Driller?.Name, sheduleRecord.Name);
Assert.Equal(fakeShedule.Driller?.Surname, sheduleRecord.Surname);
Assert.Equal(fakeShedule.Driller?.Patronymic, sheduleRecord.Patronymic);
}
[Fact]
public async Task GetAsync_ShouldReturn_UpdatedTimeBalanceBlock()
{
//arrange
fakeDailyReport.TimeBalanceBlock = fakeTimeBalanceBlock;
//act
var result = await dailyReportService.GetAsync(idWell, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.NotNull(result.TimeBalanceBlock);
Assert.Equal(fakeSectionType.Id, result.TimeBalanceBlock.IdSection);
Assert.Equal(fakeSectionType.Caption, result.TimeBalanceBlock.SectionName);
Assert.Equal(2000, result.TimeBalanceBlock?.WellDepth.Plan);
Assert.Equal(120, result.TimeBalanceBlock?.WellDepth.Fact);
Assert.Equal(40, result.TimeBalanceBlock?.WellOperationSlipsTimeCount);
}
[Fact]
public async Task GetAsync_ShouldReturn_AddedProcessMapWellDrillingBlock()
{
//act
var result = await dailyReportService.GetAsync(idWell, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.Single(result.ProcessMapWellDrillingBlock);
var processMapWellDrillingRecord = result.ProcessMapWellDrillingBlock.Single();
Assert.Equal(fakeProcessMapReportWellDrilling.DrillingMode, processMapWellDrillingRecord.DrillingMode);
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Plan, processMapWellDrillingRecord.Rop.Plan);
Assert.Equal(fakeProcessMapReportWellDrilling.Rop.Fact, processMapWellDrillingRecord.Rop.Fact);
Assert.Equal(fakeProcessMapReportWellDrilling.DeltaDepth, processMapWellDrillingRecord.WellBoreDepth);
Assert.Equal(fakeProcessMapReportWellDrilling.DrilledTime, processMapWellDrillingRecord.MechDrillingHours);
}
[Fact]
public async Task GetAsync_ShouldReturn_UpdatedSubsystemBlock()
{
//arrange
fakeDailyReport.SubsystemBlock = fakeSubsystemBlock;
//act
var result = await dailyReportService.GetAsync(idDailyReport, fakeDailyReport.Date, CancellationToken.None);
//assert
Assert.NotNull(result.SubsystemBlock);
Assert.Equal(2, result.SubsystemBlock?.Subsystems.Count());
var subsystemRecord0 = result.SubsystemBlock?.Subsystems.ElementAt(0);
Assert.Equal("АвтоСПО", subsystemRecord0?.Name);
Assert.Equal(24, subsystemRecord0?.UsagePerDay?.UsedTimeHours);
Assert.Equal(1500, subsystemRecord0?.UsagePerDay?.SumDepthInterval);
Assert.Equal(15, subsystemRecord0?.UsagePerDay?.KUsage);
Assert.Equal(500, subsystemRecord0?.UsagePerWell?.UsedTimeHours);
Assert.Equal(3000, subsystemRecord0?.UsagePerWell?.SumDepthInterval);
Assert.Equal(100, subsystemRecord0?.UsagePerWell?.KUsage);
var subsystemRecord1 = result.SubsystemBlock?.Subsystems.ElementAt(1);
Assert.Equal("АПД", subsystemRecord1?.Name);
Assert.Equal(200, subsystemRecord1?.UsagePerDay?.UsedTimeHours);
Assert.Equal(250, subsystemRecord1?.UsagePerDay?.SumDepthInterval);
Assert.Equal(30, subsystemRecord1?.UsagePerDay?.KUsage);
Assert.Equal(200, subsystemRecord1?.UsagePerWell?.UsedTimeHours);
Assert.Equal(250, subsystemRecord1?.UsagePerWell?.SumDepthInterval);
Assert.Equal(30, subsystemRecord1?.UsagePerWell?.KUsage);
}
[Fact]
public async Task GetAsync_ShouldReturn_FictiveDailyReport()
{
//arrange
var expectedCount = (fakeLastFactWellOperation.DateStart - fakeFirstFactWellOperation.DateStart).TotalDays + 1;
//act
var result = await dailyReportService.GetAsync(idWell, new FileReportRequest(), CancellationToken.None);
//assert
Assert.Equal(expectedCount, result.Count);
}
[Theory]
[MemberData(nameof(FactWellOperationDatesRange))]
public async Task GetDatesRangeAsync_ShouldReturn_DateRangeByFactWellOperations(DatesRangeDto datesRange)
{
//arrange
wellOperationRepositoryMock.GetDatesRangeAsync(Arg.Any<int>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
.Returns(datesRange);
//act
var result = await dailyReportService.GetDatesRangeAsync(idWell, CancellationToken.None);
//assert
Assert.NotNull(result);
Assert.True(result.From <= result.To);
Assert.True(result.To < DateTime.UtcNow.Date);
}
public static IEnumerable<object[]> DateDailyReport()
{
yield return new object[]
{
new DateOnly(2090, 01, 01),
};
yield return new object[]
{
new DateOnly(2000, 01, 01)
};
}
public static IEnumerable<object[]> FactWellOperationDatesRange()
{
yield return new object[]
{
new DatesRangeDto
{
From = new DateTime(2023, 11, 1),
To = new DateTime(2023, 11, 9)
}
};
yield return new object[]
{
new DatesRangeDto
{
From = new DateTime(2023, 11, 1),
To = new DateTime(2023, 11, 1)
}
};
yield return new object[]
{
new DatesRangeDto
{
From = DateTime.UtcNow,
To = DateTime.UtcNow
}
};
yield return new object[]
{
new DatesRangeDto
{
From = new DateTime(2023, 11, 1),
To = new DateTime(2023, 11, 11)
}
};
}
}