Compare commits

...

6 Commits

Author SHA1 Message Date
1c9d0a6c47 refactor(MappingProfile): update to ignore Envelope, Sender and Receiver 2025-09-02 23:58:35 +02:00
23ec4fe322 remove re-read process 2025-09-02 23:14:16 +02:00
8ca0519dbc feat(history): CreateHistoryCommand wurde verbessert, um DTO zurückzugeben und den Empfänger zu validieren.
- Der Rückgabetyp des Handlers wurde von „long?“ zu „EnvelopeHistoryDto?“ geändert.
 - AutoMapper-Integration für die Zuordnung von EnvelopeHistory zu DTO hinzugefügt.
 - IRepository<EnvelopeReceiver> zur Validierung der Benutzerreferenz eingeführt.
 - Validierung implementiert, um sicherzustellen, dass genau ein Empfänger gefunden wird.
 - BadRequestException-Behandlung für fehlende oder mehrere Empfänger hinzugefügt.
2025-09-02 23:11:41 +02:00
c67bac3e16 test(history): Aktualisieren Sie HistoryTests, um die Erstellung von Umschlägen auf Repository-Basis zu verwenden. 2025-09-02 18:48:18 +02:00
6cdd1db7a9 feat(Fake): add extension method to Fake to create Envelope 2025-09-02 15:25:59 +02:00
a87a524271 feat(MappingProfile): UUID-Generierung beim Zuordnen von CreateEnvelopeCommand zu Envelope hinzufügen 2025-09-02 12:19:06 +02:00
6 changed files with 108 additions and 46 deletions

View File

@@ -16,6 +16,7 @@ public class MappingProfile : Profile
public MappingProfile() public MappingProfile()
{ {
CreateMap<Envelope, CreateEnvelopeReceiverResponse>(); CreateMap<Envelope, CreateEnvelopeReceiverResponse>();
CreateMap<CreateEnvelopeCommand, Envelope>(); CreateMap<CreateEnvelopeCommand, Envelope>()
.ForMember(dest => dest.Uuid, opt => opt.MapFrom(_ => Guid.NewGuid().ToString()));
} }
} }

View File

@@ -1,17 +1,20 @@
using DigitalData.Core.Abstraction.Application.Repository; using AutoMapper;
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Exceptions;
using EnvelopeGenerator.Application.Dto.EnvelopeHistory;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Application.Model; using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Domain.Entities;
using MediatR; using MediatR;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Histories.Commands; namespace EnvelopeGenerator.Application.Histories.Commands;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<long?> public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<EnvelopeHistoryDto?>
{ {
/// <summary> /// <summary>
/// ///
@@ -47,17 +50,25 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<long?>
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand, long?> public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand, EnvelopeHistoryDto?>
{ {
private readonly IRepository<EnvelopeHistory> _repo; private readonly IRepository<EnvelopeHistory> _repo;
private readonly IRepository<EnvelopeReceiver> _erRepo;
private readonly IMapper _mapper;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <param name="repo"></param> /// <param name="repo"></param>
public CreateHistoryCommandHandler(IRepository<EnvelopeHistory> repo) /// <param name="erRepo"></param>
/// <param name="mapper"></param>
public CreateHistoryCommandHandler(IRepository<EnvelopeHistory> repo, IRepository<EnvelopeReceiver> erRepo, IMapper mapper)
{ {
_repo = repo; _repo = repo;
_erRepo = erRepo;
_mapper = mapper;
} }
/// <summary> /// <summary>
@@ -66,26 +77,32 @@ public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand,
/// <param name="request"></param> /// <param name="request"></param>
/// <param name="cancel"></param> /// <param name="cancel"></param>
/// <returns></returns> /// <returns></returns>
public async Task<long?> Handle(CreateHistoryCommand request, CancellationToken cancel) public async Task<EnvelopeHistoryDto?> Handle(CreateHistoryCommand request, CancellationToken cancel)
{ {
if(request.UserReference is null)
{
var receivers = await _erRepo
.ReadOnly()
.Where(request)
.Include(er => er.Receiver)
.ToListAsync(cancel);
if (receivers.Count != 1)
throw new BadRequestException(
receivers.Count > 1
? "Multiple receivers found for the given envelope and receiver criteria."
: "No receiver found for the given envelope and receiver criteria."
);
var receiver = receivers.Single().Receiver
?? throw new BadRequestException("No receiver found for the given envelope and receiver criteria.");
request.UserReference = receiver.EmailAddress;
}
// create entitiy // create entitiy
await _repo.CreateAsync(request, cancel); var hist = await _repo.CreateAsync(request, cancel);
// check if created return _mapper.Map<EnvelopeHistoryDto>(hist);
var query = _repo.ReadOnly();
query = request.EnvelopeId is null
? query.Where(request.Envelope)
: query.Where(h => h.EnvelopeId == request.EnvelopeId);
query = request.UserReference is null
? query.Where(request.Receiver)
: query.Where(h => h.UserReference == request.UserReference);
var record = await query
.Where(h => h.ActionDate == request.ActionDate)
.SingleOrDefaultAsync(cancel);
return record?.Id;
} }
} }

View File

@@ -14,6 +14,9 @@ public class MappingProfile: Profile
/// </summary> /// </summary>
public MappingProfile() public MappingProfile()
{ {
CreateMap<CreateHistoryCommand, EnvelopeHistory>(); CreateMap<CreateHistoryCommand, EnvelopeHistory>()
.ForMember(dest => dest.Envelope, opt => opt.Ignore())
.ForMember(dest => dest.Sender, opt => opt.Ignore())
.ForMember(dest => dest.Receiver, opt => opt.Ignore());
} }
} }

