Browse Source

Started with json migration.

pull/335/head
Sebastian Stehle 7 years ago
parent
commit
ca0161543c
  1. 2
      src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppClientsConverter.cs
  2. 2
      src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppContributorsConverter.cs
  3. 2
      src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs
  4. 2
      src/Squidex.Domain.Apps.Core.Model/Apps/Json/LanguagesConfigConverter.cs
  5. 2
      src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs
  6. 4
      src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs
  7. 22
      src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs
  8. 2
      src/Squidex.Domain.Apps.Core.Model/Rules/Json/RuleConverter.cs
  9. 5
      src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs
  10. 3
      src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaConverter.cs
  11. 19
      src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs
  12. 6
      src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverterFlat.cs
  13. 17
      src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs
  14. 4
      src/Squidex.Domain.Apps.Core.Operations/ConvertContent/Value.cs
  15. 22
      src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ValueConverters.cs
  16. 11
      src/Squidex.Domain.Apps.Core.Operations/EnrichContent/ContentEnricher.cs
  17. 50
      src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs
  18. 4
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ContentReferencesExtensions.cs
  19. 36
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs
  20. 27
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs
  21. 12
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs
  22. 4
      src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs
  23. 3
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedEvent.cs
  24. 7
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleActionHandler.cs
  25. 26
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs
  26. 38
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs
  27. 19
      src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs
  28. 8
      src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs
  29. 84
      src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs
  30. 34
      src/Squidex.Domain.Apps.Core.Operations/Tags/TagNormalizer.cs
  31. 5
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs
  32. 153
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs
  33. 7
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs
  34. 2
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/ObjectValidator.cs
  35. 4
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs
  36. 4
      src/Squidex.Infrastructure.GetEventStore/EventSourcing/Formatter.cs
  37. 8
      src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs
  38. 12
      src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs
  39. 2
      src/Squidex.Infrastructure/Assets/AssetFile.cs
  40. 26
      src/Squidex.Infrastructure/EventSourcing/DefaultEventDataFormatter.cs
  41. 6
      src/Squidex.Infrastructure/EventSourcing/EventData.cs
  42. 23
      src/Squidex.Infrastructure/Json/IJsonSerializer.cs
  43. 34
      src/Squidex.Infrastructure/Json/JsonExtension.cs
  44. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/ClaimsPrincipalConverter.cs
  45. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs
  46. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs
  47. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs
  48. 161
      src/Squidex.Infrastructure/Json/Newtonsoft/JsonValueConverter.cs
  49. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/LanguageConverter.cs
  50. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/NamedGuidIdConverter.cs
  51. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/NamedLongIdConverter.cs
  52. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs
  53. 60
      src/Squidex.Infrastructure/Json/Newtonsoft/NewtonsoftJsonSerializer.cs
  54. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/PropertiesBagConverter.cs
  55. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/RefTokenConverter.cs
  56. 2
      src/Squidex.Infrastructure/Json/Newtonsoft/TypeNameSerializationBinder.cs
  57. 18
      src/Squidex.Infrastructure/Json/Objects/IJsonValue.cs
  58. 100
      src/Squidex.Infrastructure/Json/Objects/JsonArray.cs
  59. 55
      src/Squidex.Infrastructure/Json/Objects/JsonNull.cs
  60. 129
      src/Squidex.Infrastructure/Json/Objects/JsonObject.cs
  61. 60
      src/Squidex.Infrastructure/Json/Objects/JsonScalar.cs
  62. 114
      src/Squidex.Infrastructure/Json/Objects/JsonValue.cs
  63. 19
      src/Squidex.Infrastructure/Json/Objects/JsonValueType.cs
  64. 6
      src/Squidex.Infrastructure/Orleans/J.cs
  65. 20
      src/Squidex.Infrastructure/Orleans/J{T}.cs
  66. 8
      tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppClientJsonTests.cs
  67. 6
      tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppContributorsJsonTests.cs
  68. 8
      tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs
  69. 10
      tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPlanTests.cs
  70. 10
      tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/LanguagesConfigJsonTests.cs
  71. 8
      tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs
  72. 3
      tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs
  73. 8
      tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs
  74. 5
      tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs
  75. 46
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionFlatTests.cs
  76. 6
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs
  77. 90
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs
  78. 36
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs
  79. 38
      tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs
  80. 36
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs
  81. 9
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleEventFormatterTests.cs
  82. 17
      tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs
  83. 14
      tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs
  84. 37
      tests/Squidex.Domain.Apps.Core.Tests/Operations/Tags/TagNormalizerTests.cs
  85. 14
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs
  86. 8
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/AssetsFieldTests.cs
  87. 8
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/BooleanFieldTests.cs
  88. 15
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs
  89. 14
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/DateTimeFieldTests.cs
  90. 45
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs
  91. 8
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/JsonFieldTests.cs
  92. 12
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs
  93. 8
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs
  94. 6
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs
  95. 8
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs
  96. 6
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs
  97. 13
      tests/Squidex.Domain.Apps.Core.Tests/TestData.cs
  98. 14
      tests/Squidex.Infrastructure.Tests/EventSourcing/DefaultEventDataFormatterTests.cs
  99. 3
      tests/Squidex.Infrastructure.Tests/EventSourcing/EnvelopeTests.cs
  100. 10
      tests/Squidex.Infrastructure.Tests/Json/ClaimsPrincipalConverterTests.cs

2
src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppClientsConverter.cs

