using Bogus; using DigitalData.Core.Abstraction.Application.Repository; using DigitalData.UserManager.Domain.Entities; using EnvelopeGenerator.Application; using EnvelopeGenerator.Application.EnvelopeReceivers.Commands; using EnvelopeGenerator.Application.Envelopes.Commands; using EnvelopeGenerator.Application.Histories.Commands; using EnvelopeGenerator.Application.Receivers.Commands; using EnvelopeGenerator.Application.Users.Commands; using EnvelopeGenerator.Infrastructure; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using QuestPDF.Fluent; using QuestPDF.Infrastructure; using EnvelopeGenerator.Domain.Constants; using EnvelopeGenerator.Domain.Entities; namespace EnvelopeGenerator.Tests.Application; public class Fake { public static readonly Faker Provider = new("de"); public static Host CreateHost() => Microsoft.Extensions.Hosting.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() .ToFake(); public class Host : IHost { #region Root private readonly IHost _root; public Host(IHost root) { _root = root; } public IServiceProvider Services => _root.Services; public void Dispose() { _root.Dispose(); } public Task StartAsync(CancellationToken cancel = default) { return _root.StartAsync(cancel); } public Task StopAsync(CancellationToken cancel = default) { return _root.StopAsync(cancel); } #endregion #region Shortcuts public IMediator Mediator => Services.GetRequiredService(); public IRepository GetRepository() => Services.GetRequiredService>(); public async Task AddSamples() { await AddSampleReceivers(); await AddSampleUser(); return this; } #endregion #region Sample Receivers public List<(int Id, string EmailAddress)> _sampleReceivers = new(); public IEnumerable<(int Id, string EmailAddress)> SampleReceivers => _sampleReceivers.Any() ? _sampleReceivers : throw new InvalidOperationException( "No sample receivers have been initialized. Call AddSampleReceivers() before accessing this property." ); public async Task AddSampleReceivers() { var mediator = Mediator; foreach (var cmd in Provider.CreateReceiverCommands()) { var (receiver, _) = await mediator.Send(cmd); _sampleReceivers.Add((receiver.Id, cmd.EmailAddress)); } return this; } #endregion #region Sample User private User? _user; public User User => _user ?? throw new InvalidOperationException( "The 'User' instance has not been initialized. Call AddSampleUser() before accessing this property."); public async Task AddSampleUser() { var repo = GetRepository(); var cmd = Provider.CreateUserCommand(); _user = await repo.CreateAsync(cmd); return this; } #endregion } } public static class Extensions { public static Fake.Host ToFake(this IHost host) => new(host); public static T PickEnum(this Faker faker) where T : struct, Enum { var values = Enum.GetValues(typeof(T)); var index = faker.Random.Int(0, values.Length - 1); return (T)values.GetValue(index)!; } #region Receiver Command public static CreateReceiverCommand CreateReceiverCommand(this Faker fake) => new() { EmailAddress = fake.Internet.Email(), }; public static List CreateReceiverCommands(this Faker fake, int minCount = 10, int maxCount = 20) => Enumerable.Range(0, fake.Random.Number(minCount, maxCount)) .Select(_ => fake.CreateReceiverCommand()) .ToList(); #endregion #region Envelope public static CreateEnvelopeCommand CreateEnvelopeCommand(this Faker fake, int userId) => new() { Message = fake.Lorem.Paragraph(fake.Random.Number(2, 5)), Title = fake.Lorem.Paragraph(fake.Random.Number(1, 2)), UserId = userId, UseSQLExecutor = false }; public static List CreateEnvelopeCommands(this Faker fake, params int[] userIDs) => 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 byte[] CreatePdfAsByte(this Faker faker) { string name = faker.Name.FullName(); string address = faker.Address.FullAddress(); string lorem = faker.Lorem.Paragraphs(2); QuestPDF.Settings.License = LicenseType.Community; var document = QuestPDF.Fluent.Document.Create(container => { container.Page(page => { page.Margin(50); page.Header().Text("Random PDF").FontSize(20).Bold(); page.Content().Column(col => { col.Item().Text($"Vor- und Nachname: {name}"); col.Item().Text($"Adresse: {address}"); col.Item().Text(lorem); }); }); }); using var ms = new MemoryStream(); document.GeneratePdf(ms); 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() }; public static List CreateDocumentCommands(this Faker fake, int minCount = 10, int maxCount = 20) => Enumerable.Range(0, fake.Random.Number(minCount, maxCount)) .Select(_ => fake.CreateDocumentCommand()) .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) { return new() { Status = status ?? fake.PickEnum(), Comment = fake.Lorem.Sentence(), Key = key, }; } #endregion #region User Command public static CreateUserCommand CreateUserCommand(this Faker fake) => new() { Prename = fake.Name.FirstName(), Name = fake.Name.LastName(), Username = fake.Internet.UserName(), Shortname = fake.Random.String2(3, 8), Email = fake.Internet.Email() }; public static List CreateUserCommands(this Faker fake, int minCount = 10, int maxCount = 20) => Enumerable.Range(0, fake.Random.Number(minCount, maxCount)) .Select(_ => fake.CreateUserCommand()) .ToList(); #endregion }