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()
{
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.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
using Microsoft.EntityFrameworkCore;
using EnvelopeGenerator.Application.Extensions;
using EnvelopeGenerator.Domain.Constants;
namespace EnvelopeGenerator.Application.Histories.Commands;
/// <summary>
///
/// </summary>
public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<long?>
public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<EnvelopeHistoryDto?>
{
/// <summary>
///
@@ -47,17 +50,25 @@ public record CreateHistoryCommand : EnvelopeReceiverQueryBase, IRequest<long?>
/// <summary>
///
/// </summary>
public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand, long?>
public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand, EnvelopeHistoryDto?>
{
private readonly IRepository<EnvelopeHistory> _repo;
private readonly IRepository<EnvelopeReceiver> _erRepo;
private readonly IMapper _mapper;
/// <summary>
///
/// </summary>
/// <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;
_erRepo = erRepo;
_mapper = mapper;
}
/// <summary>
@@ -66,26 +77,32 @@ public class CreateHistoryCommandHandler : IRequestHandler<CreateHistoryCommand,
/// <param name="request"></param>
/// <param name="cancel"></param>
/// <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
await _repo.CreateAsync(request, cancel);
// check if created
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;
var hist = await _repo.CreateAsync(request, cancel);
return _mapper.Map<EnvelopeHistoryDto>(hist);
}
}

View File

@@ -14,6 +14,9 @@ public class MappingProfile: Profile
/// </summary>
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.Envelopes.Commands;
using EnvelopeGenerator.Application.Histories.Commands;
using EnvelopeGenerator.Application.Model;
using EnvelopeGenerator.Application.Receivers.Commands;
using EnvelopeGenerator.Application.Users.Commands;
using EnvelopeGenerator.Infrastructure;
@@ -16,8 +15,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
using EnvelopeGenerator.Domain;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Tests.Application;
@@ -164,10 +163,29 @@ public static class Extensions
=> Enumerable.Range(0, userIDs.Length)
.Select(fake.CreateEnvelopeCommand)
.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
#region Document
public static string CreatePdfAsBase64(this Faker faker)
public static byte[] CreatePdfAsByte(this Faker faker)
{
string name = faker.Name.FullName();
string address = faker.Address.FullAddress();
@@ -191,9 +209,11 @@ public static class Extensions
using var ms = new MemoryStream();
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()
{
DataAsBase64 = faker.CreatePdfAsBase64()
@@ -205,6 +225,21 @@ public static class Extensions
.ToList();
#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
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.Queries;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Domain.Entities;
namespace EnvelopeGenerator.Tests.Application;
@@ -24,29 +25,29 @@ public class HistoryTests : TestBase
public async Task CreateHistory_And_ReadHistory_Should_Work()
{
/// Arrange
CancellationToken cancel = default;
// Create envelope
var createEnvelopeCmd = FakeCreateEnvelopeCommand;
var envelope = await Mediator.Send(createEnvelopeCmd).ThrowIfNull(Exceptions.NotFound);
var envelope = FakeEnvelope;
envelope = await GetRepository<Envelope>().CreateAsync(envelope, cancel);
// Create receiver
var createReceiverCmd = this.CreateReceiverCommand();
(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 createCmd = Fake.Provider.CreateHistoryCommand(key);
// Act
var id = await Mediator.Send(createCmd);
var hist = await Mediator.Send(createCmd);
// Assert
Assert.That(id, Is.Not.Null);
// ReadHistory query
var query = new ReadHistoryQuery(1);
var result = await Mediator.Send(query);
Assert.That(result, Is.Not.Empty);
Assert.That(hist, Is.Not.Null);
}
[Test]

View File

@@ -1,7 +1,8 @@
using Bogus;
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.UserManager.Domain.Entities;
using EnvelopeGenerator.Application.Envelopes.Commands;
using EnvelopeGenerator.Application.Receivers.Commands;
using EnvelopeGenerator.Domain.Entities;
using MediatR;
namespace EnvelopeGenerator.Tests.Application;
@@ -10,11 +11,15 @@ public class TestBase : Faker
{
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]
public virtual async Task Setup()