@ -9,7 +9,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Newtonsoft;
namespace Squidex.Domain.Apps.Core.Apps.Json namespace Squidex.Domain.Apps.Core.Apps.Json
{ {

2
src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppContributorsConverter.cs

@ -9,7 +9,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Newtonsoft;
namespace Squidex.Domain.Apps.Core.Apps.Json namespace Squidex.Domain.Apps.Core.Apps.Json
{ {

2
src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs

@ -9,7 +9,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Newtonsoft;
namespace Squidex.Domain.Apps.Core.Apps.Json namespace Squidex.Domain.Apps.Core.Apps.Json
{ {

2
src/Squidex.Domain.Apps.Core.Model/Apps/Json/LanguagesConfigConverter.cs

@ -7,7 +7,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Newtonsoft;
namespace Squidex.Domain.Apps.Core.Apps.Json namespace Squidex.Domain.Apps.Core.Apps.Json
{ {

2
src/Squidex.Domain.Apps.Core.Model/Apps/Json/RolesConverter.cs

@ -6,7 +6,7 @@
// ========================================================================== // ==========================================================================
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Newtonsoft;
using Squidex.Infrastructure.Security; using Squidex.Infrastructure.Security;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

4
src/Squidex.Domain.Apps.Core.Model/Contents/ContentData.cs

@ -9,7 +9,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Contents namespace Squidex.Domain.Apps.Core.Contents
{ {
@ -61,7 +61,7 @@ namespace Squidex.Domain.Apps.Core.Contents
{ {
var resultValue = new ContentFieldData(); 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; resultValue[partitionValue.Key] = partitionValue.Value;
} }

22
src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs

@ -7,21 +7,24 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Contents namespace Squidex.Domain.Apps.Core.Contents
{ {
public sealed class ContentFieldData : Dictionary<string, JToken>, IEquatable<ContentFieldData> public sealed class ContentFieldData : Dictionary<string, IJsonValue>, IEquatable<ContentFieldData>
{ {
private static readonly JTokenEqualityComparer JTokenEqualityComparer = new JTokenEqualityComparer();
public ContentFieldData() public ContentFieldData()
: base(StringComparer.OrdinalIgnoreCase) : 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)); Guard.NotNullOrEmpty(key, nameof(key));
@ -30,11 +33,6 @@ namespace Squidex.Domain.Apps.Core.Contents
return this; return this;
} }
public ContentFieldData AddValue(JToken value)
{
return AddValue(InvariantPartitioning.Instance.Master.Key, value);
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return Equals(obj as ContentFieldData); return Equals(obj as ContentFieldData);
@ -42,12 +40,12 @@ namespace Squidex.Domain.Apps.Core.Contents
public bool Equals(ContentFieldData other) public bool Equals(ContentFieldData other)
{ {
return other != null && (ReferenceEquals(this, other) || this.EqualsDictionary(other, EqualityComparer<string>.Default, JTokenEqualityComparer)); return other != null && (ReferenceEquals(this, other) || this.EqualsDictionary(other));
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return this.DictionaryHashCode(EqualityComparer<string>.Default, JTokenEqualityComparer); return this.DictionaryHashCode();
} }
} }
} }

2
src/Squidex.Domain.Apps.Core.Model/Rules/Json/RuleConverter.cs

@ -7,7 +7,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Newtonsoft;
namespace Squidex.Domain.Apps.Core.Rules.Json namespace Squidex.Domain.Apps.Core.Rules.Json
{ {

5
src/Squidex.Domain.Apps.Core.Model/Rules/RuleJob.cs

@ -6,7 +6,6 @@
// ========================================================================== // ==========================================================================
using System; using System;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
namespace Squidex.Domain.Apps.Core.Rules namespace Squidex.Domain.Apps.Core.Rules
@ -23,12 +22,12 @@ namespace Squidex.Domain.Apps.Core.Rules
public string ActionName { get; set; } public string ActionName { get; set; }
public string ActionData { get; set; }
public string Description { get; set; } public string Description { get; set; }
public Instant Created { get; set; } public Instant Created { get; set; }
public Instant Expires { get; set; } public Instant Expires { get; set; }
public JObject ActionData { get; set; }
} }
} }

3
src/Squidex.Domain.Apps.Core.Model/Schemas/Json/SchemaConverter.cs

@ -7,8 +7,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using Squidex.Infrastructure; using Squidex.Infrastructure.Json.Newtonsoft;
using Squidex.Infrastructure.Json;
namespace Squidex.Domain.Apps.Core.Schemas.Json namespace Squidex.Domain.Apps.Core.Schemas.Json
{ {

19
src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverter.cs

@ -7,13 +7,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent namespace Squidex.Domain.Apps.Core.ConvertContent
{ {
@ -41,11 +40,11 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
return result; 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) if (text.Length <= maxFieldLength)
{ {
@ -57,18 +56,18 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
stringBuilder.Append(text); 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); 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);
} }
} }
} }

6
src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ContentConverterFlat.cs

@ -7,10 +7,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent namespace Squidex.Domain.Apps.Core.ConvertContent
{ {
@ -30,7 +30,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
languagePreferences = languagePreferences.Union(languageConfig.LanguageFallbacks).ToList(); languagePreferences = languagePreferences.Union(languageConfig.LanguageFallbacks).ToList();
} }
var result = new Dictionary<string, JToken>(); var result = new Dictionary<string, IJsonValue>();
foreach (var fieldValue in content) foreach (var fieldValue in content)
{ {
@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
foreach (var language in languagePreferences) 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; result[fieldValue.Key] = value;

17
src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs

@ -8,13 +8,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
#pragma warning disable RECS0002 // Convert anonymous method to method group #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) foreach (var value in data.Values)
{ {
if (value.IsNull()) if (value.Type == JsonValueType.Null)
{ {
continue; continue;
} }
@ -78,13 +77,13 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
{ {
foreach (var partition in data) 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++) for (var i = 0; i < array.Count; i++)
{ {
var id = array[i].ToString(); 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) foreach (var partition in data)
{ {
if (!(partition.Value is JArray jArray)) if (!(partition.Value is JsonArray array))
{ {
continue; continue;
} }
var newArray = new JArray(); var newArray = JsonValue.Array();
foreach (var item in jArray.OfType<JObject>()) foreach (var item in array.OfType<JsonObject>())
{ {
var newItem = new JObject(); var newItem = JsonValue.Object();
foreach (var kvp in item) foreach (var kvp in item)
{ {

4
src/Squidex.Domain.Apps.Core.Operations/ConvertContent/Value.cs

@ -5,12 +5,12 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Newtonsoft.Json.Linq; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent namespace Squidex.Domain.Apps.Core.ConvertContent
{ {
public static class Value public static class Value
{ {
public static readonly JToken Unset = JValue.CreateUndefined(); public static readonly IJsonValue Unset = JsonValue.Create("UNSET");
} }
} }

22
src/Squidex.Domain.Apps.Core.Operations/ConvertContent/ValueConverters.cs

@ -7,41 +7,41 @@
using System; using System;
using System.Text; using System.Text;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ConvertContent 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 class ValueConverters
{ {
public static ValueConverter DecodeJson() public static ValueConverter DecodeJson(IJsonSerializer jsonSerializer)
{ {
return (value, field) => return (value, field) =>
{ {
if (!value.IsNull() && field is IField<JsonFieldProperties>) if (field is IField<JsonFieldProperties> && value is JsonScalar<string> 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<IJsonValue>(decoded);
} }
return value; return value;
}; };
} }
public static ValueConverter EncodeJson() public static ValueConverter EncodeJson(IJsonSerializer jsonSerializer)
{ {
return (value, field) => return (value, field) =>
{ {
if (!value.IsNull() && field is IField<JsonFieldProperties>) if (value.Type != JsonValueType.Null && field is IField<JsonFieldProperties>)
{ {
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; return value;
@ -57,7 +57,7 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
{ {
return (value, field) => return (value, field) =>
{ {
if (value.IsNull()) if (value.Type == JsonValueType.Null)
{ {
return value; return value;
} }

11
src/Squidex.Domain.Apps.Core.Operations/EnrichContent/ContentEnricher.cs

@ -5,12 +5,11 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.EnrichContent namespace Squidex.Domain.Apps.Core.EnrichContent
{ {
@ -56,7 +55,7 @@ namespace Squidex.Domain.Apps.Core.EnrichContent
var defaultValue = DefaultValueFactory.CreateDefaultValue(field, SystemClock.Instance.GetCurrentInstant()); var defaultValue = DefaultValueFactory.CreateDefaultValue(field, SystemClock.Instance.GetCurrentInstant());
if (field.RawProperties.IsRequired || defaultValue.IsNull()) if (field.RawProperties.IsRequired || defaultValue.Type == JsonValueType.Null)
{ {
return; return;
} }
@ -65,13 +64,13 @@ namespace Squidex.Domain.Apps.Core.EnrichContent
if (!fieldData.TryGetValue(key, out var value) || ShouldApplyDefaultValue(field, value)) 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<StringFieldProperties> && value is JValue jValue && Equals(jValue.Value, string.Empty)); return value.Type == JsonValueType.Null || (field is IField<StringFieldProperties> && value is JsonScalar<string> s && string.IsNullOrEmpty(s.Value));
} }
} }
} }

50
src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs

@ -6,14 +6,14 @@
// ========================================================================== // ==========================================================================
using System.Globalization; using System.Globalization;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.EnrichContent namespace Squidex.Domain.Apps.Core.EnrichContent
{ {
public sealed class DefaultValueFactory : IFieldVisitor<JToken> public sealed class DefaultValueFactory : IFieldVisitor<IJsonValue>
{ {
private readonly Instant now; private readonly Instant now;
@ -22,71 +22,71 @@ namespace Squidex.Domain.Apps.Core.EnrichContent
this.now = now; this.now = now;
} }
public static JToken CreateDefaultValue(IField field, Instant now) public static IJsonValue CreateDefaultValue(IField field, Instant now)
{ {
Guard.NotNull(field, nameof(field)); Guard.NotNull(field, nameof(field));
return field.Accept(new DefaultValueFactory(now)); 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<AssetsFieldProperties> field) public IJsonValue Visit(IField<AssetsFieldProperties> field)
{ {
return new JArray(); return JsonValue.Array();
} }
public JToken Visit(IField<BooleanFieldProperties> field) public IJsonValue Visit(IField<BooleanFieldProperties> field)
{ {
return field.Properties.DefaultValue; return JsonValue.Create(field.Properties.DefaultValue);
} }
public JToken Visit(IField<GeolocationFieldProperties> field) public IJsonValue Visit(IField<GeolocationFieldProperties> field)
{ {
return JValue.CreateNull(); return JsonValue.Null;
} }
public JToken Visit(IField<JsonFieldProperties> field) public IJsonValue Visit(IField<JsonFieldProperties> field)
{ {
return JValue.CreateNull(); return JsonValue.Object();
} }
public JToken Visit(IField<NumberFieldProperties> field) public IJsonValue Visit(IField<NumberFieldProperties> field)
{ {
return field.Properties.DefaultValue; return JsonValue.Create(field.Properties.DefaultValue);
} }
public JToken Visit(IField<ReferencesFieldProperties> field) public IJsonValue Visit(IField<ReferencesFieldProperties> field)
{ {
return new JArray(); return JsonValue.Array();
} }
public JToken Visit(IField<StringFieldProperties> field) public IJsonValue Visit(IField<StringFieldProperties> field)
{ {
return field.Properties.DefaultValue; return JsonValue.Create(field.Properties.DefaultValue);
} }
public JToken Visit(IField<TagsFieldProperties> field) public IJsonValue Visit(IField<TagsFieldProperties> field)
{ {
return new JArray(); return JsonValue.Array();
} }
public JToken Visit(IField<DateTimeFieldProperties> field) public IJsonValue Visit(IField<DateTimeFieldProperties> field)
{ {
if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Now) if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Now)
{ {
return now.ToString(); return JsonValue.Create(now.ToString());
} }
if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Today) 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());
} }
} }
} }

4
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.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
continue; 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); var ids = field.ExtractReferences(partitionValue.Value);

36
src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesCleaner.cs

@ -7,44 +7,44 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
public sealed class ReferencesCleaner : IFieldVisitor<JToken> public sealed class ReferencesCleaner : IFieldVisitor<IJsonValue>
{ {
private readonly JToken value; private readonly IJsonValue value;
private readonly ICollection<Guid> oldReferences; private readonly ICollection<Guid> oldReferences;
private ReferencesCleaner(JToken value, ICollection<Guid> oldReferences) private ReferencesCleaner(IJsonValue value, ICollection<Guid> oldReferences)
{ {
this.value = value; this.value = value;
this.oldReferences = oldReferences; this.oldReferences = oldReferences;
} }
public static JToken CleanReferences(IField field, JToken value, ICollection<Guid> oldReferences) public static IJsonValue CleanReferences(IField field, IJsonValue value, ICollection<Guid> oldReferences)
{ {
return field.Accept(new ReferencesCleaner(value, oldReferences)); return field.Accept(new ReferencesCleaner(value, oldReferences));
} }
public JToken Visit(IField<AssetsFieldProperties> field) public IJsonValue Visit(IField<AssetsFieldProperties> field)
{ {
return CleanIds(); return CleanIds();
} }
public JToken Visit(IField<ReferencesFieldProperties> field) public IJsonValue Visit(IField<ReferencesFieldProperties> field)
{ {
if (oldReferences.Contains(field.Properties.SchemaId)) if (oldReferences.Contains(field.Properties.SchemaId))
{ {
return new JArray(); return JsonValue.Array();
} }
return CleanIds(); return CleanIds();
} }
private JToken CleanIds() private IJsonValue CleanIds()
{ {
var ids = value.ToGuidSet(); var ids = value.ToGuidSet();
@ -55,45 +55,45 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
isRemoved |= ids.Remove(oldReference); isRemoved |= ids.Remove(oldReference);
} }
return isRemoved ? ids.ToJToken() : value; return isRemoved ? ids.ToJsonArray() : value;
} }
public JToken Visit(IField<BooleanFieldProperties> field) public IJsonValue Visit(IField<BooleanFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IField<DateTimeFieldProperties> field) public IJsonValue Visit(IField<DateTimeFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IField<GeolocationFieldProperties> field) public IJsonValue Visit(IField<GeolocationFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IField<JsonFieldProperties> field) public IJsonValue Visit(IField<JsonFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IField<NumberFieldProperties> field) public IJsonValue Visit(IField<NumberFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IField<StringFieldProperties> field) public IJsonValue Visit(IField<StringFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IField<TagsFieldProperties> field) public IJsonValue Visit(IField<TagsFieldProperties> field)
{ {
return value; return value;
} }
public JToken Visit(IArrayField field) public IJsonValue Visit(IArrayField field)
{ {
return value; return value;
} }

27
src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtensions.cs

@ -7,22 +7,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
public static class ReferencesExtensions public static class ReferencesExtensions
{ {
public static IEnumerable<Guid> ExtractReferences(this IField field, JToken value) public static IEnumerable<Guid> ExtractReferences(this IField field, IJsonValue value)
{ {
return ReferencesExtractor.ExtractReferences(field, value); return ReferencesExtractor.ExtractReferences(field, value);
} }
public static JToken CleanReferences(this IField field, JToken value, ICollection<Guid> oldReferences) public static IJsonValue CleanReferences(this IField field, IJsonValue value, ICollection<Guid> oldReferences)
{ {
if (value.IsNull()) if (value.Type == JsonValueType.Null)
{ {
return value; return value;
} }
@ -30,31 +29,27 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
return ReferencesCleaner.CleanReferences(field, value, oldReferences); return ReferencesCleaner.CleanReferences(field, value, oldReferences);
} }
public static JToken ToJToken(this HashSet<Guid> ids) public static JsonArray ToJsonArray(this HashSet<Guid> ids)
{ {
var result = new JArray(); var result = JsonValue.Array();
foreach (var id in ids) foreach (var id in ids)
{ {
result.Add(new JValue(id)); result.Add(JsonValue.Create(id.ToString()));
} }
return result; return result;
} }
public static HashSet<Guid> ToGuidSet(this JToken value) public static HashSet<Guid> ToGuidSet(this IJsonValue value)
{ {
if (value is JArray ids) if (value is JsonArray array)
{ {
var result = new HashSet<Guid>(); var result = new HashSet<Guid>();
foreach (var id in ids) foreach (var id in array)
{
if (id.Type == JTokenType.Guid)
{ {
result.Add((Guid)id); if (id.Type == JsonValueType.String && Guid.TryParse(id.ToString(), out var guid))
}
else if (id.Type == JTokenType.String && Guid.TryParse((string)id, out var guid))
{ {
result.Add(guid); result.Add(guid);
} }

12
src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ReferencesExtractor.cs

@ -8,21 +8,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
public sealed class ReferencesExtractor : IFieldVisitor<IEnumerable<Guid>> public sealed class ReferencesExtractor : IFieldVisitor<IEnumerable<Guid>>
{ {
private readonly JToken value; private readonly IJsonValue value;
private ReferencesExtractor(JToken value) private ReferencesExtractor(IJsonValue value)
{ {
this.value = value; this.value = value;
} }
public static IEnumerable<Guid> ExtractReferences(IField field, JToken value) public static IEnumerable<Guid> ExtractReferences(IField field, IJsonValue value)
{ {
return field.Accept(new ReferencesExtractor(value)); return field.Accept(new ReferencesExtractor(value));
} }
@ -31,9 +31,9 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
var result = new List<Guid>(); var result = new List<Guid>();
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) foreach (var nestedField in field.Fields)
{ {

4
src/Squidex.Domain.Apps.Core.Operations/ExtractReferenceIds/ValueReferencesConverter.cs

@ -8,7 +8,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ConvertContent;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ExtractReferenceIds namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
{ {
@ -20,7 +20,7 @@ namespace Squidex.Domain.Apps.Core.ExtractReferenceIds
return (value, field) => return (value, field) =>
{ {
if (value.IsNull()) if (value.Type == JsonValueType.Null)
{ {
return value; return value;
} }

3
src/Squidex.Domain.Apps.Core.Operations/HandleRules/EnrichedEvents/EnrichedEvent.cs

@ -6,7 +6,6 @@
// ========================================================================== // ==========================================================================
using System; using System;
using Newtonsoft.Json;
using NodaTime; using NodaTime;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Shared.Users; using Squidex.Shared.Users;
@ -25,10 +24,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents
public long Version { get; set; } public long Version { get; set; }
[JsonIgnore]
public abstract Guid AggregateId { get; } public abstract Guid AggregateId { get; }
[JsonIgnore]
public IUser User { get; set; } public IUser User { get; set; }
} }
} }

7
src/Squidex.Domain.Apps.Core.Operations/HandleRules/IRuleActionHandler.cs

@ -7,7 +7,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
@ -17,8 +16,10 @@ namespace Squidex.Domain.Apps.Core.HandleRules
{ {
Type ActionType { get; } 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);
} }
} }

26
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleActionHandler.cs

@ -7,7 +7,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
@ -25,6 +24,11 @@ namespace Squidex.Domain.Apps.Core.HandleRules
get { return typeof(TAction); } get { return typeof(TAction); }
} }
Type IRuleActionHandler.DataType
{
get { return typeof(TData); }
}
protected RuleActionHandler(RuleEventFormatter formatter) protected RuleActionHandler(RuleEventFormatter formatter)
{ {
Guard.NotNull(formatter, nameof(formatter)); Guard.NotNull(formatter, nameof(formatter));
@ -33,21 +37,11 @@ namespace Squidex.Domain.Apps.Core.HandleRules
} }
protected virtual string ToPayloadJson<T>(T @event) protected virtual string ToPayloadJson<T>(T @event)
{
return formatter.ToPayload(@event).ToString();
}
protected virtual string ToEnvelopeJson(EnrichedEvent @event)
{
return formatter.ToEnvelope(@event).ToString();
}
protected virtual JObject ToPayload<T>(T @event)
{ {
return formatter.ToPayload(@event); return formatter.ToPayload(@event);
} }
protected virtual JObject ToEnvelope(EnrichedEvent @event) protected virtual string ToEnvelopeJson(EnrichedEvent @event)
{ {
return formatter.ToEnvelope(@event); return formatter.ToEnvelope(@event);
} }
@ -62,16 +56,16 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return formatter.Format(text, @event); 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); 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<TData>(); var typedData = (TData)data;
return await ExecuteJobAsync(typedData); return await ExecuteJobAsync(typedData);
} }

38
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs

@ -10,11 +10,11 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Shared.Users; using Squidex.Shared.Users;
namespace Squidex.Domain.Apps.Core.HandleRules 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 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 static readonly Regex ContentDataPlaceholderNew = new Regex(@"^\{CONTENT_DATA(\.([0-9A-Za-z\-_]*)){2,}\}", RegexOptions.Compiled);
private readonly List<(char[] Pattern, Func<EnrichedEvent, string> Replacer)> patterns = new List<(char[] Pattern, Func<EnrichedEvent, string> Replacer)>(); private readonly List<(char[] Pattern, Func<EnrichedEvent, string> Replacer)> patterns = new List<(char[] Pattern, Func<EnrichedEvent, string> Replacer)>();
private readonly JsonSerializer serializer; private readonly IJsonSerializer jsonSerializer;
private readonly IRuleUrlGenerator urlGenerator; 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)); Guard.NotNull(urlGenerator, nameof(urlGenerator));
this.serializer = serializer; this.jsonSerializer = jsonSerializer;
this.urlGenerator = urlGenerator; this.urlGenerator = urlGenerator;
AddPattern("APP_ID", AppId); AddPattern("APP_ID", AppId);
@ -55,17 +55,14 @@ namespace Squidex.Domain.Apps.Core.HandleRules
patterns.Add((placeholder.ToCharArray(), generator)); patterns.Add((placeholder.ToCharArray(), generator));
} }
public virtual JObject ToPayload<T>(T @event) public virtual string ToPayload<T>(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( return jsonSerializer.Serialize(new { type = @event.Name, payload = @event, timestamp = @event.Timestamp });
new JProperty("type", @event.Name),
new JProperty("payload", ToPayload(@event)),
new JProperty("timestamp", @event.Timestamp.ToString()));
} }
public string Format(string text, EnrichedEvent @event) 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++) 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; 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 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; return Undefined;
} }
if (value is JValue jValue) return value.ToString() ?? Undefined;
{
return jValue.Value.ToString();
}
return value.ToString(Formatting.Indented) ?? Undefined;
} }
} }
} }

19
src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleService.cs

@ -11,12 +11,12 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Events; using Squidex.Domain.Apps.Events;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
namespace Squidex.Domain.Apps.Core.HandleRules namespace Squidex.Domain.Apps.Core.HandleRules
{ {
@ -26,15 +26,18 @@ namespace Squidex.Domain.Apps.Core.HandleRules
private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers; private readonly Dictionary<Type, IRuleTriggerHandler> ruleTriggerHandlers;
private readonly TypeNameRegistry typeNameRegistry; private readonly TypeNameRegistry typeNameRegistry;
private readonly IEventEnricher eventEnricher; private readonly IEventEnricher eventEnricher;
private readonly IJsonSerializer jsonSerializer;
private readonly IClock clock; private readonly IClock clock;
public RuleService( public RuleService(
IEnumerable<IRuleTriggerHandler> ruleTriggerHandlers, IEnumerable<IRuleTriggerHandler> ruleTriggerHandlers,
IEnumerable<IRuleActionHandler> ruleActionHandlers, IEnumerable<IRuleActionHandler> ruleActionHandlers,
IEventEnricher eventEnricher, IEventEnricher eventEnricher,
IJsonSerializer jsonSerializer,
IClock clock, IClock clock,
TypeNameRegistry typeNameRegistry) TypeNameRegistry typeNameRegistry)
{ {
Guard.NotNull(jsonSerializer, nameof(jsonSerializer));
Guard.NotNull(ruleTriggerHandlers, nameof(ruleTriggerHandlers)); Guard.NotNull(ruleTriggerHandlers, nameof(ruleTriggerHandlers));
Guard.NotNull(ruleActionHandlers, nameof(ruleActionHandlers)); Guard.NotNull(ruleActionHandlers, nameof(ruleActionHandlers));
Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry)); Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry));
@ -48,6 +51,8 @@ namespace Squidex.Domain.Apps.Core.HandleRules
this.eventEnricher = eventEnricher; this.eventEnricher = eventEnricher;
this.jsonSerializer = jsonSerializer;
this.clock = clock; this.clock = clock;
} }
@ -104,11 +109,13 @@ namespace Squidex.Domain.Apps.Core.HandleRules
var actionName = typeNameRegistry.GetName(actionType); var actionName = typeNameRegistry.GetName(actionType);
var actionData = await actionHandler.CreateJobAsync(enrichedEvent, rule.Action); var actionData = await actionHandler.CreateJobAsync(enrichedEvent, rule.Action);
var json = jsonSerializer.Serialize(actionData);
var job = new RuleJob var job = new RuleJob
{ {
JobId = Guid.NewGuid(), JobId = Guid.NewGuid(),
ActionName = actionName, ActionName = actionName,
ActionData = actionData.Data, ActionData = json,
AggregateId = enrichedEvent.AggregateId, AggregateId = enrichedEvent.AggregateId,
AppId = appEvent.AppId.Id, AppId = appEvent.AppId.Id,
Created = now, Created = now,
@ -120,14 +127,18 @@ namespace Squidex.Domain.Apps.Core.HandleRules
return job; 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 try
{ {
var actionType = typeNameRegistry.GetType(actionName); var actionType = typeNameRegistry.GetType(actionName);
var actionWatch = Stopwatch.StartNew(); var actionWatch = Stopwatch.StartNew();
var result = await ruleActionHandlers[actionType].ExecuteJobAsync(job); var actionHandler = ruleActionHandlers[actionType];
var deserialized = jsonSerializer.Deserialize<object>(job, actionHandler.DataType);
var result = await actionHandler.ExecuteJobAsync(deserialized);
actionWatch.Stop(); actionWatch.Stop();

8
src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs

@ -7,14 +7,14 @@
using Jint.Native; using Jint.Native;
using Jint.Runtime.Descriptors; using Jint.Runtime.Descriptors;
using Newtonsoft.Json.Linq; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
{ {
public sealed class ContentFieldProperty : PropertyDescriptor public sealed class ContentFieldProperty : PropertyDescriptor
{ {
private readonly ContentFieldObject contentField; private readonly ContentFieldObject contentField;
private JToken contentValue; private IJsonValue contentValue;
private JsValue value; private JsValue value;
private bool isChanged; 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)); } get { return contentValue ?? (contentValue = JsonMapper.Map(value)); }
} }
@ -48,7 +48,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
get { return isChanged; } get { return isChanged; }
} }
public ContentFieldProperty(ContentFieldObject contentField, JToken contentValue = null) public ContentFieldProperty(ContentFieldObject contentField, IJsonValue contentValue = null)
: base(null, true, true, true) : base(null, true, true, true)
{ {
this.contentField = contentField; this.contentField = contentField;

84
src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs

@ -9,43 +9,40 @@ using System;
using Jint; using Jint;
using Jint.Native; using Jint.Native;
using Jint.Native.Object; using Jint.Native.Object;
using Newtonsoft.Json.Linq; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
{ {
public static class JsonMapper public static class JsonMapper
{ {
public static JsValue Map(JToken value, Engine engine) public static JsValue Map(IJsonValue value, Engine engine)
{ {
if (value == null) if (value == null)
{ {
return JsValue.Null; return JsValue.Null;
} }
switch (value.Type) switch (value)
{ {
case JTokenType.Date: case JsonNull n:
case JTokenType.Guid:
case JTokenType.String:
case JTokenType.Uri:
case JTokenType.TimeSpan:
return new JsValue((string)value);
case JTokenType.Null:
return JsValue.Null; return JsValue.Null;
case JTokenType.Undefined: case JsonScalar<string> s:
return JsValue.Undefined; return new JsValue(s.Value);
case JTokenType.Integer: case JsonScalar<bool> b:
return new JsValue((long)value); return new JsValue(b.Value);
case JTokenType.Float: case JsonScalar<double> b:
return new JsValue((double)value); return new JsValue(b.Value);
case JTokenType.Boolean: case JsonObject obj:
return new JsValue((bool)value); return FromObject(obj, engine);
case JTokenType.Object: case JsonArray arr:
return FromObject(value, engine); return FromArray(arr, engine);
case JTokenType.Array: }
{
var arr = (JArray)value; throw new ArgumentException("Invalid json type.", nameof(value));
}
private static JsValue FromArray(JsonArray arr, Engine engine)
{
var target = new JsValue[arr.Count]; var target = new JsValue[arr.Count];
for (var i = 0; i < arr.Count; i++) for (var i = 0; i < arr.Count; i++)
@ -55,15 +52,9 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return engine.Array.Construct(target); return engine.Array.Construct(target);
} }
}
throw new ArgumentException("Invalid json type.", nameof(value)); private static JsValue FromObject(JsonObject obj, Engine engine)
}
private static JsValue FromObject(JToken value, Engine engine)
{ {
var obj = (JObject)value;
var target = new ObjectInstance(engine); var target = new ObjectInstance(engine);
foreach (var property in obj) foreach (var property in obj)
@ -74,69 +65,64 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return target; return target;
} }
public static JToken Map(JsValue value) public static IJsonValue Map(JsValue value)
{ {
if (value == null || value.IsNull()) if (value == null || value.IsNull() || value.IsUndefined())
{ {
return JValue.CreateNull(); return JsonValue.Null;
}
if (value.IsUndefined())
{
return JValue.CreateUndefined();
} }
if (value.IsString()) if (value.IsString())
{ {
return new JValue(value.AsString()); return JsonValue.Create(value.AsString());
} }
if (value.IsBoolean()) if (value.IsBoolean())
{ {
return new JValue(value.AsBoolean()); return JsonValue.Create(value.AsBoolean());
} }
if (value.IsNumber()) if (value.IsNumber())
{ {
return new JValue(value.AsNumber()); return JsonValue.Create(value.AsNumber());
} }
if (value.IsDate()) if (value.IsDate())
{ {
return new JValue(value.AsDate().ToDateTime()); return JsonValue.Create(value.AsDate().ToString());
} }
if (value.IsRegExp()) if (value.IsRegExp())
{ {
return JValue.CreateString(value.AsRegExp().Value?.ToString()); return JsonValue.Create(value.AsRegExp().Value?.ToString());
} }
if (value.IsArray()) if (value.IsArray())
{ {
var arr = value.AsArray(); var arr = value.AsArray();
var target = new JArray(); var result = JsonValue.Array();
for (var i = 0; i < arr.GetLength(); i++) 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()) if (value.IsObject())
{ {
var obj = value.AsObject(); var obj = value.AsObject();
var target = new JObject(); var result = JsonValue.Object();
foreach (var kvp in obj.GetOwnProperties()) 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)); throw new ArgumentException("Invalid json type.", nameof(value));

34
src/Squidex.Domain.Apps.Core.Operations/Tags/TagNormalizer.cs

@ -8,10 +8,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Tags namespace Squidex.Domain.Apps.Core.Tags
{ {
@ -24,10 +24,10 @@ namespace Squidex.Domain.Apps.Core.Tags
Guard.NotNull(newData, nameof(newData)); Guard.NotNull(newData, nameof(newData));
var newValues = new HashSet<string>(); var newValues = new HashSet<string>();
var newArrays = new List<JArray>(); var newArrays = new List<JsonArray>();
var oldValues = new HashSet<string>(); var oldValues = new HashSet<string>();
var oldArrays = new List<JArray>(); var oldArrays = new List<JsonArray>();
GetValues(schema, newValues, newArrays, newData); GetValues(schema, newValues, newArrays, newData);
@ -46,7 +46,7 @@ namespace Squidex.Domain.Apps.Core.Tags
{ {
if (normalized.TryGetValue(array[i].ToString(), out var result)) 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)); Guard.NotNull(schema, nameof(schema));
var tagsValues = new HashSet<string>(); var tagsValues = new HashSet<string>();
var tagsArrays = new List<JArray>(); var tagsArrays = new List<JsonArray>();
GetValues(schema, tagsValues, tagsArrays, datas); GetValues(schema, tagsValues, tagsArrays, datas);
@ -73,14 +73,14 @@ namespace Squidex.Domain.Apps.Core.Tags
{ {
if (denormalized.TryGetValue(array[i].ToString(), out var result)) if (denormalized.TryGetValue(array[i].ToString(), out var result))
{ {
array[i] = result; array[i] = JsonValue.Create(result);
} }
} }
} }
} }
} }
private static void GetValues(Schema schema, HashSet<string> values, List<JArray> arrays, params NamedContentData[] datas) private static void GetValues(Schema schema, HashSet<string> values, List<JsonArray> arrays, params NamedContentData[] datas)
{ {
foreach (var field in schema.Fields) foreach (var field in schema.Fields)
{ {
@ -109,14 +109,12 @@ namespace Squidex.Domain.Apps.Core.Tags
{ {
foreach (var partition in fieldData) 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)) if (nestedObject.TryGetValue(nestedField.Name, out var nestedValue))
{ {
ExtractTags(nestedValue, values, arrays); ExtractTags(nestedValue, values, arrays);
@ -133,19 +131,19 @@ namespace Squidex.Domain.Apps.Core.Tags
} }
} }
private static void ExtractTags(JToken token, ISet<string> values, ICollection<JArray> arrays) private static void ExtractTags(IJsonValue value, ISet<string> values, ICollection<JsonArray> 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);
} }
} }
} }

5
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ContentValidator.cs

@ -9,11 +9,11 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent.Validators; using Squidex.Domain.Apps.Core.ValidateContent.Validators;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
#pragma warning disable SA1028, IDE0004 // Code must not contain trailing whitespace #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 public sealed class ContentValidator
{ {
private static readonly ContentFieldData DefaultFieldData = new ContentFieldData(); private static readonly ContentFieldData DefaultFieldData = new ContentFieldData();
private static readonly JToken DefaultValue = JValue.CreateNull();
private readonly Schema schema; private readonly Schema schema;
private readonly PartitionResolver partitionResolver; private readonly PartitionResolver partitionResolver;
private readonly ValidationContext context; private readonly ValidationContext context;
@ -96,7 +95,7 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
var type = isLanguage ? "language" : "invariant value"; var type = isLanguage ? "language" : "invariant value";
return new ObjectValidator<JToken>(fieldsValidators, isPartial, type, DefaultValue); return new ObjectValidator<IJsonValue>(fieldsValidators, isPartial, type, JsonValue.Null);
} }
} }
} }

