Browse Source

Schemas made immutable.

pull/169/head
Sebastian Stehle 8 years ago
parent
commit
00fd8ef5f7
  1. 6
      src/Squidex.Domain.Apps.Core.Model/Schemas/Field{T}.cs
  2. 36
      src/Squidex.Domain.Apps.Core.Model/Schemas/Schema.cs
  3. 30
      src/Squidex.Infrastructure/Cloneable.cs
  4. 20
      src/Squidex.Infrastructure/Cloneable{T}.cs
  5. 30
      src/Squidex.Infrastructure/Freezable.cs
  6. 106
      tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaFieldTests.cs
  7. 217
      tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs
  8. 21
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/ContentConversionTests.cs
  9. 23
      tests/Squidex.Domain.Apps.Core.Tests/Operations/EnrichContent/ContentEnrichmentTests.cs
  10. 21
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ExtractReferenceIds/ReferenceExtractionTests.cs
  11. 29
      tests/Squidex.Domain.Apps.Core.Tests/Operations/ValidateContent/ContentValidationTests.cs
  12. 45
      tests/Squidex.Domain.Apps.Core.Tests/TestData.cs

6
src/Squidex.Domain.Apps.Core.Model/Schemas/Field{T}.cs

@ -40,10 +40,10 @@ namespace Squidex.Domain.Apps.Core.Schemas
{ {
var typedProperties = ValidateProperties(newProperties); var typedProperties = ValidateProperties(newProperties);
return Clone<Field>(clone => return Clone<Field<T>>(clone =>
{ {
properties = typedProperties; clone.properties = typedProperties;
properties.Freeze(); clone.properties.Freeze();
}); });
} }

36
src/Squidex.Domain.Apps.Core.Model/Schemas/Schema.cs

@ -21,7 +21,7 @@ namespace Squidex.Domain.Apps.Core.Schemas
private ImmutableList<Field> fieldsOrdered = ImmutableList<Field>.Empty; private ImmutableList<Field> fieldsOrdered = ImmutableList<Field>.Empty;
private ImmutableDictionary<long, Field> fieldsById = ImmutableDictionary<long, Field>.Empty; private ImmutableDictionary<long, Field> fieldsById = ImmutableDictionary<long, Field>.Empty;
private ImmutableDictionary<string, Field> fieldsByName = ImmutableDictionary<string, Field>.Empty; private ImmutableDictionary<string, Field> fieldsByName = ImmutableDictionary<string, Field>.Empty;
private SchemaProperties properties = new SchemaProperties(); private SchemaProperties properties;
private bool isPublished; private bool isPublished;
public string Name public string Name
@ -54,30 +54,42 @@ namespace Squidex.Domain.Apps.Core.Schemas
get { return properties; } get { return properties; }
} }
public Schema(string name) public Schema(string name, SchemaProperties properties = null)
{ {
Guard.NotNullOrEmpty(name, nameof(name)); Guard.NotNullOrEmpty(name, nameof(name));
this.name = name; this.name = name;
this.properties = properties ?? new SchemaProperties();
this.properties.Freeze();
OnCloned();
} }
public Schema(string name, IEnumerable<Field> fields, SchemaProperties properties, bool isPublished) public Schema(string name, IEnumerable<Field> fields, SchemaProperties properties, bool isPublished)
: this(name) : this(name, properties)
{ {
Guard.NotNullOrEmpty(name, nameof(name)); Guard.NotNullOrEmpty(name, nameof(name));
this.isPublished = isPublished; this.isPublished = isPublished;
this.properties = properties ?? new SchemaProperties();
this.properties.Freeze();
fieldsOrdered = ImmutableList<Field>.Empty.AddRange(fields); fieldsOrdered = ImmutableList<Field>.Empty.AddRange(fields);
OnCloned();
} }
protected override void OnCloned() protected override void OnCloned()
{ {
fieldsById = fieldsOrdered.ToImmutableDictionary(x => x.Id); if (fieldsOrdered.Count > 0)
fieldsByName = fieldsOrdered.ToImmutableDictionary(x => x.Name); {
fieldsById = fieldsOrdered.ToImmutableDictionary(x => x.Id);
fieldsByName = fieldsOrdered.ToImmutableDictionary(x => x.Name);
}
else
{
fieldsById = ImmutableDictionary<long, Field>.Empty;
fieldsByName = ImmutableDictionary<string, Field>.Empty;
}
} }
[Pure] [Pure]
@ -87,8 +99,8 @@ namespace Squidex.Domain.Apps.Core.Schemas
return Clone(clone => return Clone(clone =>
{ {
properties = newProperties; clone.properties = newProperties;
properties.Freeze(); clone.properties.Freeze();
}); });
} }
@ -151,7 +163,7 @@ namespace Squidex.Domain.Apps.Core.Schemas
{ {
return Clone(clone => return Clone(clone =>
{ {
isPublished = true; clone.isPublished = true;
}); });
} }
@ -160,7 +172,7 @@ namespace Squidex.Domain.Apps.Core.Schemas
{ {
return Clone(clone => return Clone(clone =>
{ {
isPublished = false; clone.isPublished = false;
}); });
} }

