567 lines
23 KiB
C#
567 lines
23 KiB
C#
using Microsoft.Extensions.Logging;
|
||
using Moq;
|
||
using PARR.Core.Repositories.Interfaces.Schedule;
|
||
using PARR.DAL.DomainModels;
|
||
using PARR.DAL.NextRunServices.Subservices;
|
||
using PARR.Domain.Entities.Schedule;
|
||
using PARR.Domain.Enums;
|
||
|
||
namespace PARR.DAL.Tests.TransformServices
|
||
{
|
||
public class EsppScheduleTransformServiceTests
|
||
{
|
||
private Mock<IEsppSchTypeConfigRepository> esppSchTypeConfigServiceMock;
|
||
//private Mock<INextRunModifierService> nextRunModifierServiceMock;
|
||
|
||
private ILogger<EsppScheduleTransformService> logger;
|
||
private EsppScheduleTransformService service;
|
||
|
||
public EsppScheduleTransformServiceTests()
|
||
{
|
||
esppSchTypeConfigServiceMock = new Mock<IEsppSchTypeConfigRepository>();
|
||
//nextRunModifierServiceMock = new Mock<INextRunModifierService>();
|
||
|
||
var loggerFactory = new LoggerFactory();
|
||
logger = loggerFactory.CreateLogger<EsppScheduleTransformService>();
|
||
|
||
|
||
service = new EsppScheduleTransformService(
|
||
logger,
|
||
esppSchTypeConfigServiceMock.Object
|
||
//nextRunModifierServiceMock.Object
|
||
);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Monthly2_ReturnsSameDateForAllReferenceDates()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2024, 10, 10, 10, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureNonMatchingDate = new DateTimeOffset(2025, 12, 08, 10, 0, 0, TimeSpan.Zero); // Будущее, не среда и до ожидаемой даты
|
||
var futureMatchingDate = new DateTimeOffset(2025, 12, 10, 10, 0, 0, TimeSpan.Zero); // Вторая среда и совпадает с ожидаемой датой
|
||
var expectedDate = futureMatchingDate;
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Monthly2,
|
||
Name = "Ежемесячно-2",
|
||
Description = "Расписание по дням недели в месяце"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "Порядок",
|
||
Description = "Порядковый номер дня недели"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Второй",
|
||
EsppExportValue = "Второй (экспорт)",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 2
|
||
}
|
||
},
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 2,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 2,
|
||
Name = "День недели",
|
||
Description = "День недели (например, понедельник)"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Среда",
|
||
EsppExportValue = "Среда",
|
||
TypeId = 2,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 3
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
//Act
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFutureNonMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureNonMatchingDate);
|
||
var resultFromFutureMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureMatchingDate);
|
||
|
||
//Assert
|
||
Assert.Equal(expectedDate, resultFromPast);
|
||
Assert.Equal(expectedDate, resultFromFutureNonMatching);
|
||
Assert.Equal(expectedDate, resultFromFutureMatching);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Monthly_ReturnsSameDateForAllReferenceDates()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2024, 10, 10, 10, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureNonMatchingDate = new DateTimeOffset(2025, 12, 08, 10, 0, 0, TimeSpan.Zero); // Будущее, не 15-е
|
||
var futureMatchingDate = new DateTimeOffset(2025, 12, 15, 10, 0, 0, TimeSpan.Zero); // 15-е декабря — совпадает с ожидаемой датой
|
||
var expectedDate = futureMatchingDate;
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Monthly,
|
||
Name = "Ежемесячно",
|
||
Description = "Расписание по числу месяца"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "День месяца",
|
||
Description = "Число месяца"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "15",
|
||
EsppExportValue = "15-е число",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFutureNonMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureNonMatchingDate);
|
||
var resultFromFutureMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureMatchingDate);
|
||
|
||
Assert.Equal(expectedDate, resultFromPast);
|
||
Assert.Equal(expectedDate, resultFromFutureNonMatching);
|
||
Assert.Equal(expectedDate, resultFromFutureMatching);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Annually_ReturnsSameDateForAllReferenceDates()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2024, 10, 10, 10, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureNonMatchingDate = new DateTimeOffset(2025, 11, 20, 10, 0, 0, TimeSpan.Zero); // Будущее, не январь, не 1-е
|
||
var futureMatchingDate = new DateTimeOffset(2026, 1, 1, 10, 0, 0, TimeSpan.Zero); // 1 января 2026 — совпадает с ожидаемой датой
|
||
var expectedDate = futureMatchingDate; // 1 января 2026
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Annually,
|
||
Name = "Ежегодно",
|
||
Description = "Расписание по месяцу и дню года"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "Месяц",
|
||
Description = "Месяц года"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Январь",
|
||
EsppExportValue = "Январь",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
},
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 2,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 2,
|
||
Name = "День месяца",
|
||
Description = "Число месяца"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "1",
|
||
EsppExportValue = "1-е число",
|
||
TypeId = 2,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
// Act
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFutureNonMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureNonMatchingDate);
|
||
var resultFromFutureMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureMatchingDate);
|
||
|
||
// Assert
|
||
Assert.Equal(expectedDate, resultFromPast);
|
||
Assert.Equal(expectedDate, resultFromFutureNonMatching);
|
||
Assert.Equal(expectedDate, resultFromFutureMatching);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Annually2_ReturnsSameDateForAllReferenceDates()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2024, 10, 10, 10, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureNonMatchingDate = new DateTimeOffset(2026, 01, 02, 10, 0, 0, TimeSpan.Zero); // Будущее, не понедельник
|
||
var futureMatchingDate = new DateTimeOffset(2026, 1, 5, 10, 0, 0, TimeSpan.Zero); // Первый понедельник января 2026 — совпадает с ожидаемой датой
|
||
var expectedDate = futureMatchingDate;
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Annually2,
|
||
Name = "Ежегодно-2",
|
||
Description = "Расписание по порядку дня недели в месяце (например, первый понедельник января)"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "Порядок",
|
||
Description = "Порядковый номер дня недели (например, первый)"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Первый",
|
||
EsppExportValue = "Первый",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
},
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 2,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 2,
|
||
Name = "День недели",
|
||
Description = "День недели (например, понедельник)"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Понедельник",
|
||
EsppExportValue = "Понедельник",
|
||
TypeId = 2,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 2
|
||
}
|
||
},
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 3,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 3,
|
||
Name = "Месяц",
|
||
Description = "Месяц года (например, Января)"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Января",
|
||
EsppExportValue = "Января",
|
||
TypeId = 3,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 3
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
// Act
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFutureNonMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureNonMatchingDate);
|
||
var resultFromFutureMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureMatchingDate);
|
||
|
||
// Assert
|
||
Assert.Equal(expectedDate, resultFromPast);
|
||
Assert.Equal(expectedDate, resultFromFutureNonMatching);
|
||
Assert.Equal(expectedDate, resultFromFutureMatching);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Weekly_ReturnsSameDateForAllReferenceDates()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2025, 11, 19, 10, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureNonMatchingDate = new DateTimeOffset(2025, 11, 27, 10, 0, 0, TimeSpan.Zero); // Будущее, четверг — не понедельник
|
||
var futureMatchingDate = new DateTimeOffset(2025, 12, 01, 10, 0, 0, TimeSpan.Zero); // четверг — совпадает с ожидаемой датой
|
||
var expectedDate = futureMatchingDate;
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Weekly,
|
||
Name = "Еженедельно",
|
||
Description = "Расписание по дню недели"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "День недели",
|
||
Description = "День недели"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Понедельник",
|
||
EsppExportValue = "Понедельник",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
// Act
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFutureNonMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureNonMatchingDate);
|
||
var resultFromFutureMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureMatchingDate);
|
||
|
||
// Assert
|
||
Assert.Equal(expectedDate, resultFromPast);
|
||
Assert.Equal(expectedDate, resultFromFutureNonMatching);
|
||
Assert.Equal(expectedDate, resultFromFutureMatching);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Regularly_EveryDay()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2025, 11, 20, 20, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureDate = new DateTimeOffset(2025, 11, 30, 10, 0, 0, TimeSpan.Zero); // Будущее время
|
||
var matchingDate = DateTimeOffset.UtcNow; // Совпадает время
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Regularly,
|
||
Name = "Регулярно",
|
||
Description = "Регулярное расписание"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "Интервал",
|
||
Description = "Интервал повторения (например, Ежедневно)"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Ежедневно",
|
||
EsppExportValue = "Ежедневно",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
// Act
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFuture = await service.GetNextDateAsync(Guid.NewGuid(), futureDate);
|
||
var resultFromMatching = await service.GetNextDateAsync(Guid.NewGuid(), matchingDate);
|
||
|
||
// Assert
|
||
Assert.Equal(new DateTimeOffset(
|
||
DateTimeOffset.UtcNow.Year,
|
||
DateTimeOffset.UtcNow.Month,
|
||
DateTimeOffset.UtcNow.Day,
|
||
20, 0, 0, 0, 0, TimeSpan.Zero), resultFromPast);
|
||
Assert.Equal(futureDate, resultFromFuture);
|
||
Assert.Equal(matchingDate.AddDays(1), resultFromMatching);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Regularly_Every3Year()
|
||
{
|
||
// Arrange
|
||
var pastDate = new DateTimeOffset(2020, 11, 20, 10, 0, 0, TimeSpan.Zero); // Прошлое время
|
||
var futureDate = new DateTimeOffset(2026, 11, 30, 10, 0, 0, TimeSpan.Zero); // Будущее время
|
||
var matchingDate = DateTimeOffset.UtcNow; // Совпадает время
|
||
var failureDate = new DateTimeOffset(2027, 01, 01, 23, 59, 0, TimeSpan.Zero); // Дата с ошибкой в работе
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Regularly,
|
||
Name = "Regularly",
|
||
Description = "Регулярно"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "Интервал",
|
||
Description = "Интервал повторения (например, Ежедневно)"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Каждые 3 года",
|
||
EsppExportValue = "1095 00:00:00",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
// Act
|
||
var resultFromPast = await service.GetNextDateAsync(Guid.NewGuid(), pastDate);
|
||
var resultFromFutureMatching = await service.GetNextDateAsync(Guid.NewGuid(), futureDate);
|
||
var resultFromSimpleMatching = await service.GetNextDateAsync(Guid.NewGuid(), matchingDate);
|
||
var resultFromFailure = await service.GetNextDateAsync(Guid.NewGuid(), failureDate);
|
||
|
||
// Assert
|
||
Assert.Equal(pastDate.AddHours(26280 * 2), resultFromPast);
|
||
Assert.Equal(futureDate, resultFromFutureMatching);
|
||
Assert.Equal(matchingDate.AddHours(26280), resultFromSimpleMatching);
|
||
Assert.Equal(failureDate, resultFromFailure);
|
||
}
|
||
|
||
|
||
[Fact]
|
||
public async Task GetNextDate_Weekly_TestUTCToMsk()
|
||
{
|
||
// Arrange
|
||
var beforeMSKTZ = new DateTimeOffset(2025, 11, 25, 3, 0, 0, TimeSpan.Zero);
|
||
var afterMSKTZ = new DateTimeOffset(2025, 12, 01, 3, 0, 0, TimeSpan.Zero);
|
||
|
||
var scheduleDto = new EsppScheduleDto
|
||
{
|
||
TypeSchedule = new EsppSchTypeSchedule
|
||
{
|
||
Id = (int)EsppSchTypeScheduleEnum.Weekly,
|
||
Name = "Еженедельно",
|
||
Description = "Расписание по дню недели"
|
||
},
|
||
Values = new List<EsppScheduleValDto>
|
||
{
|
||
new EsppScheduleValDto
|
||
{
|
||
Order = 1,
|
||
Type = new EsppSchType
|
||
{
|
||
Id = 1,
|
||
Name = "День недели",
|
||
Description = "День недели"
|
||
},
|
||
Value = new EsppSchTypeValue
|
||
{
|
||
Id = Guid.NewGuid(),
|
||
Value = "Понедельник",
|
||
EsppExportValue = "Понедельник",
|
||
TypeId = 1,
|
||
DateCreated = DateTimeOffset.UtcNow,
|
||
Order = 1
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
esppSchTypeConfigServiceMock
|
||
.Setup(x => x.GetEsppScheduleDtoAsync(It.IsAny<Guid>()))
|
||
.ReturnsAsync(scheduleDto);
|
||
|
||
// Act
|
||
var resultFrombeforeMSKTZ = await service.GetNextDateAsync(Guid.NewGuid(), beforeMSKTZ);
|
||
var resultFromafterMSKTZ = await service.GetNextDateAsync(Guid.NewGuid(), afterMSKTZ);
|
||
|
||
// Assert
|
||
Assert.Equal(new DateTimeOffset(2025, 12, 1, 3, 0, 0, TimeSpan.Zero), resultFrombeforeMSKTZ);
|
||
Assert.Equal(new DateTimeOffset(2025, 12, 1, 3, 0, 0, TimeSpan.Zero), resultFromafterMSKTZ);
|
||
}
|
||
}
|
||
}
|