Browse Source

Null value fix.

pull/680/head
Sebastian Stehle 5 years ago
parent
commit
5db950d16e
  1. 23
      backend/src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs
  2. 18
      backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs
  3. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueGenerator.cs
  4. 64
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/FieldConvertersTests.cs
  5. 18
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/DefaultValues/DefaultValuesTests.cs
  6. 19826
      frontend/package-lock.json

23
backend/src/Squidex.Domain.Apps.Core.Model/Contents/ContentFieldData.cs

@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects; using Squidex.Infrastructure.Json.Objects;
@ -30,17 +31,31 @@ namespace Squidex.Domain.Apps.Core.Contents
{ {
} }
public ContentFieldData AddInvariant(object? value) public bool TryGetNonNull(string key, [MaybeNullWhen(false)] out IJsonValue result)
{ {
this[InvariantPartitioning.Key] = JsonValue.Create(value); result = null!;
return this; if (TryGetValue(key, out var found) && found != null && found.Type != JsonValueType.Null)
{
result = found;
return true;
}
return false;
}
public ContentFieldData AddInvariant(object? value)
{
return AddValue(InvariantPartitioning.Key, JsonValue.Create(value));
} }
public ContentFieldData AddLocalized(string key, object? value) public ContentFieldData AddLocalized(string key, object? value)
{ {
Guard.NotNullOrEmpty(key, nameof(key)); return AddValue(key, JsonValue.Create(value));
}
public ContentFieldData AddValue(string key, IJsonValue? value)
{
this[key] = JsonValue.Create(value); this[key] = JsonValue.Create(value);
return this; return this;

18
backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/FieldConverters.cs

@ -59,21 +59,21 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
public static FieldConverter ResolveInvariant(LanguagesConfig languages) public static FieldConverter ResolveInvariant(LanguagesConfig languages)
{ {
var codeForInvariant = InvariantPartitioning.Key; var iv = InvariantPartitioning.Key;
return (data, field) => return (data, field) =>
{ {
if (field.Partitioning.Equals(Partitioning.Invariant) && !data.ContainsKey(codeForInvariant)) if (field.Partitioning.Equals(Partitioning.Invariant) && !data.TryGetNonNull(iv, out _))
{ {
var result = new ContentFieldData(1); var result = new ContentFieldData(1);
if (data.TryGetValue(languages.Master, out var value)) if (data.TryGetNonNull(languages.Master, out var value))
{ {
result[codeForInvariant] = value; result[iv] = value;
} }
else if (data.Count > 0) else if (data.Count > 0)
{ {
result[codeForInvariant] = data.Values.First(); result[iv] = data.Values.First();
} }
return result; return result;
@ -85,13 +85,13 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
public static FieldConverter ResolveLanguages(LanguagesConfig languages) public static FieldConverter ResolveLanguages(LanguagesConfig languages)
{ {
var codeForInvariant = InvariantPartitioning.Key; var iv = InvariantPartitioning.Key;
return (data, field) => return (data, field) =>
{ {
if (field.Partitioning.Equals(Partitioning.Language)) if (field.Partitioning.Equals(Partitioning.Language))
{ {
if (data.TryGetValue(codeForInvariant, out var value)) if (data.TryGetNonNull(iv, out var value))
{ {
var result = new ContentFieldData var result = new ContentFieldData
{ {
@ -119,11 +119,11 @@ namespace Squidex.Domain.Apps.Core.ConvertContent
{ {
foreach (var languageCode in languages.AllKeys) foreach (var languageCode in languages.AllKeys)
{ {
if (!data.ContainsKey(languageCode)) if (!data.TryGetNonNull(languageCode, out _))
{ {
foreach (var fallback in languages.GetPriorities(languageCode)) foreach (var fallback in languages.GetPriorities(languageCode))
{ {
if (data.TryGetValue(fallback, out var value)) if (data.TryGetNonNull(fallback, out var value))
{ {
data[languageCode] = value; data[languageCode] = value;
break; break;

2
backend/src/Squidex.Domain.Apps.Core.Operations/DefaultValues/DefaultValueGenerator.cs

@ -64,7 +64,7 @@ namespace Squidex.Domain.Apps.Core.DefaultValues
return; return;
} }
if (!fieldData.ContainsKey(partitionKey)) if (!fieldData.TryGetNonNull(partitionKey, out _))
{ {
fieldData.AddLocalized(partitionKey, defaultValue); fieldData.AddLocalized(partitionKey, defaultValue);
} }

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

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System.Collections.Generic;
using System.Linq; using System.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;
@ -21,8 +22,15 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
private readonly LanguagesConfig languagesConfig = LanguagesConfig.English.Set(Language.DE); private readonly LanguagesConfig languagesConfig = LanguagesConfig.English.Set(Language.DE);
private static IEnumerable<object?[]> InvalidValues()
{
yield return new object?[] { null };
yield return new object?[] { JsonValue.Null };
yield return new object?[] { JsonValue.False }; // Undefined
}
[Fact] [Fact]
public void Should_filter_for_value_conversion() public void Should_convert_data_with_value_converter()
{ {
var field = Fields.String(1, "string", Partitioning.Invariant); var field = Fields.String(1, "string", Partitioning.Invariant);
@ -38,7 +46,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
} }
[Fact] [Fact]
public void Should_return_same_values_when_excluding_changed_types_if_all_values_are_valid() public void Should_return_field_data_when_excluding_changed_types_and_all_values_are_valid()
{ {
var field = Fields.Number(1, "number", Partitioning.Invariant); var field = Fields.Number(1, "number", Partitioning.Invariant);
@ -49,11 +57,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var result = FieldConverters.ExcludeChangedTypes(TestUtils.DefaultSerializer)(source, field); var result = FieldConverters.ExcludeChangedTypes(TestUtils.DefaultSerializer)(source, field);
Assert.Same(source, result); Assert.Equal(source, result);
} }
[Fact] [Fact]
public void Should_return_null_when_excluding_changed_types_if_any_value_is_invalid() public void Should_return_null_when_excluding_changed_types_and_one_value_is_invalid()
{ {
var field = Fields.Number(1, "number", Partitioning.Invariant); var field = Fields.Number(1, "number", Partitioning.Invariant);
@ -68,7 +76,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
} }
[Fact] [Fact]
public void Should_return_same_values_if_field_not_hidden() public void Should_return_field_data_if_field_not_hidden()
{ {
var field = Fields.String(1, "string", Partitioning.Language); var field = Fields.String(1, "string", Partitioning.Language);
@ -76,7 +84,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var result = FieldConverters.ExcludeHidden(source, field); var result = FieldConverters.ExcludeHidden(source, field);
Assert.Same(source, result); Assert.Equal(source, result);
} }
[Fact] [Fact]
@ -110,8 +118,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
Assert.Equal(expected, result); Assert.Equal(expected, result);
} }
[Fact] [Theory]
public void Should_resolve_languages_and_resolve_master_language_from_invariant() [MemberData(nameof(InvalidValues))]
public void Should_resolve_master_language_from_invariant(IJsonValue? value)
{ {
var field = Fields.String(1, "string", Partitioning.Language); var field = Fields.String(1, "string", Partitioning.Language);
@ -120,6 +129,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
.AddLocalized("iv", "A") .AddLocalized("iv", "A")
.AddLocalized("it", "B"); .AddLocalized("it", "B");
if (value != JsonValue.False)
{
source["en"] = value!;
}
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddLocalized("en", "A"); .AddLocalized("en", "A");
@ -130,7 +144,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
} }
[Fact] [Fact]
public void Should_return_same_values_if_resolving_languages_from_invariant_field() public void Should_not_resolve_master_language_if_not_found()
{ {
var field = Fields.String(1, "string", Partitioning.Invariant); var field = Fields.String(1, "string", Partitioning.Invariant);
@ -138,11 +152,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
var result = FieldConverters.ResolveLanguages(languagesConfig)(source, field); var result = FieldConverters.ResolveLanguages(languagesConfig)(source, field);
Assert.Same(source, result); Assert.Equal(source, result);
} }
[Fact] [Fact]
public void Should_resolve_invariant_and_use_direct_value() public void Should_resolve_invariant()
{ {
var field = Fields.String(1, "string", Partitioning.Invariant); var field = Fields.String(1, "string", Partitioning.Invariant);
@ -159,8 +173,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
Assert.Equal(expected, result); Assert.Equal(expected, result);
} }
[Fact] [Theory]
public void Should_resolve_invariant_and_resolve_invariant_from_master_language() [MemberData(nameof(InvalidValues))]
public void Should_resolve_invariant_from_master_language(IJsonValue? value)
{ {
var field = Fields.String(1, "string", Partitioning.Invariant); var field = Fields.String(1, "string", Partitioning.Invariant);
@ -169,6 +184,11 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
.AddLocalized("de", "DE") .AddLocalized("de", "DE")
.AddLocalized("en", "EN"); .AddLocalized("en", "EN");
if (value != JsonValue.False)
{
source[InvariantPartitioning.Key] = value!;
}
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddInvariant("EN"); .AddInvariant("EN");
@ -179,7 +199,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
} }
[Fact] [Fact]
public void Should_resolve_invariant_and_resolve_invariant_from_first_language() public void Should_resolve_invariant_from_first_language()
{ {
var field = Fields.String(1, "string", Partitioning.Invariant); var field = Fields.String(1, "string", Partitioning.Invariant);
@ -198,7 +218,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
} }
[Fact] [Fact]
public void Should_return_same_values_if_resolving_invariant_from_language_field() public void Should_not_resolve_invariant_if_not_found()
{ {
var field = Fields.String(1, "string", Partitioning.Language); var field = Fields.String(1, "string", Partitioning.Language);
@ -209,8 +229,9 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
Assert.Same(source, result); Assert.Same(source, result);
} }
[Fact] [Theory]
public void Should_return_language_from_fallback_if_found() [MemberData(nameof(InvalidValues))]
public void Should_resolve_from_fallback_language_if_found(IJsonValue? value)
{ {
var field = Fields.String(1, "string", Partitioning.Language); var field = Fields.String(1, "string", Partitioning.Language);
@ -225,12 +246,17 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
.AddLocalized("en", "EN") .AddLocalized("en", "EN")
.AddLocalized("it", "IT"); .AddLocalized("it", "IT");
if (value != JsonValue.False)
{
source["de"] = value!;
}
var expected = var expected =
new ContentFieldData() new ContentFieldData()
.AddLocalized("en", "EN") .AddLocalized("en", "EN")
.AddLocalized("de", "EN")
.AddLocalized("it", "IT") .AddLocalized("it", "IT")
.AddLocalized("es", "IT"); .AddLocalized("es", "IT")
.AddLocalized("de", "EN");
var result = FieldConverters.ResolveFallbackLanguages(config)(source, field); var result = FieldConverters.ResolveFallbackLanguages(config)(source, field);

18
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/DefaultValues/DefaultValuesTests.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System.Collections.Generic;
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;
@ -37,8 +38,16 @@ namespace Squidex.Domain.Apps.Core.Operations.DefaultValues
new BooleanFieldProperties { DefaultValue = true }); new BooleanFieldProperties { DefaultValue = true });
} }
[Fact] private static IEnumerable<object?[]> InvalidValues()
public void Should_enrich_with_default_values() {
yield return new object?[] { null };
yield return new object?[] { JsonValue.Null };
yield return new object?[] { JsonValue.False }; // Undefined
}
[Theory]
[MemberData(nameof(InvalidValues))]
public void Should_enrich_with_default_values(IJsonValue? value)
{ {
var data = var data =
new ContentData() new ContentData()
@ -49,6 +58,11 @@ namespace Squidex.Domain.Apps.Core.Operations.DefaultValues
new ContentFieldData() new ContentFieldData()
.AddInvariant(456)); .AddInvariant(456));
if (value != JsonBoolean.False)
{
data["my-string"]!["en"] = value!;
}
data.GenerateDefaultValues(schema, languagesConfig.ToResolver()); data.GenerateDefaultValues(schema, languagesConfig.ToResolver());
Assert.Equal(456, ((JsonNumber)data["my-number"]!["iv"]).Value); Assert.Equal(456, ((JsonNumber)data["my-number"]!["iv"]).Value);

19826
frontend/package-lock.json

File diff suppressed because it is too large
Loading…
Cancel
Save