30
src/Squidex.Infrastructure/Cloneable.cs

@ -0,0 +1,30 @@
// ==========================================================================
// Cloneable.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
namespace Squidex.Infrastructure
{
public abstract class Cloneable
{
protected T Clone<T>(Action<T> updater) where T : Cloneable
{
var clone = (T)MemberwiseClone();
updater(clone);
clone.OnCloned();
return clone;
}
protected virtual void OnCloned()
{
}
}
}

20
src/Squidex.Infrastructure/Cloneable{T}.cs

@ -0,0 +1,20 @@
// ==========================================================================
// Cloneable{T}.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
namespace Squidex.Infrastructure
{
public abstract class Cloneable<T> : Cloneable where T : Cloneable
{
protected T Clone(Action<T> updater)
{
return base.Clone<T>(updater);
}
}
}

30
src/Squidex.Infrastructure/Freezable.cs

@ -0,0 +1,30 @@
// ==========================================================================
// Freezable.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
namespace Squidex.Infrastructure
{
public abstract class Freezable
{
public bool IsFrozen { get; private set; }
protected void ThrowIfFrozen()
{
if (IsFrozen)
{
throw new InvalidOperationException("Object is frozen");
}
}
public void Freeze()
{
IsFrozen = true;
}
}
}

106
tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaFieldTests.cs

