From da1c116a2ff3895f284194c01988bd078eed6d66 Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 10:52:24 +0200 Subject: [PATCH 01/18] Created statsservice to handle updating stats when collection or plant is added, updated or deleted Upon logging out we no longer remove the entire connection, just the email, the connection is removed on onclose --- Shared/Models/Stats.cs | 8 ++++ api/Core/Services/StatsService.cs | 21 ++++++++ api/Events/Auth/Client/ClientWantsToLogOut.cs | 2 +- .../Client/ClientWantsToCreateCollection.cs | 7 ++- .../Client/ClientWantsToDeleteCollection.cs | 7 ++- .../Client/ClientWantsToCreatePlant.cs | 6 ++- .../Client/ClientWantsToDeletePlant.cs | 7 ++- .../Client/ClientWantsToGetCriticalPlants.cs | 7 ++- .../Client/ClientWantsToUpdatePlant.cs | 7 ++- api/Events/Statistics/ClientWantsStats.cs | 28 +++++++++++ api/Events/Stats/ClientWantsStats.cs | 48 ------------------- api/WebSocketConnectionService.cs | 6 +++ 12 files changed, 99 insertions(+), 55 deletions(-) create mode 100644 Shared/Models/Stats.cs create mode 100644 api/Core/Services/StatsService.cs create mode 100644 api/Events/Statistics/ClientWantsStats.cs delete mode 100644 api/Events/Stats/ClientWantsStats.cs diff --git a/Shared/Models/Stats.cs b/Shared/Models/Stats.cs new file mode 100644 index 0000000..163c91b --- /dev/null +++ b/Shared/Models/Stats.cs @@ -0,0 +1,8 @@ +namespace Shared.Models; + +public class Stats +{ + public int TotalPlants { get; set; } + public int HappyPlants { get; set; } + public int Collections { get; set; } +} \ No newline at end of file diff --git a/api/Core/Services/StatsService.cs b/api/Core/Services/StatsService.cs new file mode 100644 index 0000000..16c1c35 --- /dev/null +++ b/api/Core/Services/StatsService.cs @@ -0,0 +1,21 @@ +using Shared.Dtos; +using Shared.Models; + +namespace api.Core.Services; + +public class StatsService(CollectionsService collectionsService, PlantService plantService) +{ + public async Task GetStats(string email) + { + var totalPlants = await plantService.GetTotalPlantsCount(email); + var happyPlants = await plantService.GetHappyPlantsCount(email); + var collections = await collectionsService.GetTotalCollectionsCount(email); + + return new Stats + { + TotalPlants = totalPlants, + HappyPlants = happyPlants, + Collections = collections + }; + } +} diff --git a/api/Events/Auth/Client/ClientWantsToLogOut.cs b/api/Events/Auth/Client/ClientWantsToLogOut.cs index dd514a4..a361ecd 100644 --- a/api/Events/Auth/Client/ClientWantsToLogOut.cs +++ b/api/Events/Auth/Client/ClientWantsToLogOut.cs @@ -12,7 +12,7 @@ public class ClientWantsToLogOut(WebSocketConnectionService connectionService) { public override Task Handle(ClientWantsToLogOutDto dto, IWebSocketConnection socket) { - connectionService.RemoveConnection(socket); + connectionService.RemoveEmailFromConnection(socket); socket.SendDto(new ServerLogsOutUser()); return Task.CompletedTask; } diff --git a/api/Events/Collections/Client/ClientWantsToCreateCollection.cs b/api/Events/Collections/Client/ClientWantsToCreateCollection.cs index 7298b0e..4553efd 100644 --- a/api/Events/Collections/Client/ClientWantsToCreateCollection.cs +++ b/api/Events/Collections/Client/ClientWantsToCreateCollection.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.Collections.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -13,16 +14,20 @@ public class ClientWantsToCreateCollectionDto : BaseDtoWithJwt public required CreateCollectionDto CreateCollectionDto { get; set; } } -public class ClientWantsToCreateCollection(CollectionsService collectionsService, JwtService jwtService) : BaseEventHandler +public class ClientWantsToCreateCollection(CollectionsService collectionsService, JwtService jwtService, StatsService statsService) : BaseEventHandler { public override async Task Handle(ClientWantsToCreateCollectionDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); await collectionsService.CreateCollection(dto.CreateCollectionDto, email); var allCollections = await collectionsService.GetCollectionsForUser(email); + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSendsAllCollections() { Collections = allCollections.ToList() }); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs b/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs index 08bc019..69966f9 100644 --- a/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs +++ b/api/Events/Collections/Client/ClientWantsToDeleteCollection.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.Collections.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -13,16 +14,20 @@ public class ClientWantsToDeleteCollectionDto : BaseDtoWithJwt public Guid CollectionId { get; set; } } -public class ClientWantsToDeleteCollection(CollectionsService collectionsService, JwtService jwtService) : BaseEventHandler +public class ClientWantsToDeleteCollection(CollectionsService collectionsService, JwtService jwtService, StatsService statsService) : BaseEventHandler { public override async Task Handle(ClientWantsToDeleteCollectionDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); await collectionsService.DeleteCollection(dto.CollectionId, email); var allCollections = await collectionsService.GetCollectionsForUser(email); + + var stats = await statsService.GetStats(email); socket.SendDto(new ServerSendsAllCollections() { Collections = allCollections.ToList() }); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs index eaf2632..333d868 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs @@ -1,6 +1,7 @@ using api.Core.Services; using api.EventFilters; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -15,12 +16,13 @@ public class ClientWantsToCreatePlantDto: BaseDtoWithJwt } [ValidateDataAnnotations] -public class ClientWantsToCreatePlant(PlantService plantService, JwtService jwtService): BaseEventHandler +public class ClientWantsToCreatePlant(PlantService plantService, JwtService jwtService, StatsService statsService): BaseEventHandler { public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); var plant = await plantService.CreatePlant(dto.CreatePlantDto, email); + var stats = await statsService.GetStats(email); var serverCreatesNewPlant = new ServerSavesPlant { @@ -28,5 +30,7 @@ public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketCon }; socket.SendDto(serverCreatesNewPlant); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs index bb4068f..76319a3 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToDeletePlant.cs @@ -3,6 +3,7 @@ using api.EventFilters; using api.Events.Global; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -16,13 +17,17 @@ public class ClientWantsToDeletePlantDto: BaseDtoWithJwt } [ValidateDataAnnotations] -public class ClientWantsToDeletePlant(PlantService plantService, JwtService jwtService): BaseEventHandler +public class ClientWantsToDeletePlant(PlantService plantService, JwtService jwtService, StatsService statsService): BaseEventHandler { public override async Task Handle(ClientWantsToDeletePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); + var stats = await statsService.GetStats(email); + await plantService.DeletePlant(dto.PlantId, email); socket.SendDto( new ServerConfirmsDelete()); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } diff --git a/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs b/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs index 01b27f3..5b92e63 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToGetCriticalPlants.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -9,16 +10,20 @@ namespace api.Events.PlantEvents.Client; public class ClientWantsToGetCriticalPlantsDto : BaseDtoWithJwt; -public class ClientWantsToGetCriticalPlants(JwtService jwtService, PlantService plantService) : BaseEventHandler +public class ClientWantsToGetCriticalPlants(JwtService jwtService, PlantService plantService, StatsService statsService) : BaseEventHandler { public override async Task Handle(ClientWantsToGetCriticalPlantsDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); var plants = await plantService.GetCriticalPlants(email); + var stats = await statsService.GetStats(email); + var serverResponse = new ServerSendsCriticalPlants { Plants = plants }; socket.SendDto(serverResponse); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs index 9f2b8ce..1dc8348 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToUpdatePlant.cs @@ -1,5 +1,6 @@ using api.Core.Services; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using api.Extensions; using Fleck; using lib; @@ -13,15 +14,19 @@ public class ClientWantsToUpdatePlantDto: BaseDtoWithJwt public required UpdatePlantDto UpdatePlantDto { get; set; } } -public class ClientWantsToUpdatePlant(PlantService plantService, JwtService jwtService): BaseEventHandler +public class ClientWantsToUpdatePlant(PlantService plantService, JwtService jwtService, StatsService statsService): BaseEventHandler { public override async Task Handle(ClientWantsToUpdatePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); var plant = await plantService.UpdatePlant(dto.UpdatePlantDto, email); + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSavesPlant { Plant = plant }); + + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Events/Statistics/ClientWantsStats.cs b/api/Events/Statistics/ClientWantsStats.cs new file mode 100644 index 0000000..0220931 --- /dev/null +++ b/api/Events/Statistics/ClientWantsStats.cs @@ -0,0 +1,28 @@ +using api.Core.Services; +using api.Extensions; +using Fleck; +using lib; +using Shared.Models; + +namespace api.Events.Statistics; + +public class ClientWantsStatsDto : BaseDtoWithJwt +{ + +} + +public class ClientWantsStats(StatsService statsService, JwtService jwtService) : BaseEventHandler +{ + public override async Task Handle(ClientWantsStatsDto dto, IWebSocketConnection socket) + { + var email = jwtService.GetEmailFromJwt(dto.Jwt!); + + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSendsStats{Stats = stats}); + } +} + +public class ServerSendsStats : BaseDto +{ + public Stats Stats { get; set; } = null!; +} diff --git a/api/Events/Stats/ClientWantsStats.cs b/api/Events/Stats/ClientWantsStats.cs deleted file mode 100644 index b581887..0000000 --- a/api/Events/Stats/ClientWantsStats.cs +++ /dev/null @@ -1,48 +0,0 @@ -using api.Core.Services; -using api.Extensions; -using Fleck; -using lib; -using Shared.Models; - -namespace api.Events.Stats; - -public class ClientWantsStatsDto : BaseDtoWithJwt -{ - -} - -public class ClientWantsStats(PlantService plantService, CollectionsService collectionsService, JwtService jwtService) : BaseEventHandler -{ - public override async Task Handle(ClientWantsStatsDto dto, IWebSocketConnection socket) - { - var email = jwtService.GetEmailFromJwt(dto.Jwt!); - - var totalPlants = await plantService.GetTotalPlantsCount(email); - var happyPlants = await plantService.GetHappyPlantsCount(email); - var collections = await collectionsService.GetTotalCollectionsCount(email); - - var statsDto = new ServerSendsStats - { - Stats = new Stats - { - TotalPlants = totalPlants, - HappyPlants = happyPlants, - Collections = collections - } - }; - - socket.SendDto(statsDto); - } -} - -public class ServerSendsStats : BaseDto -{ - public Stats Stats { get; set; } -} - -public class Stats -{ - public int TotalPlants { get; set; } - public int HappyPlants { get; set; } - public int Collections { get; set; } -} \ No newline at end of file diff --git a/api/WebSocketConnectionService.cs b/api/WebSocketConnectionService.cs index 6b57682..a7c1cde 100644 --- a/api/WebSocketConnectionService.cs +++ b/api/WebSocketConnectionService.cs @@ -19,6 +19,12 @@ public void UpdateConnectionEmail(IWebSocketConnection connection, string email) var clientId = connection.ConnectionInfo.Id; _connectedClients[clientId].Email = email; } + + public void RemoveEmailFromConnection(IWebSocketConnection connection) + { + var clientId = connection.ConnectionInfo.Id; + _connectedClients[clientId].Email = null; + } public void RemoveConnection(IWebSocketConnection connection) { From 7fe14d50e4f839ed3e0fbba23aec6118069ecc18 Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 10:59:17 +0200 Subject: [PATCH 02/18] added service! --- api/Extensions/AddServicesAndRepositoriesExtension.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/api/Extensions/AddServicesAndRepositoriesExtension.cs b/api/Extensions/AddServicesAndRepositoriesExtension.cs index 35b8d38..a341e3c 100644 --- a/api/Extensions/AddServicesAndRepositoriesExtension.cs +++ b/api/Extensions/AddServicesAndRepositoriesExtension.cs @@ -26,6 +26,7 @@ public static void AddServicesAndRepositories(this IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); // External services if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Testing") From 58c63f08639bc853f36e9d6a0bbd6f0981757b05 Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 11:06:10 +0200 Subject: [PATCH 03/18] updated test to reflect changes --- Tests/PlantTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/PlantTests.cs b/Tests/PlantTests.cs index 88de0fb..3ccc9d6 100644 --- a/Tests/PlantTests.cs +++ b/Tests/PlantTests.cs @@ -1,6 +1,7 @@ using api.Events.Collections.Server; using api.Events.PlantEvents.Client; using api.Events.PlantEvents.Server; +using api.Events.Statistics; using lib; using Shared.Dtos.FromClient.Plant; using Shared.Dtos.FromClient.Requirements; @@ -22,7 +23,8 @@ public async Task CreatePlant() await webSocketTestClient.DoAndAssert(new ClientWantsToCreatePlantDto { CreatePlantDto = createPlantDto, Jwt = jwt }, receivedMessages => { - return receivedMessages.Count(e => e.eventType == nameof(ServerSavesPlant)) == 1; + return receivedMessages.Count(e => e.eventType == nameof(ServerSavesPlant)) == 1 && + receivedMessages.Count(e => e.eventType == nameof(ServerSendsStats)) == 1; }); await webSocketTestClient.DoAndAssert(new ClientWantsAllPlantsDto From 1f4cfde34f6ddb874a64de47516f4617d033d86a Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 11:34:28 +0200 Subject: [PATCH 04/18] split tests to avoid timeout issue in pipeline --- Tests/PlantTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Tests/PlantTests.cs b/Tests/PlantTests.cs index 3ccc9d6..8812236 100644 --- a/Tests/PlantTests.cs +++ b/Tests/PlantTests.cs @@ -26,7 +26,16 @@ await webSocketTestClient.DoAndAssert(new ClientWantsToCreatePlantDto { CreatePl return receivedMessages.Count(e => e.eventType == nameof(ServerSavesPlant)) == 1 && receivedMessages.Count(e => e.eventType == nameof(ServerSendsStats)) == 1; }); - + } + + [Test] + public async Task GetAllPlants() + { + var jwtAndEmail = await SignUpAndLogIn(); + var jwt = jwtAndEmail[DictionaryKeys.Jwt]; + + var webSocketTestClient = await new WebSocketTestClient().ConnectAsync(); + await webSocketTestClient.DoAndAssert(new ClientWantsAllPlantsDto { Jwt = jwt, From 5ed77e49d1dcb59bf28b0cfc7b3c1cc9cf1112e0 Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 11:41:33 +0200 Subject: [PATCH 05/18] avoid awaiting tasks individually to hopefulle speed up the testing process and avoid timeout --- api/Core/Services/StatsService.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/api/Core/Services/StatsService.cs b/api/Core/Services/StatsService.cs index 16c1c35..9d3c695 100644 --- a/api/Core/Services/StatsService.cs +++ b/api/Core/Services/StatsService.cs @@ -7,15 +7,17 @@ public class StatsService(CollectionsService collectionsService, PlantService pl { public async Task GetStats(string email) { - var totalPlants = await plantService.GetTotalPlantsCount(email); - var happyPlants = await plantService.GetHappyPlantsCount(email); - var collections = await collectionsService.GetTotalCollectionsCount(email); + var totalPlantsTask = plantService.GetTotalPlantsCount(email); + var happyPlantsTask = plantService.GetHappyPlantsCount(email); + var collectionsTask = collectionsService.GetTotalCollectionsCount(email); + + await Task.WhenAll(totalPlantsTask, happyPlantsTask, collectionsTask); return new Stats { - TotalPlants = totalPlants, - HappyPlants = happyPlants, - Collections = collections + TotalPlants = totalPlantsTask.Result, + HappyPlants = happyPlantsTask.Result, + Collections = collectionsTask.Result }; } } From c2edf048054bc11e2fa876173b7fe957b41768e8 Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 11:52:07 +0200 Subject: [PATCH 06/18] further combined the requests to db --- .../Repositories/CollectionsRepository.cs | 7 ------- .../Repositories/PlantRepository.cs | 19 ++++++++++--------- api/Core/Services/CollectionsService.cs | 5 ----- api/Core/Services/PlantService.cs | 10 ---------- api/Core/Services/StatsService.cs | 18 ++++-------------- 5 files changed, 14 insertions(+), 45 deletions(-) diff --git a/Infrastructure/Repositories/CollectionsRepository.cs b/Infrastructure/Repositories/CollectionsRepository.cs index bdac8c3..f434f85 100644 --- a/Infrastructure/Repositories/CollectionsRepository.cs +++ b/Infrastructure/Repositories/CollectionsRepository.cs @@ -67,11 +67,4 @@ public async Task RemovePlantFromCollection(Collection collection, Plant plant) collection.Plants.Remove(plant); await applicationDbContext.SaveChangesAsync(); } - - public async Task GetTotalCollectionsCount(string email) - { - await using var applicationDbContext = await dbContextFactory.CreateDbContextAsync(); - return await applicationDbContext.Collections - .CountAsync(collection => collection.UserEmail == email); - } } \ No newline at end of file diff --git a/Infrastructure/Repositories/PlantRepository.cs b/Infrastructure/Repositories/PlantRepository.cs index 3f21e69..0727ce1 100644 --- a/Infrastructure/Repositories/PlantRepository.cs +++ b/Infrastructure/Repositories/PlantRepository.cs @@ -114,20 +114,21 @@ public async Task> GetCriticalPlants(string requesterEmail) .Select(p => p.Plant) .ToListAsync(); } - - public async Task GetHappyPlantsCount(string userEmail) + public async Task GetStats(string userEmail) { await using var context = await dbContextFactory.CreateDbContextAsync(); - return await context.Plants + var totalPlants = await context.Plants.CountAsync(p => p.UserEmail == userEmail); + var happyPlants = await context.Plants .Include(plant => plant.ConditionsLogs) .Where(p => p.UserEmail == userEmail && p.ConditionsLogs.Count != 0) .CountAsync(p => p.ConditionsLogs.OrderByDescending(log => log.TimeStamp).FirstOrDefault()!.Mood > 2); - } + var collections = await context.Collections.CountAsync(c => c.UserEmail == userEmail); - public async Task GetTotalPlantsCount(string userEmail) - { - await using var context = await dbContextFactory.CreateDbContextAsync(); - return await context.Plants - .CountAsync(p => p.UserEmail == userEmail); + return new Stats + { + TotalPlants = totalPlants, + HappyPlants = happyPlants, + Collections = collections + }; } } \ No newline at end of file diff --git a/api/Core/Services/CollectionsService.cs b/api/Core/Services/CollectionsService.cs index 7ac6a66..eb4a888 100644 --- a/api/Core/Services/CollectionsService.cs +++ b/api/Core/Services/CollectionsService.cs @@ -74,9 +74,4 @@ private async Task VerifyCollectionExistsAndUserHasAccess(Guid colle if (collection.UserEmail != loggedInUser) throw new NoAccessException("You don't have access to this collection"); return collection; } - - public async Task GetTotalCollectionsCount(string email) - { - return await collectionsRepository.GetTotalCollectionsCount(email); - } } \ No newline at end of file diff --git a/api/Core/Services/PlantService.cs b/api/Core/Services/PlantService.cs index 5a271d7..3922459 100644 --- a/api/Core/Services/PlantService.cs +++ b/api/Core/Services/PlantService.cs @@ -134,16 +134,6 @@ public async Task> GetCriticalPlants(string requesterE return criticalPlants; } - - public async Task GetHappyPlantsCount(string userEmail) - { - return await plantRepository.GetHappyPlantsCount(userEmail); - } - - public async Task GetTotalPlantsCount(string userEmail) - { - return await plantRepository.GetTotalPlantsCount(userEmail); - } private string GenerateRandomNickname() { diff --git a/api/Core/Services/StatsService.cs b/api/Core/Services/StatsService.cs index 9d3c695..3722478 100644 --- a/api/Core/Services/StatsService.cs +++ b/api/Core/Services/StatsService.cs @@ -1,23 +1,13 @@ -using Shared.Dtos; +using Infrastructure.Repositories; +using Shared.Dtos; using Shared.Models; namespace api.Core.Services; -public class StatsService(CollectionsService collectionsService, PlantService plantService) +public class StatsService(PlantRepository plantRepository) { public async Task GetStats(string email) { - var totalPlantsTask = plantService.GetTotalPlantsCount(email); - var happyPlantsTask = plantService.GetHappyPlantsCount(email); - var collectionsTask = collectionsService.GetTotalCollectionsCount(email); - - await Task.WhenAll(totalPlantsTask, happyPlantsTask, collectionsTask); - - return new Stats - { - TotalPlants = totalPlantsTask.Result, - HappyPlants = happyPlantsTask.Result, - Collections = collectionsTask.Result - }; + return await plantRepository.GetStats(email); } } From c2c4e9427f393418453fc79abd783dd51c46930c Mon Sep 17 00:00:00 2001 From: mariaruth1 <113031776+mariaruth1@users.noreply.github.com> Date: Tue, 28 May 2024 12:03:13 +0200 Subject: [PATCH 07/18] i dont event know anymore? --- .../PlantEvents/Client/ClientWantsToCreatePlant.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs index 333d868..e028f5a 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs @@ -21,16 +21,18 @@ public class ClientWantsToCreatePlant(PlantService plantService, JwtService jwtS public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); - var plant = await plantService.CreatePlant(dto.CreatePlantDto, email); - var stats = await statsService.GetStats(email); + var plant = plantService.CreatePlant(dto.CreatePlantDto, email); + var stats = statsService.GetStats(email); + + await Task.WhenAll(plant, stats); var serverCreatesNewPlant = new ServerSavesPlant { - Plant = plant + Plant = plant.Result }; socket.SendDto(serverCreatesNewPlant); - socket.SendDto(new ServerSendsStats{Stats = stats}); + socket.SendDto(new ServerSendsStats{Stats = stats.Result}); } } \ No newline at end of file From 53a640781ca94c0d278547f68cea81442c3d37a3 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 12:13:24 +0200 Subject: [PATCH 08/18] print received messages for debugging --- Tests/PlantTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/PlantTests.cs b/Tests/PlantTests.cs index 8812236..95bad0e 100644 --- a/Tests/PlantTests.cs +++ b/Tests/PlantTests.cs @@ -16,13 +16,13 @@ public async Task CreatePlant() { var jwtAndEmail = await SignUpAndLogIn(); var jwt = jwtAndEmail[DictionaryKeys.Jwt]; - var email = jwtAndEmail[DictionaryKeys.Email]; - var createPlantDto = GenerateRandomCreatePlantDto(email); + var createPlantDto = GenerateRandomCreatePlantDto(); var webSocketTestClient = await new WebSocketTestClient().ConnectAsync(); await webSocketTestClient.DoAndAssert(new ClientWantsToCreatePlantDto { CreatePlantDto = createPlantDto, Jwt = jwt }, receivedMessages => { + receivedMessages.ForEach(e => Console.WriteLine(e.eventType)); return receivedMessages.Count(e => e.eventType == nameof(ServerSavesPlant)) == 1 && receivedMessages.Count(e => e.eventType == nameof(ServerSendsStats)) == 1; }); @@ -47,7 +47,7 @@ await webSocketTestClient.DoAndAssert(new ClientWantsAllPlantsDto }); } - private CreatePlantDto GenerateRandomCreatePlantDto(string email) + private CreatePlantDto GenerateRandomCreatePlantDto() { var createPlantDto = new CreatePlantDto { From 15d472a216a433e193b72f03a4097419a4fa520b Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 12:21:58 +0200 Subject: [PATCH 09/18] small extension to print out error messages --- Tests/PlantTests.cs | 2 +- Tests/WebSocketTestClientExtension.cs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Tests/WebSocketTestClientExtension.cs diff --git a/Tests/PlantTests.cs b/Tests/PlantTests.cs index 95bad0e..01b249c 100644 --- a/Tests/PlantTests.cs +++ b/Tests/PlantTests.cs @@ -1,4 +1,3 @@ -using api.Events.Collections.Server; using api.Events.PlantEvents.Client; using api.Events.PlantEvents.Server; using api.Events.Statistics; @@ -19,6 +18,7 @@ public async Task CreatePlant() var createPlantDto = GenerateRandomCreatePlantDto(); var webSocketTestClient = await new WebSocketTestClient().ConnectAsync(); + webSocketTestClient.SubscribeToErrors(); await webSocketTestClient.DoAndAssert(new ClientWantsToCreatePlantDto { CreatePlantDto = createPlantDto, Jwt = jwt }, receivedMessages => { diff --git a/Tests/WebSocketTestClientExtension.cs b/Tests/WebSocketTestClientExtension.cs new file mode 100644 index 0000000..0b381d7 --- /dev/null +++ b/Tests/WebSocketTestClientExtension.cs @@ -0,0 +1,21 @@ +using System.Text.Json; +using api.Events.Global; +using lib; +using Websocket.Client; + +namespace Tests; + +public static class WebSocketTestClientExtension +{ + public static void SubscribeToErrors(this WebSocketTestClient client) + { + client.Client.MessageReceived.Subscribe(msg => + { + var baseDto = JsonSerializer.Deserialize(msg.Text); + if (baseDto is ServerSendsErrorMessage errorMessage) + { + Console.WriteLine(errorMessage.Error); + } + }); + } +} \ No newline at end of file From 80c919565664e2392a45db1521269a19980a1ff4 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 13:53:42 +0200 Subject: [PATCH 10/18] does it work? --- Tests/PlantTests.cs | 6 +----- Tests/TestBase.cs | 4 +++- api/Events/Auth/Client/ClientWantsToLogIn.cs | 1 + .../Client/ClientWantsToCreatePlant.cs | 13 +++++-------- api/Program.cs | 6 ++++-- api/logo.png | Bin 12284 -> 0 bytes 6 files changed, 14 insertions(+), 16 deletions(-) delete mode 100644 api/logo.png diff --git a/Tests/PlantTests.cs b/Tests/PlantTests.cs index 01b249c..5de8a3e 100644 --- a/Tests/PlantTests.cs +++ b/Tests/PlantTests.cs @@ -1,6 +1,5 @@ using api.Events.PlantEvents.Client; using api.Events.PlantEvents.Server; -using api.Events.Statistics; using lib; using Shared.Dtos.FromClient.Plant; using Shared.Dtos.FromClient.Requirements; @@ -18,13 +17,10 @@ public async Task CreatePlant() var createPlantDto = GenerateRandomCreatePlantDto(); var webSocketTestClient = await new WebSocketTestClient().ConnectAsync(); - webSocketTestClient.SubscribeToErrors(); await webSocketTestClient.DoAndAssert(new ClientWantsToCreatePlantDto { CreatePlantDto = createPlantDto, Jwt = jwt }, receivedMessages => { - receivedMessages.ForEach(e => Console.WriteLine(e.eventType)); - return receivedMessages.Count(e => e.eventType == nameof(ServerSavesPlant)) == 1 && - receivedMessages.Count(e => e.eventType == nameof(ServerSendsStats)) == 1; + return receivedMessages.Count(e => e.eventType == nameof(ServerSavesPlant)) == 1; }); } diff --git a/Tests/TestBase.cs b/Tests/TestBase.cs index 9260a42..a0e31da 100644 --- a/Tests/TestBase.cs +++ b/Tests/TestBase.cs @@ -35,8 +35,10 @@ await webSocketTestClient.DoAndAssert(new ClientWantsToSignUpDto { RegisterUserD var jwtSubscription = webSocketTestClient.Client.MessageReceived.Subscribe(msg => { + var eventType = JsonSerializer.Deserialize(msg.Text).eventType; + if (eventType != nameof(ServerAuthenticatesUser)) return; var serverAuthenticates = JsonSerializer.Deserialize(msg.Text, options: new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - jwt = serverAuthenticates.Jwt; + jwt = serverAuthenticates!.Jwt; }); webSocketTestClient.Send(new ClientWantsToLogInDto { LoginDto = loginDto }); diff --git a/api/Events/Auth/Client/ClientWantsToLogIn.cs b/api/Events/Auth/Client/ClientWantsToLogIn.cs index 2477d41..b3ed53e 100644 --- a/api/Events/Auth/Client/ClientWantsToLogIn.cs +++ b/api/Events/Auth/Client/ClientWantsToLogIn.cs @@ -44,6 +44,7 @@ public override async Task Handle(ClientWantsToLogInDto dto, IWebSocketConnectio Jwt = jwt, }); + socket.SendDto(new ServerSendsUserInfo { GetUserDto = getUserDto diff --git a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs index e028f5a..ff059e9 100644 --- a/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs +++ b/api/Events/PlantEvents/Client/ClientWantsToCreatePlant.cs @@ -12,7 +12,7 @@ namespace api.Events.PlantEvents.Client; public class ClientWantsToCreatePlantDto: BaseDtoWithJwt { - public CreatePlantDto CreatePlantDto { get; set; } + public required CreatePlantDto CreatePlantDto { get; set; } } [ValidateDataAnnotations] @@ -21,18 +21,15 @@ public class ClientWantsToCreatePlant(PlantService plantService, JwtService jwtS public override async Task Handle(ClientWantsToCreatePlantDto dto, IWebSocketConnection socket) { var email = jwtService.GetEmailFromJwt(dto.Jwt!); - var plant = plantService.CreatePlant(dto.CreatePlantDto, email); - var stats = statsService.GetStats(email); - - await Task.WhenAll(plant, stats); + var plant = await plantService.CreatePlant(dto.CreatePlantDto, email); var serverCreatesNewPlant = new ServerSavesPlant { - Plant = plant.Result + Plant = plant }; - socket.SendDto(serverCreatesNewPlant); - socket.SendDto(new ServerSendsStats{Stats = stats.Result}); + var stats = await statsService.GetStats(email); + socket.SendDto(new ServerSendsStats{Stats = stats}); } } \ No newline at end of file diff --git a/api/Program.cs b/api/Program.cs index c833a96..2e4815c 100644 --- a/api/Program.cs +++ b/api/Program.cs @@ -26,6 +26,8 @@ public static class Startup nameof(ClientWantsToSignUp) ]; + private static readonly List NonProdEnvironments = ["Development", "Testing"]; + public static async Task Main(string[] args) { var app = await StartApi(args); @@ -86,7 +88,7 @@ public static async Task StartApi(string[] args) var scope = app.Services.CreateScope(); var db = await app.Services.GetRequiredService>().CreateDbContextAsync(); - if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + if (NonProdEnvironments.Contains(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))) { await db.Database.EnsureDeletedAsync(); } @@ -94,7 +96,7 @@ public static async Task StartApi(string[] args) await db.Database.EnsureCreatedAsync(); await db.Database.MigrateAsync(); - if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development") + if (NonProdEnvironments.Contains(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))) { await db.SeedDevelopmentDataAsync(scope, app.Configuration["AzureBlob:DefaultPlantImageUrl"] ?? "https://example.com"); } diff --git a/api/logo.png b/api/logo.png deleted file mode 100644 index 0ac63e43657dfb2eb19bce1e4409f08654a77347..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12284 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 Date: Tue, 28 May 2024 13:59:24 +0200 Subject: [PATCH 11/18] ripped off websockettestclient to see if the timing is the problem --- Tests/WebSocketTestClient.cs | 56 +++++++++++++++++++++++++++ Tests/WebSocketTestClientExtension.cs | 21 ---------- 2 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 Tests/WebSocketTestClient.cs delete mode 100644 Tests/WebSocketTestClientExtension.cs diff --git a/Tests/WebSocketTestClient.cs b/Tests/WebSocketTestClient.cs new file mode 100644 index 0000000..65c9a44 --- /dev/null +++ b/Tests/WebSocketTestClient.cs @@ -0,0 +1,56 @@ +using System.Text.Json; +using lib; +using Websocket.Client; + +namespace Tests +{ + public class WebSocketTestClient + { + public readonly WebsocketClient Client; + public readonly List ReceivedMessages = []; + + public WebSocketTestClient(string? url = null) + { + Client = url == null ? new WebsocketClient(new Uri("ws://localhost:" + (Environment.GetEnvironmentVariable("FULLSTACK_API_PORT") ?? "8181"))) : new WebsocketClient(new Uri(url)); + Client.MessageReceived.Subscribe((Action) (msg => + { + BaseDto baseDto = JsonSerializer.Deserialize(msg.Text); + lock (ReceivedMessages) + ReceivedMessages.Add(baseDto); + })); + } + + public async Task ConnectAsync() + { + await Client.Start(); + if (!Client.IsRunning) + throw new Exception("Could not start client!"); + return this; + } + + public void Send(T dto) where T : BaseDto + { + Client.Send(JsonSerializer.Serialize(dto)); + } + + public async Task DoAndAssert(T? action = null, Func, bool>? condition = null) where T : BaseDto + { + if ((object) (T) action != null) + Send(action); + if (condition != null) + { + DateTime startTime = DateTime.UtcNow; + while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(10.0)) + { + lock (ReceivedMessages) + { + if (condition(ReceivedMessages)) + return; + } + await Task.Delay(100); + } + throw new TimeoutException("Condition not met: "); + } + } + } +} \ No newline at end of file diff --git a/Tests/WebSocketTestClientExtension.cs b/Tests/WebSocketTestClientExtension.cs deleted file mode 100644 index 0b381d7..0000000 --- a/Tests/WebSocketTestClientExtension.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Text.Json; -using api.Events.Global; -using lib; -using Websocket.Client; - -namespace Tests; - -public static class WebSocketTestClientExtension -{ - public static void SubscribeToErrors(this WebSocketTestClient client) - { - client.Client.MessageReceived.Subscribe(msg => - { - var baseDto = JsonSerializer.Deserialize(msg.Text); - if (baseDto is ServerSendsErrorMessage errorMessage) - { - Console.WriteLine(errorMessage.Error); - } - }); - } -} \ No newline at end of file From 6b954293ba50ba72176aae6d63dc66bf4e407f81 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:03:05 +0200 Subject: [PATCH 12/18] can we log errors? --- Tests/WebSocketTestClient.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Tests/WebSocketTestClient.cs b/Tests/WebSocketTestClient.cs index 65c9a44..b120184 100644 --- a/Tests/WebSocketTestClient.cs +++ b/Tests/WebSocketTestClient.cs @@ -1,4 +1,5 @@ using System.Text.Json; +using api.Events.Global; using lib; using Websocket.Client; @@ -12,12 +13,20 @@ public class WebSocketTestClient public WebSocketTestClient(string? url = null) { Client = url == null ? new WebsocketClient(new Uri("ws://localhost:" + (Environment.GetEnvironmentVariable("FULLSTACK_API_PORT") ?? "8181"))) : new WebsocketClient(new Uri(url)); - Client.MessageReceived.Subscribe((Action) (msg => + Client.MessageReceived.Subscribe(msg => { BaseDto baseDto = JsonSerializer.Deserialize(msg.Text); + + if (baseDto.eventType == "ServerSendsError") + { + var error = JsonSerializer.Deserialize(msg.Text); + throw new Exception(error!.Error); + } + + lock (ReceivedMessages) ReceivedMessages.Add(baseDto); - })); + }); } public async Task ConnectAsync() From 4fbad2d058f64507b8853a9e50b0463156cdbe8c Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:06:28 +0200 Subject: [PATCH 13/18] listen for more errors --- Tests/WebSocketTestClient.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Tests/WebSocketTestClient.cs b/Tests/WebSocketTestClient.cs index b120184..d75ba23 100644 --- a/Tests/WebSocketTestClient.cs +++ b/Tests/WebSocketTestClient.cs @@ -17,13 +17,12 @@ public WebSocketTestClient(string? url = null) { BaseDto baseDto = JsonSerializer.Deserialize(msg.Text); - if (baseDto.eventType == "ServerSendsError") + if (baseDto.eventType == "ServerSendsErrorMessage" || baseDto.eventType.Contains("ServerResponds") || baseDto.eventType.Contains("ServerRejects")) { var error = JsonSerializer.Deserialize(msg.Text); throw new Exception(error!.Error); } - lock (ReceivedMessages) ReceivedMessages.Add(baseDto); }); @@ -49,7 +48,7 @@ public async Task DoAndAssert(T? action = null, Func, bool>? co if (condition != null) { DateTime startTime = DateTime.UtcNow; - while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(10.0)) + while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(5.0)) { lock (ReceivedMessages) { From ebfac260a19208d4b199f5fbbc38b7fbf68d1c30 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:08:11 +0200 Subject: [PATCH 14/18] print error --- Tests/WebSocketTestClient.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Tests/WebSocketTestClient.cs b/Tests/WebSocketTestClient.cs index d75ba23..02340c8 100644 --- a/Tests/WebSocketTestClient.cs +++ b/Tests/WebSocketTestClient.cs @@ -16,13 +16,15 @@ public WebSocketTestClient(string? url = null) Client.MessageReceived.Subscribe(msg => { BaseDto baseDto = JsonSerializer.Deserialize(msg.Text); + Console.WriteLine("Received message: " + baseDto.eventType); - if (baseDto.eventType == "ServerSendsErrorMessage" || baseDto.eventType.Contains("ServerResponds") || baseDto.eventType.Contains("ServerRejects")) + if (baseDto.eventType == "ServerSendsErrorMessage" || baseDto.eventType.Contains("ServerResponds") || + baseDto.eventType.Contains("ServerRejects")) { var error = JsonSerializer.Deserialize(msg.Text); - throw new Exception(error!.Error); + Console.WriteLine("Error: " + error!.Error); } - + lock (ReceivedMessages) ReceivedMessages.Add(baseDto); }); From d4b45c4a81cf0fc19006048d023ee92ad9145ec3 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:12:57 +0200 Subject: [PATCH 15/18] try without user info --- api/Events/Auth/Client/ClientWantsToLogIn.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/Events/Auth/Client/ClientWantsToLogIn.cs b/api/Events/Auth/Client/ClientWantsToLogIn.cs index b3ed53e..3a99fb6 100644 --- a/api/Events/Auth/Client/ClientWantsToLogIn.cs +++ b/api/Events/Auth/Client/ClientWantsToLogIn.cs @@ -45,10 +45,11 @@ public override async Task Handle(ClientWantsToLogInDto dto, IWebSocketConnectio }); - socket.SendDto(new ServerSendsUserInfo + /* socket.SendDto(new ServerSendsUserInfo { GetUserDto = getUserDto }); + */ } } From 6152c6862cf1be0ac0750c8b611b1b070498a41e Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:20:00 +0200 Subject: [PATCH 16/18] send detailed error in testing --- Tests/WebSocketTestClient.cs | 8 ++++++-- api/Events/Auth/Client/ClientWantsToLogIn.cs | 3 +-- api/GlobalExceptionHandler.cs | 9 +++++---- api/Program.cs | 6 +++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Tests/WebSocketTestClient.cs b/Tests/WebSocketTestClient.cs index 02340c8..3bde890 100644 --- a/Tests/WebSocketTestClient.cs +++ b/Tests/WebSocketTestClient.cs @@ -9,19 +9,23 @@ public class WebSocketTestClient { public readonly WebsocketClient Client; public readonly List ReceivedMessages = []; + private static readonly JsonSerializerOptions JsonSerializerOptions = new() + { + PropertyNameCaseInsensitive = true + }; public WebSocketTestClient(string? url = null) { Client = url == null ? new WebsocketClient(new Uri("ws://localhost:" + (Environment.GetEnvironmentVariable("FULLSTACK_API_PORT") ?? "8181"))) : new WebsocketClient(new Uri(url)); Client.MessageReceived.Subscribe(msg => { - BaseDto baseDto = JsonSerializer.Deserialize(msg.Text); + BaseDto baseDto = JsonSerializer.Deserialize(msg.Text, JsonSerializerOptions); Console.WriteLine("Received message: " + baseDto.eventType); if (baseDto.eventType == "ServerSendsErrorMessage" || baseDto.eventType.Contains("ServerResponds") || baseDto.eventType.Contains("ServerRejects")) { - var error = JsonSerializer.Deserialize(msg.Text); + var error = JsonSerializer.Deserialize(msg.Text, JsonSerializerOptions); Console.WriteLine("Error: " + error!.Error); } diff --git a/api/Events/Auth/Client/ClientWantsToLogIn.cs b/api/Events/Auth/Client/ClientWantsToLogIn.cs index 3a99fb6..a4ff964 100644 --- a/api/Events/Auth/Client/ClientWantsToLogIn.cs +++ b/api/Events/Auth/Client/ClientWantsToLogIn.cs @@ -45,11 +45,10 @@ public override async Task Handle(ClientWantsToLogInDto dto, IWebSocketConnectio }); - /* socket.SendDto(new ServerSendsUserInfo + socket.SendDto(new ServerSendsUserInfo { GetUserDto = getUserDto }); - */ } } diff --git a/api/GlobalExceptionHandler.cs b/api/GlobalExceptionHandler.cs index 511ca11..99cd37c 100644 --- a/api/GlobalExceptionHandler.cs +++ b/api/GlobalExceptionHandler.cs @@ -28,10 +28,11 @@ public static void Handle(this Exception ex, IWebSocketConnection socket, string _ => new ServerSendsErrorMessage { Error = message ?? ex.Message } }; else - serverResponse = new ServerSendsErrorMessage - { - Error = "Something went wrong. Please try again later." - }; + { + serverResponse = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Testing" + ? new ServerSendsErrorMessage { Error = ex.Message } + : new ServerSendsErrorMessage { Error = "Something went wrong. Please try again later." }; + } socket.SendDto(serverResponse); } diff --git a/api/Program.cs b/api/Program.cs index 2e4815c..c32f851 100644 --- a/api/Program.cs +++ b/api/Program.cs @@ -27,6 +27,10 @@ public static class Startup ]; private static readonly List NonProdEnvironments = ["Development", "Testing"]; + private static readonly JsonSerializerOptions JsonSerializerOptions = new() + { + PropertyNameCaseInsensitive = true + }; public static async Task Main(string[] args) { @@ -137,7 +141,7 @@ public static async Task StartApi(string[] args) try { // Check if the message contains a JWT token and if it is valid - var dto = JsonSerializer.Deserialize(message, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + var dto = JsonSerializer.Deserialize(message, JsonSerializerOptions); if (dto is not null && PublicEvents.Contains(dto.eventType) == false) { if (dto.Jwt is null) From 5baa4842f28d93d79ade659156b118f590e8caf8 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:28:29 +0200 Subject: [PATCH 17/18] adjust pipeline not to require azure credentials as they are mocked either way --- .github/workflows/test.yaml | 3 --- api/EnvironmentHelper.cs | 26 +++++++++++++++++++ .../AddServicesAndRepositoriesExtension.cs | 2 +- api/Extensions/ConfigureExtensions.cs | 6 +++-- api/GlobalExceptionHandler.cs | 2 +- api/Program.cs | 9 +++---- 6 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 api/EnvironmentHelper.cs diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 828f1cf..06377de 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,7 +35,4 @@ jobs: MQTT_CLIENT_ID: ${{ secrets.MQTT_CLIENT_ID }} MQTT_SUBSCRIBE_TOPIC: ${{ secrets.MQTT_SUBSCRIBE_TOPIC }} MQTT_PUBLISH_TOPIC: ${{ secrets.MQTT_PUBLISH_TOPIC }} - - AZURE_VISION_KEY: ${{ secrets.AZURE_VISION_KEY }} - AZURE_VISION_ENDPOINT: ${{ secrets.AZURE_VISION_ENDPOINT }} run: cd Tests && dotnet test \ No newline at end of file diff --git a/api/EnvironmentHelper.cs b/api/EnvironmentHelper.cs new file mode 100644 index 0000000..8546b43 --- /dev/null +++ b/api/EnvironmentHelper.cs @@ -0,0 +1,26 @@ +namespace api; + +public static class EnvironmentHelper +{ + private static readonly List NonProdEnvironments = ["Development", "Testing"]; + + public static bool IsTesting() + { + return Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Testing"; + } + + public static bool IsDevelopment() + { + return Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development"; + } + + public static bool IsNonProd() + { + return NonProdEnvironments.Contains(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")); + } + + public static bool IsCi() + { + return Environment.GetEnvironmentVariable("CI") == "true"; + } +} \ No newline at end of file diff --git a/api/Extensions/AddServicesAndRepositoriesExtension.cs b/api/Extensions/AddServicesAndRepositoriesExtension.cs index a341e3c..3206523 100644 --- a/api/Extensions/AddServicesAndRepositoriesExtension.cs +++ b/api/Extensions/AddServicesAndRepositoriesExtension.cs @@ -29,7 +29,7 @@ public static void AddServicesAndRepositories(this IServiceCollection services) services.AddSingleton(); // External services - if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Testing") + if (EnvironmentHelper.IsTesting()) { services.AddSingleton(); services.AddSingleton(); diff --git a/api/Extensions/ConfigureExtensions.cs b/api/Extensions/ConfigureExtensions.cs index e3c2ee4..43bfcd2 100644 --- a/api/Extensions/ConfigureExtensions.cs +++ b/api/Extensions/ConfigureExtensions.cs @@ -6,7 +6,7 @@ public static class ConfigureExtensions { public static void ConfigureOptions(this WebApplicationBuilder builder) { - if (Environment.GetEnvironmentVariable("CI") is not null) + if (EnvironmentHelper.IsCi()) { builder.Services.Configure(options => { @@ -25,7 +25,9 @@ public static void ConfigureOptions(this WebApplicationBuilder builder) options.SubscribeTopic = Environment.GetEnvironmentVariable("MQTT_SUBSCRIBE_TOPIC") ?? throw new Exception("MQTT subscribe topic is missing"); options.PublishTopic = Environment.GetEnvironmentVariable("MQTT_PUBLISH_TOPIC") ?? throw new Exception("MQTT publish topic is missing"); }); - + + if (EnvironmentHelper.IsTesting()) return; + builder.Services.Configure(options => { options.RemoveBackgroundEndpoint = Environment.GetEnvironmentVariable("AZURE_VISION_REMOVE_BACKGROUND_ENDPOINT") ?? throw new Exception("Azure Vision endpoint is missing"); diff --git a/api/GlobalExceptionHandler.cs b/api/GlobalExceptionHandler.cs index 99cd37c..2d878c0 100644 --- a/api/GlobalExceptionHandler.cs +++ b/api/GlobalExceptionHandler.cs @@ -29,7 +29,7 @@ public static void Handle(this Exception ex, IWebSocketConnection socket, string }; else { - serverResponse = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Testing" + serverResponse = EnvironmentHelper.IsTesting() ? new ServerSendsErrorMessage { Error = ex.Message } : new ServerSendsErrorMessage { Error = "Something went wrong. Please try again later." }; } diff --git a/api/Program.cs b/api/Program.cs index c32f851..d3df78d 100644 --- a/api/Program.cs +++ b/api/Program.cs @@ -1,6 +1,5 @@ using System.Reflection; using System.Text.Json; -using api.Core.Options; using api.Core.Services; using api.Events.Auth.Client; using api.Extensions; @@ -9,7 +8,6 @@ using lib; using Microsoft.EntityFrameworkCore; using Serilog; -using Shared.Dtos; using Shared.Exceptions; using Shared.Models; using Testcontainers.PostgreSql; @@ -26,7 +24,6 @@ public static class Startup nameof(ClientWantsToSignUp) ]; - private static readonly List NonProdEnvironments = ["Development", "Testing"]; private static readonly JsonSerializerOptions JsonSerializerOptions = new() { PropertyNameCaseInsensitive = true @@ -52,7 +49,7 @@ public static async Task StartApi(string[] args) var builder = WebApplication.CreateBuilder(args); - if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Testing") + if (EnvironmentHelper.IsTesting()) { var dbContainer = new PostgreSqlBuilder() @@ -92,7 +89,7 @@ public static async Task StartApi(string[] args) var scope = app.Services.CreateScope(); var db = await app.Services.GetRequiredService>().CreateDbContextAsync(); - if (NonProdEnvironments.Contains(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))) + if (EnvironmentHelper.IsNonProd()) { await db.Database.EnsureDeletedAsync(); } @@ -100,7 +97,7 @@ public static async Task StartApi(string[] args) await db.Database.EnsureCreatedAsync(); await db.Database.MigrateAsync(); - if (NonProdEnvironments.Contains(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))) + if (EnvironmentHelper.IsNonProd()) { await db.SeedDevelopmentDataAsync(scope, app.Configuration["AzureBlob:DefaultPlantImageUrl"] ?? "https://example.com"); } From 935ebb239dca3280bee1d1f4074d0480614bf5d8 Mon Sep 17 00:00:00 2001 From: Julia Ilasova <1julka1il@gmail.com> Date: Tue, 28 May 2024 14:29:17 +0200 Subject: [PATCH 18/18] remove logging every message --- Tests/WebSocketTestClient.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/WebSocketTestClient.cs b/Tests/WebSocketTestClient.cs index 3bde890..4e863d1 100644 --- a/Tests/WebSocketTestClient.cs +++ b/Tests/WebSocketTestClient.cs @@ -20,7 +20,6 @@ public WebSocketTestClient(string? url = null) Client.MessageReceived.Subscribe(msg => { BaseDto baseDto = JsonSerializer.Deserialize(msg.Text, JsonSerializerOptions); - Console.WriteLine("Received message: " + baseDto.eventType); if (baseDto.eventType == "ServerSendsErrorMessage" || baseDto.eventType.Contains("ServerResponds") || baseDto.eventType.Contains("ServerRejects"))