153
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs

@ -7,45 +7,80 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using NodaTime.Text; using NodaTime.Text;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ValidateContent namespace Squidex.Domain.Apps.Core.ValidateContent
{ {
public sealed class JsonValueConverter : IFieldVisitor<object> public sealed class JsonValueConverter : IFieldVisitor<object>
{ {
private readonly JToken value; private readonly IJsonValue value;
private JsonValueConverter(JToken value) private JsonValueConverter(IJsonValue value)
{ {
this.value = 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)); return field.Accept(new JsonValueConverter(json));
} }
public object Visit(IArrayField field) public object Visit(IArrayField field)
{ {
return value.ToObject<List<JObject>>(); return ConvertToObjectList();
} }
public object Visit(IField<AssetsFieldProperties> field) public object Visit(IField<AssetsFieldProperties> field)
{ {
return value.ToObject<List<Guid>>(); return ConvertToGuidList();
}
public object Visit(IField<ReferencesFieldProperties> field)
{
return ConvertToGuidList();
}
public object Visit(IField<TagsFieldProperties> field)
{
return ConvertToStringList();
} }
public object Visit(IField<BooleanFieldProperties> field) public object Visit(IField<BooleanFieldProperties> field)
{ {
return (bool?)value; if (value is JsonScalar<bool> b)
{
return b.Value;
}
throw new InvalidCastException("Invalid json type, expected boolean.");
}
public object Visit(IField<NumberFieldProperties> field)
{
if (value is JsonScalar<double> b)
{
return b.Value;
}
throw new InvalidCastException("Invalid json type, expected number.");
}
public object Visit(IField<StringFieldProperties> field)
{
if (value is JsonScalar<string> b)
{
return b.Value;
}
throw new InvalidCastException("Invalid json type, expected string.");
} }
public object Visit(IField<DateTimeFieldProperties> field) public object Visit(IField<DateTimeFieldProperties> field)
{ {
if (value.Type == JTokenType.String) if (value.Type == JsonValueType.String)
{ {
var parseResult = InstantPattern.General.Parse(value.ToString()); var parseResult = InstantPattern.General.Parse(value.ToString());
@ -62,56 +97,126 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
public object Visit(IField<GeolocationFieldProperties> field) public object Visit(IField<GeolocationFieldProperties> field)
{ {
var geolocation = (JObject)value; if (value is JsonObject geolocation)
foreach (var property in geolocation.Properties())
{ {
if (!string.Equals(property.Name, "latitude", StringComparison.OrdinalIgnoreCase) && foreach (var propertyName in geolocation.Keys)
!string.Equals(property.Name, "longitude", StringComparison.OrdinalIgnoreCase)) {
if (!string.Equals(propertyName, "latitude", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(propertyName, "longitude", StringComparison.OrdinalIgnoreCase))
{ {
throw new InvalidCastException("Geolocation can only have latitude and longitude property."); throw new InvalidCastException("Geolocation can only have latitude and longitude property.");
} }
} }
var lat = (double)geolocation["latitude"]; if (geolocation.TryGetValue("latitude", out var latValue) && latValue is JsonScalar<double> latNumber)
var lon = (double)geolocation["longitude"]; {
var lat = latNumber.Value;
if (!lat.IsBetween(-90, 90)) if (!lat.IsBetween(-90, 90))
{ {
throw new InvalidCastException("Latitude must be between -90 and 90."); throw new InvalidCastException("Latitude must be between -90 and 90.");
} }
}
else
{
throw new InvalidCastException("Invalid json type, expected latitude/longitude object.");
}
if (geolocation.TryGetValue("longitude", out var lonValue) && lonValue is JsonScalar<double> lonNumber)
{
var lon = lonNumber.Value;
if (!lon.IsBetween(-180, 180)) if (!lon.IsBetween(-180, 180))
{ {
throw new InvalidCastException("Longitude must be between -180 and 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<JsonFieldProperties> field) public object Visit(IField<JsonFieldProperties> field)
{ {
return value; return value;
} }
public object Visit(IField<NumberFieldProperties> field) private object ConvertToGuidList()
{ {
return (double?)value; if (value is JsonArray array)
} {
var result = new List<Guid>();
public object Visit(IField<ReferencesFieldProperties> field) foreach (var item in array)
{ {
return value.ToObject<List<Guid>>(); if (item is JsonScalar<string> s && Guid.TryParse(s.Value, out var guid))
{
result.Add(guid);
}
else
{
throw new InvalidCastException("Invalid json type, expected array of guid strings.");
}
} }
public object Visit(IField<StringFieldProperties> field) return result;
}
throw new InvalidCastException("Invalid json type, expected array of guid strings.");
}
private object ConvertToStringList()
{
if (value is JsonArray array)
{ {
return value.ToString(); var result = new List<string>();
foreach (var item in array)
{
if (item is JsonScalar<string> s)
{
result.Add(s.Value);
}
else
{
throw new InvalidCastException("Invalid json type, expected array of strings.");
}
} }
public object Visit(IField<TagsFieldProperties> field) return result;
}
throw new InvalidCastException("Invalid json type, expected array of strings.");
}
private object ConvertToObjectList()
{
if (value is JsonArray array)
{
var result = new List<JsonObject>();
foreach (var item in array)
{
if (item is JsonObject obj)
{ {
return value.ToObject<List<string>>(); 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.");
} }
} }
} }

7
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs

@ -7,9 +7,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ValidateContent.Validators namespace Squidex.Domain.Apps.Core.ValidateContent.Validators
{ {
@ -30,9 +29,9 @@ namespace Squidex.Domain.Apps.Core.ValidateContent.Validators
{ {
object typedValue = null; 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<Task>(); var tasks = new List<Task>();

2
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) public async Task ValidateAsync(object value, ValidationContext context, AddError addError)
{ {
if (value is IDictionary<string, TValue> values) if (value is IReadOnlyDictionary<string, TValue> values)
{ {
foreach (var fieldData in values) foreach (var fieldData in values)
{ {

4
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs

@ -8,11 +8,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent.Validators; using Squidex.Domain.Apps.Core.ValidateContent.Validators;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.ValidateContent 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)); nestedSchema[nestedField.Name] = (false, new FieldValidator(nestedField.Accept(this).ToArray(), nestedField));
} }
yield return new CollectionItemValidator(new ObjectValidator<JToken>(nestedSchema, false, "field", JValue.CreateNull())); yield return new CollectionItemValidator(new ObjectValidator<IJsonValue>(nestedSchema, false, "field", JsonValue.Null));
} }
public IEnumerable<IValidator> Visit(IField<AssetsFieldProperties> field) public IEnumerable<IValidator> Visit(IField<AssetsFieldProperties> field)

4
src/Squidex.Infrastructure.GetEventStore/EventSourcing/Formatter.cs

@ -32,8 +32,8 @@ namespace Squidex.Infrastructure.EventSourcing
public static EventStoreData Write(EventData eventData) public static EventStoreData Write(EventData eventData)
{ {
var body = Encoding.UTF8.GetBytes(eventData.Payload.ToString()); var body = Encoding.UTF8.GetBytes(eventData.Payload);
var meta = Encoding.UTF8.GetBytes(eventData.Metadata.ToString()); var meta = Encoding.UTF8.GetBytes(eventData.Metadata);
return new EventStoreData(Guid.NewGuid(), eventData.Type, true, body, meta); return new EventStoreData(Guid.NewGuid(), eventData.Type, true, body, meta);
} }

8
src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEvent.cs

@ -5,8 +5,8 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json.Linq;
using Squidex.Infrastructure.MongoDb; using Squidex.Infrastructure.MongoDb;
namespace Squidex.Infrastructure.EventSourcing namespace Squidex.Infrastructure.EventSourcing
@ -23,16 +23,16 @@ namespace Squidex.Infrastructure.EventSourcing
[BsonElement] [BsonElement]
[BsonRequired] [BsonRequired]
public JToken Metadata { get; set; } public BsonDocument Metadata { get; set; }
public static MongoEvent FromEventData(EventData data) 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() 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 };
} }
} }
} }

12
src/Squidex.Infrastructure.RabbitMq/CQRS/Events/RabbitMqEventConsumer.cs

@ -9,16 +9,16 @@ using System;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json;
using RabbitMQ.Client; using RabbitMQ.Client;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.CQRS.Events namespace Squidex.Infrastructure.CQRS.Events
{ {
public sealed class RabbitMqEventConsumer : DisposableObjectBase, IInitializable, IEventConsumer public sealed class RabbitMqEventConsumer : DisposableObjectBase, IInitializable, IEventConsumer
{ {
private readonly JsonSerializerSettings serializerSettings; private readonly IJsonSerializer jsonSerializer;
private readonly string eventPublisherName; private readonly string eventPublisherName;
private readonly string exchange; private readonly string exchange;
private readonly string eventsFilter; private readonly string eventsFilter;
@ -36,12 +36,12 @@ namespace Squidex.Infrastructure.CQRS.Events
get { return eventsFilter; } 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(uri, nameof(uri));
Guard.NotNullOrEmpty(eventPublisherName, nameof(eventPublisherName)); Guard.NotNullOrEmpty(eventPublisherName, nameof(eventPublisherName));
Guard.NotNullOrEmpty(exchange, nameof(exchange)); Guard.NotNullOrEmpty(exchange, nameof(exchange));
Guard.NotNull(serializerSettings, nameof(serializerSettings)); Guard.NotNull(jsonSerializer, nameof(jsonSerializer));
connectionFactory = new ConnectionFactory { Uri = new Uri(uri, UriKind.Absolute) }; connectionFactory = new ConnectionFactory { Uri = new Uri(uri, UriKind.Absolute) };
connection = new Lazy<IConnection>(connectionFactory.CreateConnection); connection = new Lazy<IConnection>(connectionFactory.CreateConnection);
@ -49,8 +49,8 @@ namespace Squidex.Infrastructure.CQRS.Events
this.exchange = exchange; this.exchange = exchange;
this.eventsFilter = eventsFilter; this.eventsFilter = eventsFilter;
this.jsonSerializer = jsonSerializer;
this.eventPublisherName = eventPublisherName; this.eventPublisherName = eventPublisherName;
this.serializerSettings = serializerSettings;
} }
protected override void DisposeObject(bool disposing) protected override void DisposeObject(bool disposing)
@ -88,7 +88,7 @@ namespace Squidex.Infrastructure.CQRS.Events
public Task On(Envelope<IEvent> @event) public Task On(Envelope<IEvent> @event)
{ {
var jsonString = JsonConvert.SerializeObject(@event, serializerSettings); var jsonString = jsonSerializer.Serialize(@event);
var jsonBytes = Encoding.UTF8.GetBytes(jsonString); var jsonBytes = Encoding.UTF8.GetBytes(jsonString);
channel.Value.BasicPublish(exchange, string.Empty, null, jsonBytes); channel.Value.BasicPublish(exchange, string.Empty, null, jsonBytes);

2
src/Squidex.Infrastructure/Assets/AssetFile.cs

@ -7,7 +7,6 @@
using System; using System;
using System.IO; using System.IO;
using Newtonsoft.Json;
namespace Squidex.Infrastructure.Assets namespace Squidex.Infrastructure.Assets
{ {
@ -21,7 +20,6 @@ namespace Squidex.Infrastructure.Assets
public long FileSize { get; } public long FileSize { get; }
[JsonConstructor]
public AssetFile(string fileName, string mimeType, long fileSize, Func<Stream> openAction) public AssetFile(string fileName, string mimeType, long fileSize, Func<Stream> openAction)
{ {
Guard.NotNullOrEmpty(fileName, nameof(fileName)); Guard.NotNullOrEmpty(fileName, nameof(fileName));

26
src/Squidex.Infrastructure/EventSourcing/DefaultEventDataFormatter.cs

@ -6,38 +6,38 @@
// ========================================================================== // ==========================================================================
using System; using System;
using Newtonsoft.Json; using Squidex.Infrastructure.Json;
using Newtonsoft.Json.Linq;
namespace Squidex.Infrastructure.EventSourcing namespace Squidex.Infrastructure.EventSourcing
{ {
public class DefaultEventDataFormatter : IEventDataFormatter public class DefaultEventDataFormatter : IEventDataFormatter
{ {
private readonly JsonSerializer serializer; private readonly IJsonSerializer serializer;
private readonly TypeNameRegistry typeNameRegistry; private readonly TypeNameRegistry typeNameRegistry;
public DefaultEventDataFormatter(TypeNameRegistry typeNameRegistry, JsonSerializer serializer = null) public DefaultEventDataFormatter(TypeNameRegistry typeNameRegistry, IJsonSerializer serializer)
{ {
Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry)); Guard.NotNull(typeNameRegistry, nameof(typeNameRegistry));
Guard.NotNull(serializer, nameof(serializer));
this.typeNameRegistry = typeNameRegistry; this.typeNameRegistry = typeNameRegistry;
this.serializer = serializer ?? JsonSerializer.CreateDefault(); this.serializer = serializer;
} }
public Envelope<IEvent> Parse(EventData eventData, bool migrate = true) public Envelope<IEvent> Parse(EventData eventData, bool migrate = true)
{ {
var eventType = typeNameRegistry.GetType(eventData.Type); var eventType = typeNameRegistry.GetType(eventData.Type);
var headers = eventData.Metadata.ToObject<EnvelopeHeaders>(serializer); var eventHeaders = serializer.Deserialize<EnvelopeHeaders>(eventData.Metadata);
var content = eventData.Payload.ToObject(eventType, serializer) as IEvent; var eventContent = serializer.Deserialize<IEvent>(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<IEvent>(content, headers); var envelope = new Envelope<IEvent>(eventContent, eventHeaders);
return envelope; return envelope;
} }
@ -55,10 +55,10 @@ namespace Squidex.Infrastructure.EventSourcing
envelope.SetCommitId(commitId); envelope.SetCommitId(commitId);
var headers = JToken.FromObject(envelope.Headers, serializer); var eventHeaders = serializer.Serialize(envelope.Headers);
var content = JToken.FromObject(envelope.Payload, serializer); var eventContent = serializer.Serialize(envelope.Payload);
return new EventData { Type = eventType, Payload = content, Metadata = headers }; return new EventData { Type = eventType, Payload = eventContent, Metadata = eventHeaders };
} }
} }
} }

6
src/Squidex.Infrastructure/EventSourcing/EventData.cs

@ -5,15 +5,13 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Newtonsoft.Json.Linq;
namespace Squidex.Infrastructure.EventSourcing namespace Squidex.Infrastructure.EventSourcing
{ {
public class EventData 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; } public string Type { get; set; }
} }

23
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>(T value);
void Serialize<T>(T value, Stream stream);
T Deserialize<T>(string value, Type actualType = null);
T Deserialize<T>(Stream stream, Type actualType = null);
}
}

34
src/Squidex.Infrastructure/Json/JsonExtension.cs

@ -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;
}
}
}

2
src/Squidex.Infrastructure/Json/ClaimsPrincipalConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/ClaimsPrincipalConverter.cs

@ -10,7 +10,7 @@ using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class ClaimsPrincipalConverter : JsonClassConverter<ClaimsPrincipal> public sealed class ClaimsPrincipalConverter : JsonClassConverter<ClaimsPrincipal>
{ {

2
src/Squidex.Infrastructure/Json/ConverterContractResolver.cs → src/Squidex.Infrastructure/Json/Newtonsoft/ConverterContractResolver.cs

@ -9,7 +9,7 @@ using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class ConverterContractResolver : CamelCasePropertyNamesContractResolver public sealed class ConverterContractResolver : CamelCasePropertyNamesContractResolver
{ {

2
src/Squidex.Infrastructure/Json/InstantConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/InstantConverter.cs

@ -10,7 +10,7 @@ using Newtonsoft.Json;
using NodaTime; using NodaTime;
using NodaTime.Text; using NodaTime.Text;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class InstantConverter : JsonConverter public sealed class InstantConverter : JsonConverter
{ {

2
src/Squidex.Infrastructure/Json/JsonClassConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/JsonClassConverter.cs

@ -8,7 +8,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public abstract class JsonClassConverter<T> : JsonConverter where T : class public abstract class JsonClassConverter<T> : JsonConverter where T : class
{ {

161
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<bool> s:
writer.WriteValue(s.Value);
break;
case JsonScalar<string> s:
writer.WriteValue(s.Value);
break;
case JsonScalar<double> 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;
}
}
}
}
}

2
src/Squidex.Infrastructure/Json/LanguageConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/LanguageConverter.cs

@ -8,7 +8,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class LanguageConverter : JsonClassConverter<Language> public sealed class LanguageConverter : JsonClassConverter<Language>
{ {

2
src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/NamedGuidIdConverter.cs

@ -8,7 +8,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class NamedGuidIdConverter : JsonClassConverter<NamedId<Guid>> public sealed class NamedGuidIdConverter : JsonClassConverter<NamedId<Guid>>
{ {

2
src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/NamedLongIdConverter.cs

@ -8,7 +8,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class NamedLongIdConverter : JsonClassConverter<NamedId<long>> public sealed class NamedLongIdConverter : JsonClassConverter<NamedId<long>>
{ {

2
src/Squidex.Infrastructure/Json/NamedStringIdConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/NamedStringIdConverter.cs

@ -9,7 +9,7 @@ using System;
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class NamedStringIdConverter : JsonClassConverter<NamedId<string>> public sealed class NamedStringIdConverter : JsonClassConverter<NamedId<string>>
{ {

60
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<T>(string value, Type actualType = null)
{
actualType = actualType ?? typeof(T);
return (T)JsonConvert.DeserializeObject(value, actualType, settings);
}
public T Deserialize<T>(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>(T value)
{
return JsonConvert.SerializeObject(value, settings);
}
public void Serialize<T>(T value, Stream stream)
{
using (var writer = new StreamWriter(stream))
{
serializer.Serialize(writer, value);
writer.Flush();
}
}
}
}

2
src/Squidex.Infrastructure/Json/PropertiesBagConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/PropertiesBagConverter.cs

@ -10,7 +10,7 @@ using Newtonsoft.Json;
using NodaTime; using NodaTime;
using NodaTime.Extensions; using NodaTime.Extensions;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class PropertiesBagConverter<T> : JsonClassConverter<T> where T : PropertiesBag, new() public sealed class PropertiesBagConverter<T> : JsonClassConverter<T> where T : PropertiesBag, new()
{ {

2
src/Squidex.Infrastructure/Json/RefTokenConverter.cs → src/Squidex.Infrastructure/Json/Newtonsoft/RefTokenConverter.cs

@ -8,7 +8,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public sealed class RefTokenConverter : JsonClassConverter<RefToken> public sealed class RefTokenConverter : JsonClassConverter<RefToken>
{ {

2
src/Squidex.Infrastructure/Json/TypeNameSerializationBinder.cs → src/Squidex.Infrastructure/Json/Newtonsoft/TypeNameSerializationBinder.cs

@ -8,7 +8,7 @@
using System; using System;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
namespace Squidex.Infrastructure.Json namespace Squidex.Infrastructure.Json.Newtonsoft
{ {
public class TypeNameSerializationBinder : DefaultSerializationBinder public class TypeNameSerializationBinder : DefaultSerializationBinder
{ {

18
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<IJsonValue>
{
JsonValueType Type { get; }
string ToJsonString();
}
}

100
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>, IJsonValue, IEquatable<JsonArray>
{
public JsonValueType Type
{
get { return JsonValueType.Array; }
}
public JsonArray()
{
}
public JsonArray(IList<IJsonValue> 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)}]";
}
}
}

55
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<JsonNull>
{
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";
}
}
}

129
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<string, IJsonValue>, IJsonValue, IEquatable<JsonObject>
{
private readonly Dictionary<string, IJsonValue> inner = new Dictionary<string, IJsonValue>();
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<string> Keys
{
get { return inner.Keys; }
}
public IEnumerable<IJsonValue> 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<KeyValuePair<string, IJsonValue>> 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}\""))}}}";
}
}
}

60
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<T> : IJsonValue, IEquatable<JsonScalar<T>>
{
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<T>);
}
public bool Equals(IJsonValue other)
{
return Equals(other as JsonScalar<T>);
}
public bool Equals(JsonScalar<T> 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();
}
}
}

114
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<string> Empty = new JsonScalar<string>(JsonValueType.String, string.Empty);
public static readonly JsonScalar<bool> True = new JsonScalar<bool>(JsonValueType.Boolean, true);
public static readonly JsonScalar<bool> False = new JsonScalar<bool>(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<double>(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<string>(JsonValueType.String, value);
}
}
}

19
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
}
}

6
src/Squidex.Infrastructure/Orleans/J.cs

@ -6,13 +6,15 @@
// ========================================================================== // ==========================================================================
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json; using Squidex.Infrastructure.Json;
#pragma warning disable SA1401 // Fields must be private
namespace Squidex.Infrastructure.Orleans namespace Squidex.Infrastructure.Orleans
{ {
public static class J public static class J
{ {
internal static readonly JsonSerializer DefaultSerializer = JsonSerializer.CreateDefault(); public static IJsonSerializer DefaultSerializer;
public static J<T> AsJ<T>(this T value) public static J<T> AsJ<T>(this T value)
{ {

20
src/Squidex.Infrastructure/Orleans/J{T}.cs

@ -6,13 +6,12 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Orleans.CodeGeneration; using Orleans.CodeGeneration;
using Orleans.Concurrency; using Orleans.Concurrency;
using Orleans.Serialization; using Orleans.Serialization;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Log; using Squidex.Infrastructure.Log;
namespace Squidex.Infrastructure.Orleans namespace Squidex.Infrastructure.Orleans
@ -22,7 +21,6 @@ namespace Squidex.Infrastructure.Orleans
{ {
public T Value { get; } public T Value { get; }
[JsonConstructor]
public J(T value) public J(T value)
{ {
Value = value; Value = value;
@ -63,12 +61,7 @@ namespace Squidex.Infrastructure.Orleans
var stream = new StreamWriterWrapper(context.StreamWriter); var stream = new StreamWriterWrapper(context.StreamWriter);
using (var writer = new JsonTextWriter(new StreamWriter(stream))) jsonSerializer.Serialize(input, stream);
{
jsonSerializer.Serialize(writer, input);
writer.Flush();
}
} }
} }
@ -81,18 +74,15 @@ namespace Squidex.Infrastructure.Orleans
var stream = new StreamReaderWrapper(context.StreamReader); var stream = new StreamReaderWrapper(context.StreamReader);
using (var reader = new JsonTextReader(new StreamReader(stream))) return jsonSerializer.Deserialize<object>(stream, expected);
{
return jsonSerializer.Deserialize(reader, expected);
}
} }
} }
private static JsonSerializer GetSerializer(ISerializerContext context) private static IJsonSerializer GetSerializer(ISerializerContext context)
{ {
try try
{ {
return context?.ServiceProvider?.GetService<JsonSerializer>() ?? J.DefaultSerializer; return context?.ServiceProvider?.GetService<IJsonSerializer>() ?? J.DefaultSerializer;
} }
catch catch
{ {

8
tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppClientJsonTests.cs

@ -6,8 +6,6 @@
// ========================================================================== // ==========================================================================
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Xunit; using Xunit;
@ -15,8 +13,6 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
{ {
public class AppClientJsonTests public class AppClientJsonTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_serialize_and_deserialize() public void Should_serialize_and_deserialize()
{ {
@ -34,9 +30,9 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
clients = clients.Revoke("4"); clients = clients.Revoke("4");
var appClients = JToken.FromObject(clients, serializer).ToObject<AppClients>(serializer); var serialized = clients.SerializeAndDeserialize();
appClients.Should().BeEquivalentTo(clients); serialized.Should().BeEquivalentTo(clients);
} }
} }
} }

6
tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppContributorsJsonTests.cs

@ -6,8 +6,6 @@
// ========================================================================== // ==========================================================================
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Xunit; using Xunit;
@ -15,8 +13,6 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
{ {
public class AppContributorsJsonTests public class AppContributorsJsonTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_serialize_and_deserialize() 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("2", Role.Editor);
contributors = contributors.Assign("3", Role.Owner); contributors = contributors.Assign("3", Role.Owner);
var serialized = JToken.FromObject(contributors, serializer).ToObject<AppContributors>(serializer); var serialized = contributors.SerializeAndDeserialize();
serialized.Should().BeEquivalentTo(contributors); serialized.Should().BeEquivalentTo(contributors);
} }

8
tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs

@ -7,8 +7,6 @@
using System; using System;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Xunit; using Xunit;
@ -16,8 +14,6 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
{ {
public class AppPatternJsonTests public class AppPatternJsonTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_serialize_and_deserialize() public void Should_serialize_and_deserialize()
{ {
@ -35,9 +31,9 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
patterns = patterns.Remove(guid1); patterns = patterns.Remove(guid1);
var appPatterns = JToken.FromObject(patterns, serializer).ToObject<AppPatterns>(serializer); var serialized = patterns.SerializeAndDeserialize();
appPatterns.Should().BeEquivalentTo(patterns); serialized.Should().BeEquivalentTo(patterns);
} }
} }
} }

10
tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPlanTests.cs

@ -6,8 +6,6 @@
// ========================================================================== // ==========================================================================
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Xunit; using Xunit;
@ -16,16 +14,14 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
{ {
public class AppPlanTests public class AppPlanTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_serialize_and_deserialize() 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<AppPlan>(serializer); var serialized = plan.SerializeAndDeserialize();
serialized.Should().BeEquivalentTo(sut); serialized.Should().BeEquivalentTo(plan);
} }
} }
} }

10
tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/LanguagesConfigJsonTests.cs

@ -7,8 +7,6 @@
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Xunit; using Xunit;
@ -17,20 +15,18 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
{ {
public class LanguagesConfigJsonTests public class LanguagesConfigJsonTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_serialize_and_deserialize() public void Should_serialize_and_deserialize()
{ {
var sut = LanguagesConfig.Build( var languages = LanguagesConfig.Build(
new LanguageConfig(Language.EN), new LanguageConfig(Language.EN),
new LanguageConfig(Language.DE, true, Language.EN), new LanguageConfig(Language.DE, true, Language.EN),
new LanguageConfig(Language.IT, false, Language.DE)) new LanguageConfig(Language.IT, false, Language.DE))
.MakeMaster(Language.IT); .MakeMaster(Language.IT);
var serialized = JToken.FromObject(sut, serializer).ToObject<LanguagesConfig>(serializer); var serialized = languages.SerializeAndDeserialize();
serialized.Should().BeEquivalentTo(sut); serialized.Should().BeEquivalentTo(languages);
Assert.Same(serialized.FirstOrDefault(x => x.Key == "it"), serialized.Master); Assert.Same(serialized.FirstOrDefault(x => x.Key == "it"), serialized.Master);
} }

8
tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/RolesJsonTests.cs

@ -6,8 +6,6 @@
// ========================================================================== // ==========================================================================
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Xunit; using Xunit;
@ -15,16 +13,14 @@ namespace Squidex.Domain.Apps.Core.Model.Apps
{ {
public class RolesJsonTests public class RolesJsonTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_serialize_and_deserialize() public void Should_serialize_and_deserialize()
{ {
var sut = Roles.CreateDefaults("my-app"); var sut = Roles.CreateDefaults("my-app");
var serialized = JToken.FromObject(sut, serializer).ToObject<Roles>(serializer); var roles = sut.SerializeAndDeserialize();
serialized.Should().BeEquivalentTo(sut); roles.Should().BeEquivalentTo(sut);
} }
} }
} }

3
tests/Squidex.Domain.Apps.Core.Tests/Model/Contents/ContentDataTests.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
#pragma warning disable xUnit2013 // Do not use equality check to check for collection size. #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", .AddField("field2",
new ContentFieldData() new ContentFieldData()
.AddValue("en", 2) .AddValue("en", 2)
.AddValue("it", null)); .AddValue("it", JsonValue.Null));
var actual = input.ToCleaned(); var actual = input.ToCleaned();

8
tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs

@ -9,8 +9,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Triggers; using Squidex.Domain.Apps.Core.Rules.Triggers;
using Xunit; using Xunit;
@ -21,8 +19,6 @@ namespace Squidex.Domain.Apps.Core.Model.Rules
{ {
public class RuleTests public class RuleTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
public static readonly List<object[]> Triggers = public static readonly List<object[]> Triggers =
typeof(Rule).Assembly.GetTypes() typeof(Rule).Assembly.GetTypes()
.Where(x => x.BaseType == typeof(RuleTrigger)) .Where(x => x.BaseType == typeof(RuleTrigger))
@ -123,9 +119,9 @@ namespace Squidex.Domain.Apps.Core.Model.Rules
{ {
var rule_1 = rule_0.Disable(); var rule_1 = rule_0.Disable();
var appClients = JToken.FromObject(rule_1, serializer).ToObject<Rule>(serializer); var serialized = rule_1.SerializeAndDeserialize();
appClients.Should().BeEquivalentTo(rule_1); serialized.Should().BeEquivalentTo(rule_1);
} }
[Theory] [Theory]

5
tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs

@ -9,8 +9,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Xunit; using Xunit;
@ -20,7 +18,6 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas
{ {
public class SchemaTests public class SchemaTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer();
private readonly Schema schema_0 = new Schema("my-schema"); private readonly Schema schema_0 = new Schema("my-schema");
[Fact] [Fact]
@ -282,7 +279,7 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas
public void Should_serialize_and_deserialize_schema() public void Should_serialize_and_deserialize_schema()
{ {
var schemaSource = TestData.MixedSchema(); var schemaSource = TestData.MixedSchema();
var schemaTarget = JToken.FromObject(schemaSource, serializer).ToObject<Schema>(serializer); var schemaTarget = schemaSource.SerializeAndDeserialize();
schemaTarget.Should().BeEquivalentTo(schemaSource); schemaTarget.Should().BeEquivalentTo(schemaSource);
} }

46
tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionFlatTests.cs

@ -6,11 +6,11 @@
// ========================================================================== // ==========================================================================
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ConvertContent;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
#pragma warning disable xUnit2013 // Do not use equality check to check for collection size. #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)) .AddValue("en", 2))
.AddField("field2", .AddField("field2",
new ContentFieldData() new ContentFieldData()
.AddValue("de", null) .AddValue("de", JsonValue.Null)
.AddValue("en", 4)) .AddValue("en", 4))
.AddField("field3", .AddField("field3",
new ContentFieldData() new ContentFieldData()
@ -57,10 +57,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var expected = new Dictionary<string, object> var expected = new Dictionary<string, object>
{ {
{ "field1", new ContentFieldData().AddValue("de", 1).AddValue("en", 2) }, {
{ "field2", new ContentFieldData().AddValue("de", null).AddValue("en", 4) }, "field1",
{ "field3", (JValue)6 }, new ContentFieldData()
{ "field4", (JValue)7 } .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)); Assert.True(expected.EqualsDictionary(output));
@ -77,7 +87,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
.AddValue("en", 2)) .AddValue("en", 2))
.AddField("field2", .AddField("field2",
new ContentFieldData() new ContentFieldData()
.AddValue("de", null) .AddValue("de", JsonValue.Null)
.AddValue("en", 4)) .AddValue("en", 4))
.AddField("field3", .AddField("field3",
new ContentFieldData() new ContentFieldData()
@ -91,13 +101,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
new LanguageConfig(Language.EN), new LanguageConfig(Language.EN),
new LanguageConfig(Language.DE, false, Language.EN)); new LanguageConfig(Language.DE, false, Language.EN));
var output = (Dictionary<string, JToken>)data.ToFlatLanguageModel(fallbackConfig, new List<Language> { Language.DE }); var output = (Dictionary<string, IJsonValue>)data.ToFlatLanguageModel(fallbackConfig, new List<Language> { Language.DE });
var expected = new Dictionary<string, JToken> var expected = new Dictionary<string, IJsonValue>
{ {
{ "field1", 1 }, { "field1", JsonValue.Create(1) },
{ "field2", 4 }, { "field2", JsonValue.Create(4) },
{ "field3", 6 } { "field3", JsonValue.Create(6) }
}; };
Assert.True(expected.EqualsDictionary(output)); Assert.True(expected.EqualsDictionary(output));
@ -114,7 +124,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
.AddValue("en", 2)) .AddValue("en", 2))
.AddField("field2", .AddField("field2",
new ContentFieldData() new ContentFieldData()
.AddValue("de", null) .AddValue("de", JsonValue.Null)
.AddValue("en", 4)) .AddValue("en", 4))
.AddField("field3", .AddField("field3",
new ContentFieldData() new ContentFieldData()
@ -123,13 +133,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
new ContentFieldData() new ContentFieldData()
.AddValue("it", 7)); .AddValue("it", 7));
var output = (Dictionary<string, JToken>)data.ToFlatLanguageModel(languagesConfig, new List<Language> { Language.DE, Language.EN }); var output = (Dictionary<string, IJsonValue>)data.ToFlatLanguageModel(languagesConfig, new List<Language> { Language.DE, Language.EN });
var expected = new Dictionary<string, JToken> var expected = new Dictionary<string, IJsonValue>
{ {
{ "field1", 1 }, { "field1", JsonValue.Create(1) },
{ "field2", 4 }, { "field2", JsonValue.Create(4) },
{ "field3", 6 } { "field3", JsonValue.Create(6) }
}; };
Assert.True(expected.EqualsDictionary(output)); Assert.True(expected.EqualsDictionary(output));

6
tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs

@ -5,10 +5,10 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ConvertContent;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ConvertContent namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
@ -174,7 +174,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
new NamedContentData() new NamedContentData()
.AddField("field1", .AddField("field1",
new ContentFieldData() new ContentFieldData()
.AddValue("en", new JArray("hello", "loved"))) .AddValue("en", new JsonArray("hello", "loved")))
.AddField("field2", .AddField("field2",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", "world")); .AddValue("iv", "world"));
@ -191,7 +191,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
new NamedContentData() new NamedContentData()
.AddField("field1", .AddField("field1",
new ContentFieldData() new ContentFieldData()
.AddValue("en", new JArray(new JObject(new JProperty("p1", "hello"))))) .AddValue("en", new JsonArray(JsonValue.Object().Add("p1", "hello"))))
.AddField("field2", .AddField("field2",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", "world")); .AddValue("iv", "world"));

90
tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs

@ -8,12 +8,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FakeItEasy; using FakeItEasy;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ConvertContent;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ConvertContent namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
@ -21,6 +22,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
public class FieldConvertersTests public class FieldConvertersTests
{ {
private readonly IAssetUrlGenerator assetUrlGenerator = A.Fake<IAssetUrlGenerator>(); private readonly IAssetUrlGenerator assetUrlGenerator = A.Fake<IAssetUrlGenerator>();
private readonly IJsonSerializer serializer = TestData.DefaultSerializer();
private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE); private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE);
private readonly RootField<JsonFieldProperties> jsonField = Fields.Json(1, "1", Partitioning.Invariant); private readonly RootField<JsonFieldProperties> jsonField = Fields.Json(1, "1", Partitioning.Invariant);
private readonly RootField<StringFieldProperties> stringLanguageField = Fields.String(1, "1", Partitioning.Language); private readonly RootField<StringFieldProperties> stringLanguageField = Fields.String(1, "1", Partitioning.Language);
@ -42,7 +44,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
var input = var input =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JObject()); .AddValue("iv", JsonValue.Object());
var actual = FieldConverters.ForValues((f, i) => Value.Unset)(input, stringInvariantField); var actual = FieldConverters.ForValues((f, i) => Value.Unset)(input, stringInvariantField);
@ -56,9 +58,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
var input = var input =
new ContentFieldData() 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 = var expected =
new ContentFieldData() new ContentFieldData()
@ -73,20 +75,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var input = var input =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("field1", 100), .Add("field1", 100)
new JProperty("field2", 200), .Add("field2", 200)
new JProperty("invalid", 300)))); .Add("invalid", 300)));
var actual = FieldConverters.ForNestedName2Id(ValueConverters.ExcludeHidden())(input, arrayField); var actual = FieldConverters.ForNestedName2Id(ValueConverters.ExcludeHidden())(input, arrayField);
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("1", 100)))); .Add("1", 100)));
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
@ -97,20 +99,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var input = var input =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("field1", 100), .Add("field1", 100)
new JProperty("field2", 200), .Add("field2", 200)
new JProperty("invalid", 300)))); .Add("invalid", 300)));
var actual = FieldConverters.ForNestedName2Name(ValueConverters.ExcludeHidden())(input, arrayField); var actual = FieldConverters.ForNestedName2Name(ValueConverters.ExcludeHidden())(input, arrayField);
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("field1", 100)))); .Add("field1", 100)));
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
@ -121,20 +123,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var input = var input =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("1", 100), .Add("1", 100)
new JProperty("2", 200), .Add("2", 200)
new JProperty("99", 300)))); .Add("99", 300)));
var actual = FieldConverters.ForNestedId2Id(ValueConverters.ExcludeHidden())(input, arrayField); var actual = FieldConverters.ForNestedId2Id(ValueConverters.ExcludeHidden())(input, arrayField);
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("1", 100)))); .Add("1", 100)));
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
@ -145,20 +147,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var input = var input =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("1", 100), .Add("1", 100)
new JProperty("2", 200), .Add("2", 200)
new JProperty("99", 300)))); .Add("99", 300)));
var actual = FieldConverters.ForNestedId2Name(ValueConverters.ExcludeHidden())(input, arrayField); var actual = FieldConverters.ForNestedId2Name(ValueConverters.ExcludeHidden())(input, arrayField);
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( new JsonArray(
new JObject( JsonValue.Object()
new JProperty("field1", 100)))); .Add("field1", 100)));
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
@ -422,11 +424,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
var source = var source =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray("1", "2")); .AddValue("iv", new JsonArray("1", "2"));
var expected = var expected =
new ContentFieldData() 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<string>(new[] { "1" }), assetUrlGenerator)(source, assetsField); var rtesult = FieldConverters.ResolveAssetUrls(new HashSet<string>(new[] { "1" }), assetUrlGenerator)(source, assetsField);
@ -438,11 +440,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
var source = var source =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray("1", "2")); .AddValue("iv", new JsonArray("1", "2"));
var expected = var expected =
new ContentFieldData() 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<string>(new[] { "*" }), assetUrlGenerator)(source, assetsField); var rtesult = FieldConverters.ResolveAssetUrls(new HashSet<string>(new[] { "*" }), assetUrlGenerator)(source, assetsField);
@ -454,11 +456,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
var source = var source =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray("1", "2")); .AddValue("iv", new JsonArray("1", "2"));
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray("1", "2")); .AddValue("iv", new JsonArray("1", "2"));
var rtesult = FieldConverters.ResolveAssetUrls(new HashSet<string>(new[] { "2" }), assetUrlGenerator)(source, assetsField); var rtesult = FieldConverters.ResolveAssetUrls(new HashSet<string>(new[] { "2" }), assetUrlGenerator)(source, assetsField);
@ -470,11 +472,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
var source = var source =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray("1", "2")); .AddValue("iv", new JsonArray("1", "2"));
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray("1", "2")); .AddValue("iv", new JsonArray("1", "2"));
var rtesult = FieldConverters.ResolveAssetUrls(null, assetUrlGenerator)(source, assetsField); var rtesult = FieldConverters.ResolveAssetUrls(null, assetUrlGenerator)(source, assetsField);

