Новые условия (#15)
Tests / frontend-test (push) Successful in 46s
Tests / backend-test (push) Successful in 1m48s

Co-authored-by: gorbenko.pavel <gorbenko.pavel@tansu.kz>
Reviewed-on: http://git.tnsu.kz/gorbenko.pavel/tnsu-approval-route/pulls/15
This commit was merged in pull request #15.
This commit is contained in:
2026-08-24 12:27:25 +00:00
parent a1fa862ed4
commit e4a6cb8167
12 changed files with 137 additions and 31 deletions
@@ -332,8 +332,9 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
resolved.IsSuccess.ShouldBeTrue();
resolved.Value.Steps.ShouldHaveSingleItem();
resolved.Value.Steps[0].ExecutorEmail.ShouldBeNull();
resolved.Value.Steps[0].Warning.ShouldNotBeNull();
resolved.Value.Steps[0].Warning.ShouldContain("departmentId");
var warning = resolved.Value.Steps[0].Warning;
warning.ShouldNotBeNull();
warning.ShouldContain("departmentId");
}
[Fact(DisplayName = "Резолв маршрута с шагом «Руководитель указанного отдела» и переданным departmentId — резолвится через портал")]
@@ -413,8 +414,9 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
resolved.IsSuccess.ShouldBeTrue();
resolved.Value.Steps.ShouldHaveSingleItem();
resolved.Value.Steps[0].ExecutorEmail.ShouldBeNull();
resolved.Value.Steps[0].Warning.ShouldNotBeNull();
resolved.Value.Steps[0].Warning.ShouldContain(targetDepartmentId.ToString());
var warning = resolved.Value.Steps[0].Warning;
warning.ShouldNotBeNull();
warning.ShouldContain(targetDepartmentId.ToString());
}
[Fact(DisplayName = "Резолв маршрута включает шаг с условием «больше», когда переданное значение поля его удовлетворяет")]
@@ -527,6 +529,39 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
resolved.Value.Steps[0].ExecutorEmail.ShouldBe("urgent@tnsu.kz");
}
[Theory(DisplayName = "Резолв маршрута с условиями «не равно», «содержит», «не содержит»")]
[InlineData(ComparisonOperator.NotEqual, "Urgent", "Normal", true)]
[InlineData(ComparisonOperator.NotEqual, "Urgent", "URGENT", false)]
[InlineData(ComparisonOperator.Contains, "urge", "Very Urgent", true)]
[InlineData(ComparisonOperator.Contains, "urge", "Normal", false)]
[InlineData(ComparisonOperator.NotContains, "urge", "Normal", true)]
[InlineData(ComparisonOperator.NotContains, "urge", "Very Urgent", false)]
public async Task ResolveAsync_TextConditions_IncludeStepOnlyWhenConditionHolds(
ComparisonOperator operation, string expected, string actual, bool shouldMatch)
{
// Arrange
var requestTypeId = await CreateRequestTypeWithListAsync($"Condition request {operation} {actual}");
var route = await _service.CreateAsync(
new CreateTemplateRouteRequest(requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
CancellationToken.None);
var stepService = _services.GetRequiredService<TemplateRouteStepService>();
await stepService.CreateAsync(
route.Value.Id,
new CreateTemplateRouteStepRequest(1, "text-condition@tnsu.kz", null, null, null, RouteStepStatus.Approval, false, "Priority", operation, expected),
CancellationToken.None);
// Action
var resolved = await _service.ResolveAsync(
new ResolveTemplateRouteRequest(requestTypeId, "someone@tnsu.kz", null, RouteStepStatus.Approval,
[new ResolveFieldValueDto("Priority", actual)]),
CancellationToken.None);
// Assert
resolved.IsSuccess.ShouldBeTrue();
resolved.Value.Steps.Count.ShouldBe(shouldMatch ? 1 : 0);
}
[Fact(DisplayName = "Резолв маршрута с ролью в проекте подставляет исполнителя из проекта")]
public async Task ResolveAsync_ByProjectRole_UsesProjectExecutorEmail()
{
@@ -690,8 +725,9 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
resolved.IsSuccess.ShouldBeTrue();
resolved.Value.Steps.ShouldHaveSingleItem();
resolved.Value.Steps[0].ExecutorEmail.ShouldBeNull();
resolved.Value.Steps[0].Warning.ShouldNotBeNull();
resolved.Value.Steps[0].Warning.ShouldContain("руководитель");
var warning = resolved.Value.Steps[0].Warning;
warning.ShouldNotBeNull();
warning.ShouldContain("руководитель");
}
[Fact(DisplayName = "Резолв шага с должностью возвращает warning, если сотрудник по должности не найден")]
@@ -718,8 +754,9 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
resolved.IsSuccess.ShouldBeTrue();
resolved.Value.Steps.ShouldHaveSingleItem();
resolved.Value.Steps[0].ExecutorEmail.ShouldBeNull();
resolved.Value.Steps[0].Warning.ShouldNotBeNull();
resolved.Value.Steps[0].Warning.ShouldContain("должности");
var warning = resolved.Value.Steps[0].Warning;
warning.ShouldNotBeNull();
warning.ShouldContain("должности");
}
[Fact(DisplayName = "Резолв шага с ролью в проекте возвращает warning, если исполнитель с такой ролью не найден")]
@@ -746,8 +783,9 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
resolved.IsSuccess.ShouldBeTrue();
resolved.Value.Steps.ShouldHaveSingleItem();
resolved.Value.Steps[0].ExecutorEmail.ShouldBeNull();
resolved.Value.Steps[0].Warning.ShouldNotBeNull();
resolved.Value.Steps[0].Warning.ShouldContain("роль");
var warning = resolved.Value.Steps[0].Warning;
warning.ShouldNotBeNull();
warning.ShouldContain("роль");
}
[Fact(DisplayName = "Резолв маршрута откатывается на маршрут без отдела, если точного совпадения по отделу нет")]