diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedContentEvent.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedContentEvent.cs index 376de10d3..c641bc1e4 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedContentEvent.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedContentEvent.cs @@ -28,6 +28,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents public NamedContentData Data { get; set; } + public NamedContentData? DataOld { get; set; } + public Status Status { get; set; } public override long Partition diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs index 6f436a0be..306b30b81 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs @@ -38,7 +38,10 @@ namespace Squidex.Domain.Apps.Entities.Contents { var result = new EnrichedContentEvent(); - var content = await contentLoader.GetAsync(@event.Headers.AggregateId(), @event.Headers.EventStreamNumber()); + var content = + await contentLoader.GetAsync( + @event.Headers.AggregateId(), + @event.Headers.EventStreamNumber()); SimpleMapper.Map(content, result); @@ -53,24 +56,39 @@ namespace Squidex.Domain.Apps.Entities.Contents result.Type = EnrichedContentEventType.Deleted; break; case ContentChangesPublished _: - case ContentUpdated _: result.Type = EnrichedContentEventType.Updated; break; + case ContentStatusChanged contentStatusChanged: - switch (contentStatusChanged.Change) { - case StatusChange.Published: - result.Type = EnrichedContentEventType.Published; - break; - case StatusChange.Unpublished: - result.Type = EnrichedContentEventType.Unpublished; - break; - default: - result.Type = EnrichedContentEventType.StatusChanged; - break; + switch (contentStatusChanged.Change) + { + case StatusChange.Published: + result.Type = EnrichedContentEventType.Published; + break; + case StatusChange.Unpublished: + result.Type = EnrichedContentEventType.Unpublished; + break; + default: + result.Type = EnrichedContentEventType.StatusChanged; + break; + } + + break; } - break; + case ContentUpdated _: + { + result.Type = EnrichedContentEventType.Updated; + + var previousContent = + await contentLoader.GetAsync( + content.Id, + content.Version - 1); + + result.DataOld = previousContent.Data ?? previousContent.DataDraft; + break; + } } result.Name = $"{content.SchemaId.Name.ToPascalCase()}{result.Type}"; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentChangedTriggerHandlerTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentChangedTriggerHandlerTests.cs index 39d41bbe0..ae8924498 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentChangedTriggerHandlerTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentChangedTriggerHandlerTests.cs @@ -71,6 +71,28 @@ namespace Squidex.Domain.Apps.Entities.Contents Assert.Equal(type, result!.Type); } + [Fact] + public async Task Should_enrich_with_old_data_when_updated() + { + var @event = new ContentUpdated(); + + var envelope = Envelope.Create(@event).SetEventStreamNumber(12); + + var dataNow = new NamedContentData(); + var dataOld = new NamedContentData(); + + A.CallTo(() => contentLoader.GetAsync(@event.ContentId, 12)) + .Returns(new ContentEntity { SchemaId = SchemaMatch, Version = 12, Data = dataNow }); + + A.CallTo(() => contentLoader.GetAsync(@event.ContentId, 11)) + .Returns(new ContentEntity { SchemaId = SchemaMatch, Version = 11, Data = dataOld }); + + var result = await sut.CreateEnrichedEventAsync(envelope) as EnrichedContentEvent; + + Assert.Same(dataNow, result!.Data); + Assert.Same(dataOld, result!.DataOld); + } + [Fact] public void Should_not_trigger_precheck_when_event_type_not_correct() {