diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppClientsConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppClientsConverter.cs index bde833f22..ecaac12c2 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppClientsConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppClientsConverter.cs @@ -9,7 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Domain.Apps.Core.Apps.Json { diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppContributorsConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppContributorsConverter.cs index 997bcfe11..e72ecc0b0 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppContributorsConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppContributorsConverter.cs @@ -9,7 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Domain.Apps.Core.Apps.Json { diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs index 34a23812e..465029571 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs @@ -9,7 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Domain.Apps.Core.Apps.Json { diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/LanguagesConfigConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/LanguagesConfigConverter.cs index ed396589d..a229d5593 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/LanguagesConfigConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/LanguagesConfigConverter.cs @@ -7,7 +7,7 @@ using System; using Newtonsoft.Json; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Domain.Apps.Core.Apps.Json { diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs index 043c2b4af..51b23d192 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs @@ -6,7 +6,7 @@ // ========================================================================== using Newtonsoft.Json; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; using Squidex.Infrastructure.Security; using System; using System.Collections.Generic; diff --git a/src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs b/src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs index 2ebc1d054..fcfe4813e 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs @@ -9,7 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using Squidex.Infrastructure; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.Contents { @@ -61,7 +61,7 @@ namespace Squidex.Domain.Apps.Core.Contents { var resultValue = new ContentFieldData(); - foreach (var partitionValue in fieldValue.Value.Where(x => !x.Value.IsNull())) + foreach (var partitionValue in fieldValue.Value.Where(x => x.Value.Type != JsonValueType.Null)) { resultValue[partitionValue.Key] = partitionValue.Value; } diff --git a/src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs b/src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs index 9f4cf3a75..41afa54f3 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs @@ -7,21 +7,24 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.Contents { - public sealed class ContentFieldData : Dictionary, IEquatable + public sealed class ContentFieldData : Dictionary, IEquatable { - private static readonly JTokenEqualityComparer JTokenEqualityComparer = new JTokenEqualityComparer(); - public ContentFieldData() : base(StringComparer.OrdinalIgnoreCase) { } - public ContentFieldData AddValue(string key, JToken value) + public ContentFieldData AddValue(string key, object value) + { + return AddJsonValue(key, JsonValue.Create(value)); + } + + public ContentFieldData AddJsonValue(string key, IJsonValue value) { Guard.NotNullOrEmpty(key, nameof(key)); @@ -30,11 +33,6 @@ namespace Squidex.Domain.Apps.Core.Contents return this; } - public ContentFieldData AddValue(JToken value) - { - return AddValue(InvariantPartitioning.Instance.Master.Key, value); - } - public override bool Equals(object obj) { return Equals(obj as ContentFieldData); @@ -42,12 +40,12 @@ namespace Squidex.Domain.Apps.Core.Contents public bool Equals(ContentFieldData other) { - return other != null && (ReferenceEquals(this, other) || this.EqualsDictionary(other, EqualityComparer.Default, JTokenEqualityComparer)); + return other != null && (ReferenceEquals(this, other) || this.EqualsDictionary(other)); } public override int GetHashCode() { - return this.DictionaryHashCode(EqualityComparer.Default, JTokenEqualityComparer); + return this.DictionaryHashCode(); } } } \ No newline at end of file diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Json/RuleConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Json/RuleConverter.cs index e9b8b77e4..7ffd04107 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/Json/RuleConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Json/RuleConverter.cs @@ -7,7 +7,7 @@ using System; using Newtonsoft.Json; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Domain.Apps.Core.Rules.Json { diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs index c83cf9626..811cd51f5 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs @@ -6,7 +6,6 @@ // ========================================================================== using System; -using Newtonsoft.Json.Linq; using NodaTime; namespace Squidex.Domain.Apps.Core.Rules @@ -23,12 +22,12 @@ namespace Squidex.Domain.Apps.Core.Rules public string ActionName { get; set; } + public string ActionData { get; set; } + public string Description { get; set; } public Instant Created { get; set; } public Instant Expires { get; set; } - - public JObject ActionData { get; set; } } } diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaConverter.cs index 3ca34038b..8cd129428 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaConverter.cs @@ -7,8 +7,7 @@ using System; using Newtonsoft.Json; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Domain.Apps.Core.Schemas.Json { diff --git a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs index de8e250a7..8a9ba47cc 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs @@ -7,13 +7,12 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Text; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ConvertContent { @@ -41,11 +40,11 @@ namespace Squidex.Domain.Apps.Core.ConvertContent return result; } - private static void AppendText(JToken value, StringBuilder stringBuilder, int maxFieldLength, string separator, bool allowObjects) + private static void AppendText(IJsonValue value, StringBuilder stringBuilder, int maxFieldLength, string separator, bool allowObjects) { - if (value?.Type == JTokenType.String) + if (value.Type == JsonValueType.String) { - var text = ((JValue)value).ToString(CultureInfo.InvariantCulture); + var text = value.ToString(); if (text.Length <= maxFieldLength) { @@ -57,18 +56,18 @@ namespace Squidex.Domain.Apps.Core.ConvertContent stringBuilder.Append(text); } } - else if (value?.Type == JTokenType.Array) + else if (value is JsonArray array) { - foreach (var item in value) + foreach (var item in array) { AppendText(item, stringBuilder, maxFieldLength, separator, true); } } - else if (value?.Type == JTokenType.Object && allowObjects) + else if (value is JsonObject obj && allowObjects) { - foreach (JProperty property in value) + foreach (var item in obj.Values) { - AppendText(property.Value, stringBuilder, maxFieldLength, separator, true); + AppendText(item, stringBuilder, maxFieldLength, separator, true); } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverterFlat.cs b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverterFlat.cs index 5bff83392..8a6e82895 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverterFlat.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverterFlat.cs @@ -7,10 +7,10 @@ using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ConvertContent { @@ -30,7 +30,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent languagePreferences = languagePreferences.Union(languageConfig.LanguageFallbacks).ToList(); } - var result = new Dictionary(); + var result = new Dictionary(); foreach (var fieldValue in content) { @@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent foreach (var language in languagePreferences) { - if (fieldData.TryGetValue(language, out var value) && value != null) + if (fieldData.TryGetValue(language, out var value) && value.Type != JsonValueType.Null) { result[fieldValue.Key] = value; diff --git a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs index 3ccbaf753..1052b8941 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs @@ -8,13 +8,12 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Infrastructure; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; #pragma warning disable RECS0002 // Convert anonymous method to method group @@ -44,7 +43,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent { foreach (var value in data.Values) { - if (value.IsNull()) + if (value.Type == JsonValueType.Null) { continue; } @@ -78,13 +77,13 @@ namespace Squidex.Domain.Apps.Core.ConvertContent { foreach (var partition in data) { - if (partition.Value is JArray array) + if (partition.Value is JsonArray array) { for (var i = 0; i < array.Count; i++) { var id = array[i].ToString(); - array[i] = urlGenerator.GenerateUrl(id); + array[i] = JsonValue.Create(urlGenerator.GenerateUrl(id)); } } } @@ -273,16 +272,16 @@ namespace Squidex.Domain.Apps.Core.ConvertContent foreach (var partition in data) { - if (!(partition.Value is JArray jArray)) + if (!(partition.Value is JsonArray array)) { continue; } - var newArray = new JArray(); + var newArray = JsonValue.Array(); - foreach (var item in jArray.OfType()) + foreach (var item in array.OfType()) { - var newItem = new JObject(); + var newItem = JsonValue.Object(); foreach (var kvp in item) { diff --git a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/Value.cs b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/Value.cs index 2229afdfa..a83740e60 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/Value.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/Value.cs @@ -5,12 +5,12 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Newtonsoft.Json.Linq; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ConvertContent { public static class Value { - public static readonly JToken Unset = JValue.CreateUndefined(); + public static readonly IJsonValue Unset = JsonValue.Create("UNSET"); } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ValueConverters.cs b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ValueConverters.cs index 343077c38..2db70c052 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ValueConverters.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ValueConverters.cs @@ -7,41 +7,41 @@ using System; using System.Text; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ConvertContent { - public delegate JToken ValueConverter(JToken value, IField field); + public delegate IJsonValue ValueConverter(IJsonValue value, IField field); public static class ValueConverters { - public static ValueConverter DecodeJson() + public static ValueConverter DecodeJson(IJsonSerializer jsonSerializer) { return (value, field) => { - if (!value.IsNull() && field is IField) + if (field is IField && value is JsonScalar s) { - var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(value.ToString())); + var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(s.Value)); - return JToken.Parse(decoded); + return jsonSerializer.Deserialize(decoded); } return value; }; } - public static ValueConverter EncodeJson() + public static ValueConverter EncodeJson(IJsonSerializer jsonSerializer) { return (value, field) => { - if (!value.IsNull() && field is IField) + if (value.Type != JsonValueType.Null && field is IField) { - var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(value.ToString())); + var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(jsonSerializer.Serialize(value))); - return encoded; + return JsonValue.Create(encoded); } return value; @@ -57,7 +57,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent { return (value, field) => { - if (value.IsNull()) + if (value.Type == JsonValueType.Null) { return value; } diff --git a/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/ContentEnricher.cs b/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/ContentEnricher.cs index 2460a2c00..22f88bb85 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/ContentEnricher.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/ContentEnricher.cs @@ -5,12 +5,11 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.EnrichContent { @@ -56,7 +55,7 @@ namespace Squidex.Domain.Apps.Core.EnrichContent var defaultValue = DefaultValueFactory.CreateDefaultValue(field, SystemClock.Instance.GetCurrentInstant()); - if (field.RawProperties.IsRequired || defaultValue.IsNull()) + if (field.RawProperties.IsRequired || defaultValue.Type == JsonValueType.Null) { return; } @@ -65,13 +64,13 @@ namespace Squidex.Domain.Apps.Core.EnrichContent if (!fieldData.TryGetValue(key, out var value) || ShouldApplyDefaultValue(field, value)) { - fieldData.AddValue(key, defaultValue); + fieldData.AddJsonValue(key, defaultValue); } } - private static bool ShouldApplyDefaultValue(IField field, JToken value) + private static bool ShouldApplyDefaultValue(IField field, IJsonValue value) { - return value.IsNull() || (field is IField && value is JValue jValue && Equals(jValue.Value, string.Empty)); + return value.Type == JsonValueType.Null || (field is IField && value is JsonScalar s && string.IsNullOrEmpty(s.Value)); } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs b/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs index a4f8be960..0d05fc571 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs @@ -6,14 +6,14 @@ // ========================================================================== using System.Globalization; -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.EnrichContent { - public sealed class DefaultValueFactory : IFieldVisitor + public sealed class DefaultValueFactory : IFieldVisitor { private readonly Instant now; @@ -22,71 +22,71 @@ namespace Squidex.Domain.Apps.Core.EnrichContent this.now = now; } - public static JToken CreateDefaultValue(IField field, Instant now) + public static IJsonValue CreateDefaultValue(IField field, Instant now) { Guard.NotNull(field, nameof(field)); return field.Accept(new DefaultValueFactory(now)); } - public JToken Visit(IArrayField field) + public IJsonValue Visit(IArrayField field) { - return new JArray(); + return JsonValue.Array(); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return new JArray(); + return JsonValue.Array(); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return field.Properties.DefaultValue; + return JsonValue.Create(field.Properties.DefaultValue); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return JValue.CreateNull(); + return JsonValue.Null; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return JValue.CreateNull(); + return JsonValue.Object(); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return field.Properties.DefaultValue; + return JsonValue.Create(field.Properties.DefaultValue); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return new JArray(); + return JsonValue.Array(); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return field.Properties.DefaultValue; + return JsonValue.Create(field.Properties.DefaultValue); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { - return new JArray(); + return JsonValue.Array(); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Now) { - return now.ToString(); + return JsonValue.Create(now.ToString()); } if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Today) { - return now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture); + return JsonValue.Create(now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)); } - return field.Properties.DefaultValue?.ToString(); + return JsonValue.Create(field.Properties.DefaultValue?.ToString()); } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs index 9d4fddf8d..125d529f2 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs @@ -11,7 +11,7 @@ using System.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ExtractReferenceIds { @@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds continue; } - foreach (var partitionValue in fieldData.Where(x => !x.Value.IsNull())) + foreach (var partitionValue in fieldData.Where(x => x.Value.Type != JsonValueType.Null)) { var ids = field.ExtractReferences(partitionValue.Value); diff --git a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs index a817aba20..a7c459a13 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs @@ -7,44 +7,44 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ExtractReferenceIds { - public sealed class ReferencesCleaner : IFieldVisitor + public sealed class ReferencesCleaner : IFieldVisitor { - private readonly JToken value; + private readonly IJsonValue value; private readonly ICollection oldReferences; - private ReferencesCleaner(JToken value, ICollection oldReferences) + private ReferencesCleaner(IJsonValue value, ICollection oldReferences) { this.value = value; this.oldReferences = oldReferences; } - public static JToken CleanReferences(IField field, JToken value, ICollection oldReferences) + public static IJsonValue CleanReferences(IField field, IJsonValue value, ICollection oldReferences) { return field.Accept(new ReferencesCleaner(value, oldReferences)); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return CleanIds(); } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { if (oldReferences.Contains(field.Properties.SchemaId)) { - return new JArray(); + return JsonValue.Array(); } return CleanIds(); } - private JToken CleanIds() + private IJsonValue CleanIds() { var ids = value.ToGuidSet(); @@ -55,45 +55,45 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds isRemoved |= ids.Remove(oldReference); } - return isRemoved ? ids.ToJToken() : value; + return isRemoved ? ids.ToJsonArray() : value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IField field) + public IJsonValue Visit(IField field) { return value; } - public JToken Visit(IArrayField field) + public IJsonValue Visit(IArrayField field) { return value; } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs index b7170f9aa..0a701501f 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs @@ -7,22 +7,21 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ExtractReferenceIds { public static class ReferencesExtensions { - public static IEnumerable ExtractReferences(this IField field, JToken value) + public static IEnumerable ExtractReferences(this IField field, IJsonValue value) { return ReferencesExtractor.ExtractReferences(field, value); } - public static JToken CleanReferences(this IField field, JToken value, ICollection oldReferences) + public static IJsonValue CleanReferences(this IField field, IJsonValue value, ICollection oldReferences) { - if (value.IsNull()) + if (value.Type == JsonValueType.Null) { return value; } @@ -30,31 +29,27 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds return ReferencesCleaner.CleanReferences(field, value, oldReferences); } - public static JToken ToJToken(this HashSet ids) + public static JsonArray ToJsonArray(this HashSet ids) { - var result = new JArray(); + var result = JsonValue.Array(); foreach (var id in ids) { - result.Add(new JValue(id)); + result.Add(JsonValue.Create(id.ToString())); } return result; } - public static HashSet ToGuidSet(this JToken value) + public static HashSet ToGuidSet(this IJsonValue value) { - if (value is JArray ids) + if (value is JsonArray array) { var result = new HashSet(); - foreach (var id in ids) + foreach (var id in array) { - if (id.Type == JTokenType.Guid) - { - result.Add((Guid)id); - } - else if (id.Type == JTokenType.String && Guid.TryParse((string)id, out var guid)) + if (id.Type == JsonValueType.String && Guid.TryParse(id.ToString(), out var guid)) { result.Add(guid); } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs index 1f661ef9c..d92b70b86 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs @@ -8,21 +8,21 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ExtractReferenceIds { public sealed class ReferencesExtractor : IFieldVisitor> { - private readonly JToken value; + private readonly IJsonValue value; - private ReferencesExtractor(JToken value) + private ReferencesExtractor(IJsonValue value) { this.value = value; } - public static IEnumerable ExtractReferences(IField field, JToken value) + public static IEnumerable ExtractReferences(IField field, IJsonValue value) { return field.Accept(new ReferencesExtractor(value)); } @@ -31,9 +31,9 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds { var result = new List(); - if (value is JArray items) + if (value is JsonArray array) { - foreach (JObject item in items) + foreach (JsonObject item in array) { foreach (var nestedField in field.Fields) { diff --git a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs index e99459cc7..384a90ccb 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs @@ -8,7 +8,7 @@ using System; using System.Collections.Generic; using Squidex.Domain.Apps.Core.ConvertContent; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ExtractReferenceIds { @@ -20,7 +20,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds return (value, field) => { - if (value.IsNull()) + if (value.Type == JsonValueType.Null) { return value; } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedEvent.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedEvent.cs index f5d03da66..6c02810a4 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedEvent.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedEvent.cs @@ -6,7 +6,6 @@ // ========================================================================== using System; -using Newtonsoft.Json; using NodaTime; using Squidex.Infrastructure; using Squidex.Shared.Users; @@ -25,10 +24,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents public long Version { get; set; } - [JsonIgnore] public abstract Guid AggregateId { get; } - [JsonIgnore] public IUser User { get; set; } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleActionHandler.cs index deced9228..7ca0dc581 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleActionHandler.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleActionHandler.cs @@ -7,7 +7,6 @@ using System; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules; @@ -17,8 +16,10 @@ namespace Squidex.Domain.Apps.Core.HandleRules { Type ActionType { get; } - Task<(string Description, JObject Data)> CreateJobAsync(EnrichedEvent @event, RuleAction action); + Type DataType { get; } - Task<(string Dump, Exception Exception)> ExecuteJobAsync(JObject data); + Task<(string Description, object Data)> CreateJobAsync(EnrichedEvent @event, RuleAction action); + + Task<(string Dump, Exception Exception)> ExecuteJobAsync(object data); } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs index 0143f1956..e9632578c 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs @@ -7,7 +7,6 @@ using System; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.Rules; using Squidex.Infrastructure; @@ -25,6 +24,11 @@ namespace Squidex.Domain.Apps.Core.HandleRules get { return typeof(TAction); } } + Type IRuleActionHandler.DataType + { + get { return typeof(TData); } + } + protected RuleActionHandler(RuleEventFormatter formatter) { Guard.NotNull(formatter, nameof(formatter)); @@ -33,21 +37,11 @@ namespace Squidex.Domain.Apps.Core.HandleRules } protected virtual string ToPayloadJson(T @event) - { - return formatter.ToPayload(@event).ToString(); - } - - protected virtual string ToEnvelopeJson(EnrichedEvent @event) - { - return formatter.ToEnvelope(@event).ToString(); - } - - protected virtual JObject ToPayload(T @event) { return formatter.ToPayload(@event); } - protected virtual JObject ToEnvelope(EnrichedEvent @event) + protected virtual string ToEnvelopeJson(EnrichedEvent @event) { return formatter.ToEnvelope(@event); } @@ -62,16 +56,16 @@ namespace Squidex.Domain.Apps.Core.HandleRules return formatter.Format(text, @event); } - async Task<(string Description, JObject Data)> IRuleActionHandler.CreateJobAsync(EnrichedEvent @event, RuleAction action) + async Task<(string Description, object Data)> IRuleActionHandler.CreateJobAsync(EnrichedEvent @event, RuleAction action) { var (description, data) = await CreateJobAsync(@event, (TAction)action); - return (description, JObject.FromObject(data)); + return (description, data); } - async Task<(string Dump, Exception Exception)> IRuleActionHandler.ExecuteJobAsync(JObject data) + async Task<(string Dump, Exception Exception)> IRuleActionHandler.ExecuteJobAsync(object data) { - var typedData = data.ToObject(); + var typedData = (TData)data; return await ExecuteJobAsync(typedData); } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs index 895a722ae..8f3bb8919 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs @@ -10,11 +10,11 @@ using System.Collections.Generic; using System.Globalization; using System.Text; using System.Text.RegularExpressions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; using Squidex.Shared.Users; namespace Squidex.Domain.Apps.Core.HandleRules @@ -27,15 +27,15 @@ namespace Squidex.Domain.Apps.Core.HandleRules private static readonly Regex ContentDataPlaceholderOld = new Regex(@"^CONTENT_DATA(\.([0-9A-Za-z\-_]*)){2,}", RegexOptions.Compiled); private static readonly Regex ContentDataPlaceholderNew = new Regex(@"^\{CONTENT_DATA(\.([0-9A-Za-z\-_]*)){2,}\}", RegexOptions.Compiled); private readonly List<(char[] Pattern, Func Replacer)> patterns = new List<(char[] Pattern, Func Replacer)>(); - private readonly JsonSerializer serializer; + private readonly IJsonSerializer jsonSerializer; private readonly IRuleUrlGenerator urlGenerator; - public RuleEventFormatter(JsonSerializer serializer, IRuleUrlGenerator urlGenerator) + public RuleEventFormatter(IJsonSerializer jsonSerializer, IRuleUrlGenerator urlGenerator) { - Guard.NotNull(serializer, nameof(serializer)); + Guard.NotNull(jsonSerializer, nameof(jsonSerializer)); Guard.NotNull(urlGenerator, nameof(urlGenerator)); - this.serializer = serializer; + this.jsonSerializer = jsonSerializer; this.urlGenerator = urlGenerator; AddPattern("APP_ID", AppId); @@ -55,17 +55,14 @@ namespace Squidex.Domain.Apps.Core.HandleRules patterns.Add((placeholder.ToCharArray(), generator)); } - public virtual JObject ToPayload(T @event) + public virtual string ToPayload(T @event) { - return JObject.FromObject(@event, serializer); + return jsonSerializer.Serialize(@event); } - public virtual JObject ToEnvelope(EnrichedEvent @event) + public virtual string ToEnvelope(EnrichedEvent @event) { - return new JObject( - new JProperty("type", @event.Name), - new JProperty("payload", ToPayload(@event)), - new JProperty("timestamp", @event.Timestamp.ToString())); + return jsonSerializer.Serialize(new { type = @event.Name, payload = @event, timestamp = @event.Timestamp }); } public string Format(string text, EnrichedEvent @event) @@ -264,14 +261,14 @@ namespace Squidex.Domain.Apps.Core.HandleRules for (var j = 2; j < path.Length; j++) { - if (value is JObject obj && obj.TryGetValue(path[j], out value)) + if (value is JsonObject obj && obj.TryGetValue(path[j], out value)) { continue; } - if (value is JArray arr && int.TryParse(path[j], out var idx) && idx >= 0 && idx < arr.Count) + if (value is JsonArray array && int.TryParse(path[j], out var idx) && idx >= 0 && idx < array.Count) { - value = arr[idx]; + value = array[idx]; } else { @@ -279,17 +276,12 @@ namespace Squidex.Domain.Apps.Core.HandleRules } } - if (value == null || value.Type == JTokenType.Null || value.Type == JTokenType.Undefined) + if (value == null || value.Type == JsonValueType.Null) { return Undefined; } - if (value is JValue jValue) - { - return jValue.Value.ToString(); - } - - return value.ToString(Formatting.Indented) ?? Undefined; + return value.ToString() ?? Undefined; } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs index 18329060a..e85ca990d 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs @@ -11,12 +11,12 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Events; using Squidex.Infrastructure; using Squidex.Infrastructure.EventSourcing; +using Squidex.Infrastructure.Json; namespace Squidex.Domain.Apps.Core.HandleRules { @@ -26,15 +26,18 @@ namespace Squidex.Domain.Apps.Core.HandleRules private readonly Dictionary ruleTriggerHandlers; private readonly TypeNameRegistry typeNameRegistry; private readonly IEventEnricher eventEnricher; + private readonly IJsonSerializer jsonSerializer; private readonly IClock clock; public RuleService( IEnumerable ruleTriggerHandlers, IEnumerable ruleActionHandlers, IEventEnricher eventEnricher, + IJsonSerializer jsonSerializer, IClock clock, TypeNameRegistry typeNameRegistry) { + Guard.NotNull(jsonSerializer, nameof(jsonSerializer)); Guard.NotNull(ruleTriggerHandlers, nameof(ruleTriggerHandlers)); Guard.NotNull(ruleActionHandlers, nameof(ruleActionHandlers)); Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry)); @@ -48,6 +51,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules this.eventEnricher = eventEnricher; + this.jsonSerializer = jsonSerializer; + this.clock = clock; } @@ -104,11 +109,13 @@ namespace Squidex.Domain.Apps.Core.HandleRules var actionName = typeNameRegistry.GetName(actionType); var actionData = await actionHandler.CreateJobAsync(enrichedEvent, rule.Action); + var json = jsonSerializer.Serialize(actionData); + var job = new RuleJob { JobId = Guid.NewGuid(), ActionName = actionName, - ActionData = actionData.Data, + ActionData = json, AggregateId = enrichedEvent.AggregateId, AppId = appEvent.AppId.Id, Created = now, @@ -120,14 +127,18 @@ namespace Squidex.Domain.Apps.Core.HandleRules return job; } - public virtual async Task<(string Dump, RuleResult Result, TimeSpan Elapsed)> InvokeAsync(string actionName, JObject job) + public virtual async Task<(string Dump, RuleResult Result, TimeSpan Elapsed)> InvokeAsync(string actionName, string job) { try { var actionType = typeNameRegistry.GetType(actionName); var actionWatch = Stopwatch.StartNew(); - var result = await ruleActionHandlers[actionType].ExecuteJobAsync(job); + var actionHandler = ruleActionHandlers[actionType]; + + var deserialized = jsonSerializer.Deserialize(job, actionHandler.DataType); + + var result = await actionHandler.ExecuteJobAsync(deserialized); actionWatch.Stop(); diff --git a/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs b/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs index 11ec3918e..ee279b40a 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs @@ -7,14 +7,14 @@ using Jint.Native; using Jint.Runtime.Descriptors; -using Newtonsoft.Json.Linq; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper { public sealed class ContentFieldProperty : PropertyDescriptor { private readonly ContentFieldObject contentField; - private JToken contentValue; + private IJsonValue contentValue; private JsValue value; private bool isChanged; @@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper } } - public JToken ContentValue + public IJsonValue ContentValue { get { return contentValue ?? (contentValue = JsonMapper.Map(value)); } } @@ -48,7 +48,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper get { return isChanged; } } - public ContentFieldProperty(ContentFieldObject contentField, JToken contentValue = null) + public ContentFieldProperty(ContentFieldObject contentField, IJsonValue contentValue = null) : base(null, true, true, true) { this.contentField = contentField; diff --git a/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs b/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs index 6ea3cd584..ec9d52054 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs @@ -9,61 +9,52 @@ using System; using Jint; using Jint.Native; using Jint.Native.Object; -using Newtonsoft.Json.Linq; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper { public static class JsonMapper { - public static JsValue Map(JToken value, Engine engine) + public static JsValue Map(IJsonValue value, Engine engine) { if (value == null) { return JsValue.Null; } - switch (value.Type) + switch (value) { - case JTokenType.Date: - case JTokenType.Guid: - case JTokenType.String: - case JTokenType.Uri: - case JTokenType.TimeSpan: - return new JsValue((string)value); - case JTokenType.Null: + case JsonNull n: return JsValue.Null; - case JTokenType.Undefined: - return JsValue.Undefined; - case JTokenType.Integer: - return new JsValue((long)value); - case JTokenType.Float: - return new JsValue((double)value); - case JTokenType.Boolean: - return new JsValue((bool)value); - case JTokenType.Object: - return FromObject(value, engine); - case JTokenType.Array: - { - var arr = (JArray)value; - - var target = new JsValue[arr.Count]; - - for (var i = 0; i < arr.Count; i++) - { - target[i] = Map(arr[i], engine); - } - - return engine.Array.Construct(target); - } + case JsonScalar s: + return new JsValue(s.Value); + case JsonScalar b: + return new JsValue(b.Value); + case JsonScalar b: + return new JsValue(b.Value); + case JsonObject obj: + return FromObject(obj, engine); + case JsonArray arr: + return FromArray(arr, engine); } throw new ArgumentException("Invalid json type.", nameof(value)); } - private static JsValue FromObject(JToken value, Engine engine) + private static JsValue FromArray(JsonArray arr, Engine engine) { - var obj = (JObject)value; + var target = new JsValue[arr.Count]; + for (var i = 0; i < arr.Count; i++) + { + target[i] = Map(arr[i], engine); + } + + return engine.Array.Construct(target); + } + + private static JsValue FromObject(JsonObject obj, Engine engine) + { var target = new ObjectInstance(engine); foreach (var property in obj) @@ -74,69 +65,64 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper return target; } - public static JToken Map(JsValue value) + public static IJsonValue Map(JsValue value) { - if (value == null || value.IsNull()) - { - return JValue.CreateNull(); - } - - if (value.IsUndefined()) + if (value == null || value.IsNull() || value.IsUndefined()) { - return JValue.CreateUndefined(); + return JsonValue.Null; } if (value.IsString()) { - return new JValue(value.AsString()); + return JsonValue.Create(value.AsString()); } if (value.IsBoolean()) { - return new JValue(value.AsBoolean()); + return JsonValue.Create(value.AsBoolean()); } if (value.IsNumber()) { - return new JValue(value.AsNumber()); + return JsonValue.Create(value.AsNumber()); } if (value.IsDate()) { - return new JValue(value.AsDate().ToDateTime()); + return JsonValue.Create(value.AsDate().ToString()); } if (value.IsRegExp()) { - return JValue.CreateString(value.AsRegExp().Value?.ToString()); + return JsonValue.Create(value.AsRegExp().Value?.ToString()); } if (value.IsArray()) { var arr = value.AsArray(); - var target = new JArray(); + var result = JsonValue.Array(); for (var i = 0; i < arr.GetLength(); i++) { - target.Add(Map(arr.Get(i.ToString()))); + result.Add(Map(arr.Get(i.ToString()))); } - return target; + return result; } if (value.IsObject()) { var obj = value.AsObject(); - var target = new JObject(); + var result = JsonValue.Object(); foreach (var kvp in obj.GetOwnProperties()) { - target[kvp.Key] = Map(kvp.Value.Value); + result[kvp.Key] = Map(kvp.Value.Value); } - return target; + return result; } throw new ArgumentException("Invalid json type.", nameof(value)); diff --git a/src/Squidex.Domain.Apps.Core.Operations/Tags/TagNormalizer.cs b/src/Squidex.Domain.Apps.Core.Operations/Tags/TagNormalizer.cs index ed9cd3f05..7ecac0baf 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/Tags/TagNormalizer.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/Tags/TagNormalizer.cs @@ -8,10 +8,10 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.Tags { @@ -24,10 +24,10 @@ namespace Squidex.Domain.Apps.Core.Tags Guard.NotNull(newData, nameof(newData)); var newValues = new HashSet(); - var newArrays = new List(); + var newArrays = new List(); var oldValues = new HashSet(); - var oldArrays = new List(); + var oldArrays = new List(); GetValues(schema, newValues, newArrays, newData); @@ -46,7 +46,7 @@ namespace Squidex.Domain.Apps.Core.Tags { if (normalized.TryGetValue(array[i].ToString(), out var result)) { - array[i] = result; + array[i] = JsonValue.Create(result); } } } @@ -59,7 +59,7 @@ namespace Squidex.Domain.Apps.Core.Tags Guard.NotNull(schema, nameof(schema)); var tagsValues = new HashSet(); - var tagsArrays = new List(); + var tagsArrays = new List(); GetValues(schema, tagsValues, tagsArrays, datas); @@ -73,14 +73,14 @@ namespace Squidex.Domain.Apps.Core.Tags { if (denormalized.TryGetValue(array[i].ToString(), out var result)) { - array[i] = result; + array[i] = JsonValue.Create(result); } } } } } - private static void GetValues(Schema schema, HashSet values, List arrays, params NamedContentData[] datas) + private static void GetValues(Schema schema, HashSet values, List arrays, params NamedContentData[] datas) { foreach (var field in schema.Fields) { @@ -109,14 +109,12 @@ namespace Squidex.Domain.Apps.Core.Tags { foreach (var partition in fieldData) { - if (partition.Value is JArray jArray) + if (partition.Value is JsonArray array) { - foreach (var value in jArray) + foreach (var value in array) { - if (value.Type == JTokenType.Object) + if (value is JsonObject nestedObject) { - var nestedObject = (JObject)value; - if (nestedObject.TryGetValue(nestedField.Name, out var nestedValue)) { ExtractTags(nestedValue, values, arrays); @@ -133,19 +131,19 @@ namespace Squidex.Domain.Apps.Core.Tags } } - private static void ExtractTags(JToken token, ISet values, ICollection arrays) + private static void ExtractTags(IJsonValue value, ISet values, ICollection arrays) { - if (token is JArray jArray) + if (value is JsonArray array) { - foreach (var value in jArray) + foreach (var item in array) { - if (value.Type == JTokenType.String) + if (item.Type == JsonValueType.String) { - values.Add(value.ToString()); + values.Add(item.ToString()); } } - arrays.Add(jArray); + arrays.Add(array); } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs index 38517df83..ab089b5d7 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs @@ -9,11 +9,11 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent.Validators; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; #pragma warning disable SA1028, IDE0004 // Code must not contain trailing whitespace @@ -22,7 +22,6 @@ namespace Squidex.Domain.Apps.Core.ValidateContent public sealed class ContentValidator { private static readonly ContentFieldData DefaultFieldData = new ContentFieldData(); - private static readonly JToken DefaultValue = JValue.CreateNull(); private readonly Schema schema; private readonly PartitionResolver partitionResolver; private readonly ValidationContext context; @@ -96,7 +95,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent var type = isLanguage ? "language" : "invariant value"; - return new ObjectValidator(fieldsValidators, isPartial, type, DefaultValue); + return new ObjectValidator(fieldsValidators, isPartial, type, JsonValue.Null); } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs index a43f8a095..397ed286f 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs @@ -7,45 +7,80 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json.Linq; using NodaTime.Text; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ValidateContent { public sealed class JsonValueConverter : IFieldVisitor { - private readonly JToken value; + private readonly IJsonValue value; - private JsonValueConverter(JToken value) + private JsonValueConverter(IJsonValue value) { this.value = value; } - public static object ConvertValue(IField field, JToken json) + public static object ConvertValue(IField field, IJsonValue json) { return field.Accept(new JsonValueConverter(json)); } public object Visit(IArrayField field) { - return value.ToObject>(); + return ConvertToObjectList(); } public object Visit(IField field) { - return value.ToObject>(); + return ConvertToGuidList(); + } + + public object Visit(IField field) + { + return ConvertToGuidList(); + } + + public object Visit(IField field) + { + return ConvertToStringList(); } public object Visit(IField field) { - return (bool?)value; + if (value is JsonScalar b) + { + return b.Value; + } + + throw new InvalidCastException("Invalid json type, expected boolean."); + } + + public object Visit(IField field) + { + if (value is JsonScalar b) + { + return b.Value; + } + + throw new InvalidCastException("Invalid json type, expected number."); + } + + public object Visit(IField field) + { + if (value is JsonScalar b) + { + return b.Value; + } + + throw new InvalidCastException("Invalid json type, expected string."); } public object Visit(IField field) { - if (value.Type == JTokenType.String) + if (value.Type == JsonValueType.String) { var parseResult = InstantPattern.General.Parse(value.ToString()); @@ -62,31 +97,49 @@ namespace Squidex.Domain.Apps.Core.ValidateContent public object Visit(IField field) { - var geolocation = (JObject)value; - - foreach (var property in geolocation.Properties()) + if (value is JsonObject geolocation) { - if (!string.Equals(property.Name, "latitude", StringComparison.OrdinalIgnoreCase) && - !string.Equals(property.Name, "longitude", StringComparison.OrdinalIgnoreCase)) + foreach (var propertyName in geolocation.Keys) { - throw new InvalidCastException("Geolocation can only have latitude and longitude property."); + if (!string.Equals(propertyName, "latitude", StringComparison.OrdinalIgnoreCase) && + !string.Equals(propertyName, "longitude", StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidCastException("Geolocation can only have latitude and longitude property."); + } } - } - var lat = (double)geolocation["latitude"]; - var lon = (double)geolocation["longitude"]; + if (geolocation.TryGetValue("latitude", out var latValue) && latValue is JsonScalar latNumber) + { + var lat = latNumber.Value; - if (!lat.IsBetween(-90, 90)) - { - throw new InvalidCastException("Latitude must be between -90 and 90."); - } + if (!lat.IsBetween(-90, 90)) + { + throw new InvalidCastException("Latitude must be between -90 and 90."); + } + } + else + { + throw new InvalidCastException("Invalid json type, expected latitude/longitude object."); + } - if (!lon.IsBetween(-180, 180)) - { - throw new InvalidCastException("Longitude must be between -180 and 180."); + if (geolocation.TryGetValue("longitude", out var lonValue) && lonValue is JsonScalar lonNumber) + { + var lon = lonNumber.Value; + + if (!lon.IsBetween(-180, 180)) + { + throw new InvalidCastException("Longitude must be between -180 and 180."); + } + } + else + { + throw new InvalidCastException("Invalid json type, expected latitude/longitude object."); + } + + return value; } - return value; + throw new InvalidCastException("Invalid json type, expected latitude/longitude object."); } public object Visit(IField field) @@ -94,24 +147,76 @@ namespace Squidex.Domain.Apps.Core.ValidateContent return value; } - public object Visit(IField field) + private object ConvertToGuidList() { - return (double?)value; - } + if (value is JsonArray array) + { + var result = new List(); - public object Visit(IField field) - { - return value.ToObject>(); + foreach (var item in array) + { + if (item is JsonScalar s && Guid.TryParse(s.Value, out var guid)) + { + result.Add(guid); + } + else + { + throw new InvalidCastException("Invalid json type, expected array of guid strings."); + } + } + + return result; + } + + throw new InvalidCastException("Invalid json type, expected array of guid strings."); } - public object Visit(IField field) + private object ConvertToStringList() { - return value.ToString(); + if (value is JsonArray array) + { + var result = new List(); + + foreach (var item in array) + { + if (item is JsonScalar s) + { + result.Add(s.Value); + } + else + { + throw new InvalidCastException("Invalid json type, expected array of strings."); + } + } + + return result; + } + + throw new InvalidCastException("Invalid json type, expected array of strings."); } - public object Visit(IField field) + private object ConvertToObjectList() { - return value.ToObject>(); + if (value is JsonArray array) + { + var result = new List(); + + foreach (var item in array) + { + if (item is JsonObject obj) + { + result.Add(obj); + } + else + { + throw new InvalidCastException("Invalid json type, expected array of objects."); + } + } + + return result; + } + + throw new InvalidCastException("Invalid json type, expected array of objects."); } } } diff --git a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs index 97471857e..40bf1a89d 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs @@ -7,9 +7,8 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; -using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ValidateContent.Validators { @@ -30,9 +29,9 @@ namespace Squidex.Domain.Apps.Core.ValidateContent.Validators { object typedValue = null; - if (value is JToken jToken) + if (value is IJsonValue jsonValue) { - typedValue = jToken.IsNull() ? null : JsonValueConverter.ConvertValue(field, jToken); + typedValue = jsonValue.Type == JsonValueType.Null ? null : JsonValueConverter.ConvertValue(field, jsonValue); } var tasks = new List(); diff --git a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ObjectValidator.cs b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ObjectValidator.cs index 6dd8a9c28..429962996 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ObjectValidator.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ObjectValidator.cs @@ -27,7 +27,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent.Validators public async Task ValidateAsync(object value, ValidationContext context, AddError addError) { - if (value is IDictionary values) + if (value is IReadOnlyDictionary values) { foreach (var fieldData in values) { diff --git a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs index fc104e7e5..3a40a2b61 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs @@ -8,11 +8,11 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent.Validators; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.ValidateContent { @@ -45,7 +45,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent nestedSchema[nestedField.Name] = (false, new FieldValidator(nestedField.Accept(this).ToArray(), nestedField)); } - yield return new CollectionItemValidator(new ObjectValidator(nestedSchema, false, "field", JValue.CreateNull())); + yield return new CollectionItemValidator(new ObjectValidator(nestedSchema, false, "field", JsonValue.Null)); } public IEnumerable Visit(IField field) diff --git a/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Formatter.cs b/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Formatter.cs index c28abf358..6fdfaa288 100644 --- a/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Formatter.cs +++ b/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Formatter.cs @@ -32,8 +32,8 @@ namespace Squidex.Infrastructure.EventSourcing public static EventStoreData Write(EventData eventData) { - var body = Encoding.UTF8.GetBytes(eventData.Payload.ToString()); - var meta = Encoding.UTF8.GetBytes(eventData.Metadata.ToString()); + var body = Encoding.UTF8.GetBytes(eventData.Payload); + var meta = Encoding.UTF8.GetBytes(eventData.Metadata); return new EventStoreData(Guid.NewGuid(), eventData.Type, true, body, meta); } diff --git a/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs b/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs index 395fa594f..8748ba8b1 100644 --- a/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs +++ b/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs @@ -5,8 +5,8 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; -using Newtonsoft.Json.Linq; using Squidex.Infrastructure.MongoDb; namespace Squidex.Infrastructure.EventSourcing @@ -23,16 +23,16 @@ namespace Squidex.Infrastructure.EventSourcing [BsonElement] [BsonRequired] - public JToken Metadata { get; set; } + public BsonDocument Metadata { get; set; } public static MongoEvent FromEventData(EventData data) { - return new MongoEvent { Type = data.Type, Metadata = data.Metadata, Payload = data.Payload.ToString() }; + return new MongoEvent { Type = data.Type, Metadata = BsonDocument.Parse(data.Payload), Payload = data.Payload }; } public EventData ToEventData() { - return new EventData { Type = Type, Metadata = Metadata, Payload = JObject.Parse(Payload) }; + return new EventData { Type = Type, Metadata = Metadata.ToJson().ToString(), Payload = Payload }; } } } \ No newline at end of file diff --git a/src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs b/src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs index 238698bda..b378743c1 100644 --- a/src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs +++ b/src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs @@ -9,16 +9,16 @@ using System; using System.Text; using System.Threading; using System.Threading.Tasks; -using Newtonsoft.Json; using RabbitMQ.Client; using Squidex.Infrastructure.EventSourcing; +using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Tasks; namespace Squidex.Infrastructure.CQRS.Events { public sealed class RabbitMqEventConsumer : DisposableObjectBase, IInitializable, IEventConsumer { - private readonly JsonSerializerSettings serializerSettings; + private readonly IJsonSerializer jsonSerializer; private readonly string eventPublisherName; private readonly string exchange; private readonly string eventsFilter; @@ -36,12 +36,12 @@ namespace Squidex.Infrastructure.CQRS.Events get { return eventsFilter; } } - public RabbitMqEventConsumer(JsonSerializerSettings serializerSettings, string eventPublisherName, string uri, string exchange, string eventsFilter) + public RabbitMqEventConsumer(IJsonSerializer jsonSerializer, string eventPublisherName, string uri, string exchange, string eventsFilter) { Guard.NotNullOrEmpty(uri, nameof(uri)); Guard.NotNullOrEmpty(eventPublisherName, nameof(eventPublisherName)); Guard.NotNullOrEmpty(exchange, nameof(exchange)); - Guard.NotNull(serializerSettings, nameof(serializerSettings)); + Guard.NotNull(jsonSerializer, nameof(jsonSerializer)); connectionFactory = new ConnectionFactory { Uri = new Uri(uri, UriKind.Absolute) }; connection = new Lazy(connectionFactory.CreateConnection); @@ -49,8 +49,8 @@ namespace Squidex.Infrastructure.CQRS.Events this.exchange = exchange; this.eventsFilter = eventsFilter; + this.jsonSerializer = jsonSerializer; this.eventPublisherName = eventPublisherName; - this.serializerSettings = serializerSettings; } protected override void DisposeObject(bool disposing) @@ -88,7 +88,7 @@ namespace Squidex.Infrastructure.CQRS.Events public Task On(Envelope @event) { - var jsonString = JsonConvert.SerializeObject(@event, serializerSettings); + var jsonString = jsonSerializer.Serialize(@event); var jsonBytes = Encoding.UTF8.GetBytes(jsonString); channel.Value.BasicPublish(exchange, string.Empty, null, jsonBytes); diff --git a/src/Squidex.Infrastructure/Assets/AssetFile.cs b/src/Squidex.Infrastructure/Assets/AssetFile.cs index bbaa0917d..4f5ef010f 100644 --- a/src/Squidex.Infrastructure/Assets/AssetFile.cs +++ b/src/Squidex.Infrastructure/Assets/AssetFile.cs @@ -7,7 +7,6 @@ using System; using System.IO; -using Newtonsoft.Json; namespace Squidex.Infrastructure.Assets { @@ -21,7 +20,6 @@ namespace Squidex.Infrastructure.Assets public long FileSize { get; } - [JsonConstructor] public AssetFile(string fileName, string mimeType, long fileSize, Func openAction) { Guard.NotNullOrEmpty(fileName, nameof(fileName)); diff --git a/src/Squidex.Infrastructure/EventSourcing/DefaultEventDataFormatter.cs b/src/Squidex.Infrastructure/EventSourcing/DefaultEventDataFormatter.cs index 98b7919b1..22735b68d 100644 --- a/src/Squidex.Infrastructure/EventSourcing/DefaultEventDataFormatter.cs +++ b/src/Squidex.Infrastructure/EventSourcing/DefaultEventDataFormatter.cs @@ -6,38 +6,38 @@ // ========================================================================== using System; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using Squidex.Infrastructure.Json; namespace Squidex.Infrastructure.EventSourcing { public class DefaultEventDataFormatter : IEventDataFormatter { - private readonly JsonSerializer serializer; + private readonly IJsonSerializer serializer; private readonly TypeNameRegistry typeNameRegistry; - public DefaultEventDataFormatter(TypeNameRegistry typeNameRegistry, JsonSerializer serializer = null) + public DefaultEventDataFormatter(TypeNameRegistry typeNameRegistry, IJsonSerializer serializer) { Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry)); + Guard.NotNull(serializer, nameof(serializer)); this.typeNameRegistry = typeNameRegistry; - this.serializer = serializer ?? JsonSerializer.CreateDefault(); + this.serializer = serializer; } public Envelope Parse(EventData eventData, bool migrate = true) { var eventType = typeNameRegistry.GetType(eventData.Type); - var headers = eventData.Metadata.ToObject(serializer); - var content = eventData.Payload.ToObject(eventType, serializer) as IEvent; + var eventHeaders = serializer.Deserialize(eventData.Metadata); + var eventContent = serializer.Deserialize(eventData.Payload, eventType); - if (migrate && content is IMigratedEvent migratedEvent) + if (migrate && eventContent is IMigratedEvent migratedEvent) { - content = migratedEvent.Migrate(); + eventContent = migratedEvent.Migrate(); } - var envelope = new Envelope(content, headers); + var envelope = new Envelope(eventContent, eventHeaders); return envelope; } @@ -55,10 +55,10 @@ namespace Squidex.Infrastructure.EventSourcing envelope.SetCommitId(commitId); - var headers = JToken.FromObject(envelope.Headers, serializer); - var content = JToken.FromObject(envelope.Payload, serializer); + var eventHeaders = serializer.Serialize(envelope.Headers); + var eventContent = serializer.Serialize(envelope.Payload); - return new EventData { Type = eventType, Payload = content, Metadata = headers }; + return new EventData { Type = eventType, Payload = eventContent, Metadata = eventHeaders }; } } } diff --git a/src/Squidex.Infrastructure/EventSourcing/EventData.cs b/src/Squidex.Infrastructure/EventSourcing/EventData.cs index 739ea8068..a3d82188f 100644 --- a/src/Squidex.Infrastructure/EventSourcing/EventData.cs +++ b/src/Squidex.Infrastructure/EventSourcing/EventData.cs @@ -5,15 +5,13 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Newtonsoft.Json.Linq; - namespace Squidex.Infrastructure.EventSourcing { public class EventData { - public JToken Payload { get; set; } + public string Payload { get; set; } - public JToken Metadata { get; set; } + public string Metadata { get; set; } public string Type { get; set; } } diff --git a/src/Squidex.Infrastructure/Json/IJsonSerializer.cs b/src/Squidex.Infrastructure/Json/IJsonSerializer.cs new file mode 100644 index 000000000..e42fb9ea3 --- /dev/null +++ b/src/Squidex.Infrastructure/Json/IJsonSerializer.cs @@ -0,0 +1,23 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.IO; + +namespace Squidex.Infrastructure.Json +{ + public interface IJsonSerializer + { + string Serialize(T value); + + void Serialize(T value, Stream stream); + + T Deserialize(string value, Type actualType = null); + + T Deserialize(Stream stream, Type actualType = null); + } +} diff --git a/src/Squidex.Infrastructure/Json/JsonExtension.cs b/src/Squidex.Infrastructure/Json/JsonExtension.cs deleted file mode 100644 index 23d8cea4c..000000000 --- a/src/Squidex.Infrastructure/Json/JsonExtension.cs +++ /dev/null @@ -1,34 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschränkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Newtonsoft.Json.Linq; - -namespace Squidex.Infrastructure.Json -{ - public static class JsonExtension - { - public static bool IsNull(this JToken token) - { - if (token == null) - { - return true; - } - - if (token.Type == JTokenType.Null) - { - return true; - } - - if (token is JValue value) - { - return value.Value == null; - } - - return false; - } - } -} diff --git a/src/Squidex.Infrastructure/Json/ClaimsPrincipalConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/ClaimsPrincipalConverter.cs similarity index 97% rename from src/Squidex.Infrastructure/Json/ClaimsPrincipalConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/ClaimsPrincipalConverter.cs index c183e6424..bde9e0013 100644 --- a/src/Squidex.Infrastructure/Json/ClaimsPrincipalConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/ClaimsPrincipalConverter.cs @@ -10,7 +10,7 @@ using System.Linq; using System.Security.Claims; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class ClaimsPrincipalConverter : JsonClassConverter { diff --git a/src/Squidex.Infrastructure/Json/ConverterContractResolver.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/ConverterContractResolver.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs index 55609ed0d..e626d5e1d 100644 --- a/src/Squidex.Infrastructure/Json/ConverterContractResolver.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs @@ -9,7 +9,7 @@ using System; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class ConverterContractResolver : CamelCasePropertyNamesContractResolver { diff --git a/src/Squidex.Infrastructure/Json/InstantConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs similarity index 97% rename from src/Squidex.Infrastructure/Json/InstantConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs index deca1ee95..463d24411 100644 --- a/src/Squidex.Infrastructure/Json/InstantConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs @@ -10,7 +10,7 @@ using Newtonsoft.Json; using NodaTime; using NodaTime.Text; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class InstantConverter : JsonConverter { diff --git a/src/Squidex.Infrastructure/Json/JsonClassConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/JsonClassConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs index 954e472dd..078bd451e 100644 --- a/src/Squidex.Infrastructure/Json/JsonClassConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs @@ -8,7 +8,7 @@ using System; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public abstract class JsonClassConverter : JsonConverter where T : class { diff --git a/src/Squidex.Infrastructure/Json/Newtonsoft/JsonValueConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/JsonValueConverter.cs new file mode 100644 index 000000000..949a3a90c --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/JsonValueConverter.cs @@ -0,0 +1,161 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Globalization; +using System.Linq; +using Newtonsoft.Json; +using Squidex.Infrastructure.Json.Objects; + +namespace Squidex.Infrastructure.Json.Newtonsoft +{ + public sealed class JsonValueConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return typeof(IJsonValue).IsAssignableFrom(objectType); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return ReadJson(reader); + } + + private IJsonValue ReadJson(JsonReader reader) + { + switch (reader.TokenType) + { + case JsonToken.Comment: + reader.Read(); + break; + case JsonToken.StartObject: + { + var result = JsonValue.Object(); + + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + var propertyName = reader.Value.ToString(); + + if (!reader.Read()) + { + throw new JsonSerializationException("Unexpected end when reading Object."); + } + + var value = ReadJson(reader); + + result[propertyName] = value; + break; + case JsonToken.EndObject: + return result; + } + } + + throw new JsonSerializationException("Unexpected end when reading Object."); + } + + case JsonToken.StartArray: + { + var result = JsonValue.Array(); + + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.Comment: + break; + default: + var value = ReadJson(reader); + + result.Add(value); + break; + case JsonToken.EndArray: + return result; + } + } + + throw new JsonSerializationException("Unexpected end when reading Object."); + } + + case JsonToken.Integer: + return JsonValue.Create((long)reader.Value); + case JsonToken.Float: + return JsonValue.Create((double)reader.Value); + case JsonToken.Boolean: + return JsonValue.Create((bool)reader.Value); + case JsonToken.Date: + return JsonValue.Create(((DateTime)reader.Value).ToString("yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture)); + case JsonToken.String: + return JsonValue.Create(reader.Value.ToString()); + case JsonToken.Null: + case JsonToken.Undefined: + return JsonValue.Null; + } + + throw new NotSupportedException(); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + return; + } + + WriteJson(writer, (IJsonValue)value); + } + + private void WriteJson(JsonWriter writer, IJsonValue value) + { + switch (value) + { + case JsonNull n: + writer.WriteNull(); + break; + case JsonScalar s: + writer.WriteValue(s.Value); + break; + case JsonScalar s: + writer.WriteValue(s.Value); + break; + case JsonScalar s: + writer.WriteValue(s.Value); + break; + case JsonArray array: + { + writer.WriteStartArray(); + + foreach (var item in array) + { + WriteJson(writer, item); + } + + writer.WriteEndArray(); + break; + } + + case JsonObject obj: + { + writer.WriteStartObject(); + + foreach (var kvp in obj) + { + writer.WritePropertyName(kvp.Key); + + WriteJson(writer, kvp.Value); + } + + writer.WriteEndObject(); + break; + } + } + } + } +} diff --git a/src/Squidex.Infrastructure/Json/LanguageConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/LanguageConverter.cs similarity index 95% rename from src/Squidex.Infrastructure/Json/LanguageConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/LanguageConverter.cs index c2c11ac78..11d45a037 100644 --- a/src/Squidex.Infrastructure/Json/LanguageConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/LanguageConverter.cs @@ -8,7 +8,7 @@ using System; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class LanguageConverter : JsonClassConverter { diff --git a/src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/NamedGuidIdConverter.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/NamedGuidIdConverter.cs index 1695a96f9..f40e50481 100644 --- a/src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/NamedGuidIdConverter.cs @@ -8,7 +8,7 @@ using System; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class NamedGuidIdConverter : JsonClassConverter> { diff --git a/src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/NamedLongIdConverter.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/NamedLongIdConverter.cs index cc85acd9b..b90415b71 100644 --- a/src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/NamedLongIdConverter.cs @@ -8,7 +8,7 @@ using System; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class NamedLongIdConverter : JsonClassConverter> { diff --git a/src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs index 3076ef02c..78f39fb1f 100644 --- a/src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs @@ -9,7 +9,7 @@ using System; using System.Linq; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class NamedStringIdConverter : JsonClassConverter> { diff --git a/src/Squidex.Infrastructure/Json/Newtonsoft/NewtonsoftJsonSerializer.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/NewtonsoftJsonSerializer.cs new file mode 100644 index 000000000..a9a045ed3 --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/NewtonsoftJsonSerializer.cs @@ -0,0 +1,60 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.IO; +using Newtonsoft.Json; + +namespace Squidex.Infrastructure.Json.Newtonsoft +{ + public sealed class NewtonsoftJsonSerializer : IJsonSerializer + { + private readonly JsonSerializerSettings settings; + private readonly JsonSerializer serializer; + + public NewtonsoftJsonSerializer(JsonSerializerSettings settings) + { + Guard.NotNull(settings, nameof(settings)); + + this.settings = settings; + + serializer = JsonSerializer.Create(settings); + } + + public T Deserialize(string value, Type actualType = null) + { + actualType = actualType ?? typeof(T); + + return (T)JsonConvert.DeserializeObject(value, actualType, settings); + } + + public T Deserialize(Stream stream, Type actualType = null) + { + using (var streamReader = new StreamReader(stream)) + { + actualType = actualType ?? typeof(T); + + return (T)serializer.Deserialize(streamReader, actualType); + } + } + + public string Serialize(T value) + { + return JsonConvert.SerializeObject(value, settings); + } + + public void Serialize(T value, Stream stream) + { + using (var writer = new StreamWriter(stream)) + { + serializer.Serialize(writer, value); + + writer.Flush(); + } + } + } +} diff --git a/src/Squidex.Infrastructure/Json/PropertiesBagConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/PropertiesBagConverter.cs similarity index 97% rename from src/Squidex.Infrastructure/Json/PropertiesBagConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/PropertiesBagConverter.cs index f42642fb0..27bda90ae 100644 --- a/src/Squidex.Infrastructure/Json/PropertiesBagConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/PropertiesBagConverter.cs @@ -10,7 +10,7 @@ using Newtonsoft.Json; using NodaTime; using NodaTime.Extensions; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class PropertiesBagConverter : JsonClassConverter where T : PropertiesBag, new() { diff --git a/src/Squidex.Infrastructure/Json/RefTokenConverter.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/RefTokenConverter.cs similarity index 95% rename from src/Squidex.Infrastructure/Json/RefTokenConverter.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/RefTokenConverter.cs index 1e2576faa..9f12baacc 100644 --- a/src/Squidex.Infrastructure/Json/RefTokenConverter.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/RefTokenConverter.cs @@ -8,7 +8,7 @@ using System; using Newtonsoft.Json; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public sealed class RefTokenConverter : JsonClassConverter { diff --git a/src/Squidex.Infrastructure/Json/TypeNameSerializationBinder.cs b/src/Squidex.Infrastructure/Json/Newtonsoft/TypeNameSerializationBinder.cs similarity index 96% rename from src/Squidex.Infrastructure/Json/TypeNameSerializationBinder.cs rename to src/Squidex.Infrastructure/Json/Newtonsoft/TypeNameSerializationBinder.cs index 303bd51a0..8e5d41dc2 100644 --- a/src/Squidex.Infrastructure/Json/TypeNameSerializationBinder.cs +++ b/src/Squidex.Infrastructure/Json/Newtonsoft/TypeNameSerializationBinder.cs @@ -8,7 +8,7 @@ using System; using Newtonsoft.Json.Serialization; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public class TypeNameSerializationBinder : DefaultSerializationBinder { diff --git a/src/Squidex.Infrastructure/Json/Objects/IJsonValue.cs b/src/Squidex.Infrastructure/Json/Objects/IJsonValue.cs new file mode 100644 index 000000000..743cf4a2a --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/IJsonValue.cs @@ -0,0 +1,18 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; + +namespace Squidex.Infrastructure.Json.Objects +{ + public interface IJsonValue : IEquatable + { + JsonValueType Type { get; } + + string ToJsonString(); + } +} diff --git a/src/Squidex.Infrastructure/Json/Objects/JsonArray.cs b/src/Squidex.Infrastructure/Json/Objects/JsonArray.cs new file mode 100644 index 000000000..00880e34a --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/JsonArray.cs @@ -0,0 +1,100 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace Squidex.Infrastructure.Json.Objects +{ + public sealed class JsonArray : Collection, IJsonValue, IEquatable + { + public JsonValueType Type + { + get { return JsonValueType.Array; } + } + + public JsonArray() + { + } + + public JsonArray(IList values) + : base(values) + { + } + + public JsonArray(params object[] values) + : base(values?.Select(JsonValue.Create).ToList()) + { + } + + protected override void InsertItem(int index, IJsonValue item) + { + Guard.NotNull(item, nameof(item)); + + base.InsertItem(index, item); + } + + protected override void SetItem(int index, IJsonValue item) + { + Guard.NotNull(item, nameof(item)); + + base.SetItem(index, item); + } + + public override bool Equals(object obj) + { + return Equals(obj as JsonArray); + } + + public bool Equals(IJsonValue other) + { + return Equals(other as JsonArray); + } + + public bool Equals(JsonArray array) + { + if (array == null || array.Count != Count) + { + return false; + } + + for (var i = 0; i < Count; i++) + { + if (!this[i].Equals(array[i])) + { + return false; + } + } + + return true; + } + + public override int GetHashCode() + { + var hashCode = 0; + + for (var i = 0; i < Count; i++) + { + hashCode = (hashCode * 23) + this[i].GetHashCode(); + } + + return hashCode; + } + + public string ToJsonString() + { + return ToString(); + } + + public override string ToString() + { + return $"[{string.Join(", ", this)}]"; + } + } +} diff --git a/src/Squidex.Infrastructure/Json/Objects/JsonNull.cs b/src/Squidex.Infrastructure/Json/Objects/JsonNull.cs new file mode 100644 index 000000000..884462b3c --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/JsonNull.cs @@ -0,0 +1,55 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; + +namespace Squidex.Infrastructure.Json.Objects +{ + public sealed class JsonNull : IJsonValue, IEquatable + { + public static readonly JsonNull Null = new JsonNull(); + + public JsonValueType Type + { + get { return JsonValueType.Null; } + } + + private JsonNull() + { + } + + public override bool Equals(object obj) + { + return Equals(obj as JsonNull); + } + + public bool Equals(IJsonValue other) + { + return Equals(other as JsonNull); + } + + public bool Equals(JsonNull other) + { + return other != null; + } + + public override int GetHashCode() + { + return 0; + } + + public string ToJsonString() + { + return ToString(); + } + + public override string ToString() + { + return "null"; + } + } +} diff --git a/src/Squidex.Infrastructure/Json/Objects/JsonObject.cs b/src/Squidex.Infrastructure/Json/Objects/JsonObject.cs new file mode 100644 index 000000000..fe70c43ff --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/JsonObject.cs @@ -0,0 +1,129 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Squidex.Infrastructure.Json.Objects +{ + public sealed class JsonObject : IReadOnlyDictionary, IJsonValue, IEquatable + { + private readonly Dictionary inner = new Dictionary(); + + public IJsonValue this[string key] + { + get + { + return inner[key]; + } + set + { + Guard.NotNullOrEmpty(key, nameof(key)); + Guard.NotNull(value, nameof(value)); + + inner[key] = value; + } + } + + public IEnumerable Keys + { + get { return inner.Keys; } + } + + public IEnumerable Values + { + get { return inner.Values; } + } + + public int Count + { + get { return inner.Count; } + } + + public JsonValueType Type + { + get { return JsonValueType.Array; } + } + + public JsonObject Add(string key, object value) + { + return Add(key, JsonValue.Create(value)); + } + + public JsonObject Add(string key, IJsonValue value) + { + Guard.NotNullOrEmpty(key, nameof(key)); + Guard.NotNull(value, nameof(value)); + + inner.Add(key, value); + + return this; + } + + public void Clear() + { + inner.Clear(); + } + + public bool Remove(string key) + { + return inner.Remove(key); + } + + public bool ContainsKey(string key) + { + return inner.ContainsKey(key); + } + + public bool TryGetValue(string key, out IJsonValue value) + { + return inner.TryGetValue(key, out value); + } + + public IEnumerator> GetEnumerator() + { + return inner.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return inner.GetEnumerator(); + } + + public override bool Equals(object obj) + { + return Equals(obj as JsonObject); + } + + public bool Equals(IJsonValue other) + { + return Equals(other as JsonObject); + } + + public bool Equals(JsonObject other) + { + return other != null && inner.EqualsDictionary(other.inner); + } + + public override int GetHashCode() + { + return inner.DictionaryHashCode(); + } + + public string ToJsonString() + { + return ToString(); + } + + public override string ToString() + { + return $"{{{string.Join(", ", this.Select(x => $"\"{x.Key}\"={x.Value}\""))}}}"; + } + } +} diff --git a/src/Squidex.Infrastructure/Json/Objects/JsonScalar.cs b/src/Squidex.Infrastructure/Json/Objects/JsonScalar.cs new file mode 100644 index 000000000..0689f7ecd --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/JsonScalar.cs @@ -0,0 +1,60 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; + +namespace Squidex.Infrastructure.Json.Objects +{ + public sealed class JsonScalar : IJsonValue, IEquatable> + { + private readonly T value; + + public JsonValueType Type { get; } + + public T Value + { + get { return value; } + } + + internal JsonScalar(JsonValueType type, T value) + { + Type = type; + + this.value = value; + } + + public override bool Equals(object obj) + { + return Equals(obj as JsonScalar); + } + + public bool Equals(IJsonValue other) + { + return Equals(other as JsonScalar); + } + + public bool Equals(JsonScalar other) + { + return other != null && other.Type == Type && Equals(other.value, value); + } + + public override int GetHashCode() + { + return value.GetHashCode(); + } + + public string ToJsonString() + { + return Type == JsonValueType.String ? $"\"{value}\"" : ToString(); + } + + public override string ToString() + { + return value.ToString(); + } + } +} diff --git a/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs b/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs new file mode 100644 index 000000000..06c3325b8 --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/JsonValue.cs @@ -0,0 +1,114 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; + +namespace Squidex.Infrastructure.Json.Objects +{ + public static class JsonValue + { + public static readonly JsonScalar Empty = new JsonScalar(JsonValueType.String, string.Empty); + + public static readonly JsonScalar True = new JsonScalar(JsonValueType.Boolean, true); + public static readonly JsonScalar False = new JsonScalar(JsonValueType.Boolean, false); + + public static readonly JsonNull Null = JsonNull.Null; + + public static JsonArray Array() + { + return new JsonArray(); + } + + public static JsonArray Array(params object[] values) + { + return new JsonArray(values); + } + + public static JsonObject Object() + { + return new JsonObject(); + } + + public static IJsonValue Create(object value) + { + if (value == null) + { + return Null; + } + + if (value is IJsonValue v) + { + return v; + } + + switch (value) + { + case string s: + return Create(s); + case bool b: + return Create(b); + case float f: + return Create(f); + case double d: + return Create(d); + case int i: + return Create(i); + case long l: + return Create(l); + } + + throw new ArgumentException("Invalid json type"); + } + + public static IJsonValue Create(bool value) + { + return value ? True : False; + } + + public static IJsonValue Create(double value) + { + Guard.ValidNumber(value, nameof(value)); + + return new JsonScalar(JsonValueType.Number, value); + } + + public static IJsonValue Create(double? value) + { + if (value == null) + { + return Null; + } + + return Create(value.Value); + } + + public static IJsonValue Create(bool? value) + { + if (value == null) + { + return Null; + } + + return Create(value.Value); + } + + public static IJsonValue Create(string value) + { + if (value == null) + { + return Null; + } + + if (value.Length == 0) + { + return Empty; + } + + return new JsonScalar(JsonValueType.String, value); + } + } +} diff --git a/src/Squidex.Infrastructure/Json/Objects/JsonValueType.cs b/src/Squidex.Infrastructure/Json/Objects/JsonValueType.cs new file mode 100644 index 000000000..8b4a13022 --- /dev/null +++ b/src/Squidex.Infrastructure/Json/Objects/JsonValueType.cs @@ -0,0 +1,19 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Infrastructure.Json.Objects +{ + public enum JsonValueType + { + Array, + Boolean, + Null, + Number, + Object, + String + } +} diff --git a/src/Squidex.Infrastructure/Orleans/J.cs b/src/Squidex.Infrastructure/Orleans/J.cs index 9f89f09d6..aee59a82d 100644 --- a/src/Squidex.Infrastructure/Orleans/J.cs +++ b/src/Squidex.Infrastructure/Orleans/J.cs @@ -6,13 +6,15 @@ // ========================================================================== using System.Threading.Tasks; -using Newtonsoft.Json; +using Squidex.Infrastructure.Json; + +#pragma warning disable SA1401 // Fields must be private namespace Squidex.Infrastructure.Orleans { public static class J { - internal static readonly JsonSerializer DefaultSerializer = JsonSerializer.CreateDefault(); + public static IJsonSerializer DefaultSerializer; public static J AsJ(this T value) { diff --git a/src/Squidex.Infrastructure/Orleans/J{T}.cs b/src/Squidex.Infrastructure/Orleans/J{T}.cs index e39b12664..bfef10aac 100644 --- a/src/Squidex.Infrastructure/Orleans/J{T}.cs +++ b/src/Squidex.Infrastructure/Orleans/J{T}.cs @@ -6,13 +6,12 @@ // ========================================================================== using System; -using System.IO; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json; using Orleans.CodeGeneration; using Orleans.Concurrency; using Orleans.Serialization; +using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Log; namespace Squidex.Infrastructure.Orleans @@ -22,7 +21,6 @@ namespace Squidex.Infrastructure.Orleans { public T Value { get; } - [JsonConstructor] public J(T value) { Value = value; @@ -63,12 +61,7 @@ namespace Squidex.Infrastructure.Orleans var stream = new StreamWriterWrapper(context.StreamWriter); - using (var writer = new JsonTextWriter(new StreamWriter(stream))) - { - jsonSerializer.Serialize(writer, input); - - writer.Flush(); - } + jsonSerializer.Serialize(input, stream); } } @@ -81,18 +74,15 @@ namespace Squidex.Infrastructure.Orleans var stream = new StreamReaderWrapper(context.StreamReader); - using (var reader = new JsonTextReader(new StreamReader(stream))) - { - return jsonSerializer.Deserialize(reader, expected); - } + return jsonSerializer.Deserialize(stream, expected); } } - private static JsonSerializer GetSerializer(ISerializerContext context) + private static IJsonSerializer GetSerializer(ISerializerContext context) { try { - return context?.ServiceProvider?.GetService() ?? J.DefaultSerializer; + return context?.ServiceProvider?.GetService() ?? J.DefaultSerializer; } catch { diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppClientJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppClientJsonTests.cs index 5a3d8cb6d..5a2ac24a7 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppClientJsonTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppClientJsonTests.cs @@ -6,8 +6,6 @@ // ========================================================================== using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Xunit; @@ -15,8 +13,6 @@ namespace Squidex.Domain.Apps.Core.Model.Apps { public class AppClientJsonTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - [Fact] public void Should_serialize_and_deserialize() { @@ -34,9 +30,9 @@ namespace Squidex.Domain.Apps.Core.Model.Apps clients = clients.Revoke("4"); - var appClients = JToken.FromObject(clients, serializer).ToObject(serializer); + var serialized = clients.SerializeAndDeserialize(); - appClients.Should().BeEquivalentTo(clients); + serialized.Should().BeEquivalentTo(clients); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppContributorsJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppContributorsJsonTests.cs index 2f42622f7..d8f86cde3 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppContributorsJsonTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppContributorsJsonTests.cs @@ -6,8 +6,6 @@ // ========================================================================== using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Xunit; @@ -15,8 +13,6 @@ namespace Squidex.Domain.Apps.Core.Model.Apps { public class AppContributorsJsonTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - [Fact] public void Should_serialize_and_deserialize() { @@ -26,7 +22,7 @@ namespace Squidex.Domain.Apps.Core.Model.Apps contributors = contributors.Assign("2", Role.Editor); contributors = contributors.Assign("3", Role.Owner); - var serialized = JToken.FromObject(contributors, serializer).ToObject(serializer); + var serialized = contributors.SerializeAndDeserialize(); serialized.Should().BeEquivalentTo(contributors); } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs index 4a3739352..9ffe845bc 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs @@ -7,8 +7,6 @@ using System; using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Xunit; @@ -16,8 +14,6 @@ namespace Squidex.Domain.Apps.Core.Model.Apps { public class AppPatternJsonTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - [Fact] public void Should_serialize_and_deserialize() { @@ -35,9 +31,9 @@ namespace Squidex.Domain.Apps.Core.Model.Apps patterns = patterns.Remove(guid1); - var appPatterns = JToken.FromObject(patterns, serializer).ToObject(serializer); + var serialized = patterns.SerializeAndDeserialize(); - appPatterns.Should().BeEquivalentTo(patterns); + serialized.Should().BeEquivalentTo(patterns); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPlanTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPlanTests.cs index 4cf183ab3..35588c136 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPlanTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPlanTests.cs @@ -6,8 +6,6 @@ // ========================================================================== using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Infrastructure; using Xunit; @@ -16,16 +14,14 @@ namespace Squidex.Domain.Apps.Core.Model.Apps { public class AppPlanTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - [Fact] public void Should_serialize_and_deserialize() { - var sut = new AppPlan(new RefToken("user", "Me"), "free"); + var plan = new AppPlan(new RefToken("user", "Me"), "free"); - var serialized = JToken.FromObject(sut, serializer).ToObject(serializer); + var serialized = plan.SerializeAndDeserialize(); - serialized.Should().BeEquivalentTo(sut); + serialized.Should().BeEquivalentTo(plan); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/LanguagesConfigJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/LanguagesConfigJsonTests.cs index c0e36b181..0e5f6c51d 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/LanguagesConfigJsonTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/LanguagesConfigJsonTests.cs @@ -7,8 +7,6 @@ using System.Linq; using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Infrastructure; using Xunit; @@ -17,20 +15,18 @@ namespace Squidex.Domain.Apps.Core.Model.Apps { public class LanguagesConfigJsonTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - [Fact] public void Should_serialize_and_deserialize() { - var sut = LanguagesConfig.Build( + var languages = LanguagesConfig.Build( new LanguageConfig(Language.EN), new LanguageConfig(Language.DE, true, Language.EN), new LanguageConfig(Language.IT, false, Language.DE)) .MakeMaster(Language.IT); - var serialized = JToken.FromObject(sut, serializer).ToObject(serializer); + var serialized = languages.SerializeAndDeserialize(); - serialized.Should().BeEquivalentTo(sut); + serialized.Should().BeEquivalentTo(languages); Assert.Same(serialized.FirstOrDefault(x => x.Key == "it"), serialized.Master); } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs index 82b47099a..d79477f0a 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs @@ -6,8 +6,6 @@ // ========================================================================== using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Xunit; @@ -15,16 +13,14 @@ namespace Squidex.Domain.Apps.Core.Model.Apps { public class RolesJsonTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - [Fact] public void Should_serialize_and_deserialize() { var sut = Roles.CreateDefaults("my-app"); - var serialized = JToken.FromObject(sut, serializer).ToObject(serializer); + var roles = sut.SerializeAndDeserialize(); - serialized.Should().BeEquivalentTo(sut); + roles.Should().BeEquivalentTo(sut); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs index 3c0356896..fe4b91dc5 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs @@ -6,6 +6,7 @@ // ========================================================================== using Squidex.Domain.Apps.Core.Contents; +using Squidex.Infrastructure.Json.Objects; using Xunit; #pragma warning disable xUnit2013 // Do not use equality check to check for collection size. @@ -23,7 +24,7 @@ namespace Squidex.Domain.Apps.Core.Model.Contents .AddField("field2", new ContentFieldData() .AddValue("en", 2) - .AddValue("it", null)); + .AddValue("it", JsonValue.Null)); var actual = input.ToCleaned(); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs index 5a1cd96f3..70d28c50b 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs @@ -9,8 +9,6 @@ using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules.Triggers; using Xunit; @@ -21,8 +19,6 @@ namespace Squidex.Domain.Apps.Core.Model.Rules { public class RuleTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); - public static readonly List Triggers = typeof(Rule).Assembly.GetTypes() .Where(x => x.BaseType == typeof(RuleTrigger)) @@ -123,9 +119,9 @@ namespace Squidex.Domain.Apps.Core.Model.Rules { var rule_1 = rule_0.Disable(); - var appClients = JToken.FromObject(rule_1, serializer).ToObject(serializer); + var serialized = rule_1.SerializeAndDeserialize(); - appClients.Should().BeEquivalentTo(rule_1); + serialized.Should().BeEquivalentTo(rule_1); } [Theory] diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs index 8dacfd80a..1f8073699 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs @@ -9,8 +9,6 @@ using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Xunit; @@ -20,7 +18,6 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas { public class SchemaTests { - private readonly JsonSerializer serializer = TestData.DefaultSerializer(); private readonly Schema schema_0 = new Schema("my-schema"); [Fact] @@ -282,7 +279,7 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas public void Should_serialize_and_deserialize_schema() { var schemaSource = TestData.MixedSchema(); - var schemaTarget = JToken.FromObject(schemaSource, serializer).ToObject(serializer); + var schemaTarget = schemaSource.SerializeAndDeserialize(); schemaTarget.Should().BeEquivalentTo(schemaSource); } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionFlatTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionFlatTests.cs index 54e71a9b9..0429afaab 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionFlatTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionFlatTests.cs @@ -6,11 +6,11 @@ // ========================================================================== using System.Collections.Generic; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; using Xunit; #pragma warning disable xUnit2013 // Do not use equality check to check for collection size. @@ -44,7 +44,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent .AddValue("en", 2)) .AddField("field2", new ContentFieldData() - .AddValue("de", null) + .AddValue("de", JsonValue.Null) .AddValue("en", 4)) .AddField("field3", new ContentFieldData() @@ -57,10 +57,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent var expected = new Dictionary { - { "field1", new ContentFieldData().AddValue("de", 1).AddValue("en", 2) }, - { "field2", new ContentFieldData().AddValue("de", null).AddValue("en", 4) }, - { "field3", (JValue)6 }, - { "field4", (JValue)7 } + { + "field1", + new ContentFieldData() + .AddValue("de", 1) + .AddValue("en", 2) + }, + { + "field2", + new ContentFieldData() + .AddValue("de", JsonValue.Null) + .AddValue("en", 4) + }, + { "field3", JsonValue.Create(6) }, + { "field4", JsonValue.Create(7) } }; Assert.True(expected.EqualsDictionary(output)); @@ -77,7 +87,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent .AddValue("en", 2)) .AddField("field2", new ContentFieldData() - .AddValue("de", null) + .AddValue("de", JsonValue.Null) .AddValue("en", 4)) .AddField("field3", new ContentFieldData() @@ -91,13 +101,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent new LanguageConfig(Language.EN), new LanguageConfig(Language.DE, false, Language.EN)); - var output = (Dictionary)data.ToFlatLanguageModel(fallbackConfig, new List { Language.DE }); + var output = (Dictionary)data.ToFlatLanguageModel(fallbackConfig, new List { Language.DE }); - var expected = new Dictionary + var expected = new Dictionary { - { "field1", 1 }, - { "field2", 4 }, - { "field3", 6 } + { "field1", JsonValue.Create(1) }, + { "field2", JsonValue.Create(4) }, + { "field3", JsonValue.Create(6) } }; Assert.True(expected.EqualsDictionary(output)); @@ -114,7 +124,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent .AddValue("en", 2)) .AddField("field2", new ContentFieldData() - .AddValue("de", null) + .AddValue("de", JsonValue.Null) .AddValue("en", 4)) .AddField("field3", new ContentFieldData() @@ -123,13 +133,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent new ContentFieldData() .AddValue("it", 7)); - var output = (Dictionary)data.ToFlatLanguageModel(languagesConfig, new List { Language.DE, Language.EN }); + var output = (Dictionary)data.ToFlatLanguageModel(languagesConfig, new List { Language.DE, Language.EN }); - var expected = new Dictionary + var expected = new Dictionary { - { "field1", 1 }, - { "field2", 4 }, - { "field3", 6 } + { "field1", JsonValue.Create(1) }, + { "field2", JsonValue.Create(4) }, + { "field3", JsonValue.Create(6) } }; Assert.True(expected.EqualsDictionary(output)); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs index 2415089c4..43700a84c 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs @@ -5,10 +5,10 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ConvertContent @@ -174,7 +174,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent new NamedContentData() .AddField("field1", new ContentFieldData() - .AddValue("en", new JArray("hello", "loved"))) + .AddValue("en", new JsonArray("hello", "loved"))) .AddField("field2", new ContentFieldData() .AddValue("iv", "world")); @@ -191,7 +191,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent new NamedContentData() .AddField("field1", new ContentFieldData() - .AddValue("en", new JArray(new JObject(new JProperty("p1", "hello"))))) + .AddValue("en", new JsonArray(JsonValue.Object().Add("p1", "hello")))) .AddField("field2", new ContentFieldData() .AddValue("iv", "world")); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs index 58417c0c9..d5b96a58d 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs @@ -8,12 +8,13 @@ using System.Collections.Generic; using System.Linq; using FakeItEasy; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ConvertContent @@ -21,6 +22,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent public class FieldConvertersTests { private readonly IAssetUrlGenerator assetUrlGenerator = A.Fake(); + private readonly IJsonSerializer serializer = TestData.DefaultSerializer(); private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE); private readonly RootField jsonField = Fields.Json(1, "1", Partitioning.Invariant); private readonly RootField stringLanguageField = Fields.String(1, "1", Partitioning.Language); @@ -42,7 +44,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent { var input = new ContentFieldData() - .AddValue("iv", new JObject()); + .AddValue("iv", JsonValue.Object()); var actual = FieldConverters.ForValues((f, i) => Value.Unset)(input, stringInvariantField); @@ -56,9 +58,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent { var input = new ContentFieldData() - .AddValue("iv", new JObject()); + .AddValue("iv", JsonValue.Object()); - var actual = FieldConverters.ForValues(ValueConverters.EncodeJson())(input, jsonField); + var actual = FieldConverters.ForValues(ValueConverters.EncodeJson(serializer))(input, jsonField); var expected = new ContentFieldData() @@ -73,20 +75,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent var input = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("field1", 100), - new JProperty("field2", 200), - new JProperty("invalid", 300)))); + new JsonArray( + JsonValue.Object() + .Add("field1", 100) + .Add("field2", 200) + .Add("invalid", 300))); var actual = FieldConverters.ForNestedName2Id(ValueConverters.ExcludeHidden())(input, arrayField); var expected = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("1", 100)))); + new JsonArray( + JsonValue.Object() + .Add("1", 100))); Assert.Equal(expected, actual); } @@ -97,20 +99,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent var input = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("field1", 100), - new JProperty("field2", 200), - new JProperty("invalid", 300)))); + new JsonArray( + JsonValue.Object() + .Add("field1", 100) + .Add("field2", 200) + .Add("invalid", 300))); var actual = FieldConverters.ForNestedName2Name(ValueConverters.ExcludeHidden())(input, arrayField); var expected = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("field1", 100)))); + new JsonArray( + JsonValue.Object() + .Add("field1", 100))); Assert.Equal(expected, actual); } @@ -121,20 +123,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent var input = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("1", 100), - new JProperty("2", 200), - new JProperty("99", 300)))); + new JsonArray( + JsonValue.Object() + .Add("1", 100) + .Add("2", 200) + .Add("99", 300))); var actual = FieldConverters.ForNestedId2Id(ValueConverters.ExcludeHidden())(input, arrayField); var expected = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("1", 100)))); + new JsonArray( + JsonValue.Object() + .Add("1", 100))); Assert.Equal(expected, actual); } @@ -145,20 +147,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent var input = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("1", 100), - new JProperty("2", 200), - new JProperty("99", 300)))); + new JsonArray( + JsonValue.Object() + .Add("1", 100) + .Add("2", 200) + .Add("99", 300))); var actual = FieldConverters.ForNestedId2Name(ValueConverters.ExcludeHidden())(input, arrayField); var expected = new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("field1", 100)))); + new JsonArray( + JsonValue.Object() + .Add("field1", 100))); Assert.Equal(expected, actual); } @@ -422,11 +424,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent { var source = new ContentFieldData() - .AddValue("iv", new JArray("1", "2")); + .AddValue("iv", new JsonArray("1", "2")); var expected = new ContentFieldData() - .AddValue("iv", new JArray("url/to/1", "url/to/2")); + .AddValue("iv", new JsonArray("url/to/1", "url/to/2")); var rtesult = FieldConverters.ResolveAssetUrls(new HashSet(new[] { "1" }), assetUrlGenerator)(source, assetsField); @@ -438,11 +440,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent { var source = new ContentFieldData() - .AddValue("iv", new JArray("1", "2")); + .AddValue("iv", new JsonArray("1", "2")); var expected = new ContentFieldData() - .AddValue("iv", new JArray("url/to/1", "url/to/2")); + .AddValue("iv", new JsonArray("url/to/1", "url/to/2")); var rtesult = FieldConverters.ResolveAssetUrls(new HashSet(new[] { "*" }), assetUrlGenerator)(source, assetsField); @@ -454,11 +456,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent { var source = new ContentFieldData() - .AddValue("iv", new JArray("1", "2")); + .AddValue("iv", new JsonArray("1", "2")); var expected = new ContentFieldData() - .AddValue("iv", new JArray("1", "2")); + .AddValue("iv", new JsonArray("1", "2")); var rtesult = FieldConverters.ResolveAssetUrls(new HashSet(new[] { "2" }), assetUrlGenerator)(source, assetsField); @@ -470,11 +472,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent { var source = new ContentFieldData() - .AddValue("iv", new JArray("1", "2")); + .AddValue("iv", new JsonArray("1", "2")); var expected = new ContentFieldData() - .AddValue("iv", new JArray("1", "2")); + .AddValue("iv", new JsonArray("1", "2")); var rtesult = FieldConverters.ResolveAssetUrls(null, assetUrlGenerator)(source, assetsField); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs index e5cd27572..ada3f0861 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs @@ -5,9 +5,10 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ConvertContent @@ -17,23 +18,24 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent private readonly RootField stringField = Fields.String(1, "1", Partitioning.Invariant); private readonly RootField jsonField = Fields.Json(1, "1", Partitioning.Invariant); private readonly RootField numberField = Fields.Number(1, "1", Partitioning.Invariant); + private readonly IJsonSerializer jsonSerializer = TestData.DefaultSerializer(); [Fact] public void Should_encode_json_value() { - var source = new JObject(); + var source = JsonValue.Object(); - var result = ValueConverters.EncodeJson()(source, jsonField); + var result = ValueConverters.EncodeJson(jsonSerializer)(source, jsonField); - Assert.Equal("e30=", result); + Assert.Equal(JsonValue.Create("e30="), result); } [Fact] public void Should_return_same_value_if_encoding_null_value() { - var source = JValue.CreateNull(); + var source = JsonValue.Null; - var result = ValueConverters.EncodeJson()(source, jsonField); + var result = ValueConverters.EncodeJson(jsonSerializer)(source, jsonField); Assert.Same(source, result); } @@ -41,9 +43,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent [Fact] public void Should_return_same_value_if_encoding_non_json_field() { - var source = (JToken)"NO-JSON"; + var source = JsonValue.Create("NO-JSON"); - var result = ValueConverters.EncodeJson()(source, stringField); + var result = ValueConverters.EncodeJson(jsonSerializer)(source, stringField); Assert.Same(source, result); } @@ -51,19 +53,19 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent [Fact] public void Should_decode_json_values() { - var source = "e30="; + var source = JsonValue.Create("e30="); - var result = ValueConverters.DecodeJson()(source, jsonField); + var result = ValueConverters.DecodeJson(jsonSerializer)(source, jsonField); - Assert.Equal(new JObject(), result); + Assert.Equal(JsonValue.Object(), result); } [Fact] public void Should_return_same_value_if_decoding_null_value() { - var source = JValue.CreateNull(); + var source = JsonValue.Null; - var result = ValueConverters.DecodeJson()(source, jsonField); + var result = ValueConverters.DecodeJson(jsonSerializer)(source, jsonField); Assert.Same(source, result); } @@ -71,9 +73,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent [Fact] public void Should_return_same_value_if_decoding_non_json_field() { - var source = JValue.CreateNull(); + var source = JsonValue.Null; - var result = ValueConverters.EncodeJson()(source, stringField); + var result = ValueConverters.EncodeJson(jsonSerializer)(source, stringField); Assert.Same(source, result); } @@ -81,7 +83,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent [Fact] public void Should_return_unset_if_field_hidden() { - var source = 123; + var source = JsonValue.Create(123); var result = ValueConverters.ExcludeHidden()(source, stringField.Hide()); @@ -91,7 +93,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent [Fact] public void Should_return_unset_if_field_has_wrong_type() { - var source = "invalid"; + var source = JsonValue.Create("invalid"); var result = ValueConverters.ExcludeChangedTypes()(source, numberField); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs index 8c35f5e19..fff6720c4 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs @@ -6,13 +6,13 @@ // ========================================================================== using System; -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.EnrichContent; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; using Xunit; #pragma warning disable xUnit2004 // Do not use equality check to test for boolean conditions @@ -53,14 +53,14 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent data.Enrich(schema, languagesConfig.ToResolver()); - Assert.Equal(456, (int)data["my-number"]["iv"]); + Assert.Equal(456, ((JsonScalar)data["my-number"]["iv"]).Value); - Assert.Equal("de-string", (string)data["my-string"]["de"]); - Assert.Equal("en-string", (string)data["my-string"]["en"]); + Assert.Equal("de-string", data["my-string"]["de"].ToString()); + Assert.Equal("en-string", data["my-string"]["en"].ToString()); - Assert.Equal(Now.ToString(), (string)data["my-datetime"]["iv"]); + Assert.Equal(Now.ToString(), data["my-datetime"]["iv"].ToString()); - Assert.True((bool)data["my-boolean"]["iv"]); + Assert.True(((JsonScalar)data["my-boolean"]["iv"]).Value); } [Fact] @@ -77,8 +77,8 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent data.Enrich(schema, languagesConfig.ToResolver()); - Assert.Equal("en-string", (string)data["my-string"]["de"]); - Assert.Equal("en-string", (string)data["my-string"]["en"]); + Assert.Equal("en-string", data["my-string"]["de"].ToString()); + Assert.Equal("en-string", data["my-string"]["en"].ToString()); } [Fact] @@ -88,7 +88,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.Assets(1, "1", Partitioning.Invariant, new AssetsFieldProperties()); - Assert.Equal(new JArray(), DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Array(), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -98,7 +98,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.Boolean(1, "1", Partitioning.Invariant, new BooleanFieldProperties { DefaultValue = true }); - Assert.Equal(true, DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.True, DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -108,7 +108,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.DateTime(1, "1", Partitioning.Invariant, new DateTimeFieldProperties { DefaultValue = FutureDays(15) }); - Assert.Equal(FutureDays(15).ToString(), DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Create(FutureDays(15).ToString()), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -118,7 +118,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.DateTime(1, "1", Partitioning.Invariant, new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Today }); - Assert.Equal("2017-10-12", DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Create("2017-10-12"), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -128,7 +128,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.DateTime(1, "1", Partitioning.Invariant, new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Now }); - Assert.Equal("2017-10-12T16:30:10Z", DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Create("2017-10-12T16:30:10Z"), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -138,7 +138,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.Json(1, "1", Partitioning.Invariant, new JsonFieldProperties()); - Assert.Equal(new JObject(), DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Object(), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -148,7 +148,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.Geolocation(1, "1", Partitioning.Invariant, new GeolocationFieldProperties()); - Assert.Equal(JValue.CreateNull(), DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -158,7 +158,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.Number(1, "1", Partitioning.Invariant, new NumberFieldProperties { DefaultValue = 12 }); - Assert.Equal(12, DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Create(12), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -168,7 +168,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.References(1, "1", Partitioning.Invariant, new ReferencesFieldProperties()); - Assert.Equal(new JArray(), DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Array(), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -178,7 +178,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.String(1, "1", Partitioning.Invariant, new StringFieldProperties { DefaultValue = "default" }); - Assert.Equal("default", DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Create("default"), DefaultValueFactory.CreateDefaultValue(field, Now)); } [Fact] @@ -188,7 +188,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent Fields.Tags(1, "1", Partitioning.Invariant, new TagsFieldProperties()); - Assert.Equal(new JArray(), DefaultValueFactory.CreateDefaultValue(field, Now)); + Assert.Equal(JsonValue.Array(), DefaultValueFactory.CreateDefaultValue(field, Now)); } private static Instant FutureDays(int days) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs index 1d83fcd1f..684035e91 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs @@ -7,12 +7,12 @@ using System; using System.Linq; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ExtractReferenceIds; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; using Xunit; #pragma warning disable xUnit2013 // Do not use equality check to check for collection size. @@ -49,7 +49,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds new IdContentData() .AddField(5, new ContentFieldData() - .AddValue("iv", new JArray(id1.ToString(), id2.ToString()))); + .AddValue("iv", JsonValue.Array(id1.ToString(), id2.ToString()))); var ids = input.GetReferencedIds(schema).ToArray(); @@ -66,16 +66,16 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds new IdContentData() .AddField(5, new ContentFieldData() - .AddValue("iv", new JArray(id1.ToString(), id2.ToString()))); + .AddValue("iv", JsonValue.Array(id1.ToString(), id2.ToString()))); var converter = FieldConverters.ForValues(ValueReferencesConverter.CleanReferences(new[] { id2 })); var actual = input.ConvertId2Id(schema, converter); - var cleanedValue = (JArray)actual[5]["iv"]; + var cleanedValue = (JsonArray)actual[5]["iv"]; Assert.Equal(1, cleanedValue.Count); - Assert.Equal(id1.ToString(), cleanedValue[0]); + Assert.Equal(id1.ToString(), cleanedValue[0].ToString()); } [Fact] @@ -106,7 +106,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds { var sut = Fields.Assets(1, "my-asset", Partitioning.Invariant); - var result = sut.ExtractReferences("invalid").ToArray(); + var result = sut.ExtractReferences(JsonValue.Create("invalid")).ToArray(); Assert.Empty(result); } @@ -116,7 +116,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds { var sut = Fields.String(1, "my-string", Partitioning.Invariant); - var result = sut.ExtractReferences("invalid").ToArray(); + var result = sut.ExtractReferences(JsonValue.Create("invalid")).ToArray(); Assert.Empty(result); } @@ -126,9 +126,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds { var sut = Fields.Assets(1, "my-asset", Partitioning.Invariant); - var result = sut.CleanReferences(null, null); + var result = sut.CleanReferences(JsonValue.Null, null); - Assert.Null(result); + Assert.Equal(JsonValue.Null, result); } [Fact] @@ -170,9 +170,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds new ReferencesFieldProperties { SchemaId = schemaId })); var value = - new JArray( - new JObject( - new JProperty("my-refs", CreateValue(id1, id2)))); + JsonValue.Array( + JsonValue.Object() + .Add("my-refs", CreateValue(id1, id2))); var result = sut.ExtractReferences(value).ToArray(); @@ -199,7 +199,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds var sut = Fields.References(1, "my-refs", Partitioning.Invariant, new ReferencesFieldProperties { SchemaId = schemaId }); - var result = sut.ExtractReferences(null).ToArray(); + var result = sut.ExtractReferences(JsonValue.Null).ToArray(); Assert.Equal(new[] { schemaId }, result); } @@ -210,7 +210,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds var sut = Fields.References(1, "my-refs", Partitioning.Invariant, new ReferencesFieldProperties { SchemaId = schemaId }); - var result = sut.ExtractReferences("invalid").ToArray(); + var result = sut.ExtractReferences(JsonValue.Create("invalid")).ToArray(); Assert.Equal(new[] { schemaId }, result); } @@ -220,9 +220,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds { var sut = Fields.References(1, "my-refs", Partitioning.Invariant); - var result = sut.CleanReferences(null, null); + var result = sut.CleanReferences(JsonValue.Null, null); - Assert.Null(result); + Assert.Equal(JsonValue.Null, result); } [Fact] @@ -267,9 +267,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds Assert.Same(token, result); } - private static JToken CreateValue(params Guid[] ids) + private static IJsonValue CreateValue(params Guid[] ids) { - return ids == null ? JValue.CreateNull() : (JToken)new JArray(ids.OfType().ToArray()); + return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray()); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs index 7cdb92b62..bee39a8eb 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs @@ -16,6 +16,7 @@ using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json; using Squidex.Shared.Identity; using Squidex.Shared.Users; using Xunit; @@ -24,7 +25,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules { public class RuleEventFormatterTests { - private readonly JsonSerializer serializer = JsonSerializer.CreateDefault(); + private readonly IJsonSerializer serializer = TestData.DefaultSerializer(); private readonly IUser user = A.Fake(); private readonly IRuleUrlGenerator urlGenerator = A.Fake(); private readonly NamedId appId = NamedId.Of(Guid.NewGuid(), "my-app"); @@ -48,7 +49,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules { var result = sut.ToPayload(new { Value = 1 }); - Assert.True(result is JObject); + Assert.True(result is string); } [Fact] @@ -58,7 +59,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules var result = sut.ToPayload(@event); - Assert.True(result is JObject); + Assert.True(result is string); } [Fact] @@ -68,7 +69,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules var result = sut.ToEnvelope(@event); - Assert.Equal("MyEventName", result["type"]); + Assert.Contains("MyEventName", result); } [Fact] diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs index f21de9c6b..5b2d5b77b 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs @@ -8,7 +8,6 @@ using System; using System.Threading.Tasks; using FakeItEasy; -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; @@ -18,6 +17,7 @@ using Squidex.Domain.Apps.Events; using Squidex.Domain.Apps.Events.Contents; using Squidex.Infrastructure; using Squidex.Infrastructure.EventSourcing; +using Squidex.Infrastructure.Json; using Xunit; #pragma warning disable xUnit2009 // Do not use boolean check to check for string equality @@ -28,6 +28,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules { private readonly IRuleTriggerHandler ruleTriggerHandler = A.Fake(); private readonly IRuleActionHandler ruleActionHandler = A.Fake(); + private readonly IJsonSerializer serializer = TestData.DefaultSerializer(); private readonly IEventEnricher eventEnricher = A.Fake(); private readonly IClock clock = A.Fake(); private readonly TypeNameRegistry typeNameRegistry = new TypeNameRegistry(); @@ -67,7 +68,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules A.CallTo(() => ruleTriggerHandler.TriggerType) .Returns(typeof(ContentChangedTrigger)); - sut = new RuleService(new[] { ruleTriggerHandler }, new[] { ruleActionHandler }, eventEnricher, clock, typeNameRegistry); + sut = new RuleService(new[] { ruleTriggerHandler }, new[] { ruleActionHandler }, eventEnricher, serializer, clock, typeNameRegistry); } [Fact] @@ -129,7 +130,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules ruleEnvelope.SetTimestamp(now.Minus(Duration.FromDays(3))); - var actionData = new JObject(); + var actionData = "{}"; var actionDescription = "MyDescription"; A.CallTo(() => clock.GetCurrentInstant()) @@ -159,7 +160,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules ruleEnvelope.SetTimestamp(now); var actionName = "ValidAction"; - var actionData = new JObject(); + var actionData = "{}"; var actionDescription = "MyDescription"; A.CallTo(() => clock.GetCurrentInstant()) @@ -188,7 +189,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules [Fact] public async Task Should_return_succeeded_job_with_full_dump_when_handler_returns_no_exception() { - var ruleJob = new JObject(); + var ruleJob = "{}"; var actionDump = "MyDump"; @@ -206,7 +207,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules [Fact] public async Task Should_return_failed_job_with_full_dump_when_handler_returns_exception() { - var ruleJob = new JObject(); + var ruleJob = "{}"; var actionDump = "MyDump"; @@ -224,7 +225,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules [Fact] public async Task Should_return_timedout_job_with_full_dump_when_exception_from_handler_indicates_timeout() { - var ruleJob = new JObject(); + var ruleJob = "{}"; var actionDump = "MyDump"; @@ -243,7 +244,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules [Fact] public async Task Should_create_exception_details_when_job_to_execute_failed() { - var ruleJob = new JObject(); + var ruleJob = "{}"; var ruleError = new InvalidOperationException(); A.CallTo(() => ruleActionHandler.ExecuteJobAsync(ruleJob)) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs index 592e0765e..488c32b9f 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs @@ -7,9 +7,9 @@ using Jint; using Jint.Runtime; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Scripting.ContentWrapper; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.Scripting @@ -155,13 +155,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting new NamedContentData() .AddField("number", new ContentFieldData() - .AddValue("iv", new JArray(1.0, 2.0))); + .AddValue("iv", new JsonArray(1.0, 2.0))); var expected = new NamedContentData() .AddField("number", new ContentFieldData() - .AddValue("iv", new JArray(1.0, 4.0, 5.0))); + .AddValue("iv", new JsonArray(1.0, 4.0, 5.0))); var result = ExecuteScript(original, @"data.number.iv = [data.number.iv[0], data.number.iv[1] + 2, 5]"); @@ -175,13 +175,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting new NamedContentData() .AddField("number", new ContentFieldData() - .AddValue("iv", new JObject(new JProperty("lat", 1.0)))); + .AddValue("iv", JsonValue.Object().Add("lat", 1.0))); var expected = new NamedContentData() .AddField("number", new ContentFieldData() - .AddValue("iv", new JObject(new JProperty("lat", 1.0), new JProperty("lon", 4.0)))); + .AddValue("iv", JsonValue.Object().Add("lat", 1.0).Add("lon", 4.0))); var result = ExecuteScript(original, @"data.number.iv = { lat: data.number.iv.lat, lon: data.number.iv.lat + 3 }"); @@ -265,7 +265,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting new NamedContentData() .AddField("obj", new ContentFieldData() - .AddValue("iv", new JObject(new JProperty("readonly", 1)))); + .AddValue("iv", JsonValue.Object().Add("readonly", 1))); Assert.Throws(() => ExecuteScript(original, "data.obj.iv.invalid = 1")); Assert.Throws(() => ExecuteScript(original, "data.obj.iv.readonly = 2")); @@ -278,7 +278,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting new NamedContentData() .AddField("obj", new ContentFieldData() - .AddValue("iv", new JArray())); + .AddValue("iv", new JsonArray())); ExecuteScript(original, "data.obj.iv[0] = 1"); } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/Tags/TagNormalizerTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/Tags/TagNormalizerTests.cs index 7f0843ee2..6dfc8dba0 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/Tags/TagNormalizerTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/Tags/TagNormalizerTests.cs @@ -9,17 +9,16 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using FakeItEasy; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Tags; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.Tags { public class TagNormalizerTests { - private static readonly JTokenEqualityComparer JTokenEqualityComparer = new JTokenEqualityComparer(); private readonly ITagService tagService = A.Fake(); private readonly Guid appId = Guid.NewGuid(); private readonly Guid schemaId = Guid.NewGuid(); @@ -56,8 +55,8 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags await tagService.NormalizeAsync(appId, schemaId, schema, newData, oldData); - Assert.Equal(new JArray("id2_1", "id2_2"), newData["tags2"]["iv"], JTokenEqualityComparer); - Assert.Equal(new JArray("id4"), newData["array"]["iv"][0]["nestedTags2"], JTokenEqualityComparer); + Assert.Equal(JsonValue.Array("id2_1", "id2_2"), newData["tags2"]["iv"]); + Assert.Equal(JsonValue.Array("id4"), GetNestedTags(newData)); } [Fact] @@ -77,8 +76,8 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags await tagService.NormalizeAsync(appId, schemaId, schema, newData, null); - Assert.Equal(new JArray("id2_1", "id2_2"), newData["tags2"]["iv"], JTokenEqualityComparer); - Assert.Equal(new JArray("id4"), newData["array"]["iv"][0]["nestedTags2"], JTokenEqualityComparer); + Assert.Equal(JsonValue.Array("id2_1", "id2_2"), newData["tags2"]["iv"]); + Assert.Equal(JsonValue.Array("id4"), GetNestedTags(newData)); } [Fact] @@ -98,8 +97,16 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags await tagService.NormalizeAsync(appId, schemaId, schema, newData, null); - Assert.Equal(new JArray("name2_1", "name2_2"), newData["tags2"]["iv"], JTokenEqualityComparer); - Assert.Equal(new JArray("name4"), newData["array"]["iv"][0]["nestedTags2"], JTokenEqualityComparer); + Assert.Equal(JsonValue.Array("name2_1", "name2_2"), newData["tags2"]["iv"]); + Assert.Equal(JsonValue.Array("name4"), GetNestedTags(newData)); + } + + private IJsonValue GetNestedTags(NamedContentData newData) + { + var array = (JsonArray)newData["array"]["iv"]; + var arrayItem = (JsonObject)array[0]; + + return arrayItem["nestedTags2"]; } private static NamedContentData GenerateData(string prefix) @@ -107,21 +114,21 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags return new NamedContentData() .AddField("tags1", new ContentFieldData() - .AddValue("iv", new JArray($"{prefix}1"))) + .AddValue("iv", JsonValue.Array($"{prefix}1"))) .AddField("tags2", new ContentFieldData() - .AddValue("iv", new JArray($"{prefix}2_1", $"{prefix}2_2"))) + .AddValue("iv", JsonValue.Array($"{prefix}2_1", $"{prefix}2_2"))) .AddField("string", new ContentFieldData() .AddValue("iv", $"{prefix}stringValue")) .AddField("array", new ContentFieldData() .AddValue("iv", - new JArray( - new JObject( - new JProperty("nestedTags1", new JArray($"{prefix}3")), - new JProperty("nestedTags2", new JArray($"{prefix}4")), - new JProperty("string", $"{prefix}nestedStringValue"))))); + JsonValue.Array( + JsonValue.Object() + .Add("nestedTags1", JsonValue.Array($"{prefix}3")) + .Add("nestedTags2", JsonValue.Array($"{prefix}4")) + .Add("string", $"{prefix}nestedStringValue")))); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs index 44ee87e03..05897ce5c 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs @@ -9,8 +9,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new ArrayFieldProperties()); - await sut.ValidateAsync(CreateValue(new JObject()), errors, ValidationTestExtensions.ValidContext); + await sut.ValidateAsync(CreateValue(JsonValue.Object()), errors, ValidationTestExtensions.ValidContext); Assert.Empty(errors); } @@ -74,7 +74,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new ArrayFieldProperties()); - await sut.ValidateAsync("invalid", errors); + await sut.ValidateAsync(JsonValue.Create("invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -85,7 +85,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new ArrayFieldProperties { MinItems = 3 }); - await sut.ValidateAsync(CreateValue(new JObject(), new JObject()), errors); + await sut.ValidateAsync(CreateValue(JsonValue.Object(), JsonValue.Object()), errors); errors.Should().BeEquivalentTo( new[] { "Must have at least 3 item(s)." }); @@ -96,15 +96,15 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new ArrayFieldProperties { MaxItems = 1 }); - await sut.ValidateAsync(CreateValue(new JObject(), new JObject()), errors); + await sut.ValidateAsync(CreateValue(JsonValue.Object(), JsonValue.Object()), errors); errors.Should().BeEquivalentTo( new[] { "Must have not more than 1 item(s)." }); } - private static JToken CreateValue(params JObject[] ids) + private static IJsonValue CreateValue(params JsonObject[] ids) { - return ids == null ? JValue.CreateNull() : (JToken)new JArray(ids.OfType().ToArray()); + return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.OfType().ToArray()); } private static RootField Field(ArrayFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/AssetsFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/AssetsFieldTests.cs index 36aa3c0e0..7268df598 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/AssetsFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/AssetsFieldTests.cs @@ -10,10 +10,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Infrastructure.Collections; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -119,7 +119,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new AssetsFieldProperties()); - await sut.ValidateAsync("invalid", errors); + await sut.ValidateAsync(JsonValue.Create("invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -263,9 +263,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent }); } - private static JToken CreateValue(params Guid[] ids) + private static IJsonValue CreateValue(params Guid[] ids) { - return ids == null ? JValue.CreateNull() : (JToken)new JArray(ids.OfType().ToArray()); + return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray()); } private static RootField Field(AssetsFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/BooleanFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/BooleanFieldTests.cs index 537f8d9a7..0d9d708c1 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/BooleanFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/BooleanFieldTests.cs @@ -8,8 +8,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -62,15 +62,15 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new BooleanFieldProperties()); - await sut.ValidateAsync(CreateValue("Invalid"), errors); + await sut.ValidateAsync(JsonValue.Create("Invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); } - private static JValue CreateValue(object v) + private static IJsonValue CreateValue(bool? v) { - return new JValue(v); + return JsonValue.Create(v); } private static RootField Field(BooleanFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs index 441810ec7..8d6893cdd 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs @@ -8,12 +8,12 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -52,7 +52,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent new NamedContentData() .AddField("my-field", new ContentFieldData() - .AddValue(1000)); + .AddValue("iv", 1000)); await data.ValidateAsync(context, schema, languagesConfig.ToResolver(), errors); @@ -214,7 +214,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent new NamedContentData() .AddField("my-field", new ContentFieldData() - .AddValue(1000)); + .AddValue("iv", 1000)); await data.ValidatePartialAsync(context, schema, languagesConfig.ToResolver(), errors); @@ -329,10 +329,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent new NamedContentData() .AddField("my-field", new ContentFieldData() - .AddValue("iv", new JArray( - new JObject(), - new JObject(new JProperty("my-nested", 1)), - new JObject()))); + .AddValue("iv", + JsonValue.Array( + JsonValue.Object(), + JsonValue.Object().Add("my-nested", 1), + JsonValue.Object()))); await data.ValidatePartialAsync(context, schema, languagesConfig.ToResolver(), errors); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/DateTimeFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/DateTimeFieldTests.cs index ac74d57ad..f2df2df3d 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/DateTimeFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/DateTimeFieldTests.cs @@ -9,9 +9,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using NodaTime; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -33,7 +33,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new DateTimeFieldProperties()); - await sut.ValidateAsync(CreateValue(null), errors); + await sut.ValidateAsync(JsonValue.Null, errors); Assert.Empty(errors); } @@ -43,7 +43,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new DateTimeFieldProperties { IsRequired = true }); - await sut.ValidateAsync(CreateValue(null), errors); + await sut.ValidateAsync(JsonValue.Null, errors); errors.Should().BeEquivalentTo( new[] { "Field is required." }); @@ -76,7 +76,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new DateTimeFieldProperties()); - await sut.ValidateAsync(CreateValue("Invalid"), errors); + await sut.ValidateAsync(JsonValue.Create("Invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -87,7 +87,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new DateTimeFieldProperties()); - await sut.ValidateAsync(CreateValue(123), errors); + await sut.ValidateAsync(JsonValue.Create(123), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -98,9 +98,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent return Instant.FromDateTimeUtc(DateTime.UtcNow.Date.AddDays(days)); } - private static JValue CreateValue(object v) + private static IJsonValue CreateValue(Instant v) { - return v is Instant ? new JValue(v.ToString()) : new JValue(v); + return JsonValue.Create(v.ToString()); } private static RootField Field(DateTimeFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs index c19149e6b..cfff1afef 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs @@ -8,8 +8,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new GeolocationFieldProperties()); - await sut.ValidateAsync(CreateValue(JValue.CreateNull()), errors); + await sut.ValidateAsync(JsonValue.Null, errors); Assert.Empty(errors); } @@ -41,11 +41,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new GeolocationFieldProperties()); - var geolocation = new JObject( - new JProperty("latitude", 0), - new JProperty("longitude", 0)); + var geolocation = JsonValue.Object() + .Add("latitude", 0) + .Add("longitude", 0); - await sut.ValidateAsync(CreateValue(geolocation), errors); + await sut.ValidateAsync(geolocation, errors); Assert.Empty(errors); } @@ -55,11 +55,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new GeolocationFieldProperties { IsRequired = true }); - var geolocation = new JObject( - new JProperty("latitude", 200), - new JProperty("longitude", 0)); + var geolocation = JsonValue.Object() + .Add("latitude", 200) + .Add("longitude", 0); - await sut.ValidateAsync(CreateValue(geolocation), errors); + await sut.ValidateAsync(geolocation, errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -70,11 +70,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new GeolocationFieldProperties { IsRequired = true }); - var geolocation = new JObject( - new JProperty("latitude", 0), - new JProperty("longitude", 200)); + var geolocation = JsonValue.Object() + .Add("latitude", 0) + .Add("longitude", 200); - await sut.ValidateAsync(CreateValue(geolocation), errors); + await sut.ValidateAsync(geolocation, errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -85,12 +85,12 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new GeolocationFieldProperties { IsRequired = true }); - var geolocation = new JObject( - new JProperty("invalid", 0), - new JProperty("latitude", 0), - new JProperty("longitude", 0)); + var geolocation = JsonValue.Object() + .Add("invalid", 0) + .Add("latitude", 0) + .Add("longitude", 0); - await sut.ValidateAsync(CreateValue(geolocation), errors); + await sut.ValidateAsync(geolocation, errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -101,17 +101,12 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new GeolocationFieldProperties { IsRequired = true }); - await sut.ValidateAsync(CreateValue(JValue.CreateNull()), errors); + await sut.ValidateAsync(JsonValue.Null, errors); errors.Should().BeEquivalentTo( new[] { "Field is required." }); } - private static JToken CreateValue(JToken v) - { - return v; - } - private static RootField Field(GeolocationFieldProperties properties) { return Fields.Geolocation(1, "my-geolocation", Partitioning.Invariant, properties); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/JsonFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/JsonFieldTests.cs index b6cb06f80..16cba1e50 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/JsonFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/JsonFieldTests.cs @@ -8,8 +8,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new JsonFieldProperties()); - await sut.ValidateAsync(CreateValue(new JValue(1)), errors); + await sut.ValidateAsync(CreateValue(JsonValue.Create(1)), errors); Assert.Empty(errors); } @@ -41,13 +41,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new JsonFieldProperties { IsRequired = true }); - await sut.ValidateAsync(CreateValue(JValue.CreateNull()), errors); + await sut.ValidateAsync(CreateValue(JsonValue.Null), errors); errors.Should().BeEquivalentTo( new[] { "Field is required." }); } - private static JValue CreateValue(JValue v) + private static IJsonValue CreateValue(IJsonValue v) { return v; } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs index d236198f9..617032bf6 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs @@ -8,9 +8,9 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new NumberFieldProperties()); - await sut.ValidateAsync(CreateValue(null), errors); + await sut.ValidateAsync(JsonValue.Null, errors); Assert.Empty(errors); } @@ -42,7 +42,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new NumberFieldProperties { IsRequired = true }); - await sut.ValidateAsync(CreateValue(null), errors); + await sut.ValidateAsync(JsonValue.Null, errors); errors.Should().BeEquivalentTo( new[] { "Field is required." }); @@ -86,15 +86,15 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new NumberFieldProperties()); - await sut.ValidateAsync(CreateValue("Invalid"), errors); + await sut.ValidateAsync(JsonValue.Create("Invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); } - private static JValue CreateValue(object v) + private static IJsonValue CreateValue(double v) { - return new JValue(v); + return JsonValue.Create(v); } private static RootField Field(NumberFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs index 768b781bc..48301f83e 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs @@ -10,8 +10,8 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -76,7 +76,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new ReferencesFieldProperties()); - await sut.ValidateAsync("invalid", errors); + await sut.ValidateAsync(JsonValue.Create("invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -117,9 +117,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent new[] { $"Contains invalid reference '{referenceId}'." }); } - private static JToken CreateValue(params Guid[] ids) + private static IJsonValue CreateValue(params Guid[] ids) { - return ids == null ? JValue.CreateNull() : (JToken)new JArray(ids.OfType().ToArray()); + return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray()); } private static RootField Field(ReferencesFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs index 46f9a17de..56d9169e7 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs @@ -8,9 +8,9 @@ using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -103,9 +103,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent new[] { "Custom Error Message." }); } - private static JValue CreateValue(object v) + private static IJsonValue CreateValue(string v) { - return new JValue(v); + return JsonValue.Create(v); } private static RootField Field(StringFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs index 3b2a4d3c2..23988ca4f 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs @@ -9,9 +9,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FluentAssertions; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Infrastructure.Collections; +using Squidex.Infrastructure.Json.Objects; using Xunit; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent @@ -75,7 +75,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { var sut = Field(new TagsFieldProperties()); - await sut.ValidateAsync("invalid", errors); + await sut.ValidateAsync(JsonValue.Create("invalid"), errors); errors.Should().BeEquivalentTo( new[] { "Not a valid value." }); @@ -114,9 +114,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent new[] { "[1]: Not an allowed value." }); } - private static JToken CreateValue(params string[] ids) + private static IJsonValue CreateValue(params string[] ids) { - return ids == null ? JValue.CreateNull() : (JToken)new JArray(ids.OfType().ToArray()); + return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.OfType().ToArray()); } private static RootField Field(TagsFieldProperties properties) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs index 3b1e1c454..ba1d0d2ca 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs @@ -9,10 +9,10 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Newtonsoft.Json.Linq; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent.Validators; +using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Core.Operations.ValidateContent { @@ -37,14 +37,14 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent CreateFormatter(errors)); } - public static Task ValidateAsync(this IField field, JToken value, IList errors, ValidationContext context = null) + public static Task ValidateAsync(this IField field, IJsonValue value, IList errors, ValidationContext context = null) { return new FieldValidator(ValidatorsFactory.CreateValidators(field).ToArray(), field).ValidateAsync(value, CreateContext(context), CreateFormatter(errors)); } - public static Task ValidateOptionalAsync(this IField field, JToken value, IList errors, ValidationContext context = null) + public static Task ValidateOptionalAsync(this IField field, IJsonValue value, IList errors, ValidationContext context = null) { return new FieldValidator(ValidatorsFactory.CreateValidators(field).ToArray(), field).ValidateAsync(value, CreateContext(context).Optional(true), diff --git a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs index 6b10c3145..530bc3a74 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs @@ -17,13 +17,14 @@ using Squidex.Domain.Apps.Core.Schemas.Json; using Squidex.Infrastructure; using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; using Xunit; namespace Squidex.Domain.Apps.Core { public static class TestData { - public static JsonSerializer DefaultSerializer() + public static IJsonSerializer DefaultSerializer() { var typeNameRegistry = new TypeNameRegistry(); @@ -35,6 +36,7 @@ namespace Squidex.Domain.Apps.Core new AppClientsConverter(), new AppContributorsConverter(), new AppPatternsConverter(), + new ClaimsPrincipalConverter(), new InstantConverter(), new LanguageConverter(), new LanguagesConfigConverter(), @@ -50,7 +52,7 @@ namespace Squidex.Domain.Apps.Core TypeNameHandling = TypeNameHandling.Auto }; - return JsonSerializer.Create(serializerSettings); + return new NewtonsoftJsonSerializer(serializerSettings); } public static Schema MixedSchema() @@ -100,6 +102,13 @@ namespace Squidex.Domain.Apps.Core return schema; } + public static T SerializeAndDeserialize(this T value) + { + var serializer = DefaultSerializer(); + + return serializer.Deserialize(serializer.Serialize(value)); + } + public static void TestFreeze(IFreezable freezable) { var sut = new AssetsFieldProperties(); diff --git a/tests/Squidex.Infrastructure.Tests/EventSourcing/DefaultEventDataFormatterTests.cs b/tests/Squidex.Infrastructure.Tests/EventSourcing/DefaultEventDataFormatterTests.cs index aef438ac2..1dad34b54 100644 --- a/tests/Squidex.Infrastructure.Tests/EventSourcing/DefaultEventDataFormatterTests.cs +++ b/tests/Squidex.Infrastructure.Tests/EventSourcing/DefaultEventDataFormatterTests.cs @@ -7,9 +7,7 @@ using System; using System.Linq; -using Newtonsoft.Json; using NodaTime; -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.TestHelpers; using Xunit; @@ -27,18 +25,16 @@ namespace Squidex.Infrastructure.EventSourcing } } - private readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); - private readonly TypeNameRegistry typeNameRegistry = new TypeNameRegistry(); private readonly DefaultEventDataFormatter sut; public DefaultEventDataFormatterTests() { - serializerSettings.Converters.Add(new PropertiesBagConverter()); + var typeNameRegistry = + new TypeNameRegistry() + .Map(typeof(MyEvent), "Event") + .Map(typeof(MyOldEvent), "OldEvent"); - typeNameRegistry.Map(typeof(MyEvent), "Event"); - typeNameRegistry.Map(typeof(MyOldEvent), "OldEvent"); - - sut = new DefaultEventDataFormatter(typeNameRegistry, JsonSerializer.Create(serializerSettings)); + sut = new DefaultEventDataFormatter(typeNameRegistry, JsonHelper.DefaultSerializer(typeNameRegistry)); } [Fact] diff --git a/tests/Squidex.Infrastructure.Tests/EventSourcing/EnvelopeTests.cs b/tests/Squidex.Infrastructure.Tests/EventSourcing/EnvelopeTests.cs index 804d57f14..f9d3a75e5 100644 --- a/tests/Squidex.Infrastructure.Tests/EventSourcing/EnvelopeTests.cs +++ b/tests/Squidex.Infrastructure.Tests/EventSourcing/EnvelopeTests.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.TestHelpers; using Xunit; @@ -23,7 +22,7 @@ namespace Squidex.Infrastructure.EventSourcing { var value = new Envelope(new MyEvent { Value = 1 }); - var deserialized = value.SerializeAndDeserializeAndReturn(new PropertiesBagConverter()); + var deserialized = value.SerializeAndDeserialize(); Assert.Equal(1, deserialized.To().Payload.Value); } diff --git a/tests/Squidex.Infrastructure.Tests/Json/ClaimsPrincipalConverterTests.cs b/tests/Squidex.Infrastructure.Tests/Json/ClaimsPrincipalConverterTests.cs index 6abf98d8a..76e65659e 100644 --- a/tests/Squidex.Infrastructure.Tests/Json/ClaimsPrincipalConverterTests.cs +++ b/tests/Squidex.Infrastructure.Tests/Json/ClaimsPrincipalConverterTests.cs @@ -36,10 +36,10 @@ namespace Squidex.Infrastructure.Json "Google") }); - var result = value.SerializeAndDeserializeAndReturn(new ClaimsPrincipalConverter()); + var serialized = value.SerializeAndDeserialize(); - Assert.Equal(value.Identities.ElementAt(0).AuthenticationType, result.Identities.ElementAt(0).AuthenticationType); - Assert.Equal(value.Identities.ElementAt(1).AuthenticationType, result.Identities.ElementAt(1).AuthenticationType); + Assert.Equal(value.Identities.ElementAt(0).AuthenticationType, serialized.Identities.ElementAt(0).AuthenticationType); + Assert.Equal(value.Identities.ElementAt(1).AuthenticationType, serialized.Identities.ElementAt(1).AuthenticationType); } [Fact] @@ -47,7 +47,9 @@ namespace Squidex.Infrastructure.Json { ClaimsPrincipal value = null; - value.SerializeAndDeserialize(new ClaimsPrincipalConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Null(value); } } } diff --git a/tests/Squidex.Infrastructure.Tests/Json/InstantConverterTests.cs b/tests/Squidex.Infrastructure.Tests/Json/InstantConverterTests.cs index b207d365a..aba2d8269 100644 --- a/tests/Squidex.Infrastructure.Tests/Json/InstantConverterTests.cs +++ b/tests/Squidex.Infrastructure.Tests/Json/InstantConverterTests.cs @@ -19,7 +19,9 @@ namespace Squidex.Infrastructure.Json { var value = Instant.FromDateTimeUtc(DateTime.UtcNow.Date); - value.SerializeAndDeserialize(new InstantConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -27,7 +29,9 @@ namespace Squidex.Infrastructure.Json { Instant? value = Instant.FromDateTimeUtc(DateTime.UtcNow.Date); - value.SerializeAndDeserialize(new InstantConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -35,7 +39,9 @@ namespace Squidex.Infrastructure.Json { Instant? value = null; - value.SerializeAndDeserialize(new InstantConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } } } diff --git a/tests/Squidex.Infrastructure.Tests/Json/ConverterContractResolverTests.cs b/tests/Squidex.Infrastructure.Tests/Json/Newtonsoft/ConverterContractResolverTests.cs similarity index 94% rename from tests/Squidex.Infrastructure.Tests/Json/ConverterContractResolverTests.cs rename to tests/Squidex.Infrastructure.Tests/Json/Newtonsoft/ConverterContractResolverTests.cs index d96f8a780..4ea3d7c0f 100644 --- a/tests/Squidex.Infrastructure.Tests/Json/ConverterContractResolverTests.cs +++ b/tests/Squidex.Infrastructure.Tests/Json/Newtonsoft/ConverterContractResolverTests.cs @@ -11,7 +11,7 @@ using NodaTime; using Squidex.Infrastructure.TestHelpers; using Xunit; -namespace Squidex.Infrastructure.Json +namespace Squidex.Infrastructure.Json.Newtonsoft { public class ConverterContractResolverTests { @@ -77,7 +77,9 @@ namespace Squidex.Infrastructure.Json { var value = Instant.FromDateTimeUtc(DateTime.UtcNow.Date); - value.SerializeAndDeserialize(new ConverterContractResolver(new InstantConverter())); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } } } diff --git a/tests/Squidex.Infrastructure.Tests/Json/Objects/JsonValuesSerializationTests.cs b/tests/Squidex.Infrastructure.Tests/Json/Objects/JsonValuesSerializationTests.cs new file mode 100644 index 000000000..08150c3a8 --- /dev/null +++ b/tests/Squidex.Infrastructure.Tests/Json/Objects/JsonValuesSerializationTests.cs @@ -0,0 +1,113 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Infrastructure.TestHelpers; +using Xunit; + +namespace Squidex.Infrastructure.Json.Objects +{ + public class JsonValuesSerializationTests + { + [Fact] + public void Should_deserialize_integer() + { + var serialized = JsonHelper.Deserialize(123); + + Assert.Equal(JsonValue.Create(123), serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_null() + { + var value = JsonValue.Null; + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_date() + { + var value = JsonValue.Create("2008-09-15T15:53:00"); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_string() + { + var value = JsonValue.Create("my-string"); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_boolean() + { + var value = JsonValue.Create(true); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_number() + { + var value = JsonValue.Create(123); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_array() + { + var value = JsonValue.Array(1, 2); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_object() + { + var value = + JsonValue.Object() + .Add("1", 1) + .Add("2", 1); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + + [Fact] + public void Should_serialize_and_deserialize_complex_object() + { + var value = + JsonValue.Object() + .Add("1", + JsonValue.Array( + JsonValue.Object().Add("1_1", 11), + JsonValue.Object().Add("1_2", 12))) + .Add("2", + JsonValue.Object().Add("2_1", 11)); + + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); + } + } +} diff --git a/tests/Squidex.Infrastructure.Tests/LanguageTests.cs b/tests/Squidex.Infrastructure.Tests/LanguageTests.cs index cddf49510..f57e30fe7 100644 --- a/tests/Squidex.Infrastructure.Tests/LanguageTests.cs +++ b/tests/Squidex.Infrastructure.Tests/LanguageTests.cs @@ -7,7 +7,6 @@ using System; using System.Linq; -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.TestHelpers; using Xunit; @@ -125,7 +124,9 @@ namespace Squidex.Infrastructure { Language value = null; - value.SerializeAndDeserialize(new LanguageConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -133,7 +134,9 @@ namespace Squidex.Infrastructure { var value = Language.DE; - value.SerializeAndDeserialize(new LanguageConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } } } diff --git a/tests/Squidex.Infrastructure.Tests/NamedIdTests.cs b/tests/Squidex.Infrastructure.Tests/NamedIdTests.cs index 09a9d1548..bdf62cae4 100644 --- a/tests/Squidex.Infrastructure.Tests/NamedIdTests.cs +++ b/tests/Squidex.Infrastructure.Tests/NamedIdTests.cs @@ -6,7 +6,6 @@ // ========================================================================== using System; -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.TestHelpers; using Xunit; @@ -91,7 +90,9 @@ namespace Squidex.Infrastructure { NamedId value = null; - value.SerializeAndDeserialize(new NamedGuidIdConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -99,7 +100,9 @@ namespace Squidex.Infrastructure { var value = NamedId.Of(Guid.NewGuid(), "my-name"); - value.SerializeAndDeserialize(new NamedGuidIdConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -107,7 +110,9 @@ namespace Squidex.Infrastructure { NamedId value = null; - value.SerializeAndDeserialize(new NamedLongIdConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -115,7 +120,9 @@ namespace Squidex.Infrastructure { var value = NamedId.Of(123L, "my-name"); - value.SerializeAndDeserialize(new NamedLongIdConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -123,7 +130,9 @@ namespace Squidex.Infrastructure { NamedId value = null; - value.SerializeAndDeserialize(new NamedStringIdConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -131,27 +140,27 @@ namespace Squidex.Infrastructure { var value = NamedId.Of(Guid.NewGuid().ToString(), "my-name"); - value.SerializeAndDeserialize(new NamedStringIdConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] public void Should_throw_exception_if_string_id_is_not_valid() { - JsonHelper.DoesNotDeserialize>("123", new NamedStringIdConverter()); + Assert.ThrowsAny(() => JsonHelper.Deserialize>("123")); } [Fact] public void Should_throw_exception_if_long_id_is_not_valid() { - JsonHelper.DoesNotDeserialize>("123", new NamedLongIdConverter()); - JsonHelper.DoesNotDeserialize>("invalid-long,name", new NamedLongIdConverter()); + Assert.ThrowsAny(() => JsonHelper.Deserialize>("invalid-long,name")); } [Fact] public void Should_throw_exception_if_guid_id_is_not_valid() { - JsonHelper.DoesNotDeserialize>("123", new NamedGuidIdConverter()); - JsonHelper.DoesNotDeserialize>("invalid-guid,name", new NamedGuidIdConverter()); + Assert.ThrowsAny(() => JsonHelper.Deserialize>("invalid-guid,name")); } } } diff --git a/tests/Squidex.Infrastructure.Tests/Orleans/JsonExternalSerializerTests.cs b/tests/Squidex.Infrastructure.Tests/Orleans/JsonExternalSerializerTests.cs index 27e06eb9d..608347c0c 100644 --- a/tests/Squidex.Infrastructure.Tests/Orleans/JsonExternalSerializerTests.cs +++ b/tests/Squidex.Infrastructure.Tests/Orleans/JsonExternalSerializerTests.cs @@ -11,12 +11,18 @@ using System.Collections.Generic; using System.IO; using FakeItEasy; using Orleans.Serialization; +using Squidex.Infrastructure.TestHelpers; using Xunit; namespace Squidex.Infrastructure.Orleans { public class JsonExternalSerializerTests { + public JsonExternalSerializerTests() + { + J.DefaultSerializer = JsonHelper.DefaultSerializer(); + } + [Fact] public void Should_not_copy_null() { diff --git a/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs b/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs index d6888f058..defe9c236 100644 --- a/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs +++ b/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs @@ -10,7 +10,6 @@ using System.Globalization; using System.Linq; using Microsoft.CSharp.RuntimeBinder; using NodaTime; -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.TestHelpers; using Xunit; @@ -30,7 +29,7 @@ namespace Squidex.Infrastructure [Fact] public void Should_serialize_and_deserialize_empty_bag() { - var output = bag.SerializeAndDeserializeAndReturn(new PropertiesBagConverter()); + var output = bag.SerializeAndDeserialize(); Assert.Equal(bag.Count, output.Count); } @@ -46,7 +45,7 @@ namespace Squidex.Infrastructure bag.Set("Key4", true); bag.Set("Key5", Guid.NewGuid()); - var output = bag.SerializeAndDeserializeAndReturn(new PropertiesBagConverter()); + var output = bag.SerializeAndDeserialize(); foreach (var kvp in output.Properties.Take(4)) { diff --git a/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs b/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs index b985b7a97..09620ee0f 100644 --- a/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs +++ b/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs @@ -6,7 +6,6 @@ // ========================================================================== using System; -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.TestHelpers; using Xunit; @@ -111,7 +110,9 @@ namespace Squidex.Infrastructure { RefToken value = null; - value.SerializeAndDeserialize(new RefTokenConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } [Fact] @@ -119,7 +120,9 @@ namespace Squidex.Infrastructure { var value = RefToken.Parse("client:client1"); - value.SerializeAndDeserialize(new RefTokenConverter()); + var serialized = value.SerializeAndDeserialize(); + + Assert.Equal(value, serialized); } } } diff --git a/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs b/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs index d78a249d8..76bb82676 100644 --- a/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs +++ b/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs @@ -7,64 +7,59 @@ using System; using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; -using Xunit; +using Newtonsoft.Json.Converters; +using Squidex.Infrastructure.EventSourcing; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Json.Newtonsoft; namespace Squidex.Infrastructure.TestHelpers { public static class JsonHelper { - public static void SerializeAndDeserialize(this T value, IContractResolver contractResolver) + public static IJsonSerializer DefaultSerializer(TypeNameRegistry typeNameRegistry = null) { var serializerSettings = new JsonSerializerSettings { - ContractResolver = contractResolver, - NullValueHandling = NullValueHandling.Include - }; - - var result = JsonConvert.SerializeObject(Tuple.Create(value), serializerSettings); - var output = JsonConvert.DeserializeObject>(result, serializerSettings); + SerializationBinder = new TypeNameSerializationBinder(typeNameRegistry ?? new TypeNameRegistry()), - Assert.Equal(value, output.Item1); - } + ContractResolver = new ConverterContractResolver( + new ClaimsPrincipalConverter(), + new InstantConverter(), + new JsonValueConverter(), + new LanguageConverter(), + new NamedGuidIdConverter(), + new NamedLongIdConverter(), + new NamedStringIdConverter(), + new PropertiesBagConverter(), + new PropertiesBagConverter(), + new RefTokenConverter(), + new StringEnumConverter()), - public static void SerializeAndDeserialize(this T value, JsonConverter converter) - { - var output = SerializeAndDeserializeAndReturn(value, converter); + TypeNameHandling = TypeNameHandling.Auto + }; - Assert.Equal(value, output); + return new NewtonsoftJsonSerializer(serializerSettings); } - public static T SerializeAndDeserializeAndReturn(this T value, JsonConverter converter) + public static T SerializeAndDeserialize(this T value) { - var serializerSettings = CreateSettings(converter); + var serializer = DefaultSerializer(); - var result = JsonConvert.SerializeObject(Tuple.Create(value), serializerSettings); - var output = JsonConvert.DeserializeObject>(result, serializerSettings); - - return output.Item1; + return serializer.Deserialize>(serializer.Serialize(Tuple.Create(value))).Item1; } - public static void DoesNotDeserialize(string value, JsonConverter converter) + public static T Deserialize(string value) { - var serializerSettings = CreateSettings(converter); + var serializer = DefaultSerializer(); - Assert.ThrowsAny(() => JsonConvert.DeserializeObject>($"{{ \"Item1\": \"{value}\" }}", serializerSettings)); + return serializer.Deserialize>($"{{ \"Item1\": \"{value}\" }}").Item1; } - private static JsonSerializerSettings CreateSettings(JsonConverter converter) + public static T Deserialize(object value) { - var serializerSettings = new JsonSerializerSettings(); - - if (converter != null) - { - serializerSettings.Converters.Add(converter); - } - - serializerSettings.NullValueHandling = NullValueHandling.Include; - serializerSettings.TypeNameHandling = TypeNameHandling.Auto; + var serializer = DefaultSerializer(); - return serializerSettings; + return serializer.Deserialize>($"{{ \"Item1\": {value} }}").Item1; } } }