Browse Source

Event migration.

pull/111/head
Sebastian Stehle 8 years ago
parent
commit
10644150e8
  1. 13
      src/Squidex.Domain.Apps.Core/Schemas/FieldRegistry.cs
  2. 10
      src/Squidex.Domain.Apps.Events/Contents/Old/ContentArchived.cs
  3. 10
      src/Squidex.Domain.Apps.Events/Contents/Old/ContentPublished.cs
  4. 10
      src/Squidex.Domain.Apps.Events/Contents/Old/ContentRestored.cs
  5. 10
      src/Squidex.Domain.Apps.Events/Contents/Old/ContentUnpublished.cs
  6. 7
      src/Squidex.Domain.Apps.Events/Schemas/Old/WebhookAdded.cs
  7. 7
      src/Squidex.Domain.Apps.Events/Schemas/Old/WebhookDeleted.cs
  8. 47
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs
  9. 11
      src/Squidex.Domain.Apps.Read/Contents/ContentHistoryEventsCreator.cs
  10. 10
      src/Squidex.Domain.Apps.Write/Schemas/SchemaEvents.cs
  11. 22
      src/Squidex.Infrastructure/CQRS/Events/EventDataFormatter.cs
  12. 15
      src/Squidex.Infrastructure/CQRS/Events/IMigratedEvent.cs
  13. 14
      src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs
  14. 70
      tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentEventTests.cs
  15. 12
      tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentVersionLoaderTests.cs
  16. 36
      tests/Squidex.Domain.Apps.Write.Tests/Schemas/SchemaEventTests.cs
  17. 18
      tests/Squidex.Domain.Apps.Write.Tests/TestHelpers/AssertHelper.cs
  18. 16
      tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs
  19. 49
      tests/Squidex.Infrastructure.Tests/CQRS/Events/EventDataFormatterTests.cs
  20. 8
      tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs

13
src/Squidex.Domain.Apps.Core/Schemas/FieldRegistry.cs

@ -59,10 +59,6 @@ namespace Squidex.Domain.Apps.Core.Schemas
(id, name, partitioning, properties) =>
new StringField(id, name, partitioning, (StringFieldProperties)properties));
Add<DateTimeFieldProperties>(
(id, name, partitioning, properties) =>
new DateTimeField(id, name, partitioning, (DateTimeFieldProperties)properties));
Add<JsonFieldProperties>(
(id, name, partitioning, properties) =>
new JsonField(id, name, partitioning, (JsonFieldProperties)properties));
@ -71,15 +67,20 @@ namespace Squidex.Domain.Apps.Core.Schemas
(id, name, partitioning, properties) =>
new AssetsField(id, name, partitioning, (AssetsFieldProperties)properties));
Add<GeolocationFieldProperties>(
(id, name, partitioning, properties) =>
new GeolocationField(id, name, partitioning, (GeolocationFieldProperties)properties));
Add<ReferencesFieldProperties>(
(id, name, partitioning, properties) =>
new ReferencesField(id, name, partitioning, (ReferencesFieldProperties)properties));
Add<GeolocationFieldProperties>(
Add<DateTimeFieldProperties>(
(id, name, partitioning, properties) =>
new GeolocationField(id, name, partitioning, (GeolocationFieldProperties)properties));
new DateTimeField(id, name, partitioning, (DateTimeFieldProperties)properties));
typeNameRegistry.MapObsolete(typeof(ReferencesFieldProperties), "DateTime");
typeNameRegistry.MapObsolete(typeof(DateTimeFieldProperties), "References");
}

10
src/Squidex.Domain.Apps.Events/Contents/Old/ContentArchived.cs

@ -7,13 +7,19 @@
// ==========================================================================
using System;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Events.Contents
namespace Squidex.Domain.Apps.Events.Contents.Old
{
[EventType(nameof(ContentArchived))]
[Obsolete]
public sealed class ContentArchived : ContentEvent
public sealed class ContentArchived : ContentEvent, IMigratedEvent
{
public IEvent Migrate()
{
return SimpleMapper.Map(this, new ContentStatusChanged { Status = Status.Archived });
}
}
}

10
src/Squidex.Domain.Apps.Events/Contents/Old/ContentPublished.cs