36
tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ValueConvertersTests.cs

@ -5,9 +5,10 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ConvertContent;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ConvertContent namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
@ -17,23 +18,24 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
private readonly RootField<StringFieldProperties> stringField = Fields.String(1, "1", Partitioning.Invariant); private readonly RootField<StringFieldProperties> stringField = Fields.String(1, "1", Partitioning.Invariant);
private readonly RootField<JsonFieldProperties> jsonField = Fields.Json(1, "1", Partitioning.Invariant); private readonly RootField<JsonFieldProperties> jsonField = Fields.Json(1, "1", Partitioning.Invariant);
private readonly RootField<NumberFieldProperties> numberField = Fields.Number(1, "1", Partitioning.Invariant); private readonly RootField<NumberFieldProperties> numberField = Fields.Number(1, "1", Partitioning.Invariant);
private readonly IJsonSerializer jsonSerializer = TestData.DefaultSerializer();
[Fact] [Fact]
public void Should_encode_json_value() 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] [Fact]
public void Should_return_same_value_if_encoding_null_value() 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); Assert.Same(source, result);
} }
@ -41,9 +43,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
[Fact] [Fact]
public void Should_return_same_value_if_encoding_non_json_field() 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); Assert.Same(source, result);
} }
@ -51,19 +53,19 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
[Fact] [Fact]
public void Should_decode_json_values() 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] [Fact]
public void Should_return_same_value_if_decoding_null_value() 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); Assert.Same(source, result);
} }
@ -71,9 +73,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
[Fact] [Fact]
public void Should_return_same_value_if_decoding_non_json_field() 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); Assert.Same(source, result);
} }
@ -81,7 +83,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
[Fact] [Fact]
public void Should_return_unset_if_field_hidden() public void Should_return_unset_if_field_hidden()
{ {
var source = 123; var source = JsonValue.Create(123);
var result = ValueConverters.ExcludeHidden()(source, stringField.Hide()); var result = ValueConverters.ExcludeHidden()(source, stringField.Hide());
@ -91,7 +93,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
[Fact] [Fact]
public void Should_return_unset_if_field_has_wrong_type() public void Should_return_unset_if_field_has_wrong_type()
{ {
var source = "invalid"; var source = JsonValue.Create("invalid");
var result = ValueConverters.ExcludeChangedTypes()(source, numberField); var result = ValueConverters.ExcludeChangedTypes()(source, numberField);

38
tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs

@ -6,13 +6,13 @@
// ========================================================================== // ==========================================================================
using System; using System;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.EnrichContent; using Squidex.Domain.Apps.Core.EnrichContent;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
#pragma warning disable xUnit2004 // Do not use equality check to test for boolean conditions #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()); data.Enrich(schema, languagesConfig.ToResolver());
Assert.Equal(456, (int)data["my-number"]["iv"]); Assert.Equal(456, ((JsonScalar<double>)data["my-number"]["iv"]).Value);
Assert.Equal("de-string", (string)data["my-string"]["de"]); Assert.Equal("de-string", data["my-string"]["de"].ToString());
Assert.Equal("en-string", (string)data["my-string"]["en"]); 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<bool>)data["my-boolean"]["iv"]).Value);
} }
[Fact] [Fact]
@ -77,8 +77,8 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
data.Enrich(schema, languagesConfig.ToResolver()); data.Enrich(schema, languagesConfig.ToResolver());
Assert.Equal("en-string", (string)data["my-string"]["de"]); Assert.Equal("en-string", data["my-string"]["de"].ToString());
Assert.Equal("en-string", (string)data["my-string"]["en"]); Assert.Equal("en-string", data["my-string"]["en"].ToString());
} }
[Fact] [Fact]
@ -88,7 +88,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.Assets(1, "1", Partitioning.Invariant, Fields.Assets(1, "1", Partitioning.Invariant,
new AssetsFieldProperties()); new AssetsFieldProperties());
Assert.Equal(new JArray(), DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Array(), DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -98,7 +98,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.Boolean(1, "1", Partitioning.Invariant, Fields.Boolean(1, "1", Partitioning.Invariant,
new BooleanFieldProperties { DefaultValue = true }); new BooleanFieldProperties { DefaultValue = true });
Assert.Equal(true, DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.True, DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -108,7 +108,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.DateTime(1, "1", Partitioning.Invariant, Fields.DateTime(1, "1", Partitioning.Invariant,
new DateTimeFieldProperties { DefaultValue = FutureDays(15) }); 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] [Fact]
@ -118,7 +118,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.DateTime(1, "1", Partitioning.Invariant, Fields.DateTime(1, "1", Partitioning.Invariant,
new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Today }); 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] [Fact]
@ -128,7 +128,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.DateTime(1, "1", Partitioning.Invariant, Fields.DateTime(1, "1", Partitioning.Invariant,
new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Now }); 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] [Fact]
@ -138,7 +138,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.Json(1, "1", Partitioning.Invariant, Fields.Json(1, "1", Partitioning.Invariant,
new JsonFieldProperties()); new JsonFieldProperties());
Assert.Equal(new JObject(), DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Object(), DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -148,7 +148,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.Geolocation(1, "1", Partitioning.Invariant, Fields.Geolocation(1, "1", Partitioning.Invariant,
new GeolocationFieldProperties()); new GeolocationFieldProperties());
Assert.Equal(JValue.CreateNull(), DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -158,7 +158,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.Number(1, "1", Partitioning.Invariant, Fields.Number(1, "1", Partitioning.Invariant,
new NumberFieldProperties { DefaultValue = 12 }); new NumberFieldProperties { DefaultValue = 12 });
Assert.Equal(12, DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Create(12), DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -168,7 +168,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.References(1, "1", Partitioning.Invariant, Fields.References(1, "1", Partitioning.Invariant,
new ReferencesFieldProperties()); new ReferencesFieldProperties());
Assert.Equal(new JArray(), DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Array(), DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -178,7 +178,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.String(1, "1", Partitioning.Invariant, Fields.String(1, "1", Partitioning.Invariant,
new StringFieldProperties { DefaultValue = "default" }); new StringFieldProperties { DefaultValue = "default" });
Assert.Equal("default", DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Create("default"), DefaultValueFactory.CreateDefaultValue(field, Now));
} }
[Fact] [Fact]
@ -188,7 +188,7 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
Fields.Tags(1, "1", Partitioning.Invariant, Fields.Tags(1, "1", Partitioning.Invariant,
new TagsFieldProperties()); new TagsFieldProperties());
Assert.Equal(new JArray(), DefaultValueFactory.CreateDefaultValue(field, Now)); Assert.Equal(JsonValue.Array(), DefaultValueFactory.CreateDefaultValue(field, Now));
} }
private static Instant FutureDays(int days) private static Instant FutureDays(int days)

