diff --git a/EnvelopeGenerator.Application/Dto/EnvelopeDto.cs b/EnvelopeGenerator.Application/Dto/EnvelopeDto.cs index 8b335f99..81679f02 100644 --- a/EnvelopeGenerator.Application/Dto/EnvelopeDto.cs +++ b/EnvelopeGenerator.Application/Dto/EnvelopeDto.cs @@ -1,5 +1,6 @@ using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes; using DigitalData.UserManager.Application.DTOs.User; +using EnvelopeGenerator.Application.Envelopes.Queries; using EnvelopeGenerator.Domain.Entities; using Microsoft.AspNetCore.Mvc; @@ -24,7 +25,7 @@ public record EnvelopeDto /// /// /// - public int Status { get; set; } + public required EnvelopeStatus Status { get; set; } /// /// Default value is string.Empty diff --git a/EnvelopeGenerator.Application/Dto/EnvelopeHistory/EnvelopeHistoryDto.cs b/EnvelopeGenerator.Application/Dto/EnvelopeHistory/EnvelopeHistoryDto.cs index 08da8e34..7ae0163a 100644 --- a/EnvelopeGenerator.Application/Dto/EnvelopeHistory/EnvelopeHistoryDto.cs +++ b/EnvelopeGenerator.Application/Dto/EnvelopeHistory/EnvelopeHistoryDto.cs @@ -1,7 +1,6 @@ using DigitalData.UserManager.Application.DTOs.User; using EnvelopeGenerator.Application.Dto.Receiver; using EnvelopeGenerator.Domain; -using static EnvelopeGenerator.Domain.Constants; namespace EnvelopeGenerator.Application.Dto.EnvelopeHistory; @@ -28,12 +27,12 @@ public record EnvelopeHistoryDto /// /// Include code of the envelope at this history point. /// - public int Status { get; set; } + public Constants.EnvelopeStatus Status { get; set; } /// /// Type of reference for this history entry. /// - public Constants.ReferenceType ReferenceType => Status.ToString().FirstOrDefault() switch + public Constants.ReferenceType ReferenceType => ((int)Status).ToString().FirstOrDefault() switch { '1' => Constants.ReferenceType.Sender, '2' => Constants.ReferenceType.Receiver, diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs index 6af393ce..d5cd2e42 100644 --- a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeController.cs @@ -63,13 +63,13 @@ public class EnvelopeController : ControllerBase public async Task GetAsync([FromQuery] ReadEnvelopeQuery envelope) { if (User.GetId() is int intId) - return await _envelopeService.ReadByUserAsync(intId, min_status: envelope.Status, max_status: envelope.Status).ThenAsync( + return await _envelopeService.ReadByUserAsync(intId, min_status: envelope.Status?.Min, max_status: envelope.Status?.Max).ThenAsync( Success: envelopes => { if (envelope.Id is int id) envelopes = envelopes.Where(e => e.Id == id); - if (envelope.Status is int status) + if (envelope.Status is EnvelopeStatus status) envelopes = envelopes.Where(e => e.Status == status); if (envelope.Uuid is string uuid) diff --git a/EnvelopeGenerator.Terminal/CommandManager.cs b/EnvelopeGenerator.Terminal/CommandManager.cs index fb9bfc7a..40ae8e61 100644 --- a/EnvelopeGenerator.Terminal/CommandManager.cs +++ b/EnvelopeGenerator.Terminal/CommandManager.cs @@ -45,7 +45,7 @@ public class CommandManager { ReadDocumentQuery query = new(id, envelopeId); var document = await _mediator.Send(query); - console.WriteLine(JsonSerializer.Serialize(save ? document as ReadDocumentResponse : document, Options)); + console.WriteLine(JsonSerializer.Serialize(document, Options)); if (save) { diff --git a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj index cfe0e635..1ec5a917 100644 --- a/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj +++ b/EnvelopeGenerator.Tests.Application/EnvelopeGenerator.Tests.Application.csproj @@ -9,15 +9,11 @@ true - - - - - PreserveNewest true PreserveNewest + PreserveNewest diff --git a/EnvelopeGenerator.Tests.Application/HistoryTests.cs b/EnvelopeGenerator.Tests.Application/HistoryTests.cs new file mode 100644 index 00000000..da06e020 --- /dev/null +++ b/EnvelopeGenerator.Tests.Application/HistoryTests.cs @@ -0,0 +1,123 @@ +using EnvelopeGenerator.Application; +using EnvelopeGenerator.Application.Histories.Commands; +using EnvelopeGenerator.Application.Histories.Queries; +using EnvelopeGenerator.Domain; +using EnvelopeGenerator.Infrastructure; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace EnvelopeGenerator.Tests.Application; + +[TestFixture] +public class HistoryTests +{ + private IHost _host; + + private IServiceProvider Provider => _host.Services; + + [SetUp] + public void Setup() + { + _host = Host.CreateDefaultBuilder() + .ConfigureAppConfiguration((context, config) => + { + // add appsettings.json + config.SetBasePath(Directory.GetCurrentDirectory()); + config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + }) + .ConfigureServices((context, services) => + { + IConfiguration configuration = context.Configuration; + + // add Application and Infrastructure services +#pragma warning disable CS0618 + services.AddEnvelopeGeneratorServices(configuration); + services.AddEnvelopeGeneratorInfrastructureServices( + (sp, options) => options.UseInMemoryDatabase("EnvelopeGeneratorTestDb"), + context.Configuration + ); +#pragma warning restore CS0618 + }) + .Build(); + } + + [TearDown] + public void TearDown() + { + _host.Dispose(); + } + + private async Task Send(IRequest request) + { + var mediator = Provider.GetRequiredService(); + return await mediator.Send(request); + } + + [Test] + public async Task CreateHistory_And_ReadHistory_Should_Work() + { + // Arrange + var createCmd = new CreateHistoryCommand + { + EnvelopeId = 1, + UserReference = "UserA", + Status = Constants.EnvelopeStatus.EnvelopeCreated, + Comment = "First create" + }; + + // Act + var id = await Send(createCmd); + + // Assert + Assert.That(id, Is.Not.Null); + + // ReadHistory sorgusu + var query = new ReadHistoryQuery(1); + var result = await Send(query); + + Assert.That(result, Is.Not.Empty); + } + + [Test] + public async Task ReadHistory_Should_Filter_By_Status() + { + // Arrange + var createCmd1 = new CreateHistoryCommand + { + EnvelopeId = 2, + UserReference = "UserX", + Status = Constants.EnvelopeStatus.EnvelopeCreated + }; + + var createCmd2 = new CreateHistoryCommand + { + EnvelopeId = 2, + UserReference = "UserX", + Status = Constants.EnvelopeStatus.EnvelopePartlySigned + }; + + await Send(createCmd1); + await Send(createCmd2); + + // Act + var result = await Send(new ReadHistoryQuery(2, Constants.EnvelopeStatus.EnvelopePartlySigned)); + + // Assert + Assert.That(result, Has.Exactly(1).Items); + Assert.That(result, Has.All.Matches( + r => r.Status == Constants.EnvelopeStatus.EnvelopePartlySigned)); + } + + [Test] + public async Task ReadHistory_Should_Return_Empty_When_No_Record() + { + // Act + var result = await Send(new ReadHistoryQuery(999)); + + // Assert + Assert.That(result, Is.Empty); + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.Tests.Application/appsettings.json b/EnvelopeGenerator.Tests.Application/appsettings.json index 136c48a8..6c26db74 100644 --- a/EnvelopeGenerator.Tests.Application/appsettings.json +++ b/EnvelopeGenerator.Tests.Application/appsettings.json @@ -1,6 +1,7 @@ { "DiPMode": false, //Please be careful when enabling Development in Production (DiP) mode. It allows Swagger and test controllers to be enabled in a production environment. "EnableSwagger": true, + "UseDbMigration": false, "EnableTestControllers": true, "DetailedErrors": true, "Logging": { @@ -12,7 +13,8 @@ } }, "ConnectionStrings": { - "Default": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;" + "Default": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;", + "DbMigrationTest": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM_DATA_MIGR_TEST;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;" }, "PSPDFKitLicenseKey": "SXCtGGY9XA-31OGUXQK-r7c6AkdLGPm2ljuyDr1qu0kkhLvydg-Do-fxpNUF4Rq3fS_xAnZRNFRHbXpE6sQ2BMcCSVTcXVJO6tPviexjpiT-HnrDEySlUERJnnvh-tmeOWprxS6BySPnSILkmaVQtUfOIUS-cUbvvEYHTvQBKbSF8di4XHQFyfv49ihr51axm3NVV3AXwh2EiKL5C5XdqBZ4sQ4O7vXBjM2zvxdPxlxdcNYmiU83uAzw7B83O_jubPzya4CdUHh_YH7Nlp2gP56MeG1Sw2JhMtfG3Rj14Sg4ctaeL9p6AEWca5dDjJ2li5tFIV2fQSsw6A_cowLu0gtMm5i8IfJXeIcQbMC2-0wGv1oe9hZYJvFMdzhTM_FiejM0agemxt3lJyzuyP8zbBSOgp7Si6A85krLWPZptyZBTG7pp7IHboUHfPMxCXqi-zMsqewOJtQBE2mjntU-lPryKnssOpMPfswwQX7QSkJYV5EMqNmEhQX6mEkp2wcqFzMC7bJQew1aO4pOpvChUaMvb1vgRek0HxLag0nwQYX2YrYGh7F_xXJs-8HNwJe8H0-eW4x4faayCgM5rB5772CCCsD9ThZcvXFrjNHHLGJ8WuBUFm6LArvSfFQdii_7j-_sqHMpeKZt26NFgivj1A==", "Content-Security-Policy": [ // The first format parameter {0} will be replaced by the nonce value. @@ -39,6 +41,11 @@ "fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log", "maxArchiveDays": 30 }, + "warningLogs": { + "type": "File", + "fileName": "${logDirectory}\\${logFileNamePrefix}-Warning.log", + "maxArchiveDays": 30 + }, "errorLogs": { "type": "File", "fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log", @@ -50,14 +57,17 @@ "maxArchiveDays": 30 } }, - // Trace, Debug, Info, Warn, Error and *Fatal* "rules": [ { "logger": "*", - "minLevel": "Info", - "maxLevel": "Warn", + "level": "Info", "writeTo": "infoLogs" }, + { + "logger": "*", + "level": "Warn", + "writeTo": "warningLogs" + }, { "logger": "*", "level": "Error", @@ -140,17 +150,33 @@ } }, "TFARegParams": { - "TimeLimit": "00:30:00" + "TimeLimit": "90.00:00:00" }, "DbTriggerParams": { "Envelope": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ], "EnvelopeHistory": [ "TBSIG_ENVELOPE_HISTORY_AFT_INS" ], "EmailOut": [ "TBEMLP_EMAIL_OUT_AFT_INS", "TBEMLP_EMAIL_OUT_AFT_UPD" ], "EnvelopeReceiverReadOnly": [ "TBSIG_ENVELOPE_RECEIVER_READ_ONLY_UPD" ], - "Receiver": [] + "Receiver": [], + "EmailTemplate": [ "TBSIG_EMAIL_TEMPLATE_AFT_UPD" ] }, "MainPageTitle": null, "AnnotationParams": { + "Background": { + "Margin": 0.20, + "BackgroundColor": { + "R": 222, + "G": 220, + "B": 215 + }, + "BorderColor": { + "R": 204, + "G": 202, + "B": 198 + }, + "BorderStyle": "underline", + "BorderWidth": 4 + }, "DefaultAnnotation": { "Width": 1, "Height": 0.5,