@ -10,16 +10,19 @@ using System;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Xunit; using Xunit;
#pragma warning disable SA1310 // Field names must not contain underscore
namespace Squidex.Domain.Apps.Core.Model.Schemas namespace Squidex.Domain.Apps.Core.Model.Schemas
{ {
public class SchemaFieldTests public class SchemaFieldTests
{ {
private readonly NumberField sut = new NumberField(1, "my-field", Partitioning.Invariant); private readonly NumberField field_0 = new NumberField(1, "my-field", Partitioning.Invariant);
[Fact] [Fact]
public void Should_instantiate_field() public void Should_instantiate_field()
{ {
Assert.Equal("my-field", sut.Name); Assert.True(field_0.RawProperties.IsFrozen);
Assert.Equal("my-field", field_0.Name);
} }
[Fact] [Fact]
@ -31,61 +34,122 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas
[Fact] [Fact]
public void Should_hide_field() public void Should_hide_field()
{ {
sut.Hide(); var field_1 = field_0.Hide();
sut.Hide(); var field_2 = field_1.Hide();
Assert.True(sut.IsHidden); Assert.False(field_0.IsHidden);
Assert.True(field_2.IsHidden);
} }
[Fact] [Fact]
public void Should_show_field() public void Should_show_field()
{ {
sut.Hide(); var field_1 = field_0.Hide();
sut.Show(); var field_2 = field_1.Show();
sut.Show(); var field_3 = field_2.Show();
Assert.False(sut.IsHidden); Assert.True(field_1.IsHidden);
Assert.False(field_3.IsHidden);
} }
[Fact] [Fact]
public void Should_disable_field() public void Should_disable_field()
{ {
sut.Disable(); var field_1 = field_0.Disable();
sut.Disable(); var field_2 = field_1.Disable();
Assert.True(sut.IsDisabled); Assert.False(field_0.IsDisabled);
Assert.True(field_2.IsDisabled);
} }
[Fact] [Fact]
public void Should_enable_field() public void Should_enable_field()
{ {
sut.Disable(); var field_1 = field_0.Disable();
sut.Enable(); var field_2 = field_1.Enable();
sut.Enable(); var field_3 = field_2.Enable();
Assert.False(sut.IsDisabled); Assert.True(field_1.IsDisabled);
Assert.False(field_3.IsDisabled);
} }
[Fact] [Fact]
public void Should_lock_field() public void Should_lock_field()
{ {
sut.Lock(); var field_1 = field_0.Lock();
Assert.True(sut.IsLocked); Assert.False(field_0.IsLocked);
Assert.True(field_1.IsLocked);
} }
[Fact] [Fact]
public void Should_update_field() public void Should_update_field()
{ {
sut.Update(new NumberFieldProperties { Hints = "my-hints" }); var field_1 = field_0.Update(new NumberFieldProperties { Hints = "my-hints" });
Assert.Equal("my-hints", sut.RawProperties.Hints); Assert.Null(field_0.RawProperties.Hints);
Assert.True(field_1.RawProperties.IsFrozen);
Assert.Equal("my-hints", field_1.RawProperties.Hints);
} }
[Fact] [Fact]
public void Should_throw_exception_if_updating_with_invalid_properties_type() public void Should_throw_exception_if_updating_with_invalid_properties_type()
{ {
Assert.Throws<ArgumentException>(() => sut.Update(new StringFieldProperties())); Assert.Throws<ArgumentException>(() => field_0.Update(new StringFieldProperties()));
}
[Fact]
public void Should_freeze_asset_field_properties()
{
TestData.TestFreeze(new AssetsFieldProperties());
}
[Fact]
public void Should_freeze_boolean_field_properties()
{
TestData.TestFreeze(new BooleanFieldProperties());
}
[Fact]
public void Should_freeze_datetime_field_properties()
{
TestData.TestFreeze(new DateTimeFieldProperties());
}
[Fact]
public void Should_freeze_geolocation_field_properties()
{
TestData.TestFreeze(new GeolocationFieldProperties());
}
[Fact]
public void Should_freeze_json_field_properties()
{
TestData.TestFreeze(new JsonFieldProperties());
}
[Fact]
public void Should_freeze_number_field_properties()
{
TestData.TestFreeze(new NumberFieldProperties());
}
[Fact]
public void Should_freeze_references_field_properties()
{
TestData.TestFreeze(new ReferencesFieldProperties());
}
[Fact]
public void Should_freeze_string_field_properties()
{
TestData.TestFreeze(new StringFieldProperties());
}
[Fact]
public void Should_freeze_tags_field_properties()
{
TestData.TestFreeze(new TagsFieldProperties());
} }
} }
} }

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