@ -7,13 +7,19 @@
// ==========================================================================
using System;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Events.Contents
namespace Squidex.Domain.Apps.Events.Contents.Old
{
[EventType(nameof(ContentPublished))]
[Obsolete]
public sealed class ContentPublished : ContentEvent
public sealed class ContentPublished : ContentEvent, IMigratedEvent
{
public IEvent Migrate()
{
return SimpleMapper.Map(this, new ContentStatusChanged { Status = Status.Published });
}
}
}

10
src/Squidex.Domain.Apps.Events/Contents/Old/ContentRestored.cs

@ -7,13 +7,19 @@
// ==========================================================================
using System;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Events.Contents
namespace Squidex.Domain.Apps.Events.Contents.Old
{
[EventType(nameof(ContentRestored))]
[Obsolete]
public sealed class ContentRestored : ContentEvent
public sealed class ContentRestored : ContentEvent, IMigratedEvent
{
public IEvent Migrate()
{
return SimpleMapper.Map(this, new ContentStatusChanged { Status = Status.Draft });
}
}
}

10
src/Squidex.Domain.Apps.Events/Contents/Old/ContentUnpublished.cs

@ -7,13 +7,19 @@
// ==========================================================================
using System;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Events.Contents
namespace Squidex.Domain.Apps.Events.Contents.Old
{
[EventType(nameof(ContentUnpublished))]
[Obsolete]
public sealed class ContentUnpublished : ContentEvent
public sealed class ContentUnpublished : ContentEvent, IMigratedEvent
{
public IEvent Migrate()
{
return SimpleMapper.Map(this, new ContentStatusChanged { Status = Status.Draft });
}
}
}

7
src/Squidex.Domain.Apps.Events/Schemas/Old/WebhookAdded.cs

@ -13,12 +13,17 @@ namespace Squidex.Domain.Apps.Events.Schemas.Old
{
[EventType(nameof(WebhookAdded))]
[Obsolete]
public sealed class WebhookAdded : SchemaEvent
public sealed class WebhookAdded : SchemaEvent, IMigratedEvent
{
public Guid Id { get; set; }
public Uri Url { get; set; }
public string SharedSecret { get; set; }
public IEvent Migrate()
{
return new NoopEvent();
}
}
}

7
src/Squidex.Domain.Apps.Events/Schemas/Old/WebhookDeleted.cs

@ -13,8 +13,13 @@ namespace Squidex.Domain.Apps.Events.Schemas.Old
{
[EventType(nameof(WebhookDeleted))]
[Obsolete]
public sealed class WebhookDeleted : SchemaEvent
public sealed class WebhookDeleted : SchemaEvent, IMigratedEvent
{
public Guid Id { get; set; }
public IEvent Migrate()
{
return new NoopEvent();
}
}
}

47
src/Squidex.Domain.Apps.Read.MongoDb/Contents/MongoContentRepository_EventHandling.cs