36
tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs

@ -7,12 +7,12 @@
using System; using System;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.ConvertContent; using Squidex.Domain.Apps.Core.ConvertContent;
using Squidex.Domain.Apps.Core.ExtractReferenceIds; using Squidex.Domain.Apps.Core.ExtractReferenceIds;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
#pragma warning disable xUnit2013 // Do not use equality check to check for collection size. #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() new IdContentData()
.AddField(5, .AddField(5,
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray(id1.ToString(), id2.ToString()))); .AddValue("iv", JsonValue.Array(id1.ToString(), id2.ToString())));
var ids = input.GetReferencedIds(schema).ToArray(); var ids = input.GetReferencedIds(schema).ToArray();
@ -66,16 +66,16 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
new IdContentData() new IdContentData()
.AddField(5, .AddField(5,
new ContentFieldData() 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 converter = FieldConverters.ForValues(ValueReferencesConverter.CleanReferences(new[] { id2 }));
var actual = input.ConvertId2Id(schema, converter); 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(1, cleanedValue.Count);
Assert.Equal(id1.ToString(), cleanedValue[0]); Assert.Equal(id1.ToString(), cleanedValue[0].ToString());
} }
[Fact] [Fact]
@ -106,7 +106,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
{ {
var sut = Fields.Assets(1, "my-asset", Partitioning.Invariant); 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); Assert.Empty(result);
} }
@ -116,7 +116,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
{ {
var sut = Fields.String(1, "my-string", Partitioning.Invariant); 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); Assert.Empty(result);
} }
@ -126,9 +126,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
{ {
var sut = Fields.Assets(1, "my-asset", Partitioning.Invariant); 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] [Fact]
@ -170,9 +170,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
new ReferencesFieldProperties { SchemaId = schemaId })); new ReferencesFieldProperties { SchemaId = schemaId }));
var value = var value =
new JArray( JsonValue.Array(
new JObject( JsonValue.Object()
new JProperty("my-refs", CreateValue(id1, id2)))); .Add("my-refs", CreateValue(id1, id2)));
var result = sut.ExtractReferences(value).ToArray(); 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, var sut = Fields.References(1, "my-refs", Partitioning.Invariant,
new ReferencesFieldProperties { SchemaId = schemaId }); new ReferencesFieldProperties { SchemaId = schemaId });
var result = sut.ExtractReferences(null).ToArray(); var result = sut.ExtractReferences(JsonValue.Null).ToArray();
Assert.Equal(new[] { schemaId }, result); 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, var sut = Fields.References(1, "my-refs", Partitioning.Invariant,
new ReferencesFieldProperties { SchemaId = schemaId }); new ReferencesFieldProperties { SchemaId = schemaId });
var result = sut.ExtractReferences("invalid").ToArray(); var result = sut.ExtractReferences(JsonValue.Create("invalid")).ToArray();
Assert.Equal(new[] { schemaId }, result); 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 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] [Fact]
@ -267,9 +267,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
Assert.Same(token, result); 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<object>().ToArray()); return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray());
} }
} }
} }

