using Hutopy.Domain.Constants; using Hutopy.Infrastructure.Identity; using Hutopy.Web.Common; using Hutopy.Web.Features.Contents.Data; using Hutopy.Web.Features.Messages.Data; namespace Hutopy.Web; public static class WebApplicationExtensions { public static async Task SeedDatabaseWithTestDataOnlyIfNoDataIsPresentAsync( this WebApplication app, CancellationToken ct = default) { using var scope = app.Services.CreateScope(); var seeder = new TestDataSeeder( scope.ServiceProvider.GetRequiredService(), scope.ServiceProvider.GetRequiredService(), scope.ServiceProvider.GetRequiredService()); await seeder.SeedAsync(); } } internal class TestDataSeeder( ApplicationUserManager userManager, ContentDbContext contentContext, MessagingDbContext messagingContext) { private const string DefaultPassword = "Test123#"; public async Task SeedAsync() { if (contentContext.Contents.Any()) return; _users.Add(await CreateUserAsync("admin", null, Roles.Administrator)); var userA = await CreateUserAsync("userA", null); _users.Add(userA); _users.Add(await CreateUserAsync("userB", null)); foreach (var creator in _creators) { var creatorUser = await CreateUserAsync( creator.Name, creator.Images.Logo, Roles.Creator); creator.Id = creatorUser.Id; creator.CreatedBy = creator.Id; await contentContext.Subscriptions.AddAsync(new() { CreatedBy = userA.Id, CreatorId = creator.Id }); await contentContext.Creators.AddAsync(creator); var contents = GenerateContent(creator, 10); foreach (var content in contents) { var messages = GenerateMessages(content, 10); var parentMessages = messages.Where((_, index) => index % 2 == 0).ToList(); foreach (var parentMessage in parentMessages) { _ = GenerateReplies(content, parentMessage, 10); } await messagingContext.SaveChangesAsync(); } } } private List GenerateContent(Creator creator, int contentCount) { var currentDate = DateTimeOffset.UtcNow; var contents = new List(); for (var c = contentCount; c > 0; c--) { var content = new Content { Id = GuidHelper.GenerateUuidV7(), CreatedBy = creator.Id, CreatedAt = currentDate, Title = $"Title {creator.Name}-{c}", Description = $"Description {creator.Name}-{c}" }; contentContext.Contents.Add(content); contents.Add(content); currentDate = currentDate.AddSeconds(-Random.Shared.Next(100, 100_000)); } contentContext.SaveChanges(); return contents; } private List GenerateMessages(Content content, int messageCount) { var currentDate = content.CreatedAt; var messages = new List(); for (var m = messageCount; m > 0; m--) { currentDate = currentDate.AddSeconds(-Random.Shared.Next(100, 100_000)); var author = Random.Shared.GetItems(_users.ToArray(), 1).First(); var message = new Message { Id = GuidHelper.GenerateUuidV7(), SubjectId = content.Id, CreatedAt = currentDate, CreatedBy = author.Id, CreatedByName = author.Alias ?? $"{author.FirstName} {author.LastName}", CreatedByPortraitUrl = author.PortraitUrl, Value = $"Message #{m} on {content.Title}" }; messagingContext.Messages.Add(message); messages.Add(message); } return messages; } private List GenerateReplies(Content content, Message parent, int replyCount) { var currentDate = parent.CreatedAt; var replies = new List(); for (var r = replyCount; r > 0; r--) { currentDate = currentDate.AddSeconds(-Random.Shared.Next(100, 100_000)); var author = Random.Shared.GetItems(_users.ToArray(), 1).First(); var message = new Message { Id = GuidHelper.GenerateUuidV7(), SubjectId = content.Id, ParentId = parent.Id, CreatedBy = author.Id, CreatedByName = author.Alias ?? $"{author.FirstName} {author.LastName}", CreatedByPortraitUrl = author.PortraitUrl, CreatedAt = currentDate, Value = $"Reply {r} to {parent.Value} on {content.Title}" }; messagingContext.Messages.Add(message); replies.Add(message); } return replies; } private async Task CreateUserAsync(string name, string? portraitUrl, params string[] roles) { var user = new ApplicationUser { UserName = $"{name}@test", Email = $"{name}@test", EmailConfirmed = true, Alias = name, FirstName = $"FirstName of {name}", LastName = $"LastName of {name}", PortraitUrl = portraitUrl }; await userManager.CreateAsync(user, DefaultPassword); if (roles.Length > 0) await userManager.AddToRolesAsync(user, roles); return user; } private readonly List _users = [ ]; private readonly static Creator HutopyCreator = new() { Name = "hutopy", About = new() { Title = "Page officielle", Description = "Site officiel pour Hutopy. Venez-nous-y retrouver avec tous vos fans!", }, Colors = new() { BannerTop = "#A30E79", BannerBottom = "#6B0065", Accent = "#23393B", Menu = "#53B93B", }, Socials = new() { XUrl = "https://twitter.com/Hutopyinc", FacebookUrl = "https://www.facebook.com/Hutopy", InstagramUrl = "https://www.instagram.com/hutopy.inc/" }, Images = new() { Banner = "/images/usersmedia/HutopyProfile/banners/banner01.png", Logo = "/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png" } }; private readonly static Creator ArpsCreator = new() { Name = "arps", About = new() { Title = "Page officielle", Description = "Site officiel pour Arps. Venez-nous-y retrouver avec tous vos fans!", }, Colors = new() { BannerTop = "#231F20", BannerBottom = "#231F20", Accent = "#272526", Menu = "#FFFFFF" }, Socials = new() { FacebookUrl = "https://www.facebook.com/arps.company", InstagramUrl = "https://www.instagram.com/arps.co/", YoutubeUrl = "https://www.youtube.com/channel/UCgnT_psydUXohYm5Yz_wFUg", TikTokUrl = "https://www.tiktok.com/@arps.co", LinkedInUrl = "https://www.linkedin.com/in/mickael-simard-96079a90/", WebsiteUrl = "https://www.arps.ca/" }, Images = new() { Banner = "/images/usersmedia/ARPS/banners/bannerARPS01.png", Logo = "/images/usersmedia/ARPS/profilepictures/profileARPS.png" } }; private readonly static Creator ChloeBeaugrandCreator = new() { Name = "chloebeaugrand", About = new() { Title = "Page officielle", Description = "𝐿𝑎 𝑐𝑟𝑒́𝑎𝑡𝑖𝑣𝑖𝑡𝑒́ 𝑐’𝑒𝑠𝑡 𝑙’𝑖𝑛𝑡𝑒𝑙𝑙𝑖𝑔𝑒𝑛𝑐𝑒 𝑞𝑢𝑖 𝑠’𝑎𝑚𝑢𝑠𝑒!", }, Colors = new() { BannerTop = "#231F20", BannerBottom = "#272526", Accent = "#231F20", Menu = "#231F20", }, Socials = new() { FacebookUrl = "https://www.facebook.com/chloegestionmedias", InstagramUrl = "https://www.instagram.com/chloe.photo_gms", }, Images = new() { Banner = "/images/usersmedia/chloebeaugrand/banners/bannerChloeBeaugrand01.png", Logo = "/images/usersmedia/chloebeaugrand/profilepictures/profileChloeBeaugrand01.png" } }; private readonly static Creator GuillaumeMCreator = new() { Name = "guillaumem", About = new() { Title = "Page officielle", Description = "Mettre en lumière le côté humain des entrepreneurs. Chaque service, chaque produit est porteur d’une histoire, d’une passion, d’une vision unique. Mon objectif est de faire rayonner cette unicité, de créer des connexions authentiques entre ces entrepreneurs et leurs clients potentiels. Parce que derrière chaque entreprise, il y a des personnes inspirantes qui méritent d’être entendues et comprises. Et toi, quel est ton objectif pour cette année?", }, Colors = new() { BannerTop = "#0BAAB2", BannerBottom = "#006D77", Accent = "#CC6F91", Menu = "#CC6F91", }, Socials = new() { FacebookUrl = "https://www.facebook.com/GuillaumeMousseau222", InstagramUrl = "https://www.instagram.com/guillaumeaime/", TikTokUrl = "https://www.tiktok.com/@guillaumeaime" }, Images = new() { Banner = "/images/usersmedia/guillaumeMousseau/banners/bannerGuillaumeMousseau01.png", Logo = "/images/usersmedia/guillaumeMousseau/profilepictures/profileGuillaumeMousseau01.png" } }; private readonly static Creator LeffetCreator = new() { Name = "leffet", About = new() { Title = "Page officielle", Description = "Mettre en lumière le côté humain des entrepreneurs. Chaque service, chaque produit est porteur d’une histoire, d’une passion, d’une vision unique. Mon objectif est de faire rayonner cette unicité, de créer des connexions authentiques entre ces entrepreneurs et leurs clients potentiels. Parce que derrière chaque entreprise, il y a des personnes inspirantes qui méritent d’être entendues et comprises. Et toi, quel est ton objectif pour cette année?", }, Colors = new() { BannerTop = "#CC6F91", BannerBottom = "#FBC702", Accent = "#FBC702", Menu = "#FBC702", }, Socials = new() { FacebookUrl = "https://www.facebook.com/Hutopy", InstagramUrl = "https://www.instagram.com/guillaumeaime/", WebsiteUrl = "https://fondationleffet.ca/" }, Images = new() { Banner = "/images/usersmedia/leffet/banners/banner02.png", Logo = "/images/usersmedia/leffet/profilepictures/leffetProfile01.png" } }; private readonly static Creator MathieuCaron = new() { Name = "mathieucaron", About = new() { Title = "Page officielle", Description = "Mettre en lumière le côté humain des entrepreneurs. Chaque service, chaque produit est porteur d’une histoire, d’une passion, d’une vision unique. Mon objectif est de faire rayonner cette unicité, de créer des connexions authentiques entre ces entrepreneurs et leurs clients potentiels. Parce que derrière chaque entreprise, il y a des personnes inspirantes qui méritent d’être entendues et comprises. Et toi, quel est ton objectif pour cette année?", }, Colors = new() { BannerTop = "#101B49", BannerBottom = "#698FE7", Accent = "#1D1D1B", Menu = "#1D1D1B", }, Socials = new() { FacebookUrl = "https://www.facebook.com/MathieuCaronPro/", YoutubeUrl = "https://www.youtube.com/@lesinterviewsatypiquesdema4692", }, Images = new() { Banner = "/images/usersmedia/mathieuCaron/banners/bannerMathieuCaron01.png", Logo = "/images/usersmedia/mathieuCaron/profilepictures/profileMathieuCaron01.png" } }; private readonly Creator[] _creators = [ HutopyCreator, ArpsCreator, ChloeBeaugrandCreator, GuillaumeMCreator, LeffetCreator, MathieuCaron ]; }