diff --git a/src/Squidex.Domain.Apps.Entities/Apps/Guards/GuardApp.cs b/src/Squidex.Domain.Apps.Entities/Apps/Guards/GuardApp.cs index f5b9d7366..bc75dc123 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/Guards/GuardApp.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/Guards/GuardApp.cs @@ -24,7 +24,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards { if (!command.Name.IsSlug()) { - error(new ValidationError("Name must be a valid slug (lowercase characters, numbers and dashes).", nameof(command.Name))); + error(new ValidationError("Name must be a valid slug.", nameof(command.Name))); } else if (await appProvider.GetAppAsync(command.Name) != null) { diff --git a/src/Squidex.Domain.Apps.Entities/Rules/Guards/GuardRule.cs b/src/Squidex.Domain.Apps.Entities/Rules/Guards/GuardRule.cs index 181a502b0..e2fcca363 100644 --- a/src/Squidex.Domain.Apps.Entities/Rules/Guards/GuardRule.cs +++ b/src/Squidex.Domain.Apps.Entities/Rules/Guards/GuardRule.cs @@ -76,26 +76,20 @@ namespace Squidex.Domain.Apps.Entities.Rules.Guards { Guard.NotNull(command, nameof(command)); - Validate.It(() => "Cannot enable rule.", error => + if (rule.IsEnabled) { - if (rule.IsEnabled) - { - error(new ValidationError("Rule is already enabled.")); - } - }); + throw new DomainException("Rule is already enabled."); + } } public static void CanDisable(DisableRule command, Rule rule) { Guard.NotNull(command, nameof(command)); - Validate.It(() => "Cannot disable rule.", error => + if (!rule.IsEnabled) { - if (!rule.IsEnabled) - { - error(new ValidationError("Rule is already disabled.")); - } - }); + throw new DomainException("Rule is already disabled."); + } } public static void CanDelete(DeleteRule command) diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchema.cs b/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchema.cs index 2348c1f45..aaa06014b 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchema.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchema.cs @@ -26,12 +26,11 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { if (!command.Name.IsSlug()) { - error(new ValidationError("Name must be a valid slug.", nameof(command.Name))); + error(new ValidationError("Name is not a valid slug.", nameof(command.Name))); } - - if (await appProvider.GetSchemaAsync(command.AppId.Id, command.Name) != null) + else if (await appProvider.GetSchemaAsync(command.AppId.Id, command.Name) != null) { - error(new ValidationError($"A schema with name '{command.Name}' already exists", nameof(command.Name))); + error(new ValidationError("A schema with the same name already exists.")); } if (command.Fields?.Count > 0) @@ -42,21 +41,24 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { index++; - var prefix = $"Fields.{index}"; + var prefix = $"Fields[{index}]"; if (!field.Partitioning.IsValidPartitioning()) { - error(new ValidationError("Partitioning is not valid.", $"{prefix}.{nameof(field.Partitioning)}")); + error(new ValidationError("Field partitioning is not valid.", + $"{prefix}.{nameof(field.Partitioning)}")); } if (!field.Name.IsPropertyName()) { - error(new ValidationError("Name must be a valid property name.", $"{prefix}.{nameof(field.Name)}")); + error(new ValidationError("Field name must be a valid javascript property name.", + $"{prefix}.{nameof(field.Name)}")); } if (field.Properties == null) { - error(new ValidationError("Properties is required.", $"{prefix}.{nameof(field.Properties)}")); + error(new ValidationError("Field properties is required.", + $"{prefix}.{nameof(field.Properties)}")); } else { @@ -64,7 +66,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards foreach (var e in errors) { - error(e.WithPrefix(prefix)); + error(e.WithPrefix($"{prefix}.Properties")); } } @@ -72,7 +74,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { if (!(field.Properties is ArrayFieldProperties)) { - error(new ValidationError("Only array fields can have nested fields.", $"{prefix}.{nameof(field.Partitioning)}")); + error(new ValidationError("Only array fields can have nested fields.", + $"{prefix}.{nameof(field.Partitioning)}")); } else { @@ -82,16 +85,18 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { nestedIndex++; - var nestedPrefix = $"Fields.{index}.Nested.{nestedIndex}"; + var nestedPrefix = $"{prefix}.Nested[{nestedIndex}]"; if (!nestedField.Name.IsPropertyName()) { - error(new ValidationError("Name must be a valid property name.", $"{prefix}.{nameof(nestedField.Name)}")); + error(new ValidationError("Nested field name must be a valid javascript property name.", + $"{nestedPrefix}.{nameof(nestedField.Name)}")); } if (nestedField.Properties == null) { - error(new ValidationError("Properties is required.", $"{prefix}.{nameof(nestedField.Properties)}")); + error(new ValidationError("Nested field properties is required.", + $"{nestedPrefix}.{nameof(nestedField.Properties)}")); } else { @@ -99,7 +104,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards foreach (var e in errors) { - error(e.WithPrefix(nestedPrefix)); + error(e.WithPrefix($"{nestedPrefix}.Properties")); } } } @@ -107,14 +112,16 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards if (field.Nested.Select(x => x.Name).Distinct().Count() != field.Nested.Count) { - error(new ValidationError("Fields cannot have duplicate names.", $"{prefix}.Nested")); + error(new ValidationError("Fields cannot have duplicate names.", + $"{prefix}.Nested")); } } } if (command.Fields.Select(x => x.Name).Distinct().Count() != command.Fields.Count) { - error(new ValidationError("Fields cannot have duplicate names.", nameof(command.Fields))); + error(new ValidationError("Fields cannot have duplicate names.", + nameof(command.Fields))); } } }); @@ -162,7 +169,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { if (c.FieldIds != null && (c.FieldIds.Count != fields.Count || c.FieldIds.Any(x => !fields.ContainsKey(x)))) { - error(new ValidationError("Ids must cover all fields.", nameof(c.FieldIds))); + error(new ValidationError("Field ids do not cover all fields.", nameof(c.FieldIds))); } } diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs b/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs index 1ccbbe505..62b348955 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/Guards/GuardSchemaField.cs @@ -22,7 +22,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { if (!command.Name.IsPropertyName()) { - error(new ValidationError("Name must be a valid property name.", nameof(command.Name))); + error(new ValidationError("Name must be a valid javascript property name.", nameof(command.Name))); } if (command.Properties == null) @@ -49,7 +49,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards } if (arrayField.FieldsByName.ContainsKey(command.Name)) { - error(new ValidationError($"There is already a field with name '{command.Name}'", nameof(command.Name))); + error(new ValidationError($"A field with the same name already exists.")); } } else @@ -61,7 +61,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards if (schema.FieldsByName.ContainsKey(command.Name)) { - error(new ValidationError($"There is already a field with name '{command.Name}'", nameof(command.Name))); + error(new ValidationError($"A field with the same name already exists.")); } } }); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs index f153ab49a..588ab8762 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppTests.cs @@ -25,23 +25,26 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards public GuardAppTests() { - A.CallTo(() => apps.GetAppAsync("new-app")) + A.CallTo(() => apps.GetAppAsync(A.Ignored)) .Returns(Task.FromResult(null)); + A.CallTo(() => apps.GetAppAsync("existing")) + .Returns(A.Dummy()); + A.CallTo(() => users.FindByIdOrEmailAsync(A.Ignored)) - .Returns(A.Fake()); + .Returns(A.Dummy()); + + A.CallTo(() => appPlans.GetPlan("notfound")) + .Returns(null); A.CallTo(() => appPlans.GetPlan("free")) - .Returns(A.Fake()); + .Returns(A.Dummy()); } [Fact] public Task CanCreate_should_throw_exception_if_name_already_in_use() { - A.CallTo(() => apps.GetAppAsync("new-app")) - .Returns(A.Fake()); - - var command = new CreateApp { Name = "new-app" }; + var command = new CreateApp { Name = "existing" }; return ValidationAssert.ThrowsAsync(() => GuardApp.CanCreate(command, apps), new ValidationError("An app with the same name already exists.", "Name")); @@ -53,7 +56,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards var command = new CreateApp { Name = "INVALID NAME" }; return ValidationAssert.ThrowsAsync(() => GuardApp.CanCreate(command, apps), - new ValidationError("Name must be a valid slug (lowercase characters, numbers and dashes).", "Name")); + new ValidationError("Name must be a valid slug.", "Name")); } [Fact] @@ -78,10 +81,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards [Fact] public void CanChangePlan_should_throw_exception_if_plan_not_found() { - A.CallTo(() => appPlans.GetPlan("free")) - .Returns(null); - - var command = new ChangePlan { PlanId = "free", Actor = new RefToken("user", "me") }; + var command = new ChangePlan { PlanId = "notfound", Actor = new RefToken("user", "me") }; AppPlan plan = null; diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs index 6a9996072..86189e1d8 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs @@ -119,8 +119,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Guards var rule_1 = rule_0.Enable(); - ValidationAssert.Throws(() => GuardRule.CanEnable(command, rule_1), - new ValidationError("Rule is already enabled.")); ; + Assert.Throws(() => GuardRule.CanEnable(command, rule_1)); } [Fact] @@ -140,8 +139,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.Guards var rule_1 = rule_0.Disable(); - ValidationAssert.Throws(() => GuardRule.CanDisable(command, rule_1), - new ValidationError("Rule is already disabled.")); + Assert.Throws(() => GuardRule.CanDisable(command, rule_1)); } [Fact] diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs index 8d03c3259..d8819e0df 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Infrastructure; using Xunit; @@ -203,7 +204,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new UpdateField { FieldId = 2, Properties = null }; - Assert.Throws(() => GuardSchemaField.CanUpdate(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanUpdate(schema_0, command), + new ValidationError("Properties is required.", "Properties")); } [Fact] @@ -211,7 +213,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new UpdateField { FieldId = 2, Properties = new StringFieldProperties { MinLength = 10, MaxLength = 5 } }; - Assert.Throws(() => GuardSchemaField.CanUpdate(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanUpdate(schema_0, command), + new ValidationError("Max length must be greater than min length.", "Properties.MinLength", "Properties.MaxLength")); } [Fact] @@ -219,7 +222,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new AddField { Name = "field1", Properties = validProperties }; - Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanAdd(schema_0, command), + new ValidationError("A field with the same name already exists.")); } [Fact] @@ -227,7 +231,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new AddField { Name = "field301", Properties = validProperties, ParentFieldId = 3 }; - Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanAdd(schema_0, command), + new ValidationError("A field with the same name already exists.")); } [Fact] @@ -235,31 +240,35 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new AddField { Name = "INVALID_NAME", Properties = validProperties }; - Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanAdd(schema_0, command), + new ValidationError("Name must be a valid javascript property name.", "Name")); } [Fact] public void CanAdd_should_throw_exception_if_properties_not_valid() { - var command = new AddField { Name = "field3", Properties = invalidProperties }; + var command = new AddField { Name = "field4", Properties = invalidProperties }; - Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanAdd(schema_0, command), + new ValidationError("Max length must be greater than min length.", "Properties.MinLength", "Properties.MaxLength")); } [Fact] public void CanAdd_should_throw_exception_if_properties_null() { - var command = new AddField { Name = "field3", Properties = null }; + var command = new AddField { Name = "field4", Properties = null }; - Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanAdd(schema_0, command), + new ValidationError("Properties is required.", "Properties")); } [Fact] public void CanAdd_should_throw_exception_if_partitioning_not_valid() { - var command = new AddField { Name = "field3", Partitioning = "INVALID_PARTITIONING", Properties = validProperties }; + var command = new AddField { Name = "field4", Partitioning = "INVALID_PARTITIONING", Properties = validProperties }; - Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + ValidationAssert.Throws(() => GuardSchemaField.CanAdd(schema_0, command), + new ValidationError("Partitioning is not valid.", "Partitioning")); } [Fact] diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs index 3c8732370..df1c1a245 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs @@ -12,6 +12,7 @@ using FakeItEasy; using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Infrastructure; using Xunit; @@ -32,8 +33,11 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards .AddString(1, "field1", Partitioning.Invariant) .AddString(2, "field2", Partitioning.Invariant); - A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, "new-schema")) + A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, A.Ignored)) .Returns(Task.FromResult(null)); + + A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, "existing")) + .Returns(A.Dummy()); } [Fact] @@ -41,22 +45,44 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new CreateSchema { AppId = appId, Name = "INVALID NAME" }; - return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Name is not a valid slug.", "Name")); } [Fact] public Task CanCreate_should_throw_exception_if_name_already_in_use() { - A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, "new-schema")) - .Returns(Task.FromResult(A.Fake())); + var command = new CreateSchema { AppId = appId, Name = "existing" }; - var command = new CreateSchema { AppId = appId, Name = "new-schema" }; + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("A schema with the same name already exists.")); + } - return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + [Fact] + public Task CanCreate_should_throw_exception_if_field_name_invalid() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "invalid name", + Properties = new StringFieldProperties(), + Partitioning = Partitioning.Invariant.Key + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Field name must be a valid javascript property name.", + "Fields[1].Name")); } [Fact] - public Task CanCreate_should_throw_exception_if_fields_not_valid() + public Task CanCreate_should_throw_exception_if_field_properties_null() { var command = new CreateSchema { @@ -65,51 +91,213 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { new CreateSchemaField { - Name = null, + Name = "field1", Properties = null, - Partitioning = "invalid" - }, + Partitioning = Partitioning.Invariant.Key + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Field properties is required.", + "Fields[1].Properties")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_field_properties_not_valid() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { new CreateSchemaField { - Name = null, - Properties = InvalidProperties(), - Partitioning = "invalid" + Name = "field1", + Properties = new StringFieldProperties { MinLength = 10, MaxLength = 5 }, + Partitioning = Partitioning.Invariant.Key + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Max length must be greater than min length.", + "Fields[1].Properties.MinLength", + "Fields[1].Properties.MaxLength")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_field_partitioning_not_valid() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "field1", + Properties = new StringFieldProperties(), + Partitioning = "INVALID" + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Field partitioning is not valid.", + "Fields[1].Partitioning")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_fields_contains_duplicate_name() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "field1", + Properties = new StringFieldProperties(), + Partitioning = Partitioning.Invariant.Key }, new CreateSchemaField { - Name = null, + Name = "field1", + Properties = new StringFieldProperties(), + Partitioning = Partitioning.Invariant.Key + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Fields cannot have duplicate names.", + "Fields")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_nested_field_name_invalid() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "array", Properties = new ArrayFieldProperties(), - Partitioning = "invalid", + Partitioning = Partitioning.Invariant.Key, Nested = new List { new CreateSchemaNestedField { - Name = null, - Properties = InvalidProperties() - }, + Name = "invalid name", + Properties = new StringFieldProperties() + } + } + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Nested field name must be a valid javascript property name.", + "Fields[1].Nested[1].Name")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_nested_field_properties_null() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "array", + Properties = new ArrayFieldProperties(), + Partitioning = Partitioning.Invariant.Key, + Nested = new List + { new CreateSchemaNestedField { - Name = null, - Properties = InvalidProperties() + Name = "nested1", + Properties = null } } - }, + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Nested field properties is required.", + "Fields[1].Nested[1].Properties")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_nested_field_properties_not_valid() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { new CreateSchemaField { - Name = null, - Properties = InvalidProperties(), - Partitioning = "invalid", + Name = "array", + Properties = new ArrayFieldProperties(), + Partitioning = Partitioning.Invariant.Key, Nested = new List { new CreateSchemaNestedField { - Name = null, - Properties = InvalidProperties() + Name = "nested1", + Properties = new StringFieldProperties { MinLength = 10, MaxLength = 5 } + } + } + } + }, + Name = "new-schema" + }; + + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Max length must be greater than min length.", + "Fields[1].Nested[1].Properties.MinLength", + "Fields[1].Nested[1].Properties.MaxLength")); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_nested_field_have_duplicate_names() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "array", + Properties = new ArrayFieldProperties(), + Partitioning = Partitioning.Invariant.Key, + Nested = new List + { + new CreateSchemaNestedField + { + Name = "nested1", + Properties = new StringFieldProperties() }, new CreateSchemaNestedField { - Name = null, - Properties = InvalidProperties() + Name = "nested1", + Properties = new StringFieldProperties() } } } @@ -117,9 +305,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards Name = "new-schema" }; - return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider), + new ValidationError("Fields cannot have duplicate names.", + "Fields[1].Nested")); } + /* + [Fact] public Task CanCreate_should_throw_exception_if_fields_contain_duplicate_names() { @@ -163,8 +355,9 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards Name = "new-schema" }; - return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); } + */ [Fact] public Task CanCreate_should_not_throw_exception_if_command_is_valid() @@ -253,7 +446,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new ReorderFields { FieldIds = new List { 1, 3 } }; - Assert.Throws(() => GuardSchema.CanReorder(schema_0, command)); + ValidationAssert.Throws(() => GuardSchema.CanReorder(schema_0, command), + new ValidationError("Field ids do not cover all fields.", "FieldIds")); } [Fact] @@ -261,7 +455,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new ReorderFields { FieldIds = new List { 1 } }; - Assert.Throws(() => GuardSchema.CanReorder(schema_0, command)); + ValidationAssert.Throws(() => GuardSchema.CanReorder(schema_0, command), + new ValidationError("Field ids do not cover all fields.", "FieldIds")); } [Fact] @@ -269,7 +464,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards { var command = new ReorderFields { FieldIds = null }; - Assert.Throws(() => GuardSchema.CanReorder(schema_0, command)); + ValidationAssert.Throws(() => GuardSchema.CanReorder(schema_0, command), + new ValidationError("Field ids is required.", "FieldIds")); } [Fact]