162 lines
6.8 KiB
C#
162 lines
6.8 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using Shouldly;
|
|
using Tnsu.ApprovalRoute.Application.RequestTypes;
|
|
using Tnsu.ApprovalRoute.Application.TemplateRoutes;
|
|
using Tnsu.ApprovalRoute.Domain.Enums;
|
|
using Tnsu.ApprovalRoute.IntegrationTests.Infrastructure;
|
|
|
|
namespace Tnsu.ApprovalRoute.IntegrationTests.ApplicationServices;
|
|
|
|
[CollectionDefinition(Name)]
|
|
public sealed class TemplateRouteServiceCollection : ICollectionFixture<PostgresDatabaseFixture>
|
|
{
|
|
public const string Name = nameof(TemplateRouteServiceCollection);
|
|
}
|
|
|
|
[Collection(TemplateRouteServiceCollection.Name)]
|
|
public sealed class TemplateRouteServiceTests : IDisposable
|
|
{
|
|
private static readonly Guid CompanyId = Guid.Parse("00000000-0000-0000-0000-000000000002");
|
|
private static readonly Guid DepartmentId = Guid.Parse("00000000-0000-0000-0000-000000000001");
|
|
|
|
private readonly ServiceProvider _services;
|
|
private readonly TemplateRouteService _service;
|
|
private readonly RequestTypeService _requestTypeService;
|
|
|
|
public TemplateRouteServiceTests(PostgresDatabaseFixture fixture)
|
|
{
|
|
_services = TestServiceProviderFactory.Build(fixture.ConnectionString);
|
|
_service = _services.GetRequiredService<TemplateRouteService>();
|
|
_requestTypeService = _services.GetRequiredService<RequestTypeService>();
|
|
}
|
|
|
|
public void Dispose() => _services.Dispose();
|
|
|
|
private async Task<Guid> CreateRequestTypeAsync(string name) =>
|
|
(await _requestTypeService.CreateAsync(new CreateRequestTypeRequest(name, $"/{name}"), CancellationToken.None)).Value.Id;
|
|
|
|
[Fact]
|
|
public async Task CreateAsync_ThenGetAsync_ReturnsCreatedEntity()
|
|
{
|
|
var requestTypeId = await CreateRequestTypeAsync("Vacation");
|
|
|
|
var created = await _service.CreateAsync(
|
|
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: true),
|
|
CancellationToken.None);
|
|
|
|
created.IsSuccess.ShouldBeTrue();
|
|
created.Value.RequestTypeId.ShouldBe(requestTypeId);
|
|
|
|
var fetched = await _service.GetAsync(created.Value.Id, CancellationToken.None);
|
|
fetched.IsSuccess.ShouldBeTrue();
|
|
fetched.Value.CompanyId.ShouldBe(CompanyId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateAsync_UnknownRequestType_ReturnsFailedResult()
|
|
{
|
|
var result = await _service.CreateAsync(
|
|
new CreateTemplateRouteRequest(RouteType.Sequential, Guid.NewGuid(), DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
|
|
CancellationToken.None);
|
|
|
|
result.IsFailed.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateAsync_DuplicateRoute_ReturnsFailedResult()
|
|
{
|
|
var requestTypeId = await CreateRequestTypeAsync("Business trip");
|
|
var request = new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false);
|
|
|
|
var first = await _service.CreateAsync(request, CancellationToken.None);
|
|
first.IsSuccess.ShouldBeTrue();
|
|
|
|
var duplicate = await _service.CreateAsync(request, CancellationToken.None);
|
|
duplicate.IsFailed.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateAsync_ChangesFields()
|
|
{
|
|
var requestTypeId = await CreateRequestTypeAsync("Sick leave");
|
|
var created = await _service.CreateAsync(
|
|
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
|
|
CancellationToken.None);
|
|
|
|
var updated = await _service.UpdateAsync(
|
|
created.Value.Id,
|
|
new UpdateTemplateRouteRequest(RouteType.Parallel, DepartmentId, CompanyId, ByProject: false, RequiresControl: true),
|
|
CancellationToken.None);
|
|
|
|
updated.IsSuccess.ShouldBeTrue();
|
|
updated.Value.RouteType.ShouldBe(RouteType.Parallel);
|
|
updated.Value.RequiresControl.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeleteAsync_RemovesEntity()
|
|
{
|
|
var requestTypeId = await CreateRequestTypeAsync("Remote work");
|
|
var created = await _service.CreateAsync(
|
|
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: false),
|
|
CancellationToken.None);
|
|
|
|
var deleted = await _service.DeleteAsync(created.Value.Id, CancellationToken.None);
|
|
deleted.IsSuccess.ShouldBeTrue();
|
|
|
|
var fetched = await _service.GetAsync(created.Value.Id, CancellationToken.None);
|
|
fetched.IsFailed.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ResolveAsync_ExactDepartmentMatch_ReturnsMatchingStepsForStatus()
|
|
{
|
|
var requestTypeId = await CreateRequestTypeAsync("Exact match request");
|
|
var route = await _service.CreateAsync(
|
|
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId, CompanyId, ByProject: false, RequiresControl: true),
|
|
CancellationToken.None);
|
|
|
|
var stepService = _services.GetRequiredService<Application.TemplateRouteSteps.TemplateRouteStepService>();
|
|
await stepService.CreateAsync(
|
|
route.Value.Id,
|
|
new Application.TemplateRouteSteps.CreateTemplateRouteStepRequest(
|
|
1, "approver@tnsu.kz", "Lead", ProjectRole.None, HeadType.Chief, RouteStepStatus.Approval, false),
|
|
CancellationToken.None);
|
|
|
|
var resolved = await _service.ResolveAsync(
|
|
new ResolveTemplateRouteRequest(requestTypeId, "someone@tnsu.kz", null, RouteStepStatus.Approval),
|
|
CancellationToken.None);
|
|
|
|
resolved.IsSuccess.ShouldBeTrue();
|
|
resolved.Value.RouteId.ShouldBe(route.Value.Id);
|
|
resolved.Value.Steps.ShouldHaveSingleItem();
|
|
resolved.Value.Steps[0].ExecutorEmail.ShouldBe("approver@tnsu.kz");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ResolveAsync_NoDepartmentRoute_FallsBackToCompanyWideRoute()
|
|
{
|
|
var requestTypeId = await CreateRequestTypeAsync("Company-wide request");
|
|
var route = await _service.CreateAsync(
|
|
new CreateTemplateRouteRequest(RouteType.Sequential, requestTypeId, DepartmentId: null, CompanyId, ByProject: false, RequiresControl: false),
|
|
CancellationToken.None);
|
|
|
|
var resolved = await _service.ResolveAsync(
|
|
new ResolveTemplateRouteRequest(requestTypeId, "someone@tnsu.kz", null, RouteStepStatus.Execution),
|
|
CancellationToken.None);
|
|
|
|
resolved.IsSuccess.ShouldBeTrue();
|
|
resolved.Value.RouteId.ShouldBe(route.Value.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ResolveAsync_UnknownRequestType_ReturnsFailedResult()
|
|
{
|
|
var resolved = await _service.ResolveAsync(
|
|
new ResolveTemplateRouteRequest(Guid.NewGuid(), "someone@tnsu.kz", null, RouteStepStatus.Approval),
|
|
CancellationToken.None);
|
|
|
|
resolved.IsFailed.ShouldBeTrue();
|
|
}
|
|
}
|