View File

@@ -5,7 +5,6 @@ using EnvelopeGenerator.Application;
using EnvelopeGenerator.Application.EnvelopeReceivers.Commands; using EnvelopeGenerator.Application.EnvelopeReceivers.Commands;
using EnvelopeGenerator.Application.Envelopes.Commands; using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Application.Histories.Commands; using EnvelopeGenerator.Application.Histories.Commands;
using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Application.Receivers.Commands; using EnvelopeGenerator.Application.Receivers.Commands;
using EnvelopeGenerator.Application.Users.Commands; using EnvelopeGenerator.Application.Users.Commands;
using EnvelopeGenerator.Infrastructure; using EnvelopeGenerator.Infrastructure;
@@ -16,8 +15,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using QuestPDF.Fluent; using QuestPDF.Fluent;
using QuestPDF.Infrastructure; using QuestPDF.Infrastructure;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Tests.Application; namespace EnvelopeGenerator.Tests.Application;
@@ -164,10 +163,29 @@ public static class Extensions
=> Enumerable.Range(0, userIDs.Length) => Enumerable.Range(0, userIDs.Length)
.Select(fake.CreateEnvelopeCommand) .Select(fake.CreateEnvelopeCommand)
.ToList(); .ToList();
public static Envelope CreateEnvelope(this Faker faker, int userId, bool tfaEnabled = false) => new()
{
Id = faker.Random.Number(1, 1000),
UserId = userId,
Status = EnvelopeStatus.EnvelopeCreated,
Uuid = Guid.NewGuid().ToString(),
Title = faker.Lorem.Paragraph(faker.Random.Number(1, 2)),
Message = faker.Lorem.Paragraph(faker.Random.Number(2, 5)),
TfaEnabled = tfaEnabled,
AddedWhen = DateTime.UtcNow,
CertificationType = (int)CertificationType.AdvancedElectronicSignature,
UseAccessCode = false,
ContractType = (int)ContractType.Contract,
Language = "de",
SendReminderEmails = false,
Comment = faker.Lorem.Sentence(10),
DocResult = faker.CreatePdfAsByte()
};
#endregion #endregion
#region Document #region Document
public static string CreatePdfAsBase64(this Faker faker) public static byte[] CreatePdfAsByte(this Faker faker)
{ {
string name = faker.Name.FullName(); string name = faker.Name.FullName();
string address = faker.Address.FullAddress(); string address = faker.Address.FullAddress();
@@ -191,9 +209,11 @@ public static class Extensions
using var ms = new MemoryStream(); using var ms = new MemoryStream();
document.GeneratePdf(ms); document.GeneratePdf(ms);
return Convert.ToBase64String(ms.ToArray()); return ms.ToArray();
} }
public static string CreatePdfAsBase64(this Faker faker) => Convert.ToBase64String(faker.CreatePdfAsByte());
public static DocumentCreateCommand CreateDocumentCommand(this Faker faker) => new() public static DocumentCreateCommand CreateDocumentCommand(this Faker faker) => new()
{ {
DataAsBase64 = faker.CreatePdfAsBase64() DataAsBase64 = faker.CreatePdfAsBase64()
@@ -205,6 +225,21 @@ public static class Extensions
.ToList(); .ToList();
#endregion #endregion
#region Envelope Receiver
public static EnvelopeReceiver CreateEnvelopeReceiver(this Faker faker, int envelopeId, int receiverId) => new()
{
EnvelopeId = envelopeId,
ReceiverId = receiverId,
Status = ReceiverStatus.Unsigned,
AddedWhen = DateTime.UtcNow,
AccessCode = faker.Random.Number(1000, 9999).ToString(),
ChangedWhen = DateTime.UtcNow,
CompanyName = faker.Company.CompanyName(),
JobTitle = faker.Name.JobTitle(),
Name = faker.Name.FullName(),
};
#endregion
#region History #region History
public static CreateHistoryCommand CreateHistoryCommand(this Faker fake, string key, EnvelopeStatus? status = null) public static CreateHistoryCommand CreateHistoryCommand(this Faker fake, string key, EnvelopeStatus? status = null)
{ {

View File

@@ -2,6 +2,7 @@
using EnvelopeGenerator.Application.Histories.Commands; using EnvelopeGenerator.Application.Histories.Commands;
using EnvelopeGenerator.Application.Histories.Queries; using EnvelopeGenerator.Application.Histories.Queries;
using EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Tests.Application; namespace EnvelopeGenerator.Tests.Application;
@@ -24,29 +25,29 @@ public class HistoryTests : TestBase
public async Task CreateHistory_And_ReadHistory_Should_Work() public async Task CreateHistory_And_ReadHistory_Should_Work()
{ {
/// Arrange /// Arrange
CancellationToken cancel = default;
// Create envelope // Create envelope
var createEnvelopeCmd = FakeCreateEnvelopeCommand; var envelope = FakeEnvelope;
var envelope = await Mediator.Send(createEnvelopeCmd).ThrowIfNull(Exceptions.NotFound); envelope = await GetRepository<Envelope>().CreateAsync(envelope, cancel);
// Create receiver // Create receiver
var createReceiverCmd = this.CreateReceiverCommand(); var createReceiverCmd = this.CreateReceiverCommand();
(var receiver, _) = await Mediator.Send(createReceiverCmd); (var receiver, _) = await Mediator.Send(createReceiverCmd);
// Create EnvelopeReceiver
var envRcv = this.CreateEnvelopeReceiver(envelope.Id, receiver.Id);
envRcv = await GetRepository<EnvelopeReceiver>().CreateAsync(envRcv, cancel);
var key = (envelope.Uuid, receiver.Signature).ToEnvelopeKey(); var key = (envelope.Uuid, receiver.Signature).ToEnvelopeKey();
var createCmd = Fake.Provider.CreateHistoryCommand(key); var createCmd = Fake.Provider.CreateHistoryCommand(key);
// Act // Act
var id = await Mediator.Send(createCmd); var hist = await Mediator.Send(createCmd);
// Assert // Assert
Assert.That(id, Is.Not.Null); Assert.That(hist, Is.Not.Null);
// ReadHistory query
var query = new ReadHistoryQuery(1);
var result = await Mediator.Send(query);
Assert.That(result, Is.Not.Empty);
} }
[Test] [Test]

View File

@@ -1,7 +1,8 @@
using Bogus; using Bogus;
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.UserManager.Domain.Entities; using DigitalData.UserManager.Domain.Entities;
using EnvelopeGenerator.Application.Envelopes.Commands; using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Application.Receivers.Commands; using EnvelopeGenerator.Domain.Entities;
using MediatR; using MediatR;
namespace EnvelopeGenerator.Tests.Application; namespace EnvelopeGenerator.Tests.Application;
@@ -10,11 +11,15 @@ public class TestBase : Faker
{ {
private Fake.Host Host; private Fake.Host Host;
public User User => Host.User; protected User User => Host.User;
public IMediator Mediator => Host.Mediator; protected IMediator Mediator => Host.Mediator;
public CreateEnvelopeCommand FakeCreateEnvelopeCommand => this.CreateEnvelopeCommand(Host.User.Id); protected CreateEnvelopeCommand FakeCreateEnvelopeCommand => this.CreateEnvelopeCommand(Host.User.Id);
protected Envelope FakeEnvelope => this.CreateEnvelope(Host.User.Id);
protected IRepository<T> GetRepository<T>() where T : class => Host.GetRepository<T>();
[SetUp] [SetUp]
public virtual async Task Setup() public virtual async Task Setup()