@ -15,17 +15,20 @@ using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Xunit; using Xunit;
#pragma warning disable SA1310 // Field names must not contain underscore
namespace Squidex.Domain.Apps.Core.Model.Schemas namespace Squidex.Domain.Apps.Core.Model.Schemas
{ {
public class SchemaTests public class SchemaTests
{ {
private readonly JsonSerializer serializer = TestData.DefaultSerializer(); private readonly JsonSerializer serializer = TestData.DefaultSerializer();
private readonly Schema sut = new Schema("my-schema"); private readonly Schema schema_0 = new Schema("my-schema");
[Fact] [Fact]
public void Should_instantiate_schema() public void Should_instantiate_schema()
{ {
Assert.Equal("my-schema", sut.Name); Assert.True(schema_0.Properties.IsFrozen);
Assert.Equal("my-schema", schema_0.Name);
} }
[Fact] [Fact]
@ -39,108 +42,242 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas
{ {
var properties = new SchemaProperties { Hints = "my-hint", Label = "my-label" }; var properties = new SchemaProperties { Hints = "my-hint", Label = "my-label" };
sut.Update(properties); var schema_1 = schema_0.Update(properties);
Assert.Equal(properties, sut.Properties); Assert.NotSame(properties, schema_0.Properties);
Assert.Same(properties, schema_1.Properties);
} }
[Fact] [Fact]
public void Should_add_field() public void Should_add_field()
{ {
var field = AddNumberField(1); var field = CreateField(1);
var schema_1 = schema_0.AddField(field);
Assert.Equal(field, sut.FieldsById[1]); Assert.Empty(schema_0.Fields);
Assert.Equal(field, schema_1.FieldsById[1]);
} }
[Fact] [Fact]
public void Should_throw_exception_if_adding_field_with_name_that_already_exists() public void Should_throw_exception_if_adding_field_with_name_that_already_exists()
{ {
AddNumberField(1); var schema_1 = schema_0.AddField(CreateField(1));
Assert.Throws<ArgumentException>(() => sut.AddField(new NumberField(2, "my-field-1", Partitioning.Invariant))); Assert.Throws<ArgumentException>(() => schema_1.AddField(new NumberField(2, "my-field-1", Partitioning.Invariant)));
} }
[Fact] [Fact]
public void Should_throw_exception_if_adding_field_with_id_that_already_exists() public void Should_throw_exception_if_adding_field_with_id_that_already_exists()
{ {
AddNumberField(1); var schema_1 = schema_0.AddField(CreateField(1));
Assert.Throws<ArgumentException>(() => sut.AddField(new NumberField(1, "my-field-2", Partitioning.Invariant))); Assert.Throws<ArgumentException>(() => schema_1.AddField(new NumberField(1, "my-field-2", Partitioning.Invariant)));
} }
[Fact] [Fact]
public void Should_throw_exception_if_updating_with_invalid_properties_type() public void Should_hide_field()
{
var schema_1 = schema_0.AddField(CreateField(1));
var schema_2 = schema_1.HideField(1);
var schema_3 = schema_2.HideField(1);
Assert.False(schema_1.FieldsById[1].IsHidden);
Assert.True(schema_3.FieldsById[1].IsHidden);
}
[Fact]
public void Should_return_same_schema_if_field_to_hide_does_not_exist()
{
var schema_1 = schema_0.HideField(1);
Assert.Same(schema_0, schema_1);
}
[Fact]
public void Should_show_field()
{
var schema_1 = schema_0.AddField(CreateField(1));
var schema_2 = schema_1.HideField(1);
var schema_3 = schema_2.ShowField(1);
var schema_4 = schema_3.ShowField(1);
Assert.True(schema_2.FieldsById[1].IsHidden);
Assert.False(schema_4.FieldsById[1].IsHidden);
}
[Fact]
public void Should_return_same_schema_if_field_to_show_does_not_exist()
{
var schema_1 = schema_0.ShowField(1);
Assert.Same(schema_0, schema_1);
}
[Fact]
public void Should_disable_field()
{
var schema_1 = schema_0.AddField(CreateField(1));
var schema_2 = schema_1.DisableField(1);
var schema_3 = schema_2.DisableField(1);
Assert.False(schema_1.FieldsById[1].IsDisabled);
Assert.True(schema_3.FieldsById[1].IsDisabled);
}
[Fact]
public void Should_return_same_schema_if_field_to_disable_does_not_exist()
{
var schema_1 = schema_0.DisableField(1);
Assert.Same(schema_0, schema_1);
}
[Fact]
public void Should_enable_field()
{ {
AddNumberField(1); var schema_1 = schema_0.AddField(CreateField(1));
Assert.Throws<ArgumentException>(() => sut.FieldsById[1].Update(new StringFieldProperties())); var schema_2 = schema_1.DisableField(1);
var schema_3 = schema_2.EnableField(1);
var schema_4 = schema_3.EnableField(1);
Assert.True(schema_2.FieldsById[1].IsDisabled);
Assert.False(schema_4.FieldsById[1].IsDisabled);
}
[Fact]
public void Should_return_same_schema_if_field_to_enable_does_not_exist()
{
var schema_1 = schema_0.EnableField(1);
Assert.Same(schema_0, schema_1);
}
[Fact]
public void Should_lock_field()
{
var schema_1 = schema_0.AddField(CreateField(1));
var schema_2 = schema_1.LockField(1);
var schema_3 = schema_2.LockField(1);
Assert.False(schema_1.FieldsById[1].IsLocked);
Assert.True(schema_3.FieldsById[1].IsLocked);
}
[Fact]
public void Should_return_same_schema_if_field_to_lock_does_not_exist()
{
var schema_1 = schema_0.LockField(1);
Assert.Same(schema_0, schema_1);
}
[Fact]
public void Should_update_field()
{
var properties = new NumberFieldProperties();
var schema_1 = schema_0.AddField(CreateField(1));
var schema_2 = schema_1.UpdateField(1, properties);
Assert.NotSame(properties, schema_1.FieldsById[1].RawProperties);
Assert.Same(properties, schema_2.FieldsById[1].RawProperties);
} }
[Fact] [Fact]
public void Should_do_nothing_if_field_to_delete_not_found() public void Should_throw_exception_if_updating_with_invalid_properties_type()
{ {
AddNumberField(1); var schema_1 = schema_0.AddField(CreateField(1));
Assert.Throws<ArgumentException>(() => schema_1.UpdateField(1, new StringFieldProperties()));
}
sut.DeleteField(2); [Fact]
public void Should_return_same_schema_if_field_to_update_does_not_exist()
{
var schema_1 = schema_0.UpdateField(1, new StringFieldProperties());
Assert.Equal(1, sut.FieldsById.Count); Assert.Same(schema_0, schema_1);
} }
[Fact] [Fact]
public void Should_delete_field() public void Should_delete_field()
{ {
AddNumberField(1); var schema_1 = schema_0.AddField(CreateField(1));
var schema_2 = schema_1.DeleteField(1);
Assert.Empty(schema_2.FieldsById);
}
sut.DeleteField(1); [Fact]
public void Should_return_same_schema_if_field_to_delete_does_not_exist()
{
var schema_1 = schema_0.DeleteField(1);
Assert.Empty(sut.FieldsById); Assert.Same(schema_0, schema_1);
} }
[Fact] [Fact]
public void Should_publish_schema() public void Should_publish_schema()
{ {
sut.Publish(); var schema_1 = schema_0.Publish();
Assert.True(sut.IsPublished); Assert.False(schema_0.IsPublished);
Assert.True(schema_1.IsPublished);
} }
[Fact] [Fact]
public void Should_unpublish_schema() public void Should_unpublish_schema()
{ {
sut.Publish(); var schema_1 = schema_0.Publish();
sut.Unpublish(); var schema_2 = schema_1.Unpublish();
Assert.False(sut.IsPublished); Assert.True(schema_1.IsPublished);
Assert.False(schema_2.IsPublished);
} }
[Fact] [Fact]
public void Should_reorder_fields() public void Should_reorder_fields()
{ {
var field1 = AddNumberField(1); var field1 = CreateField(1);
var field2 = AddNumberField(2); var field2 = CreateField(2);
var field3 = AddNumberField(3); var field3 = CreateField(3);
sut.ReorderFields(new List<long> { 3, 2, 1 }); var schema_1 = schema_0.AddField(field1);
var schema_2 = schema_1.AddField(field2);
var schema_3 = schema_2.AddField(field3);
var schema_4 = schema_3.ReorderFields(new List<long> { 3, 2, 1 });
Assert.Equal(new List<Field> { field3, field2, field1 }, sut.Fields.ToList()); Assert.Equal(new List<Field> { field3, field2, field1 }, schema_4.Fields.ToList());
} }
[Fact] [Fact]
public void Should_throw_exception_if_not_all_fields_are_covered_for_reordering() public void Should_throw_exception_if_not_all_fields_are_covered_for_reordering()
{ {
AddNumberField(1); var field1 = CreateField(1);
AddNumberField(2); var field2 = CreateField(2);
Assert.Throws<ArgumentException>(() => sut.ReorderFields(new List<long> { 1 })); var schema_1 = schema_0.AddField(field1);
var schema_2 = schema_1.AddField(field2);
Assert.Throws<ArgumentException>(() => schema_2.ReorderFields(new List<long> { 1 }));
} }
[Fact] [Fact]
public void Should_throw_exception_if_field_to_reorder_does_not_exist() public void Should_throw_exception_if_field_to_reorder_does_not_exist()
{ {
AddNumberField(1); var field1 = CreateField(1);
AddNumberField(2); var field2 = CreateField(2);
var schema_1 = schema_0.AddField(field1);
var schema_2 = schema_1.AddField(field2);
Assert.Throws<ArgumentException>(() => sut.ReorderFields(new List<long> { 1, 4 })); Assert.Throws<ArgumentException>(() => schema_2.ReorderFields(new List<long> { 1, 4 }));
} }
[Fact] [Fact]
@ -152,13 +289,9 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas
schemaTarget.ShouldBeEquivalentTo(schemaSource); schemaTarget.ShouldBeEquivalentTo(schemaSource);
} }
private NumberField AddNumberField(int id) private static NumberField CreateField(int id)
{ {
var field = new NumberField(id, $"my-field-{id}", Partitioning.Invariant); return new NumberField(id, $"my-field-{id}", Partitioning.Invariant);
sut.AddField(field);
return field;
} }
} }
} }

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