9
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;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json;
using Squidex.Shared.Identity; using Squidex.Shared.Identity;
using Squidex.Shared.Users; using Squidex.Shared.Users;
using Xunit; using Xunit;
@ -24,7 +25,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
{ {
public class RuleEventFormatterTests public class RuleEventFormatterTests
{ {
private readonly JsonSerializer serializer = JsonSerializer.CreateDefault(); private readonly IJsonSerializer serializer = TestData.DefaultSerializer();
private readonly IUser user = A.Fake<IUser>(); private readonly IUser user = A.Fake<IUser>();
private readonly IRuleUrlGenerator urlGenerator = A.Fake<IRuleUrlGenerator>(); private readonly IRuleUrlGenerator urlGenerator = A.Fake<IRuleUrlGenerator>();
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app"); private readonly NamedId<Guid> 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 }); var result = sut.ToPayload(new { Value = 1 });
Assert.True(result is JObject); Assert.True(result is string);
} }
[Fact] [Fact]
@ -58,7 +59,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
var result = sut.ToPayload(@event); var result = sut.ToPayload(@event);
Assert.True(result is JObject); Assert.True(result is string);
} }
[Fact] [Fact]
@ -68,7 +69,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
var result = sut.ToEnvelope(@event); var result = sut.ToEnvelope(@event);
Assert.Equal("MyEventName", result["type"]); Assert.Contains("MyEventName", result);
} }
[Fact] [Fact]

