From 7dc40430efa9a29547968e267b04d4ffbb11ead1 Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Tue, 3 Sep 2024 16:21:34 +0200 Subject: [PATCH] Refactored testoutput helper usage --- .../EntityDefinitionTests.cs | 3 +- .../EntityDefinitionTests.cs | 3 +- ...GroupCheckout.cs => GroupCheckoutEvent.cs} | 0 .../BusinessProcessTests.cs | 5 +- .../EntityDefinitionTests.cs | 3 +- .../GroupCheckouts/GroupCheckout.cs | 156 ------------------ .../GroupCheckouts/GroupCheckoutEvents.cs | 42 +++++ .../GuestStayFacade.cs | 4 +- .../EventDrivenArchitecture.sln | 7 + .../EntityDefinitionTests.cs | 3 +- .../EntityDefinitionTests.cs | 3 +- .../03-BusinessProcesses.csproj | 26 +++ .../03-BusinessProcesses/UnitTest1.cs | 11 ++ 13 files changed, 94 insertions(+), 172 deletions(-) rename Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/GroupCheckouts/{GroupCheckout.cs => GroupCheckoutEvent.cs} (100%) delete mode 100644 Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckout.cs create mode 100644 Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckoutEvents.cs create mode 100644 Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/03-BusinessProcesses.csproj create mode 100644 Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/UnitTest1.cs diff --git a/Workshops/EventDrivenArchitecture/02-EntitiesDefinition/EntityDefinitionTests.cs b/Workshops/EventDrivenArchitecture/02-EntitiesDefinition/EntityDefinitionTests.cs index b1a89988..c9cd91cd 100644 --- a/Workshops/EventDrivenArchitecture/02-EntitiesDefinition/EntityDefinitionTests.cs +++ b/Workshops/EventDrivenArchitecture/02-EntitiesDefinition/EntityDefinitionTests.cs @@ -12,8 +12,6 @@ namespace EntitiesDefinition; public class EntityDefinitionTests { - private readonly ITestOutputHelper testOutputHelper; - [Fact] [Trait("Category", "SkipCI")] public async Task CheckingInGuest_Succeeds() @@ -168,6 +166,7 @@ public async Task GroupCheckoutForMultipleGuestStay_ShouldBeInitiated() private readonly GuestStayFacade guestStayFacade; private readonly Faker generate = new(); private readonly DateTimeOffset now = DateTimeOffset.Now; + private readonly ITestOutputHelper testOutputHelper; public EntityDefinitionTests(ITestOutputHelper testOutputHelper) { diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/EntityDefinitionTests.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/EntityDefinitionTests.cs index 886b1eaf..f9cce08d 100644 --- a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/EntityDefinitionTests.cs +++ b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/EntityDefinitionTests.cs @@ -14,8 +14,6 @@ namespace BusinessProcesses.Version1_Aggregates; public class EntityDefinitionTests { - private readonly ITestOutputHelper testOutputHelper; - [Fact] public async Task CheckingInGuest_Succeeds() { @@ -163,6 +161,7 @@ public async Task GroupCheckoutForMultipleGuestStay_ShouldBeInitiated() private readonly GuestStayFacade guestStayFacade; private readonly Faker generate = new(); private readonly DateTimeOffset now = DateTimeOffset.Now; + private readonly ITestOutputHelper testOutputHelper; public EntityDefinitionTests(ITestOutputHelper testOutputHelper) { diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/GroupCheckouts/GroupCheckout.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/GroupCheckouts/GroupCheckoutEvent.cs similarity index 100% rename from Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/GroupCheckouts/GroupCheckout.cs rename to Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version1-Aggregates/GroupCheckouts/GroupCheckoutEvent.cs diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/BusinessProcessTests.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/BusinessProcessTests.cs index ffc61561..c2563800 100644 --- a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/BusinessProcessTests.cs +++ b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/BusinessProcessTests.cs @@ -14,8 +14,6 @@ namespace BusinessProcesses.Version2_ImmutableEntities; public class BusinessProcessTests { - private readonly ITestOutputHelper testOutputHelper; - [Fact] public async Task GroupCheckoutForMultipleGuestStayWithoutPaymentsAndCharges_ShouldComplete() { @@ -52,7 +50,6 @@ public async Task GroupCheckoutForMultipleGuestStayWithoutPaymentsAndCharges_Sho ); } - [Fact] public async Task GroupCheckoutForMultipleGuestStayWithAllStaysSettled_ShouldComplete() { @@ -99,7 +96,6 @@ public async Task GroupCheckoutForMultipleGuestStayWithAllStaysSettled_ShouldCom ); } - [Fact] public async Task GroupCheckoutForMultipleGuestStayWithOneSettledAndRestUnsettled_ShouldFail() { @@ -215,6 +211,7 @@ public async Task GroupCheckoutForMultipleGuestStayWithAllUnsettled_ShouldFail() private readonly GuestStayFacade guestStayFacade; private readonly Faker generate = new(); private readonly DateTimeOffset now = DateTimeOffset.Now; + private readonly ITestOutputHelper testOutputHelper; public BusinessProcessTests(ITestOutputHelper testOutputHelper) { diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/EntityDefinitionTests.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/EntityDefinitionTests.cs index c42bd641..f711bcc3 100644 --- a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/EntityDefinitionTests.cs +++ b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/EntityDefinitionTests.cs @@ -14,8 +14,6 @@ namespace BusinessProcesses.Version2_ImmutableEntities; public class EntityDefinitionTests { - private readonly ITestOutputHelper testOutputHelper; - [Fact] public async Task CheckingInGuest_Succeeds() { @@ -141,6 +139,7 @@ public async Task CheckingOutGuestWithSettledBalance_FailsWithGuestCheckoutFaile private readonly GuestStayFacade guestStayFacade; private readonly Faker generate = new(); private readonly DateTimeOffset now = DateTimeOffset.Now; + private readonly ITestOutputHelper testOutputHelper; public EntityDefinitionTests(ITestOutputHelper testOutputHelper) { diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckout.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckout.cs deleted file mode 100644 index 1a382d24..00000000 --- a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckout.cs +++ /dev/null @@ -1,156 +0,0 @@ -using BusinessProcesses.Version2_ImmutableEntities.Core; - -namespace BusinessProcesses.Version2_ImmutableEntities.GroupCheckouts; - -using static GroupCheckoutEvent; - -public abstract record GroupCheckoutEvent -{ - public record GroupCheckoutInitiated( - Guid GroupCheckoutId, - Guid ClerkId, - Guid[] GuestStayIds, - DateTimeOffset InitiatedAt - ): GroupCheckoutEvent; - - public record GuestCheckoutCompleted( - Guid GroupCheckoutId, - Guid GuestStayId, - DateTimeOffset CompletedAt - ): GroupCheckoutEvent; - - public record GuestCheckoutFailed( - Guid GroupCheckoutId, - Guid GuestStayId, - DateTimeOffset FailedAt - ): GroupCheckoutEvent; - - public record GroupCheckoutCompleted( - Guid GroupCheckoutId, - Guid[] CompletedCheckouts, - DateTimeOffset CompletedAt - ): GroupCheckoutEvent; - - public record GroupCheckoutFailed( - Guid GroupCheckoutId, - Guid[] CompletedCheckouts, - Guid[] FailedCheckouts, - DateTimeOffset FailedAt - ): GroupCheckoutEvent; - - private GroupCheckoutEvent() { } -} - -public record GroupCheckout( - Guid Id, - Dictionary GuestStayCheckouts, - CheckoutStatus Status = CheckoutStatus.Initiated -) -{ - public static GroupCheckoutInitiated Initiate(Guid groupCheckoutId, Guid clerkId, Guid[] guestStayIds, - DateTimeOffset initiatedAt) => - new(groupCheckoutId, clerkId, guestStayIds, initiatedAt); - - public (GuestCheckoutCompleted?, (GroupCheckoutCompleted?, GroupCheckoutFailed?)?) RecordGuestCheckoutCompletion( - Guid guestStayId, - DateTimeOffset now - ) - { - if (Status == CheckoutStatus.Initiated && GuestStayCheckouts[guestStayId] != CheckoutStatus.Completed) - return (null, null); - - var guestCheckoutCompleted = new GuestCheckoutCompleted(Id, guestStayId, now); - - var guestStayCheckouts = GuestStayCheckouts.With(guestStayId, CheckoutStatus.Completed); - - return AreAnyOngoingCheckouts(guestStayCheckouts) - ? (guestCheckoutCompleted, null) - : (guestCheckoutCompleted, Finalize(guestStayCheckouts, now)); - } - - public (GuestCheckoutFailed?, (GroupCheckoutCompleted?, GroupCheckoutFailed?)?) RecordGuestCheckoutFailure( - Guid guestStayId, - DateTimeOffset now - ) - { - if (Status == CheckoutStatus.Initiated && GuestStayCheckouts[guestStayId] != CheckoutStatus.Completed) - return (null, null); - - var guestCheckoutFailed = new GuestCheckoutFailed(Id, guestStayId, now); - - var guestStayCheckouts = GuestStayCheckouts.With(guestStayId, CheckoutStatus.Failed); - - return AreAnyOngoingCheckouts(guestStayCheckouts) - ? (guestCheckoutFailed, null) - : (guestCheckoutFailed, Finalize(guestStayCheckouts, now)); - } - - private (GroupCheckoutCompleted?, GroupCheckoutFailed?) Finalize( - Dictionary guestStayCheckouts, - DateTimeOffset now - ) => - !AreAnyFailedCheckouts(guestStayCheckouts) - ? (new GroupCheckoutCompleted - ( - Id, - CheckoutsWith(guestStayCheckouts, CheckoutStatus.Completed), - now - ), null) - : (null, new GroupCheckoutFailed - ( - Id, - CheckoutsWith(guestStayCheckouts, CheckoutStatus.Completed), - CheckoutsWith(guestStayCheckouts, CheckoutStatus.Failed), - now - )); - - private static bool AreAnyOngoingCheckouts(Dictionary guestStayCheckouts) => - guestStayCheckouts.Values.Any(status => status is CheckoutStatus.Initiated); - - private static bool AreAnyFailedCheckouts(Dictionary guestStayCheckouts) => - guestStayCheckouts.Values.Any(status => status is CheckoutStatus.Failed); - - private static Guid[] CheckoutsWith(Dictionary guestStayCheckouts, CheckoutStatus status) => - guestStayCheckouts - .Where(pair => pair.Value == status) - .Select(pair => pair.Key) - .ToArray(); - - - public GroupCheckout Evolve(GroupCheckoutEvent @event) => - @event switch - { - GroupCheckoutInitiated initiated => this with - { - Id = initiated.GroupCheckoutId, - GuestStayCheckouts = initiated.GuestStayIds.ToDictionary(id => id, _ => CheckoutStatus.Initiated), - Status = CheckoutStatus.Initiated - }, - GuestCheckoutCompleted guestCheckedOut => this with - { - GuestStayCheckouts = GuestStayCheckouts.ToDictionary( - ks => ks.Key, - vs => vs.Key == guestCheckedOut.GuestStayId ? CheckoutStatus.Completed : vs.Value - ) - }, - GuestCheckoutFailed guestCheckedOutFailed => this with - { - GuestStayCheckouts = GuestStayCheckouts.ToDictionary( - ks => ks.Key, - vs => vs.Key == guestCheckedOutFailed.GuestStayId ? CheckoutStatus.Completed : vs.Value - ) - }, - GroupCheckoutCompleted => this with { Status = CheckoutStatus.Completed }, - GroupCheckoutFailed => this with { Status = CheckoutStatus.Failed }, - _ => this - }; - - public static GroupCheckout Initial = new(default, [], default); -} - -public enum CheckoutStatus -{ - Initiated, - Completed, - Failed -} diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckoutEvents.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckoutEvents.cs new file mode 100644 index 00000000..4bd0ae9c --- /dev/null +++ b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GroupCheckouts/GroupCheckoutEvents.cs @@ -0,0 +1,42 @@ +using BusinessProcesses.Version2_ImmutableEntities.Core; + +namespace BusinessProcesses.Version2_ImmutableEntities.GroupCheckouts; + +using static GroupCheckoutEvent; + +public abstract record GroupCheckoutEvent +{ + public record GroupCheckoutInitiated( + Guid GroupCheckoutId, + Guid ClerkId, + Guid[] GuestStayIds, + DateTimeOffset InitiatedAt + ): GroupCheckoutEvent; + + public record GuestCheckoutCompleted( + Guid GroupCheckoutId, + Guid GuestStayId, + DateTimeOffset CompletedAt + ): GroupCheckoutEvent; + + public record GuestCheckoutFailed( + Guid GroupCheckoutId, + Guid GuestStayId, + DateTimeOffset FailedAt + ): GroupCheckoutEvent; + + public record GroupCheckoutCompleted( + Guid GroupCheckoutId, + Guid[] CompletedCheckouts, + DateTimeOffset CompletedAt + ): GroupCheckoutEvent; + + public record GroupCheckoutFailed( + Guid GroupCheckoutId, + Guid[] CompletedCheckouts, + Guid[] FailedCheckouts, + DateTimeOffset FailedAt + ): GroupCheckoutEvent; + + private GroupCheckoutEvent() { } +} diff --git a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GuestStayFacade.cs b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GuestStayFacade.cs index e7a4aa2d..d9cc1e03 100644 --- a/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GuestStayFacade.cs +++ b/Workshops/EventDrivenArchitecture/03-BusinessProcesses/Version2-ImmutableEntities/GuestStayFacade.cs @@ -1,6 +1,7 @@ using BusinessProcesses.Core; using BusinessProcesses.Version2_ImmutableEntities.GroupCheckouts; using BusinessProcesses.Version2_ImmutableEntities.GuestStayAccounts; +using GroupCheckoutEvent = BusinessProcesses.Version1_Aggregates.GroupCheckouts.GroupCheckoutEvent; namespace BusinessProcesses.Version2_ImmutableEntities; @@ -63,9 +64,8 @@ public async ValueTask CheckOutGuest(CheckOutGuest command, CancellationToken ct public async ValueTask InitiateGroupCheckout(InitiateGroupCheckout command, CancellationToken ct = default) { var @event = - GroupCheckout.Initiate(command.GroupCheckoutId, command.ClerkId, command.GuestStayIds, command.Now); + new GroupCheckoutEvent.GroupCheckoutInitiated(command.GroupCheckoutId, command.ClerkId, command.GuestStayIds, command.Now); - await database.Store(command.GroupCheckoutId, GroupCheckout.Initial.Evolve(@event), ct); await eventBus.Publish([@event], ct); } } diff --git a/Workshops/EventDrivenArchitecture/EventDrivenArchitecture.sln b/Workshops/EventDrivenArchitecture/EventDrivenArchitecture.sln index a9ad6858..e65d61bb 100644 --- a/Workshops/EventDrivenArchitecture/EventDrivenArchitecture.sln +++ b/Workshops/EventDrivenArchitecture/EventDrivenArchitecture.sln @@ -20,6 +20,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "01-EventsDefinition", "Solu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "02-EntitiesDefinition", "Solutions\02-EntitiesDefinition\02-EntitiesDefinition.csproj", "{4901FBDE-1248-402F-89F2-8027655B703D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "03-BusinessProcesses", "Solutions\03-BusinessProcesses\03-BusinessProcesses.csproj", "{0C7E9C5A-090E-4D48-A2CC-D60AF87591AA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -62,9 +64,14 @@ Global {4901FBDE-1248-402F-89F2-8027655B703D}.Debug|Any CPU.Build.0 = Debug|Any CPU {4901FBDE-1248-402F-89F2-8027655B703D}.Release|Any CPU.ActiveCfg = Release|Any CPU {4901FBDE-1248-402F-89F2-8027655B703D}.Release|Any CPU.Build.0 = Release|Any CPU + {0C7E9C5A-090E-4D48-A2CC-D60AF87591AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C7E9C5A-090E-4D48-A2CC-D60AF87591AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C7E9C5A-090E-4D48-A2CC-D60AF87591AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C7E9C5A-090E-4D48-A2CC-D60AF87591AA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {7312A099-6FAD-462A-8D94-FB817B531A27} = {96700308-E324-4D7A-854D-9ED17ECEE9B7} {4901FBDE-1248-402F-89F2-8027655B703D} = {96700308-E324-4D7A-854D-9ED17ECEE9B7} + {0C7E9C5A-090E-4D48-A2CC-D60AF87591AA} = {96700308-E324-4D7A-854D-9ED17ECEE9B7} EndGlobalSection EndGlobal diff --git a/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution1-Aggregates/EntityDefinitionTests.cs b/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution1-Aggregates/EntityDefinitionTests.cs index 769c0099..7caff764 100644 --- a/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution1-Aggregates/EntityDefinitionTests.cs +++ b/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution1-Aggregates/EntityDefinitionTests.cs @@ -14,8 +14,6 @@ namespace EntitiesDefinition.Solution1_Aggregates; public class EntityDefinitionTests { - private readonly ITestOutputHelper testOutputHelper; - [Fact] public async Task CheckingInGuest_Succeeds() { @@ -163,6 +161,7 @@ public async Task GroupCheckoutForMultipleGuestStay_ShouldBeInitiated() private readonly GuestStayFacade guestStayFacade; private readonly Faker generate = new(); private readonly DateTimeOffset now = DateTimeOffset.Now; + private readonly ITestOutputHelper testOutputHelper; public EntityDefinitionTests(ITestOutputHelper testOutputHelper) { diff --git a/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution2-ImmutableEntities/EntityDefinitionTests.cs b/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution2-ImmutableEntities/EntityDefinitionTests.cs index 5be4df08..0f5aedb4 100644 --- a/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution2-ImmutableEntities/EntityDefinitionTests.cs +++ b/Workshops/EventDrivenArchitecture/Solutions/02-EntitiesDefinition/Solution2-ImmutableEntities/EntityDefinitionTests.cs @@ -14,8 +14,6 @@ namespace EntitiesDefinition.Solution2_ImmutableEntities; public class EntityDefinitionTests { - private readonly ITestOutputHelper testOutputHelper; - [Fact] public async Task CheckingInGuest_Succeeds() { @@ -163,6 +161,7 @@ public async Task GroupCheckoutForMultipleGuestStay_ShouldBeInitiated() private readonly GuestStayFacade guestStayFacade; private readonly Faker generate = new(); private readonly DateTimeOffset now = DateTimeOffset.Now; + private readonly ITestOutputHelper testOutputHelper; public EntityDefinitionTests(ITestOutputHelper testOutputHelper) { diff --git a/Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/03-BusinessProcesses.csproj b/Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/03-BusinessProcesses.csproj new file mode 100644 index 00000000..500e532a --- /dev/null +++ b/Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/03-BusinessProcesses.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + BusinessProcesses + enable + enable + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers + + + + diff --git a/Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/UnitTest1.cs b/Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/UnitTest1.cs new file mode 100644 index 00000000..585496b3 --- /dev/null +++ b/Workshops/EventDrivenArchitecture/Solutions/03-BusinessProcesses/UnitTest1.cs @@ -0,0 +1,11 @@ +using Xunit; + +namespace BusinessProcesses; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + } +}