From 16c6f627950ffada0a82a347b5fa7a19a498807f Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 6 Mar 2021 16:59:32 +0100 Subject: [PATCH] Null fix for type converter. --- .../DefaultValues/DefaultValueGenerator.cs | 2 +- .../MongoContentRepository_SnapshotStore.cs | 5 + .../MongoDb/TypeConverterStringSerializer.cs | 24 +++- .../TypeConverterStringSerializerTests.cs | 112 ++++++++++++++++++ 4 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 backend/tests/Squidex.Infrastructure.Tests/MongoDb/TypeConverterStringSerializerTests.cs diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueGenerator.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueGenerator.cs index f1d7fdce8..1e9941638 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueGenerator.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueGenerator.cs @@ -64,7 +64,7 @@ namespace Squidex.Domain.Apps.Core.DefaultValues return; } - if (!fieldData.TryGetValue(partitionKey, out var value)) + if (!fieldData.ContainsKey(partitionKey)) { fieldData.AddLocalized(partitionKey, defaultValue); } diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs index 98af06066..9c0372b19 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/MongoContentRepository_SnapshotStore.cs @@ -6,6 +6,7 @@ // ========================================================================== using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Squidex.Domain.Apps.Core.Contents; @@ -120,6 +121,10 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents { content.ReferencedIds = content.Data.GetReferencedIds(schema.SchemaDef); } + else + { + content.ReferencedIds = new HashSet(); + } return content; } diff --git a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/TypeConverterStringSerializer.cs b/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/TypeConverterStringSerializer.cs index 66d327634..4408d2a50 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/TypeConverterStringSerializer.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/MongoDb/TypeConverterStringSerializer.cs @@ -35,14 +35,32 @@ namespace Squidex.Infrastructure.MongoDb public override T Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { - var value = context.Reader.ReadString(); + if (context.Reader.CurrentBsonType == BsonType.Null) + { + context.Reader.ReadNull(); - return (T)typeConverter.ConvertFromInvariantString(value); + return default!; + } + else + { + var value = context.Reader.ReadString(); + + return (T)typeConverter.ConvertFromInvariantString(value); + } } public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, T value) { - context.Writer.WriteString(value!.ToString()); + var text = value?.ToString(); + + if (text != null) + { + context.Writer.WriteString(text); + } + else + { + context.Writer.WriteNull(); + } } } } diff --git a/backend/tests/Squidex.Infrastructure.Tests/MongoDb/TypeConverterStringSerializerTests.cs b/backend/tests/Squidex.Infrastructure.Tests/MongoDb/TypeConverterStringSerializerTests.cs new file mode 100644 index 000000000..2a5e0bfbd --- /dev/null +++ b/backend/tests/Squidex.Infrastructure.Tests/MongoDb/TypeConverterStringSerializerTests.cs @@ -0,0 +1,112 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using MongoDB.Bson; +using MongoDB.Bson.IO; +using MongoDB.Bson.Serialization; +using Xunit; + +namespace Squidex.Infrastructure.MongoDb +{ + public class TypeConverterStringSerializerTests + { + public sealed record ValueHolder + { + public T Value { get; set; } + } + + public TypeConverterStringSerializerTests() + { + TypeConverterStringSerializer.Register(); + TypeConverterStringSerializer.Register(); + } + + [Fact] + public void Should_serialize_struct() + { + var source = new ValueHolder + { + Value = DomainId.NewGuid() + }; + + var deserialized = SerializeAndDeserializeBson(source); + + Assert.Equal(source, deserialized); + } + + [Fact] + public void Should_serialize_nullable_struct() + { + var source = new ValueHolder + { + Value = DomainId.NewGuid() + }; + + var deserialized = SerializeAndDeserializeBson(source); + + Assert.Equal(source, deserialized); + } + + [Fact] + public void Should_serialize_nullable_null_struct() + { + var source = new ValueHolder + { + Value = null + }; + + var deserialized = SerializeAndDeserializeBson(source); + + Assert.Equal(source, deserialized); + } + + [Fact] + public void Should_serialize_class() + { + var source = new ValueHolder + { + Value = RefToken.Client("client") + }; + + var deserialized = SerializeAndDeserializeBson(source); + + Assert.Equal(source, deserialized); + } + + [Fact] + public void Should_serialize_null_class() + { + var source = new ValueHolder + { + Value = null + }; + + var deserialized = SerializeAndDeserializeBson(source); + + Assert.Equal(source, deserialized); + } + + private static T SerializeAndDeserializeBson(T value) + { + var document = new BsonDocument(); + + using (var writer = new BsonDocumentWriter(document)) + { + BsonSerializer.Serialize(writer, value); + + writer.Flush(); + } + + using (var reader = new BsonDocumentReader(document)) + { + var result = BsonSerializer.Deserialize(reader); + + return result; + } + } + } +}