17
tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleServiceTests.cs

@ -8,7 +8,6 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents; using Squidex.Domain.Apps.Core.HandleRules.EnrichedEvents;
@ -18,6 +17,7 @@ using Squidex.Domain.Apps.Events;
using Squidex.Domain.Apps.Events.Contents; using Squidex.Domain.Apps.Events.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.Json;
using Xunit; using Xunit;
#pragma warning disable xUnit2009 // Do not use boolean check to check for string equality #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<IRuleTriggerHandler>(); private readonly IRuleTriggerHandler ruleTriggerHandler = A.Fake<IRuleTriggerHandler>();
private readonly IRuleActionHandler ruleActionHandler = A.Fake<IRuleActionHandler>(); private readonly IRuleActionHandler ruleActionHandler = A.Fake<IRuleActionHandler>();
private readonly IJsonSerializer serializer = TestData.DefaultSerializer();
private readonly IEventEnricher eventEnricher = A.Fake<IEventEnricher>(); private readonly IEventEnricher eventEnricher = A.Fake<IEventEnricher>();
private readonly IClock clock = A.Fake<IClock>(); private readonly IClock clock = A.Fake<IClock>();
private readonly TypeNameRegistry typeNameRegistry = new TypeNameRegistry(); private readonly TypeNameRegistry typeNameRegistry = new TypeNameRegistry();
@ -67,7 +68,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
A.CallTo(() => ruleTriggerHandler.TriggerType) A.CallTo(() => ruleTriggerHandler.TriggerType)
.Returns(typeof(ContentChangedTrigger)); .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] [Fact]
@ -129,7 +130,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
ruleEnvelope.SetTimestamp(now.Minus(Duration.FromDays(3))); ruleEnvelope.SetTimestamp(now.Minus(Duration.FromDays(3)));
var actionData = new JObject(); var actionData = "{}";
var actionDescription = "MyDescription"; var actionDescription = "MyDescription";
A.CallTo(() => clock.GetCurrentInstant()) A.CallTo(() => clock.GetCurrentInstant())
@ -159,7 +160,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
ruleEnvelope.SetTimestamp(now); ruleEnvelope.SetTimestamp(now);
var actionName = "ValidAction"; var actionName = "ValidAction";
var actionData = new JObject(); var actionData = "{}";
var actionDescription = "MyDescription"; var actionDescription = "MyDescription";
A.CallTo(() => clock.GetCurrentInstant()) A.CallTo(() => clock.GetCurrentInstant())
@ -188,7 +189,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Fact] [Fact]
public async Task Should_return_succeeded_job_with_full_dump_when_handler_returns_no_exception() public async Task Should_return_succeeded_job_with_full_dump_when_handler_returns_no_exception()
{ {
var ruleJob = new JObject(); var ruleJob = "{}";
var actionDump = "MyDump"; var actionDump = "MyDump";
@ -206,7 +207,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Fact] [Fact]
public async Task Should_return_failed_job_with_full_dump_when_handler_returns_exception() public async Task Should_return_failed_job_with_full_dump_when_handler_returns_exception()
{ {
var ruleJob = new JObject(); var ruleJob = "{}";
var actionDump = "MyDump"; var actionDump = "MyDump";
@ -224,7 +225,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Fact] [Fact]
public async Task Should_return_timedout_job_with_full_dump_when_exception_from_handler_indicates_timeout() 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"; var actionDump = "MyDump";
@ -243,7 +244,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
[Fact] [Fact]
public async Task Should_create_exception_details_when_job_to_execute_failed() public async Task Should_create_exception_details_when_job_to_execute_failed()
{ {
var ruleJob = new JObject(); var ruleJob = "{}";
var ruleError = new InvalidOperationException(); var ruleError = new InvalidOperationException();
A.CallTo(() => ruleActionHandler.ExecuteJobAsync(ruleJob)) A.CallTo(() => ruleActionHandler.ExecuteJobAsync(ruleJob))

14
tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs

@ -7,9 +7,9 @@
using Jint; using Jint;
using Jint.Runtime; using Jint.Runtime;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Scripting.ContentWrapper; using Squidex.Domain.Apps.Core.Scripting.ContentWrapper;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.Scripting namespace Squidex.Domain.Apps.Core.Operations.Scripting
@ -155,13 +155,13 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
new NamedContentData() new NamedContentData()
.AddField("number", .AddField("number",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray(1.0, 2.0))); .AddValue("iv", new JsonArray(1.0, 2.0)));
var expected = var expected =
new NamedContentData() new NamedContentData()
.AddField("number", .AddField("number",
new ContentFieldData() 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]"); 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() new NamedContentData()
.AddField("number", .AddField("number",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JObject(new JProperty("lat", 1.0)))); .AddValue("iv", JsonValue.Object().Add("lat", 1.0)));
var expected = var expected =
new NamedContentData() new NamedContentData()
.AddField("number", .AddField("number",
new ContentFieldData() 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 }"); 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() new NamedContentData()
.AddField("obj", .AddField("obj",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JObject(new JProperty("readonly", 1)))); .AddValue("iv", JsonValue.Object().Add("readonly", 1)));
Assert.Throws<JavaScriptException>(() => ExecuteScript(original, "data.obj.iv.invalid = 1")); Assert.Throws<JavaScriptException>(() => ExecuteScript(original, "data.obj.iv.invalid = 1"));
Assert.Throws<JavaScriptException>(() => ExecuteScript(original, "data.obj.iv.readonly = 2")); Assert.Throws<JavaScriptException>(() => ExecuteScript(original, "data.obj.iv.readonly = 2"));
@ -278,7 +278,7 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting
new NamedContentData() new NamedContentData()
.AddField("obj", .AddField("obj",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray())); .AddValue("iv", new JsonArray()));
ExecuteScript(original, "data.obj.iv[0] = 1"); ExecuteScript(original, "data.obj.iv[0] = 1");
} }

37
tests/Squidex.Domain.Apps.Core.Tests/Operations/Tags/TagNormalizerTests.cs

@ -9,17 +9,16 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy; using FakeItEasy;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.Tags; using Squidex.Domain.Apps.Core.Tags;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.Tags namespace Squidex.Domain.Apps.Core.Operations.Tags
{ {
public class TagNormalizerTests public class TagNormalizerTests
{ {
private static readonly JTokenEqualityComparer JTokenEqualityComparer = new JTokenEqualityComparer();
private readonly ITagService tagService = A.Fake<ITagService>(); private readonly ITagService tagService = A.Fake<ITagService>();
private readonly Guid appId = Guid.NewGuid(); private readonly Guid appId = Guid.NewGuid();
private readonly Guid schemaId = 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); await tagService.NormalizeAsync(appId, schemaId, schema, newData, oldData);
Assert.Equal(new JArray("id2_1", "id2_2"), newData["tags2"]["iv"], JTokenEqualityComparer); Assert.Equal(JsonValue.Array("id2_1", "id2_2"), newData["tags2"]["iv"]);
Assert.Equal(new JArray("id4"), newData["array"]["iv"][0]["nestedTags2"], JTokenEqualityComparer); Assert.Equal(JsonValue.Array("id4"), GetNestedTags(newData));
} }
[Fact] [Fact]
@ -77,8 +76,8 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags
await tagService.NormalizeAsync(appId, schemaId, schema, newData, null); await tagService.NormalizeAsync(appId, schemaId, schema, newData, null);
Assert.Equal(new JArray("id2_1", "id2_2"), newData["tags2"]["iv"], JTokenEqualityComparer); Assert.Equal(JsonValue.Array("id2_1", "id2_2"), newData["tags2"]["iv"]);
Assert.Equal(new JArray("id4"), newData["array"]["iv"][0]["nestedTags2"], JTokenEqualityComparer); Assert.Equal(JsonValue.Array("id4"), GetNestedTags(newData));
} }
[Fact] [Fact]
@ -98,8 +97,16 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags
await tagService.NormalizeAsync(appId, schemaId, schema, newData, null); await tagService.NormalizeAsync(appId, schemaId, schema, newData, null);
Assert.Equal(new JArray("name2_1", "name2_2"), newData["tags2"]["iv"], JTokenEqualityComparer); Assert.Equal(JsonValue.Array("name2_1", "name2_2"), newData["tags2"]["iv"]);
Assert.Equal(new JArray("name4"), newData["array"]["iv"][0]["nestedTags2"], JTokenEqualityComparer); 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) private static NamedContentData GenerateData(string prefix)
@ -107,21 +114,21 @@ namespace Squidex.Domain.Apps.Core.Operations.Tags
return new NamedContentData() return new NamedContentData()
.AddField("tags1", .AddField("tags1",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray($"{prefix}1"))) .AddValue("iv", JsonValue.Array($"{prefix}1")))
.AddField("tags2", .AddField("tags2",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray($"{prefix}2_1", $"{prefix}2_2"))) .AddValue("iv", JsonValue.Array($"{prefix}2_1", $"{prefix}2_2")))
.AddField("string", .AddField("string",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", $"{prefix}stringValue")) .AddValue("iv", $"{prefix}stringValue"))
.AddField("array", .AddField("array",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", .AddValue("iv",
new JArray( JsonValue.Array(
new JObject( JsonValue.Object()
new JProperty("nestedTags1", new JArray($"{prefix}3")), .Add("nestedTags1", JsonValue.Array($"{prefix}3"))
new JProperty("nestedTags2", new JArray($"{prefix}4")), .Add("nestedTags2", JsonValue.Array($"{prefix}4"))
new JProperty("string", $"{prefix}nestedStringValue"))))); .Add("string", $"{prefix}nestedStringValue"))));
} }
} }
} }

14
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ArrayFieldTests.cs

@ -9,8 +9,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ArrayFieldProperties()); 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); Assert.Empty(errors);
} }
@ -74,7 +74,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ArrayFieldProperties()); var sut = Field(new ArrayFieldProperties());
await sut.ValidateAsync("invalid", errors); await sut.ValidateAsync(JsonValue.Create("invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -85,7 +85,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ArrayFieldProperties { MinItems = 3 }); 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( errors.Should().BeEquivalentTo(
new[] { "Must have at least 3 item(s)." }); 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 }); 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( errors.Should().BeEquivalentTo(
new[] { "Must have not more than 1 item(s)." }); 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<object>().ToArray()); return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.OfType<object>().ToArray());
} }
private static RootField<ArrayFieldProperties> Field(ArrayFieldProperties properties) private static RootField<ArrayFieldProperties> Field(ArrayFieldProperties properties)

8
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/AssetsFieldTests.cs

@ -10,10 +10,10 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Collections;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -119,7 +119,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new AssetsFieldProperties()); var sut = Field(new AssetsFieldProperties());
await sut.ValidateAsync("invalid", errors); await sut.ValidateAsync(JsonValue.Create("invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); 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<object>().ToArray()); return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray());
} }
private static RootField<AssetsFieldProperties> Field(AssetsFieldProperties properties) private static RootField<AssetsFieldProperties> Field(AssetsFieldProperties properties)

8
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/BooleanFieldTests.cs