@ -21,21 +21,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ConvertContent
{ {
public class ContentConversionTests public class ContentConversionTests
{ {
private readonly Schema schema = new Schema("my-schema"); private readonly Schema schema;
private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE); private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE);
public ContentConversionTests() public ContentConversionTests()
{ {
schema.AddField(new NumberField(1, "field1", Partitioning.Language)); schema =
schema.AddField(new NumberField(2, "field2", Partitioning.Invariant)); new Schema("my-schema")
schema.AddField(new NumberField(3, "field3", Partitioning.Invariant)); .AddField(new NumberField(1, "field1", Partitioning.Language))
.AddField(new NumberField(2, "field2", Partitioning.Invariant))
schema.AddField(new AssetsField(5, "assets1", Partitioning.Invariant)); .AddField(new NumberField(3, "field3", Partitioning.Invariant))
schema.AddField(new AssetsField(6, "assets2", Partitioning.Invariant)); .AddField(new AssetsField(5, "assets1", Partitioning.Invariant))
.AddField(new AssetsField(6, "assets2", Partitioning.Invariant))
schema.AddField(new JsonField(4, "json", Partitioning.Language)); .AddField(new JsonField(4, "json", Partitioning.Language))
.HideField(3);
schema.FieldsById[3].Hide();
} }
[Fact] [Fact]

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

@ -28,19 +28,16 @@ namespace Squidex.Domain.Apps.Core.Operations.EnrichContent
public ContentEnrichmentTests() public ContentEnrichmentTests()
{ {
schema = new Schema("my-schema"); schema =
new Schema("my-schema")
schema.AddField(new StringField(1, "my-string", Partitioning.Language, .AddField(new StringField(1, "my-string", Partitioning.Language,
new StringFieldProperties { DefaultValue = "en-string" })); new StringFieldProperties { DefaultValue = "en-string" }))
.AddField(new NumberField(2, "my-number", Partitioning.Invariant,
schema.AddField(new NumberField(2, "my-number", Partitioning.Invariant, new NumberFieldProperties()))
new NumberFieldProperties())); .AddField(new DateTimeField(3, "my-datetime", Partitioning.Invariant,
new DateTimeFieldProperties { DefaultValue = Now }))
schema.AddField(new DateTimeField(3, "my-datetime", Partitioning.Invariant, .AddField(new BooleanField(4, "my-boolean", Partitioning.Invariant,
new DateTimeFieldProperties { DefaultValue = Now })); new BooleanFieldProperties { DefaultValue = true }));
schema.AddField(new BooleanField(4, "my-boolean", Partitioning.Invariant,
new BooleanFieldProperties { DefaultValue = true }));
} }
[Fact] [Fact]

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

@ -24,21 +24,20 @@ namespace Squidex.Domain.Apps.Core.Operations.ExtractReferenceIds
public class ReferenceExtractionTests public class ReferenceExtractionTests
{ {
private readonly Guid schemaId = Guid.NewGuid(); private readonly Guid schemaId = Guid.NewGuid();
private readonly Schema schema = new Schema("my-schema"); private readonly Schema schema;
private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE); private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.EN, Language.DE);
public ReferenceExtractionTests() public ReferenceExtractionTests()
{ {
schema.AddField(new NumberField(1, "field1", Partitioning.Language)); schema =
schema.AddField(new NumberField(2, "field2", Partitioning.Invariant)); new Schema("my-schema")
schema.AddField(new NumberField(3, "field3", Partitioning.Invariant)); .AddField(new NumberField(1, "field1", Partitioning.Language))
.AddField(new NumberField(2, "field2", Partitioning.Invariant))
schema.AddField(new AssetsField(5, "assets1", Partitioning.Invariant)); .AddField(new NumberField(3, "field3", Partitioning.Invariant))
schema.AddField(new AssetsField(6, "assets2", Partitioning.Invariant)); .AddField(new AssetsField(5, "assets1", Partitioning.Invariant))
.AddField(new AssetsField(6, "assets2", Partitioning.Invariant))
schema.AddField(new JsonField(4, "json", Partitioning.Language)); .AddField(new JsonField(4, "json", Partitioning.Language))
.HideField(3);
schema.FieldsById[3].Hide();
} }
[Fact] [Fact]

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

@ -23,7 +23,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.DE, Language.EN); private readonly LanguagesConfig languagesConfig = LanguagesConfig.Build(Language.DE, Language.EN);
private readonly List<ValidationError> errors = new List<ValidationError>(); private readonly List<ValidationError> errors = new List<ValidationError>();
private readonly ValidationContext context = ValidationTestExtensions.ValidContext; private readonly ValidationContext context = ValidationTestExtensions.ValidContext;
private readonly Schema schema = new Schema("my-schema"); private Schema schema = new Schema("my-schema");
[Fact] [Fact]
public async Task Should_add_error_if_validating_data_with_unknown_field() public async Task Should_add_error_if_validating_data_with_unknown_field()
@ -45,7 +45,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_validating_data_with_invalid_field() public async Task Should_add_error_if_validating_data_with_invalid_field()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant, schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant,
new NumberFieldProperties { MaxValue = 100 })); new NumberFieldProperties { MaxValue = 100 }));
var data = var data =
@ -66,7 +66,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_non_localizable_data_field_contains_language() public async Task Should_add_error_if_non_localizable_data_field_contains_language()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant)); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant));
var data = var data =
new NamedContentData() new NamedContentData()
@ -88,7 +88,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_validating_data_with_invalid_localizable_field() public async Task Should_add_error_if_validating_data_with_invalid_localizable_field()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Language, schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Language,
new NumberFieldProperties { IsRequired = true })); new NumberFieldProperties { IsRequired = true }));
var data = var data =
@ -107,7 +107,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_required_data_field_is_not_in_bag() public async Task Should_add_error_if_required_data_field_is_not_in_bag()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant, schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant,
new NumberFieldProperties { IsRequired = true })); new NumberFieldProperties { IsRequired = true }));
var data = var data =
@ -125,7 +125,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_data_contains_invalid_language() public async Task Should_add_error_if_data_contains_invalid_language()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Language)); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Language));
var data = var data =
new NamedContentData() new NamedContentData()
@ -151,7 +151,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
new LanguageConfig(Language.ES, false), new LanguageConfig(Language.ES, false),
new LanguageConfig(Language.IT, true)); new LanguageConfig(Language.IT, true));
schema.AddField(new StringField(1, "my-field", Partitioning.Language, schema = schema.AddField(new StringField(1, "my-field", Partitioning.Language,
new StringFieldProperties { IsRequired = true })); new StringFieldProperties { IsRequired = true }));
var data = var data =
@ -168,7 +168,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_data_contains_unsupported_language() public async Task Should_add_error_if_data_contains_unsupported_language()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Language)); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Language));
var data = var data =
new NamedContentData() new NamedContentData()
@ -207,7 +207,8 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_validating_partial_data_with_invalid_field() public async Task Should_add_error_if_validating_partial_data_with_invalid_field()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant, new NumberFieldProperties { MaxValue = 100 })); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant,
new NumberFieldProperties { MaxValue = 100 }));
var data = var data =
new NamedContentData() new NamedContentData()
@ -227,7 +228,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_non_localizable_partial_data_field_contains_language() public async Task Should_add_error_if_non_localizable_partial_data_field_contains_language()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant)); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant));
var data = var data =
new NamedContentData() new NamedContentData()
@ -249,7 +250,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_not_add_error_if_validating_partial_data_with_invalid_localizable_field() public async Task Should_not_add_error_if_validating_partial_data_with_invalid_localizable_field()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Language, schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Language,
new NumberFieldProperties { IsRequired = true })); new NumberFieldProperties { IsRequired = true }));
var data = var data =
@ -263,7 +264,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_not_add_error_if_required_partial_data_field_is_not_in_bag() public async Task Should_not_add_error_if_required_partial_data_field_is_not_in_bag()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant, schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Invariant,
new NumberFieldProperties { IsRequired = true })); new NumberFieldProperties { IsRequired = true }));
var data = var data =
@ -277,7 +278,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_partial_data_contains_invalid_language() public async Task Should_add_error_if_partial_data_contains_invalid_language()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Language)); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Language));
var data = var data =
new NamedContentData() new NamedContentData()
@ -298,7 +299,7 @@ namespace Squidex.Domain.Apps.Core.Operations.ValidateContent
[Fact] [Fact]
public async Task Should_add_error_if_partial_data_contains_unsupported_language() public async Task Should_add_error_if_partial_data_contains_unsupported_language()
{ {
schema.AddField(new NumberField(1, "my-field", Partitioning.Language)); schema = schema.AddField(new NumberField(1, "my-field", Partitioning.Language));
var data = var data =
new NamedContentData() new NamedContentData()

45
tests/Squidex.Domain.Apps.Core.Tests/TestData.cs

@ -6,7 +6,10 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
using Squidex.Domain.Apps.Core.Apps.Json; using Squidex.Domain.Apps.Core.Apps.Json;
@ -15,6 +18,7 @@ using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Core.Schemas.Json; using Squidex.Domain.Apps.Core.Schemas.Json;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json; using Squidex.Infrastructure.Json;
using Xunit;
namespace Squidex.Domain.Apps.Core namespace Squidex.Domain.Apps.Core
{ {
@ -96,5 +100,46 @@ namespace Squidex.Domain.Apps.Core
return schema; return schema;
} }
public static void TestFreeze(Freezable freezable)
{
var sut = new AssetsFieldProperties();
foreach (var property in sut.GetType().GetRuntimeProperties().Where(x => x.Name != "IsFrozen"))
{
var value =
property.PropertyType.GetTypeInfo().IsValueType ?
Activator.CreateInstance(property.PropertyType) :
null;
property.SetValue(sut, value);
var result = property.GetValue(sut);
Assert.Equal(value, result);
}
sut.Freeze();
foreach (var property in sut.GetType().GetRuntimeProperties().Where(x => x.Name != "IsFrozen"))
{
var value =
property.PropertyType.GetTypeInfo().IsValueType ?
Activator.CreateInstance(property.PropertyType) :
null;
Assert.Throws<InvalidOperationException>(() =>
{
try
{
property.SetValue(sut, value);
}
catch (Exception ex)
{
throw ex.InnerException;
}
});
}
}
} }
} }

Loading…
Cancel
Save