From d3c0649a1d8d5b09d47fb968130ad739e1c5783c Mon Sep 17 00:00:00 2001 From: Oskar Dudycz Date: Fri, 17 Feb 2023 21:45:35 +0100 Subject: [PATCH] Added test for SystemTextJson serialization and projections handling with records --- docs/configuration/json.md | 16 +-- .../SystemTextJsonRecordSerializationTests.cs | 118 ++++++++++++++++++ .../Examples/UsingSystemTextJsonSerializer.cs | 16 +-- 3 files changed, 130 insertions(+), 20 deletions(-) create mode 100644 src/EventSourcingTests/Json/SystemTextJsonRecordSerializationTests.cs diff --git a/docs/configuration/json.md b/docs/configuration/json.md index 413dd9d075..86409bace1 100644 --- a/docs/configuration/json.md +++ b/docs/configuration/json.md @@ -345,20 +345,16 @@ var store = DocumentStore.For(opts => opts.Connection("some connection string"); // Opt into System.Text.Json serialization - opts.UseDefaultSerialization(serializerType: SerializerType.SystemTextJson); - - // Optionally configure the serializer directly - opts.Serializer(new SystemTextJsonSerializer - { + opts.UseDefaultSerialization( + serializerType: SerializerType.SystemTextJson, // Optionally override the enum storage - EnumStorage = EnumStorage.AsString, - + enumStorage: EnumStorage.AsString, // Optionally override the member casing - Casing = Casing.CamelCase - }); + casing: Casing.CamelCase + ); }); ``` -snippet source | anchor +snippet source | anchor ## Serializing with Jil diff --git a/src/EventSourcingTests/Json/SystemTextJsonRecordSerializationTests.cs b/src/EventSourcingTests/Json/SystemTextJsonRecordSerializationTests.cs new file mode 100644 index 0000000000..6158f6c0c1 --- /dev/null +++ b/src/EventSourcingTests/Json/SystemTextJsonRecordSerializationTests.cs @@ -0,0 +1,118 @@ +using System; +using System.Threading.Tasks; +using Marten; +using Marten.Events.Aggregation; +using Marten.Events.Projections; +using Marten.Linq; +using Marten.Services; +using Marten.Storage; +using Marten.Testing.Harness; +using Weasel.Core; +using Xunit; +using Shouldly; + +namespace EventSourcingTests.Json; + +public class SystemTextJsonRecordSerializationTests: IntegrationContext +{ + public SystemTextJsonRecordSerializationTests(DefaultStoreFixture fixture): base(fixture) + { + } + + [Fact] + public async Task ForSystemTextJson_ProjectionShouldBeUpdated() + { + StoreOptions(opts => + { + // Optionally configure the serializer directly + opts.Serializer(new SystemTextJsonSerializer + { + // Optionally override the enum storage + EnumStorage = EnumStorage.AsString, + + // Optionally override the member casing + Casing = Casing.CamelCase, + }); + + opts.Policies.AllDocumentsAreMultiTenanted(); + opts.Events.TenancyStyle = TenancyStyle.Conjoined; + opts.Events.MetadataConfig.EnableAll(); + opts.Schema.For().DatabaseSchemaName("resources"); + + opts.Projections.Add(ProjectionLifecycle.Inline); + + opts.AutoCreateSchemaObjects = AutoCreate.All; + + opts.DatabaseSchemaName = "fleetmonitor"; + opts.Events.DatabaseSchemaName = "events"; + }); + + var resourceId = Guid.NewGuid(); + var resourceName = "Test"; + + theSession.Events.Append(resourceId, new ResourceCreatedEvent(resourceName)); + await theSession.SaveChangesAsync(); + + var resource = await theSession.Query().SingleOrDefaultAsync(r => r.Id == resourceId); + + resource.ShouldNotBeNull(); + resource.Id.ShouldBe(resourceId); + resource.Name.ShouldBe(resourceName); + resource.State.ShouldBe(ResourceState.Enabled); + + theSession.Events.Append(resourceId, new ResourceDisabledEvent()); + await theSession.SaveChangesAsync(); + + resource = await theSession.Query().SingleOrDefaultAsync(r => r.Id == resourceId); + + resource.ShouldNotBeNull(); + resource.Id.ShouldBe(resourceId); + resource.Name.ShouldBe(resourceName); + resource.State.ShouldBe(ResourceState.Disabled); + } +} + +public record Event; + +public record ResourceCreatedEvent(string Name): Event; + +public record ResourceRemovedEvent(): Event; + +public record ResourceEnabledEvent(): Event; + +public record ResourceDisabledEvent(): Event; + +public class ResourceProjection: SingleStreamAggregation +{ + public ResourceProjection() + { + DeleteEvent(); + + Lifecycle = ProjectionLifecycle.Inline; + } + + public void Apply(ResourceDisabledEvent e, Resource resource) => resource.State = ResourceState.Disabled; + + public void Apply(ResourceEnabledEvent e, Resource resource) + { + resource.State = ResourceState.Enabled; + } + + public Resource Create(ResourceCreatedEvent create) + { + return new Resource { Name = create.Name, State = ResourceState.Enabled }; + } +} + +public record Resource +{ + public Guid Id { get; set; } + public string Name { get; set; } = null!; + public ResourceState State { get; set; } +} + +public enum ResourceState +{ + Disabled, + Enabled +} diff --git a/src/Marten.Testing/Examples/UsingSystemTextJsonSerializer.cs b/src/Marten.Testing/Examples/UsingSystemTextJsonSerializer.cs index 99a6f9a850..6171e8d62d 100644 --- a/src/Marten.Testing/Examples/UsingSystemTextJsonSerializer.cs +++ b/src/Marten.Testing/Examples/UsingSystemTextJsonSerializer.cs @@ -15,19 +15,15 @@ internal void using_stj() opts.Connection("some connection string"); // Opt into System.Text.Json serialization - opts.UseDefaultSerialization(serializerType: SerializerType.SystemTextJson); - - // Optionally configure the serializer directly - opts.Serializer(new SystemTextJsonSerializer - { + opts.UseDefaultSerialization( + serializerType: SerializerType.SystemTextJson, // Optionally override the enum storage - EnumStorage = EnumStorage.AsString, - + enumStorage: EnumStorage.AsString, // Optionally override the member casing - Casing = Casing.CamelCase - }); + casing: Casing.CamelCase + ); }); #endregion } -} \ No newline at end of file +}