@ -8,8 +8,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -62,15 +62,15 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new BooleanFieldProperties()); var sut = Field(new BooleanFieldProperties());
await sut.ValidateAsync(CreateValue("Invalid"), errors); await sut.ValidateAsync(JsonValue.Create("Invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); 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<BooleanFieldProperties> Field(BooleanFieldProperties properties) private static RootField<BooleanFieldProperties> Field(BooleanFieldProperties properties)

15
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs

@ -8,12 +8,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -52,7 +52,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new NamedContentData() new NamedContentData()
.AddField("my-field", .AddField("my-field",
new ContentFieldData() new ContentFieldData()
.AddValue(1000)); .AddValue("iv", 1000));
await data.ValidateAsync(context, schema, languagesConfig.ToResolver(), errors); await data.ValidateAsync(context, schema, languagesConfig.ToResolver(), errors);
@ -214,7 +214,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new NamedContentData() new NamedContentData()
.AddField("my-field", .AddField("my-field",
new ContentFieldData() new ContentFieldData()
.AddValue(1000)); .AddValue("iv", 1000));
await data.ValidatePartialAsync(context, schema, languagesConfig.ToResolver(), errors); await data.ValidatePartialAsync(context, schema, languagesConfig.ToResolver(), errors);
@ -329,10 +329,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new NamedContentData() new NamedContentData()
.AddField("my-field", .AddField("my-field",
new ContentFieldData() new ContentFieldData()
.AddValue("iv", new JArray( .AddValue("iv",
new JObject(), JsonValue.Array(
new JObject(new JProperty("my-nested", 1)), JsonValue.Object(),
new JObject()))); JsonValue.Object().Add("my-nested", 1),
JsonValue.Object())));
await data.ValidatePartialAsync(context, schema, languagesConfig.ToResolver(), errors); await data.ValidatePartialAsync(context, schema, languagesConfig.ToResolver(), errors);

14
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/DateTimeFieldTests.cs

@ -9,9 +9,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -33,7 +33,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new DateTimeFieldProperties()); var sut = Field(new DateTimeFieldProperties());
await sut.ValidateAsync(CreateValue(null), errors); await sut.ValidateAsync(JsonValue.Null, errors);
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -43,7 +43,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new DateTimeFieldProperties { IsRequired = true }); var sut = Field(new DateTimeFieldProperties { IsRequired = true });
await sut.ValidateAsync(CreateValue(null), errors); await sut.ValidateAsync(JsonValue.Null, errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Field is required." }); new[] { "Field is required." });
@ -76,7 +76,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new DateTimeFieldProperties()); var sut = Field(new DateTimeFieldProperties());
await sut.ValidateAsync(CreateValue("Invalid"), errors); await sut.ValidateAsync(JsonValue.Create("Invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -87,7 +87,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new DateTimeFieldProperties()); var sut = Field(new DateTimeFieldProperties());
await sut.ValidateAsync(CreateValue(123), errors); await sut.ValidateAsync(JsonValue.Create(123), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -98,9 +98,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
return Instant.FromDateTimeUtc(DateTime.UtcNow.Date.AddDays(days)); 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<DateTimeFieldProperties> Field(DateTimeFieldProperties properties) private static RootField<DateTimeFieldProperties> Field(DateTimeFieldProperties properties)

45
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/GeolocationFieldTests.cs

@ -8,8 +8,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new GeolocationFieldProperties()); var sut = Field(new GeolocationFieldProperties());
await sut.ValidateAsync(CreateValue(JValue.CreateNull()), errors); await sut.ValidateAsync(JsonValue.Null, errors);
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -41,11 +41,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new GeolocationFieldProperties()); var sut = Field(new GeolocationFieldProperties());
var geolocation = new JObject( var geolocation = JsonValue.Object()
new JProperty("latitude", 0), .Add("latitude", 0)
new JProperty("longitude", 0)); .Add("longitude", 0);
await sut.ValidateAsync(CreateValue(geolocation), errors); await sut.ValidateAsync(geolocation, errors);
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -55,11 +55,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new GeolocationFieldProperties { IsRequired = true }); var sut = Field(new GeolocationFieldProperties { IsRequired = true });
var geolocation = new JObject( var geolocation = JsonValue.Object()
new JProperty("latitude", 200), .Add("latitude", 200)
new JProperty("longitude", 0)); .Add("longitude", 0);
await sut.ValidateAsync(CreateValue(geolocation), errors); await sut.ValidateAsync(geolocation, errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -70,11 +70,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new GeolocationFieldProperties { IsRequired = true }); var sut = Field(new GeolocationFieldProperties { IsRequired = true });
var geolocation = new JObject( var geolocation = JsonValue.Object()
new JProperty("latitude", 0), .Add("latitude", 0)
new JProperty("longitude", 200)); .Add("longitude", 200);
await sut.ValidateAsync(CreateValue(geolocation), errors); await sut.ValidateAsync(geolocation, errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -85,12 +85,12 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new GeolocationFieldProperties { IsRequired = true }); var sut = Field(new GeolocationFieldProperties { IsRequired = true });
var geolocation = new JObject( var geolocation = JsonValue.Object()
new JProperty("invalid", 0), .Add("invalid", 0)
new JProperty("latitude", 0), .Add("latitude", 0)
new JProperty("longitude", 0)); .Add("longitude", 0);
await sut.ValidateAsync(CreateValue(geolocation), errors); await sut.ValidateAsync(geolocation, errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -101,17 +101,12 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new GeolocationFieldProperties { IsRequired = true }); var sut = Field(new GeolocationFieldProperties { IsRequired = true });
await sut.ValidateAsync(CreateValue(JValue.CreateNull()), errors); await sut.ValidateAsync(JsonValue.Null, errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Field is required." }); new[] { "Field is required." });
} }
private static JToken CreateValue(JToken v)
{
return v;
}
private static RootField<GeolocationFieldProperties> Field(GeolocationFieldProperties properties) private static RootField<GeolocationFieldProperties> Field(GeolocationFieldProperties properties)
{ {
return Fields.Geolocation(1, "my-geolocation", Partitioning.Invariant, properties); return Fields.Geolocation(1, "my-geolocation", Partitioning.Invariant, properties);

8
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/JsonFieldTests.cs

@ -8,8 +8,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new JsonFieldProperties()); var sut = Field(new JsonFieldProperties());
await sut.ValidateAsync(CreateValue(new JValue(1)), errors); await sut.ValidateAsync(CreateValue(JsonValue.Create(1)), errors);
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -41,13 +41,13 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new JsonFieldProperties { IsRequired = true }); var sut = Field(new JsonFieldProperties { IsRequired = true });
await sut.ValidateAsync(CreateValue(JValue.CreateNull()), errors); await sut.ValidateAsync(CreateValue(JsonValue.Null), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Field is required." }); new[] { "Field is required." });
} }
private static JValue CreateValue(JValue v) private static IJsonValue CreateValue(IJsonValue v)
{ {
return v; return v;
} }

12
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/NumberFieldTests.cs

@ -8,9 +8,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Collections;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new NumberFieldProperties()); var sut = Field(new NumberFieldProperties());
await sut.ValidateAsync(CreateValue(null), errors); await sut.ValidateAsync(JsonValue.Null, errors);
Assert.Empty(errors); Assert.Empty(errors);
} }
@ -42,7 +42,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new NumberFieldProperties { IsRequired = true }); var sut = Field(new NumberFieldProperties { IsRequired = true });
await sut.ValidateAsync(CreateValue(null), errors); await sut.ValidateAsync(JsonValue.Null, errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Field is required." }); new[] { "Field is required." });
@ -86,15 +86,15 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new NumberFieldProperties()); var sut = Field(new NumberFieldProperties());
await sut.ValidateAsync(CreateValue("Invalid"), errors); await sut.ValidateAsync(JsonValue.Create("Invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); 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<NumberFieldProperties> Field(NumberFieldProperties properties) private static RootField<NumberFieldProperties> Field(NumberFieldProperties properties)

8
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ReferencesFieldTests.cs

@ -10,8 +10,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -76,7 +76,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new ReferencesFieldProperties()); var sut = Field(new ReferencesFieldProperties());
await sut.ValidateAsync("invalid", errors); await sut.ValidateAsync(JsonValue.Create("invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -117,9 +117,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new[] { $"Contains invalid reference '{referenceId}'." }); 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<object>().ToArray()); return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.Select(x => (object)x.ToString()).ToArray());
} }
private static RootField<ReferencesFieldProperties> Field(ReferencesFieldProperties properties) private static RootField<ReferencesFieldProperties> Field(ReferencesFieldProperties properties)

6
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/StringFieldTests.cs

@ -8,9 +8,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Collections;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -103,9 +103,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new[] { "Custom Error Message." }); 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<StringFieldProperties> Field(StringFieldProperties properties) private static RootField<StringFieldProperties> Field(StringFieldProperties properties)

8
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/TagsFieldTests.cs

@ -9,9 +9,9 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Collections;
using Squidex.Infrastructure.Json.Objects;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
@ -75,7 +75,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
var sut = Field(new TagsFieldProperties()); var sut = Field(new TagsFieldProperties());
await sut.ValidateAsync("invalid", errors); await sut.ValidateAsync(JsonValue.Create("invalid"), errors);
errors.Should().BeEquivalentTo( errors.Should().BeEquivalentTo(
new[] { "Not a valid value." }); new[] { "Not a valid value." });
@ -114,9 +114,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new[] { "[1]: Not an allowed value." }); 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<object>().ToArray()); return ids == null ? (IJsonValue)JsonValue.Null : JsonValue.Array(ids.OfType<object>().ToArray());
} }
private static RootField<TagsFieldProperties> Field(TagsFieldProperties properties) private static RootField<TagsFieldProperties> Field(TagsFieldProperties properties)

6
tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ValidationTestExtensions.cs

@ -9,10 +9,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.ValidateContent; using Squidex.Domain.Apps.Core.ValidateContent;
using Squidex.Domain.Apps.Core.ValidateContent.Validators; using Squidex.Domain.Apps.Core.ValidateContent.Validators;
using Squidex.Infrastructure.Json.Objects;
namespace Squidex.Domain.Apps.Core.Operations.ValidateContent namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
{ {
@ -37,14 +37,14 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
CreateFormatter(errors)); CreateFormatter(errors));
} }
public static Task ValidateAsync(this IField field, JToken value, IList<string> errors, ValidationContext context = null) public static Task ValidateAsync(this IField field, IJsonValue value, IList<string> errors, ValidationContext context = null)
{ {
return new FieldValidator(ValidatorsFactory.CreateValidators(field).ToArray(), field).ValidateAsync(value, return new FieldValidator(ValidatorsFactory.CreateValidators(field).ToArray(), field).ValidateAsync(value,
CreateContext(context), CreateContext(context),
CreateFormatter(errors)); CreateFormatter(errors));
} }
public static Task ValidateOptionalAsync(this IField field, JToken value, IList<string> errors, ValidationContext context = null) public static Task ValidateOptionalAsync(this IField field, IJsonValue value, IList<string> errors, ValidationContext context = null)
{ {
return new FieldValidator(ValidatorsFactory.CreateValidators(field).ToArray(), field).ValidateAsync(value, return new FieldValidator(ValidatorsFactory.CreateValidators(field).ToArray(), field).ValidateAsync(value,
CreateContext(context).Optional(true), CreateContext(context).Optional(true),

13
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;
using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Collections;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.Json.Newtonsoft;
using Xunit; using Xunit;
namespace Squidex.Domain.Apps.Core namespace Squidex.Domain.Apps.Core
{ {
public static class TestData public static class TestData
{ {
public static JsonSerializer DefaultSerializer() public static IJsonSerializer DefaultSerializer()
{ {
var typeNameRegistry = new TypeNameRegistry(); var typeNameRegistry = new TypeNameRegistry();
@ -35,6 +36,7 @@ namespace Squidex.Domain.Apps.Core
new AppClientsConverter(), new AppClientsConverter(),
new AppContributorsConverter(), new AppContributorsConverter(),
new AppPatternsConverter(), new AppPatternsConverter(),
new ClaimsPrincipalConverter(),
new InstantConverter(), new InstantConverter(),
new LanguageConverter(), new LanguageConverter(),
new LanguagesConfigConverter(), new LanguagesConfigConverter(),
@ -50,7 +52,7 @@ namespace Squidex.Domain.Apps.Core
TypeNameHandling = TypeNameHandling.Auto TypeNameHandling = TypeNameHandling.Auto
}; };
return JsonSerializer.Create(serializerSettings); return new NewtonsoftJsonSerializer(serializerSettings);
} }
public static Schema MixedSchema() public static Schema MixedSchema()
@ -100,6 +102,13 @@ namespace Squidex.Domain.Apps.Core
return schema; return schema;
} }
public static T SerializeAndDeserialize<T>(this T value)
{
var serializer = DefaultSerializer();
return serializer.Deserialize<T>(serializer.Serialize(value));
}
public static void TestFreeze(IFreezable freezable) public static void TestFreeze(IFreezable freezable)
{ {
var sut = new AssetsFieldProperties(); var sut = new AssetsFieldProperties();

14
tests/Squidex.Infrastructure.Tests/EventSourcing/DefaultEventDataFormatterTests.cs

@ -7,9 +7,7 @@
using System; using System;
using System.Linq; using System.Linq;
using Newtonsoft.Json;
using NodaTime; using NodaTime;
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.TestHelpers; using Squidex.Infrastructure.TestHelpers;
using Xunit; 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; private readonly DefaultEventDataFormatter sut;
public DefaultEventDataFormatterTests() public DefaultEventDataFormatterTests()
{ {
serializerSettings.Converters.Add(new PropertiesBagConverter<EnvelopeHeaders>()); var typeNameRegistry =
new TypeNameRegistry()
.Map(typeof(MyEvent), "Event")
.Map(typeof(MyOldEvent), "OldEvent");
typeNameRegistry.Map(typeof(MyEvent), "Event"); sut = new DefaultEventDataFormatter(typeNameRegistry, JsonHelper.DefaultSerializer(typeNameRegistry));
typeNameRegistry.Map(typeof(MyOldEvent), "OldEvent");
sut = new DefaultEventDataFormatter(typeNameRegistry, JsonSerializer.Create(serializerSettings));
} }
[Fact] [Fact]

3
tests/Squidex.Infrastructure.Tests/EventSourcing/EnvelopeTests.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Squidex.Infrastructure.Json;
using Squidex.Infrastructure.TestHelpers; using Squidex.Infrastructure.TestHelpers;
using Xunit; using Xunit;
@ -23,7 +22,7 @@ namespace Squidex.Infrastructure.EventSourcing
{ {
var value = new Envelope<IEvent>(new MyEvent { Value = 1 }); var value = new Envelope<IEvent>(new MyEvent { Value = 1 });
var deserialized = value.SerializeAndDeserializeAndReturn(new PropertiesBagConverter<EnvelopeHeaders>()); var deserialized = value.SerializeAndDeserialize();
Assert.Equal(1, deserialized.To<MyEvent>().Payload.Value); Assert.Equal(1, deserialized.To<MyEvent>().Payload.Value);
} }

10
tests/Squidex.Infrastructure.Tests/Json/ClaimsPrincipalConverterTests.cs

@ -36,10 +36,10 @@ namespace Squidex.Infrastructure.Json
"Google") "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(0).AuthenticationType, serialized.Identities.ElementAt(0).AuthenticationType);
Assert.Equal(value.Identities.ElementAt(1).AuthenticationType, result.Identities.ElementAt(1).AuthenticationType); Assert.Equal(value.Identities.ElementAt(1).AuthenticationType, serialized.Identities.ElementAt(1).AuthenticationType);
} }
[Fact] [Fact]
@ -47,7 +47,9 @@ namespace Squidex.Infrastructure.Json
{ {
ClaimsPrincipal value = null; ClaimsPrincipal value = null;
value.SerializeAndDeserialize(new ClaimsPrincipalConverter()); var serialized = value.SerializeAndDeserialize();
Assert.Null(value);
} }
} }
} }

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save