From 9aefd2c7c9a9280fd92bdf4c0a475ae443d620eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 14 Sep 2024 20:55:53 +0200 Subject: [PATCH 01/25] fix footer not being shown after navigating after from the chat --- src/web/Jordnaer/Extensions/JsRuntimeExtensions.cs | 5 +++++ src/web/Jordnaer/Pages/Chat/ChatPage.razor | 1 + src/web/Jordnaer/wwwroot/js/utilities.js | 9 ++++++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Extensions/JsRuntimeExtensions.cs b/src/web/Jordnaer/Extensions/JsRuntimeExtensions.cs index c129f376..e55ed93e 100644 --- a/src/web/Jordnaer/Extensions/JsRuntimeExtensions.cs +++ b/src/web/Jordnaer/Extensions/JsRuntimeExtensions.cs @@ -17,6 +17,11 @@ public static async Task HideElement(this IJSRuntime jsRuntime, string sel => await jsRuntime.InvokeVoidAsyncWithErrorHandling( "utilities.hideElement", selector); + + public static async Task ShowElement(this IJSRuntime jsRuntime, string selector) + => await jsRuntime.InvokeVoidAsyncWithErrorHandling( + "utilities.showElement", + selector); public static async ValueTask GetGeolocation(this IJSRuntime jsRuntime) { var (success, geoLocation) = await jsRuntime.InvokeAsyncWithErrorHandling("utilities.getGeolocation"); diff --git a/src/web/Jordnaer/Pages/Chat/ChatPage.razor b/src/web/Jordnaer/Pages/Chat/ChatPage.razor index 6731c6b2..18dc35d0 100644 --- a/src/web/Jordnaer/Pages/Chat/ChatPage.razor +++ b/src/web/Jordnaer/Pages/Chat/ChatPage.razor @@ -281,5 +281,6 @@ { await BrowserViewportService.UnsubscribeAsync(_breakpointObserverId); await ChatSignalRClient.StopAsync(); + await JsRuntime.ShowElement(".footer"); } } diff --git a/src/web/Jordnaer/wwwroot/js/utilities.js b/src/web/Jordnaer/wwwroot/js/utilities.js index ad4e8d2a..0719cc8e 100644 --- a/src/web/Jordnaer/wwwroot/js/utilities.js +++ b/src/web/Jordnaer/wwwroot/js/utilities.js @@ -4,7 +4,14 @@ window.utilities = { if (!element) return; - element.style.setProperty("display", "none", "important") + element.style.setProperty("display", "none", "important"); + }, + showElement: function (selector) { + const element = document.querySelector(selector); + + if (!element) return; + + element.style.removeProperty("display"); }, focusElement: function (selector) { From 6174fb147229fafd23b9055a66badb9f3d74652c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 15 Sep 2024 22:35:04 +0200 Subject: [PATCH 02/25] refresh footer pages + make sure they scroll to the top on navigation --- .../Components/ScrollToTopComponentBase.cs | 47 ++++++++++++ src/web/Jordnaer/Pages/Footer/About.razor | 61 ++++++++------- src/web/Jordnaer/Pages/Footer/Contact.razor | 8 +- src/web/Jordnaer/Pages/Footer/Operation.razor | 10 ++- src/web/Jordnaer/Pages/Footer/Privacy.razor | 6 +- src/web/Jordnaer/Pages/Footer/Sponsors.razor | 75 ++++++++++--------- src/web/Jordnaer/Pages/Footer/Terms.razor | 6 +- 7 files changed, 137 insertions(+), 76 deletions(-) create mode 100644 src/web/Jordnaer/Components/ScrollToTopComponentBase.cs diff --git a/src/web/Jordnaer/Components/ScrollToTopComponentBase.cs b/src/web/Jordnaer/Components/ScrollToTopComponentBase.cs new file mode 100644 index 00000000..1fbe0105 --- /dev/null +++ b/src/web/Jordnaer/Components/ScrollToTopComponentBase.cs @@ -0,0 +1,47 @@ +using Microsoft.AspNetCore.Components; +using MudBlazor; + +namespace Jordnaer.Components; + +public class ScrollToTopComponentBase : ComponentBase, IDisposable, IAsyncDisposable +{ + [Inject] + private IScrollManager ScrollManager { get; set; } = null!; + + private CancellationTokenSource? _cancellationTokenSource; + + protected CancellationToken CancellationToken => (_cancellationTokenSource ??= new CancellationTokenSource()).Token; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await ScrollManager.ScrollToTopAsync("html"); + } + + public void Dispose() + { + GC.SuppressFinalize(this); + + if (_cancellationTokenSource is null) + { + return; + } + + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + _cancellationTokenSource = null; + } + + public async ValueTask DisposeAsync() + { + GC.SuppressFinalize(this); + + if (_cancellationTokenSource is null) + { + return; + } + + await _cancellationTokenSource.CancelAsync(); + _cancellationTokenSource.Dispose(); + _cancellationTokenSource = null; + } +} \ No newline at end of file diff --git a/src/web/Jordnaer/Pages/Footer/About.razor b/src/web/Jordnaer/Pages/Footer/About.razor index e7894f5b..6404999c 100644 --- a/src/web/Jordnaer/Pages/Footer/About.razor +++ b/src/web/Jordnaer/Pages/Footer/About.razor @@ -1,56 +1,59 @@ @page "/about" +@inherits ScrollToTopComponentBase + - + -

Hvad er Mini Møder?

+

Hvad er

+ Mini Møder Logo - Mini Møder er en hjemmeside til os, der ønsker at skabe nye relationer med andre børnefamilier. + Mini Møder er en hjemmeside til os, der ønsker at skabe nye relationer med andre børnefamilier. - Siden er skabt med særligt henblik på at hjælpe legegrupper, - hjemmegrupper og hjemmeskoler med at blive dannet og gro. - + Siden er skabt med særligt henblik på at hjælpe legegrupper, + hjemmegrupper og hjemmeskoler med at blive dannet og gro. + - Vi vil gøre det nemmere for forældre at finde venner til deres børn. - + Vi vil gøre det nemmere for børn at finde nye venner. + - + -

- Hvorfor har vi skabt Mini Møder? -

+

+ Hvorfor har vi skabt Mini Møder? +

- Vi har lavet Mini Møder fordi vi selv har manglet en konkret platform til at lede - efter legegrupper til vores børn. + Vi har lavet Mini Møder fordi vi selv har manglet en konkret platform til at lede + efter legegrupper til vores børn. - Da vi hjemmepassede vores børn, fandt vi det utrolig besværligt og kompliceret at - finde en fast gruppe af børn og voksne, - som vi kunne ses med jævnligt og skabe minder sammen med. - + Da vi hjemmepassede vores børn, fandt vi det utrolig besværligt og kompliceret at + finde en fast gruppe af børn og voksne, + som vi kunne ses med jævnligt og skabe minder sammen med. + - Vi har et dybt ønske om, at Mini Møder kan blive en grobund for tætte relationer, - gode venner og stærke forbindelser.Tryghed og tillid er efter vores mening afgørende - for børns velbefindende og trivsel. - + Vi har et dybt ønske om, at Mini Møder kan blive en grobund for tætte relationer, + gode venner og stærke forbindelser.Tryghed og tillid er efter vores mening afgørende + for børns velbefindende og trivsel. + - Børnenes primære omsorgspersoner, tætte relationer og stærke fællesskaber kan støtte - barnets sundhed og trivsel, og Mini Møder kan hjælpe med at finde disse fællesskaber, - hvor børnenes præmisser er i højsædet. - + Børnenes primære omsorgspersoner, tætte relationer og stærke fællesskaber kan støtte + barnets sundhed og trivsel, og Mini Møder kan hjælpe med at finde disse fællesskaber, + hvor børnenes præmisser er i højsædet. + - + -
-
+ + \ No newline at end of file diff --git a/src/web/Jordnaer/Pages/Footer/Contact.razor b/src/web/Jordnaer/Pages/Footer/Contact.razor index 3f47f672..e5a863a7 100644 --- a/src/web/Jordnaer/Pages/Footer/Contact.razor +++ b/src/web/Jordnaer/Pages/Footer/Contact.razor @@ -2,14 +2,16 @@ @inject IEmailService EmailService @inject ISnackbar Snackbar +@inherits ScrollToTopComponentBase + - + -

Kontakt os

+

Kontakt os

@@ -45,7 +47,7 @@ AutoGrow Class="my-3"/> - - + -

+

Drift

@@ -18,7 +20,7 @@ Jeg bygger Mini Møder i min fritid, oftest om aftenen når mine to unger er puttet. Jeg står for udvikling, drift og vedligeholdelse af hele molevitten. - + @@ -27,7 +29,7 @@ Du kan komme i kontakt med os gennem vores kontaktformular. - + Af juridiske årsager ejer jeg Mini Møder gennem min enkeltmandsvirksomhed:
diff --git a/src/web/Jordnaer/Pages/Footer/Privacy.razor b/src/web/Jordnaer/Pages/Footer/Privacy.razor index 9882819d..122b2545 100644 --- a/src/web/Jordnaer/Pages/Footer/Privacy.razor +++ b/src/web/Jordnaer/Pages/Footer/Privacy.razor @@ -1,12 +1,14 @@ @page "/privacy" +@inherits ScrollToTopComponentBase + - + -

+

Privatlivspolitik

diff --git a/src/web/Jordnaer/Pages/Footer/Sponsors.razor b/src/web/Jordnaer/Pages/Footer/Sponsors.razor index 50632855..e3df0ce3 100644 --- a/src/web/Jordnaer/Pages/Footer/Sponsors.razor +++ b/src/web/Jordnaer/Pages/Footer/Sponsors.razor @@ -1,59 +1,62 @@ @page "/sponsors" +@inherits ScrollToTopComponentBase + - + -

- Vore Sponsorer -

+

+ Vore Sponsorer +

- + - - @foreach (var sponsor in _sponsors) - { - - } - + + @foreach (var sponsor in _sponsors) + { + + } + - + -

- Bliv Sponsor -

+

+ Bliv Sponsor +

- - At være en sponsor af Mini Møder giver en unik mulighed for at støtte et - lokalt initiativ og samtidig opnå synlighed for dit brand. + + At være sponsor af Mini Møder giver en unik mulighed for at støtte vores arbejde + og samtidig opnå synlighed for dit brand. - Hvis du er interesseret i at høre mere om mulighederne for at blive en sponsor, - er du meget velkommen til at kontakte os gennem vores kontaktformular. - + Hvis du er interesseret i at høre mere om mulighederne for at blive sponsor, + er du meget velkommen til at kontakte os gennem vores kontaktformular. + -
+ +
@code { private static readonly List _sponsors = [ - new Sponsor - { - Name = string.Empty, - Description = "Moon Creative laver illustrationer og grafisk design til iværksættere og virksomheder, der ønsker at skabe forandring i mennesker", - LogoUrl = "https://usercontent.one/wp/www.mooncreative.dk/wp-content/uploads/2022/04/Logo_mooncreative_long-2-e1649063478985.png", - Link = "https://www.mooncreative.dk/" - }, - new Sponsor - { - Name = string.Empty, - Description = "Microsoft for Startups samler mennesker, viden og teknologi for at hjælpe iværksættere på alle stadier med at løse udfordringer i startfasen.", - LogoUrl = "https://i.ibb.co/v4Q7pkQ/startups-wordmark-purple.png", - Link = "https://www.microsoft.com/en-us/startups" + new Sponsor + { + Name = string.Empty, + Description = "Moon Creative laver illustrationer og grafisk design til iværksættere og virksomheder, der ønsker at skabe forandring i mennesker", + LogoUrl = "https://usercontent.one/wp/www.mooncreative.dk/wp-content/uploads/2022/04/Logo_mooncreative_long-2-e1649063478985.png", + Link = "https://www.mooncreative.dk/" + }, + new Sponsor + { + Name = string.Empty, + Description = "Microsoft for Startups samler mennesker, viden og teknologi for at hjælpe iværksættere på alle stadier med at løse udfordringer i startfasen.", + LogoUrl = "https://i.ibb.co/v4Q7pkQ/startups-wordmark-purple.png", + Link = "https://www.microsoft.com/en-us/startups" }, new Sponsor { @@ -63,5 +66,5 @@ Link = "https://elmah.io/" } ]; - + } diff --git a/src/web/Jordnaer/Pages/Footer/Terms.razor b/src/web/Jordnaer/Pages/Footer/Terms.razor index 82d329b4..fe758003 100644 --- a/src/web/Jordnaer/Pages/Footer/Terms.razor +++ b/src/web/Jordnaer/Pages/Footer/Terms.razor @@ -1,12 +1,14 @@ @page "/terms" +@inherits ScrollToTopComponentBase + - + -

+

Servicevilkår

From 716c679ed42c92a07f6092fe11d2673f408a4ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 15 Sep 2024 22:35:08 +0200 Subject: [PATCH 03/25] Create Bees.razor --- src/web/Jordnaer/Features/Theme/Bees.razor | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/web/Jordnaer/Features/Theme/Bees.razor diff --git a/src/web/Jordnaer/Features/Theme/Bees.razor b/src/web/Jordnaer/Features/Theme/Bees.razor new file mode 100644 index 00000000..cf5297ca --- /dev/null +++ b/src/web/Jordnaer/Features/Theme/Bees.razor @@ -0,0 +1,22 @@ +@if (Center) +{ +
+ +
+} +else +{ + +} + +@code { + [Parameter] + public string? Class { get; set; } + [Parameter] + public string? Style { get; set; } + [Parameter] + public bool Center { get; set; } = false; + + private int _width = 150; + private static readonly string _src = "/images/bier.png"; +} From 7a345905c30389e1e083f8ec6dc36b42a4d0b2d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 15 Sep 2024 22:35:33 +0200 Subject: [PATCH 04/25] dbcontextfactory for safety --- .../Features/Chat/ChatNotificationService.cs | 3 +- .../GroupSearch/GroupSearchService.cs | 3 +- .../ExternalProfilePictureDownloader.cs | 4 +- .../Features/Images/ProfileImageService.cs | 38 ++++++++++++------- .../Features/UserSearch/UserSearchService.cs | 5 ++- .../Chat/ChatNotificationServiceTests.cs | 16 +++++--- .../UserSearch/UserSearchServiceTests.cs | 8 +++- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/web/Jordnaer/Features/Chat/ChatNotificationService.cs b/src/web/Jordnaer/Features/Chat/ChatNotificationService.cs index cba8a5ba..bc6c389e 100644 --- a/src/web/Jordnaer/Features/Chat/ChatNotificationService.cs +++ b/src/web/Jordnaer/Features/Chat/ChatNotificationService.cs @@ -11,13 +11,14 @@ namespace Jordnaer.Features.Chat; public class ChatNotificationService( - JordnaerDbContext context, + IDbContextFactory contextFactory, ILogger logger, IPublishEndpoint publishEndpoint, IServer server) { public async Task NotifyRecipients(StartChat startChat, CancellationToken cancellationToken = default) { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var recipientIds = startChat.Recipients.Select(recipient => recipient.Id); var recipients = await context.Users .AsNoTracking() diff --git a/src/web/Jordnaer/Features/GroupSearch/GroupSearchService.cs b/src/web/Jordnaer/Features/GroupSearch/GroupSearchService.cs index 379d62ac..35aec236 100644 --- a/src/web/Jordnaer/Features/GroupSearch/GroupSearchService.cs +++ b/src/web/Jordnaer/Features/GroupSearch/GroupSearchService.cs @@ -12,7 +12,7 @@ public interface IGroupSearchService } public class GroupSearchService( - JordnaerDbContext context, + IDbContextFactory contextFactory, IZipCodeService zipCodeService) : IGroupSearchService { @@ -21,6 +21,7 @@ public async Task GetGroupsAsync(GroupSearchFilter filter, { JordnaerMetrics.GroupSearchesCounter.Add(1, MakeTagList(filter)); + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var groups = context.Groups .AsNoTracking() .AsQueryable() diff --git a/src/web/Jordnaer/Features/Images/ExternalProfilePictureDownloader.cs b/src/web/Jordnaer/Features/Images/ExternalProfilePictureDownloader.cs index 3b435ddb..c4ed0556 100644 --- a/src/web/Jordnaer/Features/Images/ExternalProfilePictureDownloader.cs +++ b/src/web/Jordnaer/Features/Images/ExternalProfilePictureDownloader.cs @@ -1,10 +1,11 @@ using Jordnaer.Database; using Mediator; +using Microsoft.EntityFrameworkCore; namespace Jordnaer.Features.Images; public class ExternalProfilePictureDownloader( - JordnaerDbContext context, + IDbContextFactory contextFactory, ILogger logger, IEnumerable providerPictureDownloader) : INotificationHandler @@ -19,6 +20,7 @@ public async ValueTask Handle(AccessTokenAcquired notification, CancellationToke return; } + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var user = await context.UserProfiles.FindAsync([notification.UserId], cancellationToken); if (user is null) { diff --git a/src/web/Jordnaer/Features/Images/ProfileImageService.cs b/src/web/Jordnaer/Features/Images/ProfileImageService.cs index 3471608d..b2173d8d 100644 --- a/src/web/Jordnaer/Features/Images/ProfileImageService.cs +++ b/src/web/Jordnaer/Features/Images/ProfileImageService.cs @@ -11,7 +11,7 @@ public interface IProfileImageService Task SetGroupProfilePictureAsync(SetGroupProfilePicture dto); } -public class ProfileImageService(JordnaerDbContext context, IImageService imageService) : IProfileImageService +public class ProfileImageService(IDbContextFactory contextFactory, IImageService imageService) : IProfileImageService { public const string ChildProfilePicturesContainerName = "childprofile-pictures"; public const string UserProfilePicturesContainerName = "userprofile-pictures"; @@ -50,14 +50,18 @@ public async Task SetGroupProfilePictureAsync(SetGroupProfilePicture dto return uri; } - private async Task UpdateChildProfilePictureAsync(SetChildProfilePicture dto, string uri) + private async Task UpdateChildProfilePictureAsync( + SetChildProfilePicture dto, + string uri, + CancellationToken cancellationToken = default) { - var currentChildProfile = await context.ChildProfiles.FindAsync(dto.ChildProfile.Id); + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentChildProfile = await context.ChildProfiles.FindAsync([dto.ChildProfile.Id], cancellationToken); if (currentChildProfile is null) { dto.ChildProfile.PictureUrl = uri; context.ChildProfiles.Add(dto.ChildProfile); - await context.SaveChangesAsync(); + await context.SaveChangesAsync(cancellationToken); return; } @@ -67,18 +71,22 @@ private async Task UpdateChildProfilePictureAsync(SetChildProfilePicture dto, st currentChildProfile.PictureUrl = uri; context.Entry(currentChildProfile).State = EntityState.Modified; - await context.SaveChangesAsync(); + await context.SaveChangesAsync(cancellationToken); } } - private async Task UpdateUserProfilePictureAsync(SetUserProfilePicture dto, string uri) + private async Task UpdateUserProfilePictureAsync( + SetUserProfilePicture dto, + string uri, + CancellationToken cancellationToken = default) { - var currentUserProfile = await context.UserProfiles.FindAsync(dto.UserProfile.Id); + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentUserProfile = await context.UserProfiles.FindAsync([dto.UserProfile.Id], cancellationToken); if (currentUserProfile is null) { dto.UserProfile.ProfilePictureUrl = uri; context.UserProfiles.Add(dto.UserProfile); - await context.SaveChangesAsync(); + await context.SaveChangesAsync(cancellationToken); return; } @@ -88,17 +96,21 @@ private async Task UpdateUserProfilePictureAsync(SetUserProfilePicture dto, stri currentUserProfile.ProfilePictureUrl = uri; context.Entry(currentUserProfile).State = EntityState.Modified; - await context.SaveChangesAsync(); + await context.SaveChangesAsync(cancellationToken); } } - private async Task UpdateGroupProfilePictureAsync(SetGroupProfilePicture dto, string uri) + private async Task UpdateGroupProfilePictureAsync( + SetGroupProfilePicture dto, + string uri, + CancellationToken cancellationToken = default) { - var currentGroup = await context.Groups.FindAsync(dto.Group.Id); + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var currentGroup = await context.Groups.FindAsync([dto.Group.Id], cancellationToken); if (currentGroup is null) { dto.Group.ProfilePictureUrl = uri; context.Groups.Add(dto.Group); - await context.SaveChangesAsync(); + await context.SaveChangesAsync(cancellationToken); return; } @@ -108,7 +120,7 @@ private async Task UpdateGroupProfilePictureAsync(SetGroupProfilePicture dto, st currentGroup.ProfilePictureUrl = uri; context.Entry(currentGroup).State = EntityState.Modified; - await context.SaveChangesAsync(); + await context.SaveChangesAsync(cancellationToken); } } } \ No newline at end of file diff --git a/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs b/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs index 0b5b8f97..6f71634a 100644 --- a/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs +++ b/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs @@ -14,12 +14,13 @@ public interface IUserSearchService public class UserSearchService( IZipCodeService zipCodeService, - JordnaerDbContext context) + IDbContextFactory contextFactory) : IUserSearchService { public async Task> GetUsersByNameAsync(string currentUserId, string searchString, CancellationToken cancellationToken = default) { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); var users = ApplyNameFilter(searchString, context.UserProfiles); var firstTenUsers = await users @@ -43,6 +44,8 @@ public async Task GetUsersAsync(UserSearchFilter filter, Cance { JordnaerMetrics.UserSearchesCounter.Add(1, MakeTagList(filter)); + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + var users = context.UserProfiles .Where(user => !string.IsNullOrEmpty(user.UserName)) .AsQueryable(); diff --git a/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs b/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs index 6573d240..9336175d 100644 --- a/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs +++ b/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Moq; using Moq.EntityFrameworkCore; using NSubstitute; @@ -19,23 +19,27 @@ namespace Jordnaer.Tests.Chat; [Trait("Category", "UnitTest")] public class ChatNotificationServiceTests { + private readonly Mock> _contextFactoryMock; private readonly Mock _contextMock; - private readonly Mock> _loggerMock; private readonly Mock _publishEndpointMock; private readonly IServer _serverMock; private readonly ChatNotificationService _service; public ChatNotificationServiceTests() { - _contextMock = new Mock( + _contextFactoryMock = new Mock>( new DbContextOptionsBuilder().Options); - _loggerMock = new Mock>(); + _contextMock = new Mock(); + _contextFactoryMock + .Setup(x => x.CreateDbContextAsync(It.IsAny())) + .ReturnsAsync(_contextMock.Object); + _publishEndpointMock = new Mock(); _serverMock = Substitute.For(); _service = new ChatNotificationService( - _contextMock.Object, - _loggerMock.Object, + _contextFactoryMock.Object, + new NullLogger(), _publishEndpointMock.Object, _serverMock ); diff --git a/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs b/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs index 86803e52..7e46af33 100644 --- a/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs +++ b/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs @@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore; using NSubstitute; using Jordnaer.Features.Search; +using Moq; using Xunit; namespace Jordnaer.Tests.UserSearch; @@ -16,16 +17,19 @@ namespace Jordnaer.Tests.UserSearch; [Collection(nameof(SqlServerContainerCollection))] public class UserSearchServiceTests : IAsyncLifetime { - private readonly JordnaerDbContext _context; + private readonly Mock> _contextFactory = new(); private readonly IZipCodeService _zipCodeServiceMock = Substitute.For(); private readonly UserSearchService _sut; private readonly Faker _faker = new(); + private readonly JordnaerDbContext _context; public UserSearchServiceTests(SqlServerContainer sqlServerContainer) { _context = sqlServerContainer.CreateContext(); + _contextFactory.Setup(x => x.CreateDbContextAsync(It.IsAny())) + .ReturnsAsync(_context); - _sut = new UserSearchService(_zipCodeServiceMock, _context); + _sut = new UserSearchService(_zipCodeServiceMock, _contextFactory.Object); } [Fact] From 4dcdc221cbb7957100445add10ccc4297fead72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 15 Sep 2024 22:35:46 +0200 Subject: [PATCH 05/25] methods for easier css color --- src/web/Jordnaer/Extensions/MudColorExtensions.cs | 10 ++++++++++ src/web/Jordnaer/Features/Theme/JordnaerPalette.cs | 12 ++---------- src/web/Jordnaer/Features/Theme/MiniDivider.razor | 1 - .../Jordnaer/Pages/Home/DesktopLandingPage.razor | 10 +++++----- .../Jordnaer/Pages/Home/MobileLandingPage.razor | 14 +++++++------- .../Jordnaer/Pages/Registration/FirstLogin.razor | 4 ++-- 6 files changed, 26 insertions(+), 25 deletions(-) create mode 100644 src/web/Jordnaer/Extensions/MudColorExtensions.cs diff --git a/src/web/Jordnaer/Extensions/MudColorExtensions.cs b/src/web/Jordnaer/Extensions/MudColorExtensions.cs new file mode 100644 index 00000000..9f2161cc --- /dev/null +++ b/src/web/Jordnaer/Extensions/MudColorExtensions.cs @@ -0,0 +1,10 @@ +using MudBlazor.Utilities; + +namespace Jordnaer.Extensions; + +public static class MudColorExtensions +{ + public static string ToBackgroundColor(this MudColor color) => $"background-color: {color}"; + + public static string ToTextColor(this MudColor color) => $"color: {color}"; +} diff --git a/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs b/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs index a635ffa5..90167ac8 100644 --- a/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs +++ b/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs @@ -43,28 +43,20 @@ public static class JordnaerPalette /// /// Dark Blue. Used for body text /// - public static readonly MudColor BlueBody = "#41556b"; - - public static readonly string BlueBodyTextStyle = $"color: {BlueBody}"; + public static readonly MudColor BlueBody = "#41556b"; /// /// Dark Red. Used for small texts, payoffs, quotes /// - public static readonly MudColor RedHeader = "#673417"; - - public static readonly string RedHeaderTextStyle = $"color: {RedHeader}"; + public static readonly MudColor RedHeader = "#673417"; /// /// Beige. Used as background for text where and are too dark/saturated. /// public static readonly MudColor BeigeBackground = "#cfc1a699"; // 99 added to apply 60% opacity - public static readonly string BeigeBackgroundStyle = $"background-color: {BeigeBackground}"; - /// /// Pale Blue. Rarely used as background for text where and are too dark/saturated. /// public static readonly MudColor PaleBlueBackground = "#a9c0cf66"; // 66 added to apply 40% opacity - - public static readonly string PaleBlueBackgroundStyle = $"background-color: {PaleBlueBackground}"; } diff --git a/src/web/Jordnaer/Features/Theme/MiniDivider.razor b/src/web/Jordnaer/Features/Theme/MiniDivider.razor index cb509da9..d45121cc 100644 --- a/src/web/Jordnaer/Features/Theme/MiniDivider.razor +++ b/src/web/Jordnaer/Features/Theme/MiniDivider.razor @@ -16,7 +16,6 @@ else public string? Style { get; set; } [Parameter] public required MiniDividerColor Color { get; set; } - [Parameter] public bool Center { get; set; } = false; diff --git a/src/web/Jordnaer/Pages/Home/DesktopLandingPage.razor b/src/web/Jordnaer/Pages/Home/DesktopLandingPage.razor index de8ae493..3c330840 100644 --- a/src/web/Jordnaer/Pages/Home/DesktopLandingPage.razor +++ b/src/web/Jordnaer/Pages/Home/DesktopLandingPage.razor @@ -5,7 +5,7 @@ - + OPSLAG @@ -14,13 +14,13 @@ - + - Velkommen - Til mødestedet for børnefamilier + Velkommen + Til mødestedet for børnefamilier @@ -30,7 +30,7 @@
- + Hvad kan jeg bruge Mini Møder til? diff --git a/src/web/Jordnaer/Pages/Home/MobileLandingPage.razor b/src/web/Jordnaer/Pages/Home/MobileLandingPage.razor index 905ff443..af2759dd 100644 --- a/src/web/Jordnaer/Pages/Home/MobileLandingPage.razor +++ b/src/web/Jordnaer/Pages/Home/MobileLandingPage.razor @@ -5,7 +5,7 @@
- + OPSLAG @@ -15,14 +15,14 @@
- + - + Velkommen - + Til mødestedet for børnefamilier @@ -34,11 +34,11 @@
- - Hvad kan jeg bruge Mini Møder til? + + Hvad kan jeg bruge Mini Møder til? - +
diff --git a/src/web/Jordnaer/Pages/Registration/FirstLogin.razor b/src/web/Jordnaer/Pages/Registration/FirstLogin.razor index 65ec16aa..f3750058 100644 --- a/src/web/Jordnaer/Pages/Registration/FirstLogin.razor +++ b/src/web/Jordnaer/Pages/Registration/FirstLogin.razor @@ -20,10 +20,10 @@ - @title + @title - @body + @body Date: Sat, 5 Oct 2024 21:28:11 +0200 Subject: [PATCH 06/25] Remove Azure App config to cut costs --- src/web/Jordnaer/Program.cs | 2 -- src/web/Jordnaer/appsettings.Development.json | 24 +++++++++++++++++++ src/web/Jordnaer/appsettings.json | 5 ++-- 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 src/web/Jordnaer/appsettings.Development.json diff --git a/src/web/Jordnaer/Program.cs b/src/web/Jordnaer/Program.cs index 3364b73c..dcd633a1 100644 --- a/src/web/Jordnaer/Program.cs +++ b/src/web/Jordnaer/Program.cs @@ -36,8 +36,6 @@ builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); -builder.AddAzureAppConfiguration(); - builder.AddAuthentication(); builder.Services.AddAuthorization(); diff --git a/src/web/Jordnaer/appsettings.Development.json b/src/web/Jordnaer/appsettings.Development.json new file mode 100644 index 00000000..a805454c --- /dev/null +++ b/src/web/Jordnaer/appsettings.Development.json @@ -0,0 +1,24 @@ +{ + "DataForsyningen": { + "BaseUrl": "https://api.dataforsyningen.dk" + }, + "FeatureManagement": { + "Contacts": false, + "Events": false, + "Posts": false, + "AccountSettings": false, + "NotificationSettings": false + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information", + "System.Net.Http": "Warning", + "Polly": "Warning", + "MudBlazor": "Information" + } + } + } +} \ No newline at end of file diff --git a/src/web/Jordnaer/appsettings.json b/src/web/Jordnaer/appsettings.json index 47e5ae97..acdcf041 100644 --- a/src/web/Jordnaer/appsettings.json +++ b/src/web/Jordnaer/appsettings.json @@ -12,13 +12,12 @@ }, "Serilog": { "MinimumLevel": { - "Default": "Debug", + "Default": "Information", "Override": { "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information", "System.Net.Http": "Warning", - "Polly": "Warning", - "MudBlazor": "Information" + "Polly": "Warning" } } } From 57a6baf5d71ed4351bbcf5218f6e1a22b716cc20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 21:57:23 +0200 Subject: [PATCH 07/25] nuget updates --- .../Jordnaer.Benchmarks.csproj | 4 +-- .../Jordnaer.Chat/Jordnaer.Chat.csproj | 6 ++-- .../Jordnaer.Shared.Infrastructure.csproj | 1 - .../Jordnaer.Shared/Jordnaer.Shared.csproj | 8 ++--- src/web/Jordnaer/Jordnaer.csproj | 36 +++++++++---------- .../Jordnaer.Chat.Tests.csproj | 16 ++++----- .../Jordnaer.E2E.Tests.csproj | 8 ++--- .../Jordnaer.Load.Tests.csproj | 6 ++-- .../web/Jordnaer.Tests/Jordnaer.Tests.csproj | 18 +++++----- 9 files changed, 51 insertions(+), 52 deletions(-) diff --git a/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj b/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj index 5143eab5..f9c84fdc 100644 --- a/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj +++ b/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj b/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj index 9439fac9..ccee49b1 100644 --- a/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj +++ b/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj @@ -11,12 +11,12 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj b/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj index 63cad0c6..fcdf48d3 100644 --- a/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj +++ b/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj @@ -11,6 +11,5 @@ - diff --git a/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj b/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj index 2df7c081..504ba73f 100644 --- a/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj +++ b/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj @@ -7,14 +7,14 @@ - + - + - - + + diff --git a/src/web/Jordnaer/Jordnaer.csproj b/src/web/Jordnaer/Jordnaer.csproj index 40269485..0243eeec 100644 --- a/src/web/Jordnaer/Jordnaer.csproj +++ b/src/web/Jordnaer/Jordnaer.csproj @@ -7,29 +7,29 @@ - + - + - - - - - - - - - - + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + @@ -39,11 +39,11 @@ - + - - - + + + diff --git a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj index 45891d78..087e767d 100644 --- a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj +++ b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj @@ -12,23 +12,23 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj b/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj index efcbd1c4..4b6c761f 100644 --- a/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj +++ b/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj @@ -19,16 +19,16 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj b/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj index 7ffc532d..028e8baf 100644 --- a/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj +++ b/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj @@ -12,10 +12,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj index 421d2232..11dd60eb 100644 --- a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj +++ b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj @@ -8,26 +8,26 @@ - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all From 2a2ccd28d418ea5c71c19d84f42db4b1c5c17809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 21:57:55 +0200 Subject: [PATCH 08/25] remove azure app config harder --- src/container_apps/Jordnaer.Chat/Program.cs | 2 -- .../AzureAppConfigurationExtensions.cs | 36 ------------------- src/web/Jordnaer/Program.cs | 1 - 3 files changed, 39 deletions(-) delete mode 100644 src/shared/Jordnaer.Shared.Infrastructure/AzureAppConfigurationExtensions.cs diff --git a/src/container_apps/Jordnaer.Chat/Program.cs b/src/container_apps/Jordnaer.Chat/Program.cs index 6118692a..c865eae6 100644 --- a/src/container_apps/Jordnaer.Chat/Program.cs +++ b/src/container_apps/Jordnaer.Chat/Program.cs @@ -11,8 +11,6 @@ { var builder = WebApplication.CreateBuilder(args); - builder.AddAzureAppConfiguration(); - builder.AddSerilog(); builder.AddDatabase(); diff --git a/src/shared/Jordnaer.Shared.Infrastructure/AzureAppConfigurationExtensions.cs b/src/shared/Jordnaer.Shared.Infrastructure/AzureAppConfigurationExtensions.cs deleted file mode 100644 index 03e7f8e6..00000000 --- a/src/shared/Jordnaer.Shared.Infrastructure/AzureAppConfigurationExtensions.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Hosting; -using Microsoft.FeatureManagement; - -namespace Jordnaer.Shared.Infrastructure; - -public static class AzureAppConfigurationExtensions -{ - public static WebApplicationBuilder AddAzureAppConfiguration(this WebApplicationBuilder builder) - { - builder.Services.AddFeatureManagement(); - - if (builder.Environment.IsDevelopment()) - { - return builder; - } - - var connectionString = builder.Configuration.GetConnectionString("AppConfig") - ?? throw new InvalidOperationException( - "Failed to find connection string to Azure App Configuration. " + - "Keys checked: 'ConnectionStrings:AppConfig'"); - - builder.Configuration.AddAzureAppConfiguration(options => - options.Connect(connectionString) - // Load all keys that have no label - .Select("*") - .ConfigureRefresh(refreshOptions => - // Only reload configs if the 'Sentinel' key is modified - refreshOptions.Register("Sentinel", refreshAll: true)) - .UseFeatureFlags()); - builder.Services.AddAzureAppConfiguration(); - - return builder; - } -} \ No newline at end of file diff --git a/src/web/Jordnaer/Program.cs b/src/web/Jordnaer/Program.cs index dcd633a1..ef078c83 100644 --- a/src/web/Jordnaer/Program.cs +++ b/src/web/Jordnaer/Program.cs @@ -117,7 +117,6 @@ app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); - app.UseAzureAppConfiguration(); } app.UseHttpsRedirection(); From 97e6f7e4a10a28b8b70d6ff60a3d27f308bb6323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 22:08:28 +0200 Subject: [PATCH 09/25] fix tests, not related Also change user search to make more testable later on --- ...ensions.cs => QueryableGroupExtensions.cs} | 2 +- .../QueryableUserProfileExtensions.cs | 93 ++++++++++++++++++ .../Features/UserSearch/UserSearchService.cs | 97 ++----------------- .../Chat/ChatNotificationServiceTests.cs | 39 ++++---- .../GroupSearchServiceExtensionsTests.cs | 2 +- .../Infrastructure/SqlServerContainer.cs | 1 + .../UserSearch/UserSearchServiceTests.cs | 18 ++-- 7 files changed, 130 insertions(+), 122 deletions(-) rename src/web/Jordnaer/Features/GroupSearch/{GroupSearchServiceExtensions.cs => QueryableGroupExtensions.cs} (88%) create mode 100644 src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs diff --git a/src/web/Jordnaer/Features/GroupSearch/GroupSearchServiceExtensions.cs b/src/web/Jordnaer/Features/GroupSearch/QueryableGroupExtensions.cs similarity index 88% rename from src/web/Jordnaer/Features/GroupSearch/GroupSearchServiceExtensions.cs rename to src/web/Jordnaer/Features/GroupSearch/QueryableGroupExtensions.cs index e0c3fc99..75b3994c 100644 --- a/src/web/Jordnaer/Features/GroupSearch/GroupSearchServiceExtensions.cs +++ b/src/web/Jordnaer/Features/GroupSearch/QueryableGroupExtensions.cs @@ -2,7 +2,7 @@ namespace Jordnaer.Features.GroupSearch; -internal static class GroupSearchServiceExtensions +internal static class QueryableGroupExtensions { internal static IQueryable ApplyNameFilter(this IQueryable groups, string? name) { diff --git a/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs b/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs new file mode 100644 index 00000000..90ab74c9 --- /dev/null +++ b/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs @@ -0,0 +1,93 @@ +using Jordnaer.Features.Search; +using Jordnaer.Shared; +using Microsoft.EntityFrameworkCore; + +namespace Jordnaer.Features.GroupSearch; + +internal static class QueryableUserProfileExtensions +{ + internal static async Task<(IQueryable UserProfiles, bool AppliedOrdering)> ApplyLocationFilterAsync( + this IQueryable users, + UserSearchFilter filter, + IZipCodeService zipCodeService, + CancellationToken cancellationToken = default) + { + if (string.IsNullOrEmpty(filter.Location) || filter.WithinRadiusKilometers is null) + { + return (users, false); + } + + var (zipCodesWithinCircle, searchedZipCode) = await zipCodeService.GetZipCodesNearLocationAsync( + filter.Location, + filter.WithinRadiusKilometers.Value, + cancellationToken); + + if (zipCodesWithinCircle.Count is 0 || searchedZipCode is null) + { + return (users, false); + } + + users = users.Where(user => user.ZipCode != null && + zipCodesWithinCircle.Contains(user.ZipCode.Value)) + .OrderBy(user => Math.Abs(user.ZipCode!.Value - searchedZipCode.Value)); + + return (users, true); + } + + internal static IQueryable ApplyCategoryFilter(this IQueryable users, + UserSearchFilter filter) + { + if (filter.Categories is not null && filter.Categories.Length > 0) + { + users = users.Where(user => + user.Categories.Any(category => filter.Categories.Contains(category.Name))); + } + + return users; + } + + internal static IQueryable ApplyNameFilter(this IQueryable users, string? filter) + { + if (!string.IsNullOrWhiteSpace(filter)) + { + users = users.Where(user => !string.IsNullOrEmpty(user.SearchableName) && + EF.Functions.Like(user.SearchableName, $"%{filter}%")); + } + + return users; + } + + internal static IQueryable ApplyChildFilters(this IQueryable users,UserSearchFilter filter) + { + if (filter.ChildGender is not null) + { + users = users.Where(user => + user.ChildProfiles.Any(child => child.Gender == filter.ChildGender)); + } + + if (filter is { MinimumChildAge: not null, MaximumChildAge: not null } && + filter.MinimumChildAge == filter.MaximumChildAge) + { + users = users.Where(user => + user.ChildProfiles.Any(child => child.Age != null && + child.Age == filter.MinimumChildAge)); + return users; + } + + if (filter.MinimumChildAge is not null) + { + users = users.Where(user => + user.ChildProfiles.Any(child => child.Age != null && + child.Age >= filter.MinimumChildAge)); + } + + if (filter.MaximumChildAge is not null) + { + users = users.Where(user => + user.ChildProfiles.Any(child => child.Age != null && + child.Age <= filter.MaximumChildAge)); + } + + return users; + } +} diff --git a/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs b/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs index 6f71634a..bb8b6063 100644 --- a/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs +++ b/src/web/Jordnaer/Features/UserSearch/UserSearchService.cs @@ -1,4 +1,5 @@ using Jordnaer.Database; +using Jordnaer.Features.GroupSearch; using Jordnaer.Features.Metrics; using Jordnaer.Features.Search; using Jordnaer.Shared; @@ -17,16 +18,15 @@ public class UserSearchService( IDbContextFactory contextFactory) : IUserSearchService { - public async Task> GetUsersByNameAsync(string currentUserId, string searchString, CancellationToken cancellationToken = default) { await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); - var users = ApplyNameFilter(searchString, context.UserProfiles); + var users = context.UserProfiles.ApplyNameFilter(searchString); var firstTenUsers = await users .Where(user => user.Id != currentUserId) .OrderBy(user => searchString.StartsWith(searchString)) - .Take(11) + .Take(11) // We take 11 to let the frontend know we might have more than it searched for .Select(user => new UserSlim { ProfilePictureUrl = user.ProfilePictureUrl, @@ -50,10 +50,10 @@ public async Task GetUsersAsync(UserSearchFilter filter, Cance .Where(user => !string.IsNullOrEmpty(user.UserName)) .AsQueryable(); - users = ApplyChildFilters(filter, users); - users = ApplyNameFilter(filter.Name, users); - users = ApplyCategoryFilter(filter, users); - (users, var isOrdered) = await ApplyLocationFilterAsync(filter, users, cancellationToken); + users = users.ApplyChildFilters(filter); + users = users.ApplyNameFilter(filter.Name); + users = users.ApplyCategoryFilter(filter); + (users, var isOrdered) = await users.ApplyLocationFilterAsync(filter, zipCodeService, cancellationToken); if (!isOrdered) { @@ -94,89 +94,6 @@ public async Task GetUsersAsync(UserSearchFilter filter, Cance return new UserSearchResult { TotalCount = totalCount, Users = paginatedUsers }; } - private async Task<(IQueryable UserProfiles, bool AppliedOrdering)> ApplyLocationFilterAsync( - UserSearchFilter filter, - IQueryable users, - CancellationToken cancellationToken = default) - { - if (string.IsNullOrEmpty(filter.Location) || filter.WithinRadiusKilometers is null) - { - return (users, false); - } - - var (zipCodesWithinCircle, searchedZipCode) = await zipCodeService.GetZipCodesNearLocationAsync( - filter.Location, - filter.WithinRadiusKilometers.Value, - cancellationToken); - - if (zipCodesWithinCircle.Count is 0 || searchedZipCode is null) - { - return (users, false); - } - - users = users.Where(user => user.ZipCode != null && - zipCodesWithinCircle.Contains(user.ZipCode.Value)) - .OrderBy(user => Math.Abs(user.ZipCode!.Value - searchedZipCode.Value)); - - return (users, true); - } - - private static IQueryable ApplyCategoryFilter(UserSearchFilter filter, IQueryable users) - { - if (filter.Categories is not null && filter.Categories.Length > 0) - { - users = users.Where(user => - user.Categories.Any(category => filter.Categories.Contains(category.Name))); - } - - return users; - } - - private static IQueryable ApplyNameFilter(string? filter, IQueryable users) - { - if (!string.IsNullOrWhiteSpace(filter)) - { - users = users.Where(user => !string.IsNullOrEmpty(user.SearchableName) && - EF.Functions.Like(user.SearchableName, $"%{filter}%")); - } - - return users; - } - - private static IQueryable ApplyChildFilters(UserSearchFilter filter, IQueryable users) - { - if (filter.ChildGender is not null) - { - users = users.Where(user => - user.ChildProfiles.Any(child => child.Gender == filter.ChildGender)); - } - - if (filter is { MinimumChildAge: not null, MaximumChildAge: not null } && - filter.MinimumChildAge == filter.MaximumChildAge) - { - users = users.Where(user => - user.ChildProfiles.Any(child => child.Age != null && - child.Age == filter.MinimumChildAge)); - return users; - } - - if (filter.MinimumChildAge is not null) - { - users = users.Where(user => - user.ChildProfiles.Any(child => child.Age != null && - child.Age >= filter.MinimumChildAge)); - } - - if (filter.MaximumChildAge is not null) - { - users = users.Where(user => - user.ChildProfiles.Any(child => child.Age != null && - child.Age <= filter.MaximumChildAge)); - } - - return users; - } - private static ReadOnlySpan> MakeTagList(UserSearchFilter filter) { return new KeyValuePair[] diff --git a/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs b/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs index 9336175d..adf9e3dc 100644 --- a/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs +++ b/tests/web/Jordnaer.Tests/Chat/ChatNotificationServiceTests.cs @@ -19,7 +19,6 @@ namespace Jordnaer.Tests.Chat; [Trait("Category", "UnitTest")] public class ChatNotificationServiceTests { - private readonly Mock> _contextFactoryMock; private readonly Mock _contextMock; private readonly Mock _publishEndpointMock; private readonly IServer _serverMock; @@ -27,10 +26,11 @@ public class ChatNotificationServiceTests public ChatNotificationServiceTests() { - _contextFactoryMock = new Mock>( + _contextMock = new Mock( new DbContextOptionsBuilder().Options); - _contextMock = new Mock(); - _contextFactoryMock + + var contextFactoryMock = new Mock>(); + contextFactoryMock .Setup(x => x.CreateDbContextAsync(It.IsAny())) .ReturnsAsync(_contextMock.Object); @@ -38,7 +38,7 @@ public ChatNotificationServiceTests() _serverMock = Substitute.For(); _service = new ChatNotificationService( - _contextFactoryMock.Object, + contextFactoryMock.Object, new NullLogger(), _publishEndpointMock.Object, _serverMock @@ -105,8 +105,7 @@ public async Task NotifyRecipients_ShouldFetchRecipientsAndPublishEmails() // Assert _publishEndpointMock - .Verify(p => p.Publish(It.IsAny(), -It.IsAny()), + .Verify(p => p.Publish(It.IsAny(), It.IsAny()), Times.Exactly(users.Count - 1)); // chat participants excluding the initiator } @@ -121,19 +120,19 @@ public void CreateEmails_ShouldGenerateCorrectEmailContent() Recipients = [ new UserSlim - { - Id = "initiator-id", - DisplayName = "Initiator", - ProfilePictureUrl = null, - UserName = null - }, - new UserSlim - { - Id = "recipient-id", - DisplayName = "Recipient", - ProfilePictureUrl = null, - UserName = null - } + { + Id = "initiator-id", + DisplayName = "Initiator", + ProfilePictureUrl = null, + UserName = null + }, + new UserSlim + { + Id = "recipient-id", + DisplayName = "Recipient", + ProfilePictureUrl = null, + UserName = null + } ] }; diff --git a/tests/web/Jordnaer.Tests/Groups/GroupSearchServiceExtensionsTests.cs b/tests/web/Jordnaer.Tests/Groups/GroupSearchServiceExtensionsTests.cs index 56a3f135..974e3d4f 100644 --- a/tests/web/Jordnaer.Tests/Groups/GroupSearchServiceExtensionsTests.cs +++ b/tests/web/Jordnaer.Tests/Groups/GroupSearchServiceExtensionsTests.cs @@ -6,7 +6,7 @@ namespace Jordnaer.Tests.Groups; [Trait("Category", "UnitTest")] -public class GroupSearchServiceExtensionsTests +public class QueryableGroupExtensionsTests { [Fact] public void ApplyNameFilter_WithNullName_ReturnsOriginalGroups() diff --git a/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs b/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs index 363004bb..3c248bb1 100644 --- a/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs +++ b/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs @@ -25,6 +25,7 @@ public virtual async Task InitializeAsync() _connectionString = Container.GetConnectionString(); await using var context = CreateContext(); + await context.Database.EnsureCreatedAsync(); } diff --git a/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs b/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs index 7e46af33..091bfecc 100644 --- a/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs +++ b/tests/web/Jordnaer.Tests/UserSearch/UserSearchServiceTests.cs @@ -15,9 +15,9 @@ namespace Jordnaer.Tests.UserSearch; [Trait("Category", "IntegrationTest")] [Collection(nameof(SqlServerContainerCollection))] -public class UserSearchServiceTests : IAsyncLifetime +public class UserSearchServiceTests { - private readonly Mock> _contextFactory = new(); + private readonly IDbContextFactory _contextFactory = Substitute.For>(); private readonly IZipCodeService _zipCodeServiceMock = Substitute.For(); private readonly UserSearchService _sut; private readonly Faker _faker = new(); @@ -26,10 +26,9 @@ public class UserSearchServiceTests : IAsyncLifetime public UserSearchServiceTests(SqlServerContainer sqlServerContainer) { _context = sqlServerContainer.CreateContext(); - _contextFactory.Setup(x => x.CreateDbContextAsync(It.IsAny())) - .ReturnsAsync(_context); + _contextFactory.CreateDbContextAsync().ReturnsForAnyArgs(_context); - _sut = new UserSearchService(_zipCodeServiceMock, _contextFactory.Object); + _sut = new UserSearchService(_zipCodeServiceMock, _contextFactory); } [Fact] @@ -39,10 +38,10 @@ public async Task Return_UserSearchResult_Given_Valid_Filter() var filter = new UserSearchFilter(); // Act + await _context.UserProfiles.ExecuteDeleteAsync(); var result = await _sut.GetUsersAsync(filter); // Assert - result.Should().BeOfType(); result.TotalCount.Should().Be(0); result.Users.Should().BeEquivalentTo(new List()); } @@ -95,6 +94,7 @@ public async Task Return_UserSearchResult_With_LastName_Filter() var users = CreateTestUsers(5); // Ensure at least one user has the specified name in their SearchableName users[0].LastName = lastName; + _context.UserProfiles.RemoveRange(_context.UserProfiles); _context.UserProfiles.AddRange(users); await _context.SaveChangesAsync(); @@ -163,6 +163,7 @@ public async Task Return_UserSearchResult_With_ChildGender_Filter() Gender = filter.ChildGender.Value, FirstName = _faker.Name.FirstName() }); + _context.UserProfiles.RemoveRange(_context.UserProfiles); _context.UserProfiles.AddRange(users); await _context.SaveChangesAsync(); @@ -186,6 +187,7 @@ public async Task Return_UserSearchResult_With_MinimumChildAge_Filter() DateOfBirth = DateTime.UtcNow.AddYears(-filter.MinimumChildAge.Value), FirstName = _faker.Name.FirstName() }); + _context.UserProfiles.RemoveRange(_context.UserProfiles); _context.UserProfiles.AddRange(users); await _context.SaveChangesAsync(); @@ -265,8 +267,4 @@ private static List CreateTestUsers(int count) return users; } - - public Task InitializeAsync() => Task.CompletedTask; - - public async Task DisposeAsync() => await _context.UserProfiles.ExecuteDeleteAsync(); } From 0aaa1513eb2f40dfff6de92d0e21dac8134c8f6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 22:14:59 +0200 Subject: [PATCH 10/25] re-register feature mangement --- src/web/Jordnaer/Program.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/web/Jordnaer/Program.cs b/src/web/Jordnaer/Program.cs index ef078c83..fef97020 100644 --- a/src/web/Jordnaer/Program.cs +++ b/src/web/Jordnaer/Program.cs @@ -22,6 +22,7 @@ using Jordnaer.Database; using Jordnaer.Features.Membership; using Jordnaer.Features.Search; +using Microsoft.FeatureManagement; using Microsoft.Net.Http.Headers; using Sidio.Sitemap.AspNetCore; using Sidio.Sitemap.Blazor; @@ -36,6 +37,8 @@ builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); +builder.Services.AddFeatureManagement(); + builder.AddAuthentication(); builder.Services.AddAuthorization(); From 8dc2094a5f80d063fe1058c28515f883fbe8ebf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 22:19:51 +0200 Subject: [PATCH 11/25] Update QueryableUserProfileExtensions.cs --- .../Features/UserSearch/QueryableUserProfileExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs b/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs index 90ab74c9..f0806626 100644 --- a/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs +++ b/src/web/Jordnaer/Features/UserSearch/QueryableUserProfileExtensions.cs @@ -2,7 +2,7 @@ using Jordnaer.Shared; using Microsoft.EntityFrameworkCore; -namespace Jordnaer.Features.GroupSearch; +namespace Jordnaer.Features.UserSearch; internal static class QueryableUserProfileExtensions { From ddc6dae648ac3c33162f0be178d38309f14801f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 22:19:53 +0200 Subject: [PATCH 12/25] Update serviceDependencies.json --- src/web/Jordnaer/Properties/serviceDependencies.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/web/Jordnaer/Properties/serviceDependencies.json b/src/web/Jordnaer/Properties/serviceDependencies.json index 16cd064c..a6a4817f 100644 --- a/src/web/Jordnaer/Properties/serviceDependencies.json +++ b/src/web/Jordnaer/Properties/serviceDependencies.json @@ -1,9 +1,5 @@ { "dependencies": { - "appInsights1": { - "type": "appInsights", - "dynamicId": null - }, "secrets1": { "type": "secrets", "dynamicId": null From b5bd79f8d7d63fb6bbfe72ac6eff90b591f6de23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 22:32:34 +0200 Subject: [PATCH 13/25] Update Jordnaer.Tests.csproj --- tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj index 11dd60eb..0359d348 100644 --- a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj +++ b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj @@ -25,8 +25,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + runtime; build; native; contentfiles; analyzers; buildtransitive From e4f4d5675340f49b16c97a4371ad1a008c410d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sat, 5 Oct 2024 22:36:10 +0200 Subject: [PATCH 14/25] Update Jordnaer.Chat.Tests.csproj --- .../Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj index 087e767d..de188411 100644 --- a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj +++ b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj @@ -27,7 +27,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive From 45f99e3cec80cff0ed9ac72c389e8443a82572b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 6 Oct 2024 09:06:30 +0200 Subject: [PATCH 15/25] Update SqlServerContainer.cs --- tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs b/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs index 3c248bb1..09ce586d 100644 --- a/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs +++ b/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs @@ -7,6 +7,7 @@ namespace Jordnaer.Tests.Infrastructure; public class SqlServerContainer : IAsyncLifetime where TDbContext : DbContext { public readonly MsSqlContainer Container = new MsSqlBuilder() + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") .WithName($"SqlServerTestcontainer-{Guid.NewGuid()}") .Build(); From c35964f99a236696e4fd52dd36e3e3d9273c205b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 6 Oct 2024 19:47:17 +0200 Subject: [PATCH 16/25] update testcontainers --- .../Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj | 4 ++-- tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj index de188411..a551d3c8 100644 --- a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj +++ b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -27,7 +27,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj index 0359d348..11dd60eb 100644 --- a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj +++ b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj @@ -25,8 +25,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + runtime; build; native; contentfiles; analyzers; buildtransitive From 73768e6e3e675b2f761d86d329b83b2d49904a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 6 Oct 2024 19:53:26 +0200 Subject: [PATCH 17/25] one more fix sqlserver container --- .../Infrastructure/JordnaerWebApplicationFactory.cs | 5 +++-- .../web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/web/Jordnaer.Tests/Infrastructure/JordnaerWebApplicationFactory.cs b/tests/web/Jordnaer.Tests/Infrastructure/JordnaerWebApplicationFactory.cs index c738e13b..ab13fe71 100644 --- a/tests/web/Jordnaer.Tests/Infrastructure/JordnaerWebApplicationFactory.cs +++ b/tests/web/Jordnaer.Tests/Infrastructure/JordnaerWebApplicationFactory.cs @@ -14,8 +14,9 @@ namespace Jordnaer.Tests.Infrastructure; public class JordnaerWebApplicationFactory : WebApplicationFactory, IAsyncLifetime { private readonly MsSqlContainer _msSqlContainer = new MsSqlBuilder() - .WithName($"SqlServerTestcontainer-{Guid.NewGuid()}") - .Build(); + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") // We set a specific image to circumvent this bug: https://github.com/testcontainers/testcontainers-dotnet/issues/1271 + .WithName($"SqlServerTestcontainer-{Guid.NewGuid()}") + .Build(); private readonly AzuriteContainer _azureBlobStorageContainer = new AzuriteBuilder() .WithName($"AzuriteTestcontainer-{Guid.NewGuid()}") diff --git a/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs b/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs index 09ce586d..d5f002a8 100644 --- a/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs +++ b/tests/web/Jordnaer.Tests/Infrastructure/SqlServerContainer.cs @@ -7,7 +7,7 @@ namespace Jordnaer.Tests.Infrastructure; public class SqlServerContainer : IAsyncLifetime where TDbContext : DbContext { public readonly MsSqlContainer Container = new MsSqlBuilder() - .WithImage("mcr.microsoft.com/mssql/server:2022-latest") + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") // We set a specific image to circumvent this bug: https://github.com/testcontainers/testcontainers-dotnet/issues/1271 .WithName($"SqlServerTestcontainer-{Guid.NewGuid()}") .Build(); From ce1c948183416195306899481a74551532399de7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 08:55:57 +0000 Subject: [PATCH 18/25] Bump CodeBeam.MudBlazor.Extensions from 7.0.1 to 7.0.2 Bumps [CodeBeam.MudBlazor.Extensions](https://github.com/CodeBeamOrg/CodeBeam.MudBlazor.Extensions) from 7.0.1 to 7.0.2. - [Release notes](https://github.com/CodeBeamOrg/CodeBeam.MudBlazor.Extensions/releases) - [Changelog](https://github.com/CodeBeamOrg/CodeBeam.MudBlazor.Extensions/blob/dev/BreakingChanges.md) - [Commits](https://github.com/CodeBeamOrg/CodeBeam.MudBlazor.Extensions/compare/7.0.1...7.0.2) --- updated-dependencies: - dependency-name: CodeBeam.MudBlazor.Extensions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- src/web/Jordnaer/Jordnaer.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Jordnaer.csproj b/src/web/Jordnaer/Jordnaer.csproj index 0243eeec..4213985f 100644 --- a/src/web/Jordnaer/Jordnaer.csproj +++ b/src/web/Jordnaer/Jordnaer.csproj @@ -42,7 +42,7 @@ - + From ca41ad9657121d71ddf06cb03be945afed8afba6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 08:42:16 +0000 Subject: [PATCH 19/25] Bump MassTransit.Abstractions from 8.2.5 to 8.3.2 Bumps [MassTransit.Abstractions](https://github.com/MassTransit/MassTransit) from 8.2.5 to 8.3.2. - [Commits](https://github.com/MassTransit/MassTransit/compare/v8.2.5...v8.3.2) --- updated-dependencies: - dependency-name: MassTransit.Abstractions dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj b/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj index 504ba73f..9a75d129 100644 --- a/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj +++ b/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj @@ -14,7 +14,7 @@ - + From 4b39aed296870212e9b0d405da67ca6fa66ddfe0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:53:45 +0000 Subject: [PATCH 20/25] Bump Microsoft.Extensions.Caching.Memory in /src/web/Jordnaer Bumps [Microsoft.Extensions.Caching.Memory](https://github.com/dotnet/runtime) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v8.0.0...v8.0.1) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Caching.Memory dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- src/web/Jordnaer/Jordnaer.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Jordnaer.csproj b/src/web/Jordnaer/Jordnaer.csproj index 4213985f..731e89a8 100644 --- a/src/web/Jordnaer/Jordnaer.csproj +++ b/src/web/Jordnaer/Jordnaer.csproj @@ -40,7 +40,7 @@ - + From 0ac0666b046cce311090d1dea0846acda0dbf91f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 08:32:01 +0000 Subject: [PATCH 21/25] Bump MudBlazor from 7.8.0 to 7.15.0 Bumps [MudBlazor](https://github.com/MudBlazor/MudBlazor) from 7.8.0 to 7.15.0. - [Release notes](https://github.com/MudBlazor/MudBlazor/releases) - [Changelog](https://github.com/MudBlazor/MudBlazor/blob/dev/CHANGELOG.md) - [Commits](https://github.com/MudBlazor/MudBlazor/compare/v7.8.0...v7.15.0) --- updated-dependencies: - dependency-name: MudBlazor dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/web/Jordnaer/Jordnaer.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Jordnaer.csproj b/src/web/Jordnaer/Jordnaer.csproj index 731e89a8..72f3b71b 100644 --- a/src/web/Jordnaer/Jordnaer.csproj +++ b/src/web/Jordnaer/Jordnaer.csproj @@ -41,7 +41,7 @@ - + From 33728e69967c06ce68d0c2165cb1b4080595ebf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 8 Dec 2024 19:46:39 +0100 Subject: [PATCH 22/25] brighter yellow colors --- src/web/Jordnaer/Features/Theme/JordnaerPalette.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs b/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs index 90167ac8..c721cd0e 100644 --- a/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs +++ b/src/web/Jordnaer/Features/Theme/JordnaerPalette.cs @@ -33,7 +33,7 @@ public static class JordnaerPalette /// /// Yellow-orange. Used as background for texts and headers /// - public static readonly MudColor YellowBackground = "#dbab45"; + public static readonly MudColor YellowBackground = "#fcca3f"; /// /// Green. Used as background for texts and headers From c7cc8dd1ae0fe25dff5e2cbb758dcec23b0c7eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 8 Dec 2024 19:46:46 +0100 Subject: [PATCH 23/25] more colorful landing page --- src/web/Jordnaer/Pages/Home/LandingPageLinkComponent.razor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/web/Jordnaer/Pages/Home/LandingPageLinkComponent.razor b/src/web/Jordnaer/Pages/Home/LandingPageLinkComponent.razor index a266b92f..5d9a2e2c 100644 --- a/src/web/Jordnaer/Pages/Home/LandingPageLinkComponent.razor +++ b/src/web/Jordnaer/Pages/Home/LandingPageLinkComponent.razor @@ -7,7 +7,7 @@
- Vær' med! + Vær' med!
@code { @@ -15,6 +15,6 @@ public bool IsMobile { get; set; } private string _buttonClass => IsMobile ? "mb-5 mx-2" : "mb-5 mx-10"; - private Variant _variant = Variant.Filled; - private Color _color = Color.Default; + private Variant _variant = Variant.Outlined; + private Color _color = Color.Tertiary; } \ No newline at end of file From dd80c73e7fc6920b5ee5a637798f959607e6dbdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 8 Dec 2024 19:50:01 +0100 Subject: [PATCH 24/25] Update RegisterConfirmation.razor --- .../Components/Account/Pages/RegisterConfirmation.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Jordnaer/Components/Account/Pages/RegisterConfirmation.razor b/src/web/Jordnaer/Components/Account/Pages/RegisterConfirmation.razor index 759636ad..27ad5f3a 100644 --- a/src/web/Jordnaer/Components/Account/Pages/RegisterConfirmation.razor +++ b/src/web/Jordnaer/Components/Account/Pages/RegisterConfirmation.razor @@ -15,7 +15,7 @@

Registreringsbekræftelse

Check venligst din email for at bekræfte din konto. - Husk at tjekke uønsket mail mappen. + Husk at tjekke spam/uønsket mail. @code { From 3bd483a021bcfb0e9ca892cb64febeb3c1ea186a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Pilgaard=20Gr=C3=B8ndahl?= Date: Sun, 8 Dec 2024 20:16:43 +0100 Subject: [PATCH 25/25] =?UTF-8?q?dotnet=209=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/container_apps_chat_cd.yml | 2 +- .github/workflows/container_apps_chat_ci.yml | 2 +- .github/workflows/website_backend_ci.yml | 2 +- .github/workflows/website_cd.yml | 2 +- .github/workflows/website_frontend_ci.yml | 4 +- .../Jordnaer.Benchmarks.csproj | 4 +- .../Jordnaer.Chat/Jordnaer.Chat.csproj | 10 ++--- .../Jordnaer.Shared.Infrastructure.csproj | 10 ++--- .../Jordnaer.Shared/Jordnaer.Shared.csproj | 18 ++++----- src/web/Jordnaer/Jordnaer.csproj | 40 +++++++++---------- .../Jordnaer.Chat.Tests.csproj | 16 ++++---- .../Jordnaer.E2E.Tests.csproj | 18 ++++----- .../Jordnaer.Load.Tests.csproj | 8 ++-- .../web/Jordnaer.Tests/Jordnaer.Tests.csproj | 18 ++++----- 14 files changed, 77 insertions(+), 77 deletions(-) diff --git a/.github/workflows/container_apps_chat_cd.yml b/.github/workflows/container_apps_chat_cd.yml index 7d8608c9..9585146d 100644 --- a/.github/workflows/container_apps_chat_cd.yml +++ b/.github/workflows/container_apps_chat_cd.yml @@ -18,7 +18,7 @@ jobs: - name: Set up dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.x" + dotnet-version: "9.x" - name: Test run: dotnet test "${{ env.TEST_DIRECTORY }}" --filter Category!=ManualTest diff --git a/.github/workflows/container_apps_chat_ci.yml b/.github/workflows/container_apps_chat_ci.yml index 44b95d0c..5029f5fb 100644 --- a/.github/workflows/container_apps_chat_ci.yml +++ b/.github/workflows/container_apps_chat_ci.yml @@ -21,7 +21,7 @@ jobs: - name: Set up dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.x" + dotnet-version: "9.x" - name: Test # Dependabot cannot access secrets, so we disable this step for Dependabot diff --git a/.github/workflows/website_backend_ci.yml b/.github/workflows/website_backend_ci.yml index e6a1a0b5..2859fed5 100644 --- a/.github/workflows/website_backend_ci.yml +++ b/.github/workflows/website_backend_ci.yml @@ -21,7 +21,7 @@ jobs: - name: Set up dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.x" + dotnet-version: "9.x" - name: Test # Dependabot cannot access secrets, so we disable this step for Dependabot diff --git a/.github/workflows/website_cd.yml b/.github/workflows/website_cd.yml index a528e30e..1deb2436 100644 --- a/.github/workflows/website_cd.yml +++ b/.github/workflows/website_cd.yml @@ -21,7 +21,7 @@ jobs: - name: Set up dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.x" + dotnet-version: "9.x" - name: Restore Nugets run: dotnet restore "${{ env.WORKING_DIRECTORY }}" diff --git a/.github/workflows/website_frontend_ci.yml b/.github/workflows/website_frontend_ci.yml index 37a0fabe..f60cd983 100644 --- a/.github/workflows/website_frontend_ci.yml +++ b/.github/workflows/website_frontend_ci.yml @@ -17,7 +17,7 @@ jobs: if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest container: - image: mcr.microsoft.com/playwright/dotnet:v1.45.1-jammy + image: mcr.microsoft.com/playwright/dotnet:v1.49.0-jammy options: --user 1001 steps: - name: Checkout @@ -26,7 +26,7 @@ jobs: - name: Set up dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: "8.x" + dotnet-version: "9.x" - name: Test run: > diff --git a/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj b/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj index f9c84fdc..a50ede04 100644 --- a/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj +++ b/benchmarks/Jordnaer.Benchmarks/Jordnaer.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable @@ -11,7 +11,7 @@ - + diff --git a/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj b/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj index ccee49b1..c94e4131 100644 --- a/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj +++ b/src/container_apps/Jordnaer.Chat/Jordnaer.Chat.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 6af4abd1-e8ca-4aa2-a593-15395d30dc2a Linux ..\..\.. @@ -11,12 +11,12 @@ - + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj b/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj index fcdf48d3..3edfaa45 100644 --- a/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj +++ b/src/shared/Jordnaer.Shared.Infrastructure/Jordnaer.Shared.Infrastructure.csproj @@ -1,15 +1,15 @@  - net8.0 + net9.0 - + - - + + - + diff --git a/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj b/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj index 9a75d129..43c92318 100644 --- a/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj +++ b/src/shared/Jordnaer.Shared/Jordnaer.Shared.csproj @@ -1,20 +1,20 @@  - net8.0 + net9.0 Jordnaer.Shared - - - - - - + + + + + + - - + + diff --git a/src/web/Jordnaer/Jordnaer.csproj b/src/web/Jordnaer/Jordnaer.csproj index 72f3b71b..c1d21b81 100644 --- a/src/web/Jordnaer/Jordnaer.csproj +++ b/src/web/Jordnaer/Jordnaer.csproj @@ -1,28 +1,28 @@  - net8.0 + net9.0 d330f5dc-6b2c-408b-bc04-d3b0ff28178b preview - + - + - + - - - - - - - - - - + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -37,13 +37,13 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + - - + + diff --git a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj index a551d3c8..aaa2e5d5 100644 --- a/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj +++ b/tests/container_apps/Jordnaer.Chat.Tests/Jordnaer.Chat.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 false true @@ -13,21 +13,21 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj b/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj index 4b6c761f..747339eb 100644 --- a/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj +++ b/tests/web/Jordnaer.E2E.Tests/Jordnaer.E2E.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 false true @@ -15,20 +15,20 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + + + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj b/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj index 028e8baf..40c2231b 100644 --- a/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj +++ b/tests/web/Jordnaer.Load.Tests/Jordnaer.Load.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 Exe false @@ -12,9 +12,9 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj index 11dd60eb..30578637 100644 --- a/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj +++ b/tests/web/Jordnaer.Tests/Jordnaer.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 false true @@ -9,24 +9,24 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + runtime; build; native; contentfiles; analyzers; buildtransitive