@ -9,7 +9,6 @@
using System;
using System.Threading.Tasks;
using MongoDB.Driver;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Events.Apps;
using Squidex.Domain.Apps.Events.Assets;
using Squidex.Domain.Apps.Events.Contents;
@ -18,8 +17,6 @@ using Squidex.Infrastructure.CQRS.Events;
using Squidex.Infrastructure.Dispatching;
using Squidex.Infrastructure.Reflection;
#pragma warning disable CS0612 // Type or member is obsolete
namespace Squidex.Domain.Apps.Read.MongoDb.Contents
{
public partial class MongoContentRepository
@ -95,39 +92,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
});
}
protected Task On(ContentPublished @event, EnvelopeHeaders headers)
{
return ForAppIdAsync(@event.AppId.Id, collection =>
{
return collection.UpdateAsync(@event, headers, x =>
{
x.Status = Status.Published;
});
});
}
protected Task On(ContentUnpublished @event, EnvelopeHeaders headers)
{
return ForAppIdAsync(@event.AppId.Id, collection =>
{
return collection.UpdateAsync(@event, headers, x =>
{
x.Status = Status.Draft;
});
});
}
protected Task On(ContentArchived @event, EnvelopeHeaders headers)
{
return ForAppIdAsync(@event.AppId.Id, collection =>
{
return collection.UpdateAsync(@event, headers, x =>
{
x.Status = Status.Archived;
});
});
}
protected Task On(ContentStatusChanged @event, EnvelopeHeaders headers)
{
return ForAppIdAsync(@event.AppId.Id, collection =>
@ -139,17 +103,6 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents
});
}
protected Task On(ContentRestored @event, EnvelopeHeaders headers)
{
return ForAppIdAsync(@event.AppId.Id, collection =>
{
return collection.UpdateAsync(@event, headers, x =>
{
x.Status = Status.Draft;
});
});
}
protected Task On(AssetDeleted @event, EnvelopeHeaders headers)
{
return ForAppIdAsync(@event.AppId.Id, collection =>

11
src/Squidex.Domain.Apps.Read/Contents/ContentHistoryEventsCreator.cs

@ -12,8 +12,6 @@ using Squidex.Domain.Apps.Read.History;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Events;
#pragma warning disable CS0612 // Type or member is obsolete
namespace Squidex.Domain.Apps.Read.Contents
{
public sealed class ContentHistoryEventsCreator : HistoryEventsCreatorBase
@ -30,15 +28,6 @@ namespace Squidex.Domain.Apps.Read.Contents
AddEventMessage<ContentDeleted>(
"deleted content item.");
AddEventMessage<ContentRestored>(
"restored content item.");
AddEventMessage<ContentPublished>(
"published content item.");
AddEventMessage<ContentUnpublished>(
"unpublished content item.");
AddEventMessage<ContentStatusChanged>(
"change status of content item to {[Status]}.");
}

10
src/Squidex.Domain.Apps.Write/Schemas/SchemaEvents.cs

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Squidex.Domain.Apps.Write.Schemas
{
public class SchemaEvents
{
}
}

22
src/Squidex.Infrastructure/CQRS/Events/EventDataFormatter.cs

@ -25,21 +25,33 @@ namespace Squidex.Infrastructure.CQRS.Events
this.serializerSettings = serializerSettings ?? new JsonSerializerSettings();
}
public virtual Envelope<IEvent> Parse(EventData eventData)
public virtual Envelope<IEvent> Parse(EventData eventData, bool migrate = true)
{
var headers = ReadJson<PropertiesBag>(eventData.Metadata);
var eventType = typeNameRegistry.GetType(eventData.Type);
var eventContent = ReadJson<IEvent>(eventData.Payload, eventType);
var eventPayload = ReadJson<IEvent>(eventData.Payload, eventType);
var envelope = new Envelope<IEvent>(eventContent, headers);
if (migrate && eventPayload is IMigratedEvent migratedEvent)
{
eventPayload = migratedEvent.Migrate();
}
var envelope = new Envelope<IEvent>(eventPayload, headers);
return envelope;
}
public virtual EventData ToEventData(Envelope<IEvent> envelope, Guid commitId)
public virtual EventData ToEventData(Envelope<IEvent> envelope, Guid commitId, bool migrate = true)
{
var eventType = typeNameRegistry.GetName(envelope.Payload.GetType());
var eventPayload = envelope.Payload;
if (migrate && eventPayload is IMigratedEvent migratedEvent)
{
eventPayload = migratedEvent.Migrate();
}
var eventType = typeNameRegistry.GetName(eventPayload.GetType());
envelope.SetCommitId(commitId);

15
src/Squidex.Infrastructure/CQRS/Events/IMigratedEvent.cs

@ -0,0 +1,15 @@
// ==========================================================================
// IMigratedEvent.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Infrastructure.CQRS.Events
{
public interface IMigratedEvent
{
IEvent Migrate();
}
}

14
src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs

@ -0,0 +1,14 @@
// ==========================================================================
// NoopEvent.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
namespace Squidex.Infrastructure.CQRS.Events
{
public sealed class NoopEvent : IEvent
{
}
}

70
tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentEventTests.cs

@ -0,0 +1,70 @@
// ==========================================================================
// SchemaEventTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Events.Contents;
using Squidex.Domain.Apps.Events.Contents.Old;
using Squidex.Domain.Apps.Write.TestHelpers;
using Squidex.Infrastructure;
using Xunit;
#pragma warning disable CS0612 // Type or member is obsolete
namespace Squidex.Domain.Apps.Write.Contents
{
public class ContentEventTests
{
private readonly RefToken actor = new RefToken("User", Guid.NewGuid().ToString());
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
private readonly NamedId<Guid> schemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema");
private readonly Guid contentId = Guid.NewGuid();
[Fact]
public void Should_migrate_content_published_to_content_status_changed()
{
var source = CreateEvent(new ContentPublished());
source.Migrate().ShouldBeSameEvent(CreateEvent(new ContentStatusChanged { Status = Status.Published }));
}
[Fact]
public void Should_migrate_content_unpublished_to_content_status_changed()
{
var source = CreateEvent(new ContentUnpublished());
source.Migrate().ShouldBeSameEvent(CreateEvent(new ContentStatusChanged { Status = Status.Draft }));
}
[Fact]
public void Should_migrate_content_restored_to_content_status_changed()
{
var source = CreateEvent(new ContentRestored());
source.Migrate().ShouldBeSameEvent(CreateEvent(new ContentStatusChanged { Status = Status.Draft }));
}
[Fact]
public void Should_migrate_content_archived_to_content_status_changed()
{
var source = CreateEvent(new ContentArchived());
source.Migrate().ShouldBeSameEvent(CreateEvent(new ContentStatusChanged { Status = Status.Archived }));
}
private T CreateEvent<T>(T contentEvent) where T : ContentEvent
{
contentEvent.Actor = actor;
contentEvent.AppId = appId;
contentEvent.SchemaId = schemaId;
contentEvent.ContentId = contentId;
return contentEvent;
}
}
}

12
tests/Squidex.Domain.Apps.Write.Tests/Contents/ContentVersionLoaderTests.cs

@ -76,7 +76,7 @@ namespace Squidex.Domain.Apps.Write.Contents
A.CallTo(() => eventStore.GetEventsAsync(streamName))
.Returns(events);
A.CallTo(() => formatter.Parse(eventData1))
A.CallTo(() => formatter.Parse(eventData1, true))
.Returns(new Envelope<IEvent>(event1));
await Assert.ThrowsAsync<DomainObjectNotFoundException>(() => sut.LoadAsync(appId, id, 0));
@ -100,9 +100,9 @@ namespace Squidex.Domain.Apps.Write.Contents
A.CallTo(() => eventStore.GetEventsAsync(streamName))
.Returns(events);
A.CallTo(() => formatter.Parse(eventData1))
A.CallTo(() => formatter.Parse(eventData1, true))
.Returns(new Envelope<IEvent>(event1));
A.CallTo(() => formatter.Parse(eventData2))
A.CallTo(() => formatter.Parse(eventData2, true))
.Returns(new Envelope<IEvent>(event2));
var data = await sut.LoadAsync(appId, id, 3);
@ -131,11 +131,11 @@ namespace Squidex.Domain.Apps.Write.Contents
A.CallTo(() => eventStore.GetEventsAsync(streamName))
.Returns(events);
A.CallTo(() => formatter.Parse(eventData1))
A.CallTo(() => formatter.Parse(eventData1, true))
.Returns(new Envelope<IEvent>(event1));
A.CallTo(() => formatter.Parse(eventData2))
A.CallTo(() => formatter.Parse(eventData2, true))
.Returns(new Envelope<IEvent>(event2));
A.CallTo(() => formatter.Parse(eventData3))
A.CallTo(() => formatter.Parse(eventData3, true))
.Returns(new Envelope<IEvent>(event3));
var data = await sut.LoadAsync(appId, id, 1);

36
tests/Squidex.Domain.Apps.Write.Tests/Schemas/SchemaEventTests.cs

@ -0,0 +1,36 @@
// ==========================================================================
// SchemaEventTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using Squidex.Domain.Apps.Events.Schemas.Old;
using Squidex.Domain.Apps.Write.TestHelpers;
using Squidex.Infrastructure.CQRS.Events;
using Xunit;
#pragma warning disable CS0612 // Type or member is obsolete
namespace Squidex.Domain.Apps.Write.Schemas
{
public class SchemaEventTests
{
[Fact]
public void Should_migrate_webhook_added_event_to_noop()
{
var source = new WebhookAdded();
source.Migrate().ShouldBeSameEventType(new NoopEvent());
}
[Fact]
public void Should_migrate_webhook_deleted_event_to_noop()
{
var source = new WebhookDeleted();
source.Migrate().ShouldBeSameEventType(new NoopEvent());
}
}
}

18
tests/Squidex.Domain.Apps.Write.Tests/TestHelpers/AssertHelper.cs

@ -23,9 +23,23 @@ namespace Squidex.Domain.Apps.Write.TestHelpers
for (var i = 0; i < source.Length; i++)
{
source[i].Should().BeOfType(others[i].GetType());
((object)source[i]).ShouldBeEquivalentTo(others[i], o => o.IncludingAllDeclaredProperties());
var lhs = source[i];
var rhs = others[i];
lhs.ShouldBeSameEvent(rhs);
}
}
public static void ShouldBeSameEvent(this IEvent lhs, IEvent rhs)
{
lhs.Should().BeOfType(rhs.GetType());
((object)lhs).ShouldBeEquivalentTo(rhs, o => o.IncludingAllDeclaredProperties());
}
public static void ShouldBeSameEventType(this IEvent lhs, IEvent rhs)
{
lhs.Should().BeOfType(rhs.GetType());
}
}
}

