апи для работы с маршрутами согласования #2

Merged
admin merged 38 commits from initial-api into main 2026-07-27 13:14:32 +00:00
14 changed files with 74 additions and 83 deletions
Showing only changes of commit 3ae1965c29 - Show all commits
@@ -16,7 +16,6 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApprovalRouteInfrastructure(builder.Configuration); builder.Services.AddApprovalRouteInfrastructure(builder.Configuration);
builder.Services.AddApprovalRouteApplication(); builder.Services.AddApprovalRouteApplication();
builder.Services.AddApprovalRouteAuth(builder.Configuration); builder.Services.AddApprovalRouteAuth(builder.Configuration);
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<ICurrentUser, CurrentUserAccessor>(); builder.Services.AddScoped<ICurrentUser, CurrentUserAccessor>();
builder.Services.AddOpenApi(options => builder.Services.AddOpenApi(options =>
{ {
@@ -6,22 +6,22 @@ public sealed record TemplateRouteDto(
int Id, int Id,
RouteType RouteType, RouteType RouteType,
int RequestTypeId, int RequestTypeId,
string? Department, Guid? DepartmentId,
string Company, Guid CompanyId,
bool ByProject, bool ByProject,
bool RequiresControl); bool RequiresControl);
public sealed record CreateTemplateRouteRequest( public sealed record CreateTemplateRouteRequest(
RouteType RouteType, RouteType RouteType,
int RequestTypeId, int RequestTypeId,
string? Department, Guid? DepartmentId,
string Company, Guid CompanyId,
bool ByProject, bool ByProject,
bool RequiresControl); bool RequiresControl);
public sealed record UpdateTemplateRouteRequest( public sealed record UpdateTemplateRouteRequest(
RouteType RouteType, RouteType RouteType,
string? Department, Guid? DepartmentId,
string Company, Guid CompanyId,
bool ByProject, bool ByProject,
bool RequiresControl); bool RequiresControl);
@@ -22,7 +22,7 @@ public sealed class TemplateRouteService(
var items = await query var items = await query
.Select(x => new TemplateRouteDto( .Select(x => new TemplateRouteDto(
x.Id, x.RouteType, x.RequestTypeId, x.Department, x.Company, x.ByProject, x.RequiresControl)) x.Id, x.RouteType, x.RequestTypeId, x.DepartmentId, x.CompanyId, x.ByProject, x.RequiresControl))
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
return Result.Ok<IReadOnlyList<TemplateRouteDto>>(items); return Result.Ok<IReadOnlyList<TemplateRouteDto>>(items);
@@ -43,8 +43,7 @@ public sealed class TemplateRouteService(
if (!requestTypeExists) if (!requestTypeExists)
return Result.Fail<TemplateRouteDto>(new NotFoundError("Тип заявки", r.RequestTypeId)); return Result.Fail<TemplateRouteDto>(new NotFoundError("Тип заявки", r.RequestTypeId));
var department = Normalize(r.Department); var duplicate = await HasDuplicateAsync(r.RequestTypeId, r.DepartmentId, r.CompanyId, r.ByProject, excludeId: null, cancellationToken);
var duplicate = await HasDuplicateAsync(r.RequestTypeId, department, r.Company, r.ByProject, excludeId: null, cancellationToken);
if (duplicate) if (duplicate)
return Result.Fail<TemplateRouteDto>(new ConflictError( return Result.Fail<TemplateRouteDto>(new ConflictError(
"Маршрут с таким типом заявки, отделом, компанией и признаком «по проекту» уже существует.")); "Маршрут с таким типом заявки, отделом, компанией и признаком «по проекту» уже существует."));
@@ -53,8 +52,8 @@ public sealed class TemplateRouteService(
{ {
RouteType = r.RouteType, RouteType = r.RouteType,
RequestTypeId = r.RequestTypeId, RequestTypeId = r.RequestTypeId,
Department = department, DepartmentId = r.DepartmentId,
Company = r.Company, CompanyId = r.CompanyId,
ByProject = r.ByProject, ByProject = r.ByProject,
RequiresControl = r.RequiresControl RequiresControl = r.RequiresControl
}; };
@@ -70,15 +69,14 @@ public sealed class TemplateRouteService(
if (entity is null) if (entity is null)
return Result.Fail<TemplateRouteDto>(new NotFoundError("Маршрут", id)); return Result.Fail<TemplateRouteDto>(new NotFoundError("Маршрут", id));
var department = Normalize(r.Department); var duplicate = await HasDuplicateAsync(entity.RequestTypeId, r.DepartmentId, r.CompanyId, r.ByProject, excludeId: entity.Id, cancellationToken);
var duplicate = await HasDuplicateAsync(entity.RequestTypeId, department, r.Company, r.ByProject, excludeId: entity.Id, cancellationToken);
if (duplicate) if (duplicate)
return Result.Fail<TemplateRouteDto>(new ConflictError( return Result.Fail<TemplateRouteDto>(new ConflictError(
"Маршрут с таким типом заявки, отделом, компанией и признаком «по проекту» уже существует.")); "Маршрут с таким типом заявки, отделом, компанией и признаком «по проекту» уже существует."));
entity.RouteType = r.RouteType; entity.RouteType = r.RouteType;
entity.Department = department; entity.DepartmentId = r.DepartmentId;
entity.Company = r.Company; entity.CompanyId = r.CompanyId;
entity.ByProject = r.ByProject; entity.ByProject = r.ByProject;
entity.RequiresControl = r.RequiresControl; entity.RequiresControl = r.RequiresControl;
await db.SaveChangesAsync(cancellationToken); await db.SaveChangesAsync(cancellationToken);
@@ -116,23 +114,22 @@ public sealed class TemplateRouteService(
new NotFoundError("Сотрудник в справочнике api.tnsu.kz по email", email)); new NotFoundError("Сотрудник в справочнике api.tnsu.kz по email", email));
var byProject = request.ProjectId is not null; var byProject = request.ProjectId is not null;
var department = Normalize(employee.Department);
var route = await db.TemplateRoutes.AsNoTracking() var route = await db.TemplateRoutes.AsNoTracking()
.Include(x => x.Steps) .Include(x => x.Steps)
.Where(x => .Where(x =>
x.RequestTypeId == request.RequestTypeId && x.RequestTypeId == request.RequestTypeId &&
x.Company == employee.Company && x.CompanyId == employee.CompanyId &&
x.ByProject == byProject && x.ByProject == byProject &&
x.Department == department) x.DepartmentId == employee.DepartmentId)
.FirstOrDefaultAsync(cancellationToken) .FirstOrDefaultAsync(cancellationToken)
?? await db.TemplateRoutes.AsNoTracking() ?? await db.TemplateRoutes.AsNoTracking()
.Include(x => x.Steps) .Include(x => x.Steps)
.Where(x => .Where(x =>
x.RequestTypeId == request.RequestTypeId && x.RequestTypeId == request.RequestTypeId &&
x.Company == employee.Company && x.CompanyId == employee.CompanyId &&
x.ByProject == byProject && x.ByProject == byProject &&
x.Department == null) x.DepartmentId == null)
.FirstOrDefaultAsync(cancellationToken); .FirstOrDefaultAsync(cancellationToken);
if (route is null) if (route is null)
@@ -154,12 +151,12 @@ public sealed class TemplateRouteService(
} }
private Task<bool> HasDuplicateAsync( private Task<bool> HasDuplicateAsync(
int requestTypeId, string? department, string company, bool byProject, int? excludeId, CancellationToken cancellationToken) => int requestTypeId, Guid? departmentId, Guid companyId, bool byProject, int? excludeId, CancellationToken cancellationToken) =>
db.TemplateRoutes.AnyAsync(x => db.TemplateRoutes.AnyAsync(x =>
x.Id != excludeId && x.Id != excludeId &&
x.RequestTypeId == requestTypeId && x.RequestTypeId == requestTypeId &&
x.Department == department && x.DepartmentId == departmentId &&
x.Company == company && x.CompanyId == companyId &&
x.ByProject == byProject, x.ByProject == byProject,
cancellationToken); cancellationToken);
@@ -181,8 +178,6 @@ public sealed class TemplateRouteService(
step.ProjectRole, step.HeadType, step.Status, step.AllowReassignToOtherApprovers); step.ProjectRole, step.HeadType, step.Status, step.AllowReassignToOtherApprovers);
} }
private static string? Normalize(string? value) => string.IsNullOrWhiteSpace(value) ? null : value;
private static TemplateRouteDto ToDto(TemplateRoute e) => new( private static TemplateRouteDto ToDto(TemplateRoute e) => new(
e.Id, e.RouteType, e.RequestTypeId, e.Department, e.Company, e.ByProject, e.RequiresControl); e.Id, e.RouteType, e.RequestTypeId, e.DepartmentId, e.CompanyId, e.ByProject, e.RequiresControl);
} }
@@ -7,7 +7,7 @@ public sealed class CreateTemplateRouteRequestValidator : AbstractValidator<Crea
{ {
public CreateTemplateRouteRequestValidator() public CreateTemplateRouteRequestValidator()
{ {
RuleFor(x => x.Company).NotEmpty().WithMessage("Компания обязательна."); RuleFor(x => x.CompanyId).NotEqual(Guid.Empty).WithMessage("Компания обязательна.");
} }
} }
@@ -15,7 +15,7 @@ public sealed class UpdateTemplateRouteRequestValidator : AbstractValidator<Upda
{ {
public UpdateTemplateRouteRequestValidator() public UpdateTemplateRouteRequestValidator()
{ {
RuleFor(x => x.Company).NotEmpty().WithMessage("Компания обязательна."); RuleFor(x => x.CompanyId).NotEqual(Guid.Empty).WithMessage("Компания обязательна.");
} }
} }
@@ -8,10 +8,10 @@ public class TemplateRoute
public RouteType RouteType { get; set; } = RouteType.Sequential; public RouteType RouteType { get; set; } = RouteType.Sequential;
public int RequestTypeId { get; set; } public int RequestTypeId { get; set; }
// Компания и отдел инициатора — названия из справочника AD (api-tnsu-portal /Employee/ByEmail), // Id компании/отдела инициатора из 1С/AD (api-tnsu-portal /Employee/ByEmail) — без FK в этой БД.
// хранятся строками без FK в этой БД. Отдел опционален, компания обязательна. // Отдел опционален, компания обязательна.
public string? Department { get; set; } public Guid? DepartmentId { get; set; }
public string Company { get; set; } = string.Empty; public Guid CompanyId { get; set; }
public bool ByProject { get; set; } public bool ByProject { get; set; }
public bool RequiresControl { get; set; } public bool RequiresControl { get; set; }
@@ -13,6 +13,8 @@ public static class InfrastructureServiceCollectionExtensions
public static IServiceCollection AddApprovalRouteInfrastructure( public static IServiceCollection AddApprovalRouteInfrastructure(
this IServiceCollection services, IConfiguration configuration) this IServiceCollection services, IConfiguration configuration)
{ {
services.AddHttpContextAccessor();
services.AddDbContext<ApprovalRouteDbContext>(opt => services.AddDbContext<ApprovalRouteDbContext>(opt =>
opt.UseNpgsql(configuration.GetConnectionString("Postgres")) opt.UseNpgsql(configuration.GetConnectionString("Postgres"))
.UseSnakeCaseNamingConvention()); .UseSnakeCaseNamingConvention());
@@ -22,10 +22,8 @@ public class ApprovalRouteDbContext(DbContextOptions<ApprovalRouteDbContext> opt
{ {
e.HasKey(x => x.Id); e.HasKey(x => x.Id);
e.Property(x => x.RouteType).HasConversion<string>().HasMaxLength(32).IsRequired(); e.Property(x => x.RouteType).HasConversion<string>().HasMaxLength(32).IsRequired();
e.Property(x => x.Company).HasMaxLength(256).IsRequired();
e.Property(x => x.Department).HasMaxLength(256);
e.HasOne(x => x.RequestType).WithMany(x => x.Routes).HasForeignKey(x => x.RequestTypeId); e.HasOne(x => x.RequestType).WithMany(x => x.Routes).HasForeignKey(x => x.RequestTypeId);
e.HasIndex(x => new { x.RequestTypeId, x.Department, x.Company, x.ByProject }).IsUnique(); e.HasIndex(x => new { x.RequestTypeId, x.DepartmentId, x.CompanyId, x.ByProject }).IsUnique();
}); });
modelBuilder.Entity<TemplateRouteStep>(e => modelBuilder.Entity<TemplateRouteStep>(e =>
@@ -1,4 +1,5 @@
// <auto-generated /> // <auto-generated />
using System;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
@@ -11,7 +12,7 @@ using Tnsu.ApprovalRoute.Infrastructure.Persistence;
namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
{ {
[DbContext(typeof(ApprovalRouteDbContext))] [DbContext(typeof(ApprovalRouteDbContext))]
[Migration("20260724085143_InitialCreate")] [Migration("20260724114550_InitialCreate")]
partial class InitialCreate partial class InitialCreate
{ {
/// <inheritdoc /> /// <inheritdoc />
@@ -64,16 +65,13 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
.HasColumnType("boolean") .HasColumnType("boolean")
.HasColumnName("by_project"); .HasColumnName("by_project");
b.Property<string>("Company") b.Property<Guid>("CompanyId")
.IsRequired() .HasColumnType("uuid")
.HasMaxLength(256) .HasColumnName("company_id");
.HasColumnType("character varying(256)")
.HasColumnName("company");
b.Property<string>("Department") b.Property<Guid?>("DepartmentId")
.HasMaxLength(256) .HasColumnType("uuid")
.HasColumnType("character varying(256)") .HasColumnName("department_id");
.HasColumnName("department");
b.Property<int>("RequestTypeId") b.Property<int>("RequestTypeId")
.HasColumnType("integer") .HasColumnType("integer")
@@ -92,9 +90,9 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
b.HasKey("Id") b.HasKey("Id")
.HasName("pk_template_routes"); .HasName("pk_template_routes");
b.HasIndex("RequestTypeId", "Department", "Company", "ByProject") b.HasIndex("RequestTypeId", "DepartmentId", "CompanyId", "ByProject")
.IsUnique() .IsUnique()
.HasDatabaseName("ix_template_routes_request_type_id_department_company_by_proje"); .HasDatabaseName("ix_template_routes_request_type_id_department_id_company_id_by");
b.ToTable("template_routes", (string)null); b.ToTable("template_routes", (string)null);
}); });
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore.Migrations; using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable #nullable disable
@@ -33,8 +34,8 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
route_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false), route_type = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
request_type_id = table.Column<int>(type: "integer", nullable: false), request_type_id = table.Column<int>(type: "integer", nullable: false),
department = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), department_id = table.Column<Guid>(type: "uuid", nullable: true),
company = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: false), company_id = table.Column<Guid>(type: "uuid", nullable: false),
by_project = table.Column<bool>(type: "boolean", nullable: false), by_project = table.Column<bool>(type: "boolean", nullable: false),
requires_control = table.Column<bool>(type: "boolean", nullable: false) requires_control = table.Column<bool>(type: "boolean", nullable: false)
}, },
@@ -81,9 +82,9 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
columns: new[] { "route_id", "order_no" }); columns: new[] { "route_id", "order_no" });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "ix_template_routes_request_type_id_department_company_by_proje", name: "ix_template_routes_request_type_id_department_id_company_id_by",
table: "template_routes", table: "template_routes",
columns: new[] { "request_type_id", "department", "company", "by_project" }, columns: new[] { "request_type_id", "department_id", "company_id", "by_project" },
unique: true); unique: true);
} }
@@ -1,4 +1,5 @@
// <auto-generated /> // <auto-generated />
using System;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
@@ -61,16 +62,13 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
.HasColumnType("boolean") .HasColumnType("boolean")
.HasColumnName("by_project"); .HasColumnName("by_project");
b.Property<string>("Company") b.Property<Guid>("CompanyId")
.IsRequired() .HasColumnType("uuid")
.HasMaxLength(256) .HasColumnName("company_id");
.HasColumnType("character varying(256)")
.HasColumnName("company");
b.Property<string>("Department") b.Property<Guid?>("DepartmentId")
.HasMaxLength(256) .HasColumnType("uuid")
.HasColumnType("character varying(256)") .HasColumnName("department_id");
.HasColumnName("department");
b.Property<int>("RequestTypeId") b.Property<int>("RequestTypeId")
.HasColumnType("integer") .HasColumnType("integer")
@@ -89,9 +87,9 @@ namespace Tnsu.ApprovalRoute.Infrastructure.Persistence.Migrations
b.HasKey("Id") b.HasKey("Id")
.HasName("pk_template_routes"); .HasName("pk_template_routes");
b.HasIndex("RequestTypeId", "Department", "Company", "ByProject") b.HasIndex("RequestTypeId", "DepartmentId", "CompanyId", "ByProject")
.IsUnique() .IsUnique()
.HasDatabaseName("ix_template_routes_request_type_id_department_company_by_proje"); .HasDatabaseName("ix_template_routes_request_type_id_department_id_company_id_by");
b.ToTable("template_routes", (string)null); b.ToTable("template_routes", (string)null);
}); });
@@ -32,7 +32,7 @@ public sealed class HttpTnsuPortalClient(
if (employee is null) if (employee is null)
return null; return null;
return new EmployeeDirectoryInfo(employee.Company ?? string.Empty, employee.Section ?? string.Empty); return new EmployeeDirectoryInfo(employee.CompanyId ?? Guid.Empty, employee.DepartmentId);
} }
public async Task<IReadOnlyList<ProjectExecutorInfo>> GetProjectExecutorsAsync(Guid projectId, CancellationToken cancellationToken) public async Task<IReadOnlyList<ProjectExecutorInfo>> GetProjectExecutorsAsync(Guid projectId, CancellationToken cancellationToken)
@@ -82,8 +82,8 @@ public sealed class HttpTnsuPortalClient(
} }
private sealed record EmployeeResponse( private sealed record EmployeeResponse(
[property: JsonPropertyName("company")] string? Company, [property: JsonPropertyName("companyId")] Guid? CompanyId,
[property: JsonPropertyName("section")] string? Section); [property: JsonPropertyName("departmentId")] Guid? DepartmentId);
private sealed record ProjectResponse( private sealed record ProjectResponse(
[property: JsonPropertyName("projectManager")] string? ProjectManager, [property: JsonPropertyName("projectManager")] string? ProjectManager,
@@ -2,6 +2,6 @@ using Tnsu.ApprovalRoute.Domain.Enums;
namespace Tnsu.ApprovalRoute.Infrastructure.TnsuPortal; namespace Tnsu.ApprovalRoute.Infrastructure.TnsuPortal;
public sealed record EmployeeDirectoryInfo(string Company, string Department); public sealed record EmployeeDirectoryInfo(Guid CompanyId, Guid? DepartmentId);
public sealed record ProjectExecutorInfo(ProjectRole ProjectRole, string Email); public sealed record ProjectExecutorInfo(ProjectRole ProjectRole, string Email);
@@ -12,8 +12,8 @@ namespace Tnsu.ApprovalRoute.IntegrationTests.ApplicationServices;
public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFixture> public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFixture>
{ {
private const string Company = "ТОО TANSU Construction"; private static readonly Guid CompanyId = Guid.Parse("00000000-0000-0000-0000-000000000002");
private const string Department = "IT"; private static readonly Guid DepartmentId = Guid.Parse("00000000-0000-0000-0000-000000000001");
private readonly ServiceProvider _services; private readonly ServiceProvider _services;
private readonly TemplateRouteService _service; private readonly TemplateRouteService _service;
@@ -24,7 +24,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
var portalClient = new Mock<ITnsuPortalClient>(); var portalClient = new Mock<ITnsuPortalClient>();
portalClient portalClient
.Setup(x => x.GetEmployeeByEmailAsync(It.IsAny<string>(), It.IsAny<CancellationToken>())) .Setup(x => x.GetEmployeeByEmailAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(new EmployeeDirectoryInfo(Company, Department)); .ReturnsAsync(new EmployeeDirectoryInfo(CompanyId, DepartmentId));
portalClient portalClient
.Setup(x => x.GetProjectExecutorsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>())) .Setup(x => x.GetProjectExecutorsAsync(It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
.ReturnsAsync([new ProjectExecutorInfo(ProjectRole.ProjectManager, "pm@tnsu.kz")]); .ReturnsAsync([new ProjectExecutorInfo(ProjectRole.ProjectManager, "pm@tnsu.kz")]);
@@ -45,7 +45,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
// Action // Action
var created = await _service.CreateAsync( var created = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department, Company, ByProject: false, RequiresControl: true), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: true),
CancellationToken.None); CancellationToken.None);
// Assert // Assert
@@ -54,7 +54,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
var fetched = await _service.GetAsync(created.Value.Id, CancellationToken.None); var fetched = await _service.GetAsync(created.Value.Id, CancellationToken.None);
fetched.IsSuccess.ShouldBeTrue(); fetched.IsSuccess.ShouldBeTrue();
fetched.Value.Company.ShouldBe(Company); fetched.Value.CompanyId.ShouldBe(CompanyId);
} }
[Fact(DisplayName = "Создание маршрута с несуществующим типом заявки возвращает неуспешный результат")] [Fact(DisplayName = "Создание маршрута с несуществующим типом заявки возвращает неуспешный результат")]
@@ -62,7 +62,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
{ {
// Action // Action
var result = await _service.CreateAsync( var result = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, 999999, Department, Company, ByProject: false, RequiresControl: false), new CreateTemplateRouteRequest(RouteType.Sequential, 999999, DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
CancellationToken.None); CancellationToken.None);
// Assert // Assert
@@ -74,7 +74,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
{ {
// Arrange // Arrange
var requestTypeId = await CreateRequestTypeAsync("Business trip"); var requestTypeId = await CreateRequestTypeAsync("Business trip");
var request = new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department, Company, ByProject: false, RequiresControl: false); var request = new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false);
var first = await _service.CreateAsync(request, CancellationToken.None); var first = await _service.CreateAsync(request, CancellationToken.None);
first.IsSuccess.ShouldBeTrue(); first.IsSuccess.ShouldBeTrue();
@@ -91,13 +91,13 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
// Arrange // Arrange
var requestTypeId = await CreateRequestTypeAsync("Sick leave"); var requestTypeId = await CreateRequestTypeAsync("Sick leave");
var created = await _service.CreateAsync( var created = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department, Company, ByProject: false, RequiresControl: false), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
CancellationToken.None); CancellationToken.None);
// Action // Action
var updated = await _service.UpdateAsync( var updated = await _service.UpdateAsync(
created.Value.Id, created.Value.Id,
new UpdateTemplateRouteRequest(RouteType.Parallel, Department, Company, ByProject: false, RequiresControl: true), new UpdateTemplateRouteRequest(RouteType.Parallel, DepartmentId, CompanyId, ByProject: false, RequiresControl: true),
CancellationToken.None); CancellationToken.None);
// Assert // Assert
@@ -112,7 +112,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
// Arrange // Arrange
var requestTypeId = await CreateRequestTypeAsync("Remote work"); var requestTypeId = await CreateRequestTypeAsync("Remote work");
var created = await _service.CreateAsync( var created = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department, Company, ByProject: false, RequiresControl: false), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
CancellationToken.None); CancellationToken.None);
// Action // Action
@@ -131,7 +131,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
// Arrange // Arrange
var requestTypeId = await CreateRequestTypeAsync("Exact match request"); var requestTypeId = await CreateRequestTypeAsync("Exact match request");
var route = await _service.CreateAsync( var route = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department, Company, ByProject: false, RequiresControl: true), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: true),
CancellationToken.None); CancellationToken.None);
var stepService = _services.GetRequiredService<TemplateRouteStepService>(); var stepService = _services.GetRequiredService<TemplateRouteStepService>();
@@ -158,7 +158,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
// Arrange // Arrange
var requestTypeId = await CreateRequestTypeAsync("Project request"); var requestTypeId = await CreateRequestTypeAsync("Project request");
var route = await _service.CreateAsync( var route = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department, Company, ByProject: true, RequiresControl: false), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: true, RequiresControl: false),
CancellationToken.None); CancellationToken.None);
var stepService = _services.GetRequiredService<TemplateRouteStepService>(); var stepService = _services.GetRequiredService<TemplateRouteStepService>();
@@ -184,7 +184,7 @@ public sealed class TemplateRouteServiceTests : IClassFixture<PostgresDatabaseFi
// Arrange // Arrange
var requestTypeId = await CreateRequestTypeAsync("Company-wide request"); var requestTypeId = await CreateRequestTypeAsync("Company-wide request");
var route = await _service.CreateAsync( var route = await _service.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, Department: null, Company, ByProject: false, RequiresControl: false), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId: null, CompanyId, ByProject: false, RequiresControl: false),
CancellationToken.None); CancellationToken.None);
// Action // Action
@@ -10,7 +10,7 @@ namespace Tnsu.ApprovalRoute.IntegrationTests.ApplicationServices;
public sealed class TemplateRouteStepServiceTests : IClassFixture<PostgresDatabaseFixture> public sealed class TemplateRouteStepServiceTests : IClassFixture<PostgresDatabaseFixture>
{ {
private const string Company = "ТОО TANSU Construction"; private static readonly Guid CompanyId = Guid.Parse("00000000-0000-0000-0000-000000000002");
private readonly TemplateRouteStepService _service; private readonly TemplateRouteStepService _service;
private readonly TemplateRouteService _routeService; private readonly TemplateRouteService _routeService;
@@ -30,7 +30,7 @@ public sealed class TemplateRouteStepServiceTests : IClassFixture<PostgresDataba
new CreateRequestTypeRequest(requestTypeName, $"/{requestTypeName}"), CancellationToken.None)).Value.Id; new CreateRequestTypeRequest(requestTypeName, $"/{requestTypeName}"), CancellationToken.None)).Value.Id;
var route = await _routeService.CreateAsync( var route = await _routeService.CreateAsync(
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, null, Company, byProject, RequiresControl: false), new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, null, CompanyId, byProject, RequiresControl: false),
CancellationToken.None); CancellationToken.None);
return route.Value.Id; return route.Value.Id;