diff --git a/src/EventSourcingTests/Projections/MultiStreamProjections/TestClasses.cs b/src/EventSourcingTests/Projections/MultiStreamProjections/TestClasses.cs index ed0018110f..c0577a9611 100644 --- a/src/EventSourcingTests/Projections/MultiStreamProjections/TestClasses.cs +++ b/src/EventSourcingTests/Projections/MultiStreamProjections/TestClasses.cs @@ -135,4 +135,32 @@ public class UserGroupsAssignment public List Groups { get; set; } = new(); } -#endregion \ No newline at end of file +#endregion + + +// Notification example +public class Notification +{ + public string Id { get; set; } + public string Title { get; set; } + public string Content { get; set; } + + public Notification(string id, string title, string content) + { + Id = id; + Title = title; + Content = content; + } +} + +public class UserNotification +{ + public string Id { get; set; } + public string UserId { get; set; } + public string NotificationId { get; set; } + public bool isOpened { get; set; } +} + +// Notification events +public record SendNotificationToUsers(Notification Notification, List UserIds); +public record UserOpenedNotification(string NotificationId, string UserId); \ No newline at end of file diff --git a/src/EventSourcingTests/Projections/MultiStreamProjections/simple_multi_stream_projection_wih_one_to_many_notification_many_first.cs b/src/EventSourcingTests/Projections/MultiStreamProjections/simple_multi_stream_projection_wih_one_to_many_notification_many_first.cs new file mode 100644 index 0000000000..93173a82cb --- /dev/null +++ b/src/EventSourcingTests/Projections/MultiStreamProjections/simple_multi_stream_projection_wih_one_to_many_notification_many_first.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Marten.Events.Projections; +using Marten.Testing.Harness; +using Shouldly; +using Xunit; + +namespace EventSourcingTests.Projections.MultiStreamProjections.Samples +{ + #region sample_view-projection-simple-with-one-to-many + + public class UserNotificationProjection: MultiStreamProjection + { + public UserNotificationProjection() + { + Identity(x => x.UserId); + Identities(x => x.UserIds); + } + + public void Apply(UserOpenedNotification @event, UserNotification view) + { + view.isOpened = true; + } + + public void Apply(SendNotificationToUsers @event, UserNotification view) + { + Assert.NotNull(view.Id); //! Fails + view.Id = $"{view.Id}:{@event.Notification.Id}"; // I want the userNotification id to be "userId:notificationId", but since the matched userId is not available here, I can't do that. + view.NotificationId = @event.Notification.Id; + } + } + + #endregion +} + +namespace EventSourcingTests.Projections.MultiStreamProjections +{ + + + public class simple_multi_stream_projection_with_one_to_many_notification_many_first: OneOffConfigurationsContext + { + [Fact] + public async Task multi_stream_projections_with_only_group_assign_should_work() + { + // Create a notification and send it to John and Anna + var notification = new Notification(Guid.NewGuid().ToString(), "Notification title", "Example content"); + + var johnUserId = Guid.NewGuid().ToString(); // UserId of John + var annaUserId = Guid.NewGuid().ToString(); // UserId of Anna + + var sendNotificationToUsers = new SendNotificationToUsers(notification, new List { johnUserId, annaUserId }); + theSession.Events.Append(sendNotificationToUsers.Notification.Id, sendNotificationToUsers); + + await theSession.SaveChangesAsync(); //! FAILS because of inner assert + + // Open the notification for John + var userOpenedNotification = new UserOpenedNotification(notification.Id, johnUserId); + theSession.Events.Append(userOpenedNotification.UserId, userOpenedNotification); + + await theSession.SaveChangesAsync(); + + // Check if the notification is opened for John + var userNotification = await theSession.LoadAsync($"{johnUserId}:{notification.Id}"); + userNotification.isOpened.ShouldBeTrue(); + + // Check if the notification is not opened for Anna + userNotification = await theSession.LoadAsync($"{annaUserId}:{notification.Id}"); + userNotification.isOpened.ShouldBeFalse(); + } + + public simple_multi_stream_projection_with_one_to_many_notification_many_first() + { + StoreOptions(_ => + { + _.Events.StreamIdentity = Marten.Events.StreamIdentity.AsString; + _.Projections.Add(ProjectionLifecycle.Inline); + }); + } + } +}