16
tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs

@ -96,9 +96,9 @@ namespace Squidex.Infrastructure.CQRS.Commands
A.CallTo(() => eventStore.GetEventsAsync(streamName))
.Returns(events);
A.CallTo(() => formatter.Parse(eventData1))
A.CallTo(() => formatter.Parse(eventData1, true))
.Returns(new Envelope<IEvent>(event1));
A.CallTo(() => formatter.Parse(eventData2))
A.CallTo(() => formatter.Parse(eventData2, true))
.Returns(new Envelope<IEvent>(event2));
await sut.LoadAsync(domainObject);
@ -124,9 +124,9 @@ namespace Squidex.Infrastructure.CQRS.Commands
A.CallTo(() => eventStore.GetEventsAsync(streamName))
.Returns(events);
A.CallTo(() => formatter.Parse(eventData1))
A.CallTo(() => formatter.Parse(eventData1, true))
.Returns(new Envelope<IEvent>(event1));
A.CallTo(() => formatter.Parse(eventData2))
A.CallTo(() => formatter.Parse(eventData2, true))
.Returns(new Envelope<IEvent>(event2));
await Assert.ThrowsAsync<DomainObjectVersionException>(() => sut.LoadAsync(domainObject, 200));
@ -143,9 +143,9 @@ namespace Squidex.Infrastructure.CQRS.Commands
var eventData1 = new EventData();
var eventData2 = new EventData();
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event1), commitId))
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event1), commitId, true))
.Returns(eventData1);
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event2), commitId))
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event2), commitId, true))
.Returns(eventData2);
A.CallTo(() => eventStore.AppendEventsAsync(commitId, streamName, 123, A<ICollection<EventData>>.That.Matches(e => e.Count == 2)))
@ -170,9 +170,9 @@ namespace Squidex.Infrastructure.CQRS.Commands
var eventData1 = new EventData();
var eventData2 = new EventData();
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event1), commitId))
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event1), commitId, true))
.Returns(eventData1);
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event2), commitId))
A.CallTo(() => formatter.ToEventData(A<Envelope<IEvent>>.That.Matches(e => e.Payload == event2), commitId, true))
.Returns(eventData2);
A.CallTo(() => eventStore.AppendEventsAsync(commitId, streamName, 123, A<ICollection<EventData>>.That.Matches(e => e.Count == 2)))

49
tests/Squidex.Infrastructure.Tests/CQRS/Events/EventDataFormatterTests.cs

@ -22,20 +22,35 @@ namespace Squidex.Infrastructure.CQRS.Events
public string MyProperty { get; set; }
}
public sealed class MyOldEvent : IEvent, IMigratedEvent
{
public string MyProperty { get; set; }
public IEvent Migrate()
{
return new MyEvent { MyProperty = MyProperty };
}
}
private readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
private readonly TypeNameRegistry typeNameRegistry = new TypeNameRegistry();
private readonly EventDataFormatter sut;
public EventDataFormatterTests()
{
serializerSettings.Converters.Add(new PropertiesBagConverter());
typeNameRegistry.Map(typeof(MyEvent), "Event");
typeNameRegistry.Map(typeof(MyOldEvent), "OldEvent");
sut = new EventDataFormatter(typeNameRegistry, serializerSettings);
}
[Fact]
public void Should_serialize_and_deserialize_envelope()
{
var commitId = Guid.NewGuid();
var inputEvent = new Envelope<MyEvent>(new MyEvent { MyProperty = "My-Property" });
inputEvent.SetAggregateId(Guid.NewGuid());
@ -45,18 +60,44 @@ namespace Squidex.Infrastructure.CQRS.Events
inputEvent.SetEventStreamNumber(1);
inputEvent.SetTimestamp(SystemClock.Instance.GetCurrentInstant());
var sut = new EventDataFormatter(typeNameRegistry, serializerSettings);
var eventData = sut.ToEventData(inputEvent.To<IEvent>(), commitId);
var outputEvent = sut.Parse(eventData).To<MyEvent>();
CompareHeaders(outputEvent.Headers, inputEvent.Headers);
AssertHeaders(inputEvent.Headers, outputEvent.Headers);
AssertPayload(inputEvent, outputEvent);
}
[Fact]
public void Should_migrate_event_serializing()
{
var inputEvent = new Envelope<MyOldEvent>(new MyOldEvent { MyProperty = "My-Property" });
var eventData = sut.ToEventData(inputEvent.To<IEvent>(), Guid.NewGuid());
var outputEvent = sut.Parse(eventData).To<MyEvent>();
Assert.Equal(inputEvent.Payload.MyProperty, outputEvent.Payload.MyProperty);
}
[Fact]
public void Should_migrate_event_deserializing()
{
var inputEvent = new Envelope<MyOldEvent>(new MyOldEvent { MyProperty = "My-Property" });
var eventData = sut.ToEventData(inputEvent.To<IEvent>(), Guid.NewGuid(), false);
var outputEvent = sut.Parse(eventData).To<MyEvent>();
Assert.Equal(inputEvent.Payload.MyProperty, outputEvent.Payload.MyProperty);
}
private static void AssertPayload(Envelope<MyEvent> inputEvent, Envelope<MyEvent> outputEvent)
{
Assert.Equal(inputEvent.Payload.MyProperty, outputEvent.Payload.MyProperty);
}
private static void CompareHeaders(PropertiesBag lhs, PropertiesBag rhs)
private static void AssertHeaders(PropertiesBag lhs, PropertiesBag rhs)
{
foreach (var key in lhs.PropertyNames.Concat(rhs.PropertyNames).Distinct())
{

8
tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs

@ -127,9 +127,9 @@ namespace Squidex.Infrastructure.CQRS.Events
A.CallTo(() => eventConsumer.Name).Returns(consumerName);
A.CallTo(() => eventConsumerInfoRepository.FindAsync(consumerName)).Returns(consumerInfo);
A.CallTo(() => formatter.Parse(eventData1)).Returns(envelope1);
A.CallTo(() => formatter.Parse(eventData2)).Returns(envelope2);
A.CallTo(() => formatter.Parse(eventData3)).Returns(envelope3);
A.CallTo(() => formatter.Parse(eventData1, true)).Returns(envelope1);
A.CallTo(() => formatter.Parse(eventData2, true)).Returns(envelope2);
A.CallTo(() => formatter.Parse(eventData3, true)).Returns(envelope3);
sut = new EventReceiver(formatter, eventStore, eventConsumerInfoRepository, log);
}
@ -183,7 +183,7 @@ namespace Squidex.Infrastructure.CQRS.Events
{
consumerInfo.Position = "2";
A.CallTo(() => formatter.Parse(eventData2)).Throws(new InvalidOperationException());
A.CallTo(() => formatter.Parse(eventData2, true)).Throws(new InvalidOperationException());
sut.Subscribe(eventConsumer);
sut.Refresh();

Loading…
Cancel
Save