diff --git a/src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs b/src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs index 22ea628b2..5a3a7f1d3 100644 --- a/src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs +++ b/src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs @@ -54,7 +54,7 @@ namespace Squidex.Domain.Apps.Entities.Apps a.Create(command); - context.Complete(EntityCreatedResult.Create(a.State.Id, a.Version)); + context.Complete(EntityCreatedResult.Create(command.AppId, a.Version)); }); } @@ -150,7 +150,7 @@ namespace Squidex.Domain.Apps.Entities.Apps } else { - var result = await appPlansBillingManager.ChangePlanAsync(command.Actor.Identifier, a.State.Id, a.State.Name, command.PlanId); + var result = await appPlansBillingManager.ChangePlanAsync(command.Actor.Identifier, command.AppId.Id, a.State.Name, command.PlanId); if (result is PlanChangedResult) { diff --git a/src/Squidex.Domain.Apps.Entities/Assets/AssetCommandMiddleware.cs b/src/Squidex.Domain.Apps.Entities/Assets/AssetCommandMiddleware.cs index 887c7acdb..dcc8a3029 100644 --- a/src/Squidex.Domain.Apps.Entities/Assets/AssetCommandMiddleware.cs +++ b/src/Squidex.Domain.Apps.Entities/Assets/AssetCommandMiddleware.cs @@ -50,10 +50,10 @@ namespace Squidex.Domain.Apps.Entities.Assets await assetStore.UploadTemporaryAsync(context.ContextId.ToString(), command.File.OpenRead()); - context.Complete(EntityCreatedResult.Create(a.State.Id, a.Version)); + context.Complete(EntityCreatedResult.Create(command.AssetId, a.Version)); }); - await assetStore.CopyTemporaryAsync(context.ContextId.ToString(), asset.State.Id.ToString(), asset.State.FileVersion, null); + await assetStore.CopyTemporaryAsync(context.ContextId.ToString(), command.AssetId.ToString(), asset.State.FileVersion, null); } finally { @@ -78,7 +78,7 @@ namespace Squidex.Domain.Apps.Entities.Assets context.Complete(new AssetSavedResult(a.Version, a.State.FileVersion)); }); - await assetStore.CopyTemporaryAsync(context.ContextId.ToString(), asset.State.Id.ToString(), asset.State.FileVersion, null); + await assetStore.CopyTemporaryAsync(context.ContextId.ToString(), command.AssetId.ToString(), asset.State.FileVersion, null); } finally { diff --git a/src/Squidex.Domain.Apps.Entities/Rules/State/RuleState.cs b/src/Squidex.Domain.Apps.Entities/Rules/State/RuleState.cs index f08e8ddae..2e593c7b0 100644 --- a/src/Squidex.Domain.Apps.Entities/Rules/State/RuleState.cs +++ b/src/Squidex.Domain.Apps.Entities/Rules/State/RuleState.cs @@ -50,6 +50,11 @@ namespace Squidex.Domain.Apps.Entities.Rules.State RuleDef = RuleDef.Disable(); } + protected void On(RuleDeleted @event) + { + IsDeleted = true; + } + public RuleState Apply(Envelope @event) { var payload = (SquidexEvent)@event.Payload; diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/SchemaCommandMiddleware.cs b/src/Squidex.Domain.Apps.Entities/Schemas/SchemaCommandMiddleware.cs index 87f0c4d4b..cb5e13e38 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/SchemaCommandMiddleware.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/SchemaCommandMiddleware.cs @@ -16,7 +16,7 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Dispatching; -namespace Squidex.Domain.Apps.Entities.State.SchemaDefs +namespace Squidex.Domain.Apps.Entities.Schemas { public class SchemaCommandMiddleware : ICommandMiddleware { @@ -41,7 +41,7 @@ namespace Squidex.Domain.Apps.Entities.State.SchemaDefs s.Create(command); - context.Complete(EntityCreatedResult.Create(s.State.Id, s.Version)); + context.Complete(EntityCreatedResult.Create(command.SchemaId, s.Version)); }); } diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs b/src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs index c3ec2642b..73becbd1b 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/SchemaDomainObject.cs @@ -34,7 +34,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas { VerifyNotCreated(); - var @event = SimpleMapper.Map(command, new SchemaCreated { SchemaId = new NamedId(State.Id, command.Name) }); + var @event = SimpleMapper.Map(command, new SchemaCreated { SchemaId = new NamedId(command.SchemaId, command.Name) }); if (command.Fields != null) { @@ -209,7 +209,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas protected override void OnRaised(Envelope @event) { - UpdateState(State.Apply(@event)); + UpdateState(State.Apply(@event, registry)); } } } \ No newline at end of file diff --git a/src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs b/src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs index 585e890e4..527c584ac 100644 --- a/src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs +++ b/src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs @@ -31,7 +31,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State public Guid AppId { get; set; } [JsonProperty] - public int TotalFields { get; set; } = 1; + public int TotalFields { get; set; } = 0; [JsonProperty] public bool IsDeleted { get; set; } @@ -62,6 +62,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State protected void On(SchemaCreated @event, FieldRegistry registry) { + Name = @event.Name; + var schema = new Schema(@event.Name); if (@event.Properties != null) @@ -73,6 +75,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State { foreach (var eventField in @event.Fields) { + TotalFields++; + var partitioning = string.Equals(eventField.Partitioning, Partitioning.Language.Key, StringComparison.OrdinalIgnoreCase) ? Partitioning.Language : @@ -96,8 +100,6 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State } schema = schema.AddField(field); - - TotalFields++; } } @@ -184,11 +186,11 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State SimpleMapper.Map(@event, this); } - public SchemaState Apply(Envelope @event) + public SchemaState Apply(Envelope @event, FieldRegistry registry) { var payload = (SquidexEvent)@event.Payload; - return Clone().Update(payload, @event.Headers, r => r.DispatchAction(payload)); + return Clone().Update(payload, @event.Headers, r => r.DispatchAction(payload, registry)); } } } diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppCommandMiddlewareTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppCommandMiddlewareTests.cs index 14a93859f..bb778526d 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppCommandMiddlewareTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppCommandMiddlewareTests.cs @@ -32,6 +32,11 @@ namespace Squidex.Domain.Apps.Entities.Apps private readonly string clientName = "client"; private readonly AppCommandMiddleware sut; + protected override Guid Id + { + get { return AppId; } + } + public AppCommandMiddlewareTests() { A.CallTo(() => appProvider.GetAppAsync(AppName)) diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs index 4dc8b389d..bea62e007 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs @@ -26,6 +26,11 @@ namespace Squidex.Domain.Apps.Entities.Apps private readonly string planId = "premium"; private readonly AppDomainObject sut = new AppDomainObject(); + protected override Guid Id + { + get { return AppId; } + } + [Fact] public void Create_should_throw_exception_if_created() { diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetCommandMiddlewareTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetCommandMiddlewareTests.cs index fbd1bbd7a..04c41ff74 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetCommandMiddlewareTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetCommandMiddlewareTests.cs @@ -30,6 +30,11 @@ namespace Squidex.Domain.Apps.Entities.Assets private readonly AssetFile file; private readonly AssetCommandMiddleware sut; + protected override Guid Id + { + get { return assetId; } + } + public AssetCommandMiddlewareTests() { file = new AssetFile("my-image.png", "image/png", 1024, () => stream); @@ -124,14 +129,18 @@ namespace Squidex.Domain.Apps.Entities.Assets private void AssertAssetImageChecked() { - A.CallTo(() => assetThumbnailGenerator.GetImageInfoAsync(stream)).MustHaveHappened(); + A.CallTo(() => assetThumbnailGenerator.GetImageInfoAsync(stream)) + .MustHaveHappened(); } private void AssertAssetHasBeenUploaded(long version, Guid commitId) { - A.CallTo(() => assetStore.UploadTemporaryAsync(commitId.ToString(), stream)).MustHaveHappened(); - A.CallTo(() => assetStore.CopyTemporaryAsync(commitId.ToString(), assetId.ToString(), version, null)).MustHaveHappened(); - A.CallTo(() => assetStore.DeleteTemporaryAsync(commitId.ToString())).MustHaveHappened(); + A.CallTo(() => assetStore.UploadTemporaryAsync(commitId.ToString(), stream)) + .MustHaveHappened(); + A.CallTo(() => assetStore.CopyTemporaryAsync(commitId.ToString(), assetId.ToString(), version, null)) + .MustHaveHappened(); + A.CallTo(() => assetStore.DeleteTemporaryAsync(commitId.ToString())) + .MustHaveHappened(); } } } diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetDomainObjectTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetDomainObjectTests.cs index 081ffecd4..ff14541a9 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetDomainObjectTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetDomainObjectTests.cs @@ -24,6 +24,11 @@ namespace Squidex.Domain.Apps.Entities.Assets private readonly AssetFile file = new AssetFile("my-image.png", "image/png", 1024, () => new MemoryStream()); private readonly AssetDomainObject sut = new AssetDomainObject(); + protected override Guid Id + { + get { return assetId; } + } + [Fact] public void Create_should_throw_exception_if_created() { diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentCommandMiddlewareTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentCommandMiddlewareTests.cs index b94d97994..96ade7d26 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentCommandMiddlewareTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentCommandMiddlewareTests.cs @@ -39,6 +39,11 @@ namespace Squidex.Domain.Apps.Entities.Contents private readonly ContentDomainObject content = new ContentDomainObject(); private readonly ContentCommandMiddleware sut; + protected override Guid Id + { + get { return contentId; } + } + private readonly NamedContentData invalidData = new NamedContentData() .AddField("my-field1", new ContentFieldData() @@ -238,7 +243,7 @@ namespace Squidex.Domain.Apps.Entities.Contents private void CreateContent() { - content.Create(new CreateContent { Data = data }); + content.Create(CreateCommand(new CreateContent { Data = data })); } } } diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentDomainObjectTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentDomainObjectTests.cs index 400964524..a92c0570f 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentDomainObjectTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentDomainObjectTests.cs @@ -32,10 +32,15 @@ namespace Squidex.Domain.Apps.Entities.Contents private readonly Guid contentId = Guid.NewGuid(); private readonly ContentDomainObject sut = new ContentDomainObject(); + protected override Guid Id + { + get { return contentId; } + } + [Fact] public void Create_should_throw_exception_if_created() { - sut.Create(new CreateContent { Data = data }); + sut.Create(CreateCommand(new CreateContent { Data = data })); Assert.Throws(() => { diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQLTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQLTests.cs index 3ace057fe..abad6c454 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQLTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQLTests.cs @@ -391,7 +391,7 @@ namespace Squidex.Domain.Apps.Entities.Contents }} }}"; - A.CallTo(() => contentQuery.FindContentAsync(app, schema.Id.ToString(), user, contentId, -1)) + A.CallTo(() => contentQuery.FindContentAsync(app, schema.Id.ToString(), user, contentId, EtagVersion.Any)) .Returns((schema, content)); var result = await sut.QueryAsync(app, user, new GraphQLQuery { Query = query }); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleCommandMiddlewareTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleCommandMiddlewareTests.cs index f721df368..61ab2de50 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleCommandMiddlewareTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleCommandMiddlewareTests.cs @@ -29,6 +29,11 @@ namespace Squidex.Domain.Apps.Entities.Rules private readonly Guid ruleId = Guid.NewGuid(); private readonly RuleCommandMiddleware sut; + protected override Guid Id + { + get { return ruleId; } + } + public RuleCommandMiddlewareTests() { A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, A.Ignored, false)) @@ -103,12 +108,12 @@ namespace Squidex.Domain.Apps.Entities.Rules private void DisableRule() { - rule.Disable(new DisableRule()); + rule.Disable(CreateCommand(new DisableRule())); } private void CreateRule() { - rule.Create(new CreateRule { Trigger = ruleTrigger, Action = ruleAction }); + rule.Create(CreateCommand(new CreateRule { Trigger = ruleTrigger, Action = ruleAction })); } } } \ No newline at end of file diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDomainObjectTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDomainObjectTests.cs index 4f4376e56..0b11c525d 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDomainObjectTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDomainObjectTests.cs @@ -26,10 +26,15 @@ namespace Squidex.Domain.Apps.Entities.Rules private readonly RuleAction ruleAction = new WebhookAction { Url = new Uri("https://squidex.io") }; private readonly RuleDomainObject sut = new RuleDomainObject(); + protected override Guid Id + { + get { return ruleId; } + } + [Fact] public void Create_should_throw_exception_if_created() { - sut.Create(new CreateRule { Trigger = ruleTrigger, Action = ruleAction }); + sut.Create(CreateRuleCommand(new CreateRule { Trigger = ruleTrigger, Action = ruleAction })); Assert.Throws(() => { @@ -44,6 +49,8 @@ namespace Squidex.Domain.Apps.Entities.Rules sut.Create(CreateRuleCommand(command)); + Assert.Equal(AppId, sut.State.AppId); + Assert.Same(ruleTrigger, sut.State.RuleDef.Trigger); Assert.Same(ruleAction, sut.State.RuleDef.Action); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/AssetsFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/AssetsFieldPropertiesTests.cs new file mode 100644 index 000000000..9f4f4c7b8 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/AssetsFieldPropertiesTests.cs @@ -0,0 +1,104 @@ +// ========================================================================== +// AssetsFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class AssetsFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_min_items_greater_than_max_items() + { + var sut = new AssetsFieldProperties { MinItems = 10, MaxItems = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max items must be greater than min items.", "MinItems", "MaxItems") + }); + } + + [Fact] + public void Should_add_error_if_min_width_greater_than_max_width() + { + var sut = new AssetsFieldProperties { MinWidth = 10, MaxWidth = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max width must be greater than min width.", "MinWidth", "MaxWidth") + }); + } + + [Fact] + public void Should_add_error_if_min_height_greater_than_max_height() + { + var sut = new AssetsFieldProperties { MinHeight = 10, MaxHeight = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max height must be greater than min height.", "MinHeight", "MaxHeight") + }); + } + + [Fact] + public void Should_add_error_if_min_size_greater_than_max_size() + { + var sut = new AssetsFieldProperties { MinSize = 10, MaxSize = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max size must be greater than min size.", "MinSize", "MaxSize") + }); + } + + [Fact] + public void Should_add_error_if_only_aspect_width_is_defined() + { + var sut = new AssetsFieldProperties { AspectWidth = 10 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Aspect width and height must be defined.", "AspectWidth", "AspectHeight") + }); + } + + [Fact] + public void Should_add_error_if_only_aspect_height_is_defined() + { + var sut = new AssetsFieldProperties { AspectHeight = 10 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Aspect width and height must be defined.", "AspectWidth", "AspectHeight") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/BooleanFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/BooleanFieldPropertiesTests.cs new file mode 100644 index 000000000..0acb80581 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/BooleanFieldPropertiesTests.cs @@ -0,0 +1,34 @@ +// ========================================================================== +// BooleanFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class BooleanFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new BooleanFieldProperties { Editor = (BooleanFieldEditor)123 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Editor is not a valid value.", "Editor") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/DateTimeFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/DateTimeFieldPropertiesTests.cs new file mode 100644 index 000000000..24791ae69 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/DateTimeFieldPropertiesTests.cs @@ -0,0 +1,126 @@ +// ========================================================================== +// DateTimeFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using NodaTime; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class DateTimeFieldPropertiesTests + { + [Fact] + public void Should_not_add_error_if_sut_is_valid() + { + var sut = new DateTimeFieldProperties + { + MinValue = FutureDays(10), + MaxValue = FutureDays(20), + DefaultValue = FutureDays(15) + }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + Assert.Empty(errors); + } + + [Fact] + public void Should_add_error_if_default_value_is_less_than_min() + { + var sut = new DateTimeFieldProperties { MinValue = FutureDays(10), DefaultValue = FutureDays(5) }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Default value must be greater than min value.", "DefaultValue") + }); + } + + [Fact] + public void Should_add_error_if_default_value_is_greater_than_min() + { + var sut = new DateTimeFieldProperties { MaxValue = FutureDays(10), DefaultValue = FutureDays(15) }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Default value must be less than max value.", "DefaultValue") + }); + } + + [Fact] + public void Should_add_error_if_min_greater_than_max() + { + var sut = new DateTimeFieldProperties { MinValue = FutureDays(10), MaxValue = FutureDays(5) }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max value must be greater than min value.", "MinValue", "MaxValue") + }); + } + + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new DateTimeFieldProperties { Editor = (DateTimeFieldEditor)123 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Editor is not a valid value.", "Editor") + }); + } + + [Fact] + public void Should_add_error_if_calculated_default_value_is_not_valid() + { + var sut = new DateTimeFieldProperties { CalculatedDefaultValue = (DateTimeCalculatedDefaultValue)123 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Calculated default value is not valid.", "CalculatedDefaultValue") + }); + } + + [Fact] + public void Should_add_error_if_calculated_default_value_default_value_is_defined() + { + var sut = new DateTimeFieldProperties { CalculatedDefaultValue = DateTimeCalculatedDefaultValue.Now, DefaultValue = FutureDays(10) }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Calculated default value and default value cannot be used together.", "CalculatedDefaultValue", "DefaultValue") + }); + } + + private static Instant FutureDays(int days) + { + return Instant.FromDateTimeUtc(DateTime.UtcNow.Date.AddDays(days)); + } + } +} \ No newline at end of file diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/GeolocationFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/GeolocationFieldPropertiesTests.cs new file mode 100644 index 000000000..ae2e794f5 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/GeolocationFieldPropertiesTests.cs @@ -0,0 +1,34 @@ +// ========================================================================== +// GeolocationPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class GeolocationFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new GeolocationFieldProperties { Editor = (GeolocationFieldEditor)123 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Editor is not a valid value.", "Editor") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/JsonFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/JsonFieldPropertiesTests.cs new file mode 100644 index 000000000..52e4601ed --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/JsonFieldPropertiesTests.cs @@ -0,0 +1,27 @@ +// ========================================================================== +// JsonFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Linq; +using Squidex.Domain.Apps.Core.Schemas; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class JsonFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new JsonFieldProperties(); + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + Assert.Empty(errors); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/NumberFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/NumberFieldPropertiesTests.cs new file mode 100644 index 000000000..add452cb4 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/NumberFieldPropertiesTests.cs @@ -0,0 +1,134 @@ +// ========================================================================== +// NumberFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class NumberFieldPropertiesTests + { + [Fact] + public void Should_not_add_error_if_sut_is_valid() + { + var sut = new NumberFieldProperties + { + MinValue = 0, + MaxValue = 100, + DefaultValue = 5 + }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + Assert.Empty(errors); + } + + [Fact] + public void Should_add_error_if_default_value_is_less_than_min() + { + var sut = new NumberFieldProperties { MinValue = 10, DefaultValue = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Default value must be greater than min value.", "DefaultValue") + }); + } + + [Fact] + public void Should_add_error_if_default_value_is_greater_than_min() + { + var sut = new NumberFieldProperties { MaxValue = 0, DefaultValue = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Default value must be less than max value.", "DefaultValue") + }); + } + + [Fact] + public void Should_add_error_if_min_greater_than_max() + { + var sut = new NumberFieldProperties { MinValue = 10, MaxValue = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max value must be greater than min value.", "MinValue", "MaxValue") + }); + } + + [Fact] + public void Should_add_error_if_allowed_values_and_max_value_is_specified() + { + var sut = new NumberFieldProperties { MaxValue = 10, AllowedValues = ImmutableList.Create(4d) }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Either allowed values or min and max value can be defined.", "AllowedValues", "MinValue", "MaxValue") + }); + } + + [Fact] + public void Should_add_error_if_allowed_values_and_min_value_is_specified() + { + var sut = new NumberFieldProperties { MinValue = 10, AllowedValues = ImmutableList.Create(4d) }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Either allowed values or min and max value can be defined.", "AllowedValues", "MinValue", "MaxValue") + }); + } + + [Fact] + public void Should_add_error_if_radio_button_has_no_allowed_values() + { + var sut = new NumberFieldProperties { Editor = NumberFieldEditor.Radio }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Radio buttons or dropdown list need allowed values.", "AllowedValues") + }); + } + + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new NumberFieldProperties { Editor = (NumberFieldEditor)123 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Editor is not a valid value.", "Editor") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/ReferencesFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/ReferencesFieldPropertiesTests.cs new file mode 100644 index 000000000..8465de44c --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/ReferencesFieldPropertiesTests.cs @@ -0,0 +1,34 @@ +// ========================================================================== +// ReferencesFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class ReferencesFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_min_greater_than_max() + { + var sut = new ReferencesFieldProperties { MinItems = 10, MaxItems = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max items must be greater than min items.", "MinItems", "MaxItems") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/StringFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/StringFieldPropertiesTests.cs new file mode 100644 index 000000000..3d6585883 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/StringFieldPropertiesTests.cs @@ -0,0 +1,105 @@ +// ========================================================================== +// StringFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class StringFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_min_greater_than_max() + { + var sut = new StringFieldProperties { MinLength = 10, MaxLength = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max length must be greater than min length.", "MinLength", "MaxLength") + }); + } + + [Fact] + public void Should_add_error_if_allowed_values_and_max_value_is_specified() + { + var sut = new StringFieldProperties { MinLength = 10, AllowedValues = ImmutableList.Create("4") }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Either allowed values or min and max length can be defined.", "AllowedValues", "MinLength", "MaxLength") + }); + } + + [Fact] + public void Should_add_error_if_allowed_values_and_min_value_is_specified() + { + var sut = new StringFieldProperties { MaxLength = 10, AllowedValues = ImmutableList.Create("4") }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Either allowed values or min and max length can be defined.", "AllowedValues", "MinLength", "MaxLength") + }); + } + + [Fact] + public void Should_add_error_if_radio_button_has_no_allowed_values() + { + var sut = new StringFieldProperties { Editor = StringFieldEditor.Radio }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Radio buttons or dropdown list need allowed values.", "AllowedValues") + }); + } + + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new StringFieldProperties { Editor = (StringFieldEditor)123 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Editor is not a valid value.", "Editor") + }); + } + + [Fact] + public void Should_add_error_if_pattern_is_not_valid_regex() + { + var sut = new StringFieldProperties { Pattern = "[0-9{1}" }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Pattern is not a valid expression.", "Pattern") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/TagsFieldPropertiesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/TagsFieldPropertiesTests.cs new file mode 100644 index 000000000..6e413d0c9 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/FieldProperties/TagsFieldPropertiesTests.cs @@ -0,0 +1,34 @@ +// ========================================================================== +// TagsFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards.FieldProperties +{ + public class TagsFieldPropertiesTests + { + [Fact] + public void Should_add_error_if_min_greater_than_max() + { + var sut = new TagsFieldProperties { MinItems = 10, MaxItems = 5 }; + + var errors = FieldPropertiesValidator.Validate(sut).ToList(); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Max items must be greater than min items.", "MinItems", "MaxItems") + }); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs new file mode 100644 index 000000000..9770155e8 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaFieldTests.cs @@ -0,0 +1,247 @@ +// ========================================================================== +// GuardSchemaFieldTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Squidex.Domain.Apps.Core; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Infrastructure; +using Xunit; + +#pragma warning disable SA1310 // Field names must not contain underscore + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards +{ + public class GuardSchemaFieldTests + { + private readonly Schema schema_0; + private readonly StringFieldProperties validProperties = new StringFieldProperties(); + private readonly StringFieldProperties invalidProperties = new StringFieldProperties { MinLength = 10, MaxLength = 5 }; + + public GuardSchemaFieldTests() + { + schema_0 = + new Schema("my-schema") + .AddField(new StringField(1, "field1", Partitioning.Invariant)) + .AddField(new StringField(2, "field2", Partitioning.Invariant)); + } + + [Fact] + public void CanHide_should_throw_exception_if_already_hidden() + { + var command = new HideField { FieldId = 1 }; + + var schema_1 = schema_0.HideField(1); + + Assert.Throws(() => GuardSchemaField.CanHide(schema_1, command)); + } + + [Fact] + public void CanHide_should_throw_exception_if_not_found() + { + var command = new HideField { FieldId = 3 }; + + Assert.Throws(() => GuardSchemaField.CanHide(schema_0, command)); + } + + [Fact] + public void CanHide_hould_not_throw_exception_if_visible() + { + var command = new HideField { FieldId = 1 }; + + GuardSchemaField.CanHide(schema_0, command); + } + + [Fact] + public void CanDisable_should_throw_exception_if_already_disabled() + { + var command = new DisableField { FieldId = 1 }; + + var schema_1 = schema_0.DisableField(1); + + Assert.Throws(() => GuardSchemaField.CanDisable(schema_1, command)); + } + + [Fact] + public void CanDisable_should_throw_exception_if_not_found() + { + var command = new DisableField { FieldId = 3 }; + + Assert.Throws(() => GuardSchemaField.CanDisable(schema_0, command)); + } + + [Fact] + public void CanDisable_Should_not_throw_exception_if_enabled() + { + var command = new DisableField { FieldId = 1 }; + + GuardSchemaField.CanDisable(schema_0, command); + } + + [Fact] + public void CanShow_should_throw_exception_if_already_shown() + { + var command = new ShowField { FieldId = 1 }; + + Assert.Throws(() => GuardSchemaField.CanShow(schema_0, command)); + } + + [Fact] + public void CanShow_should_throw_exception_if_not_found() + { + var command = new ShowField { FieldId = 3 }; + + Assert.Throws(() => GuardSchemaField.CanShow(schema_0, command)); + } + + [Fact] + public void CanShow_should_not_throw_exception_if_hidden() + { + var command = new ShowField { FieldId = 1 }; + + var schema_1 = schema_0.HideField(1); + + GuardSchemaField.CanShow(schema_1, command); + } + + [Fact] + public void CanEnable_should_throw_exception_if_already_enabled() + { + var command = new EnableField { FieldId = 1 }; + + Assert.Throws(() => GuardSchemaField.CanEnable(schema_0, command)); + } + + [Fact] + public void CanEnable_should_throw_exception_if_not_found() + { + var command = new EnableField { FieldId = 3 }; + + Assert.Throws(() => GuardSchemaField.CanEnable(schema_0, command)); + } + + [Fact] + public void CanEnable_should_not_throw_exception_if_disabled() + { + var command = new EnableField { FieldId = 1 }; + + var schema_1 = schema_0.DisableField(1); + + GuardSchemaField.CanEnable(schema_1, command); + } + + [Fact] + public void CanLock_should_throw_exception_if_already_locked() + { + var command = new LockField { FieldId = 1 }; + + var schema_1 = schema_0.LockField(1); + + Assert.Throws(() => GuardSchemaField.CanLock(schema_1, command)); + } + + [Fact] + public void LockField_should_throw_exception_if_not_found() + { + var command = new LockField { FieldId = 3 }; + + Assert.Throws(() => GuardSchemaField.CanLock(schema_0, command)); + } + + [Fact] + public void CanLock_should_not_throw_exception_if_not_locked() + { + var command = new LockField { FieldId = 1 }; + + GuardSchemaField.CanLock(schema_0, command); + } + + [Fact] + public void CanDelete_should_throw_exception_if_not_found() + { + var command = new DeleteField { FieldId = 3 }; + + Assert.Throws(() => GuardSchemaField.CanDelete(schema_0, command)); + } + + [Fact] + public void CanDelete_should_throw_exception_if_locked() + { + var command = new DeleteField { FieldId = 1 }; + + var schema_1 = schema_0.LockField(1); + + Assert.Throws(() => GuardSchemaField.CanDelete(schema_1, command)); + } + + [Fact] + public void CanDelete_should_not_throw_exception_if_not_locked() + { + var command = new DeleteField { FieldId = 1 }; + + GuardSchemaField.CanDelete(schema_0, command); + } + + [Fact] + public void CanUpdate_should_throw_exception_if_locked() + { + var command = new UpdateField { FieldId = 1, Properties = new StringFieldProperties() }; + + var schema_1 = schema_0.LockField(1); + + Assert.Throws(() => GuardSchemaField.CanUpdate(schema_1, command)); + } + + [Fact] + public void CanUpdate_should_not_throw_exception_if_not_locked() + { + var command = new UpdateField { FieldId = 1, Properties = new StringFieldProperties() }; + + GuardSchemaField.CanUpdate(schema_0, command); + } + + [Fact] + public void CanAdd_should_throw_exception_if_field_already_exists() + { + var command = new AddField { Name = "field1", Properties = new StringFieldProperties() }; + + Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + } + + [Fact] + public void CanAdd_should_throw_exception_if_name_not_valid() + { + var command = new AddField { Name = "INVALID_NAME", Properties = validProperties }; + + Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + } + + [Fact] + public void CanAdd_should_throw_exception_if_properties_not_valid() + { + var command = new AddField { Name = "field3", Properties = invalidProperties }; + + Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + } + + [Fact] + public void CanAdd_should_throw_exception_if_partitioning_not_valid() + { + var command = new AddField { Name = "field3", Partitioning = "INVALID_PARTITIONING", Properties = validProperties }; + + Assert.Throws(() => GuardSchemaField.CanAdd(schema_0, command)); + } + + [Fact] + public void CanAdd_should_not_throw_exception_if_field_not_exists() + { + var command = new AddField { Name = "field3", Properties = new StringFieldProperties() }; + + GuardSchemaField.CanAdd(schema_0, command); + } + } +} \ No newline at end of file diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs new file mode 100644 index 000000000..326149595 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs @@ -0,0 +1,201 @@ +// ========================================================================== +// GuardSchemaTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using FakeItEasy; +using Squidex.Domain.Apps.Core; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Domain.Apps.Entities; +using Squidex.Domain.Apps.Entities.Schemas; +using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Infrastructure; +using Xunit; + +#pragma warning disable SA1310 // Field names must not contain underscore + +namespace Squidex.Domain.Apps.Entities.Schemas.Guards +{ + public class GuardSchemaTests + { + private readonly IAppProvider appProvider = A.Fake(); + private readonly Schema schema_0; + private readonly NamedId appId = new NamedId(Guid.NewGuid(), "my-app"); + + public GuardSchemaTests() + { + schema_0 = + new Schema("my-schema") + .AddField(new StringField(1, "field1", Partitioning.Invariant)) + .AddField(new StringField(2, "field2", Partitioning.Invariant)); + + A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, "new-schema", false)) + .Returns(Task.FromResult(null)); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_name_not_valid() + { + var command = new CreateSchema { AppId = appId, Name = "INVALID NAME" }; + + return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_name_already_in_use() + { + A.CallTo(() => appProvider.GetSchemaAsync(A.Ignored, "new-schema", false)) + .Returns(Task.FromResult(A.Fake())); + + var command = new CreateSchema { AppId = appId, Name = "new-schema" }; + + return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_fields_not_valid() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = null, + Properties = null, + Partitioning = "invalid" + }, + new CreateSchemaField + { + Name = null, + Properties = InvalidProperties(), + Partitioning = "invalid" + } + }, + Name = "new-schema" + }; + + return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + } + + [Fact] + public Task CanCreate_should_throw_exception_if_fields_contain_duplicate_names() + { + var command = new CreateSchema + { + AppId = appId, + Fields = new List + { + new CreateSchemaField + { + Name = "field1", + Properties = ValidProperties(), + Partitioning = "invariant" + }, + new CreateSchemaField + { + Name = "field1", + Properties = ValidProperties(), + Partitioning = "invariant" + } + }, + Name = "new-schema" + }; + + return Assert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider)); + } + + [Fact] + public Task CanCreate_should_not_throw_exception_if_command_is_valid() + { + var command = new CreateSchema { AppId = appId, Name = "new-schema" }; + + return GuardSchema.CanCreate(command, appProvider); + } + + [Fact] + public void CanPublish_should_throw_exception_if_already_published() + { + var command = new PublishSchema(); + + var schema_1 = schema_0.Publish(); + + Assert.Throws(() => GuardSchema.CanPublish(schema_1, command)); + } + + [Fact] + public void CanPublish_should_not_throw_exception_if_not_published() + { + var command = new PublishSchema(); + + GuardSchema.CanPublish(schema_0, command); + } + + [Fact] + public void CanUnpublish_should_throw_exception_if_already_unpublished() + { + var command = new UnpublishSchema(); + + Assert.Throws(() => GuardSchema.CanUnpublish(schema_0, command)); + } + + [Fact] + public void CanUnpublish_should_not_throw_exception_if_already_published() + { + var command = new UnpublishSchema(); + + var schema_1 = schema_0.Publish(); + + GuardSchema.CanUnpublish(schema_1, command); + } + + [Fact] + public void CanReorder_should_throw_exception_if_field_ids_contains_invalid_id() + { + var command = new ReorderFields { FieldIds = new List { 1, 3 } }; + + Assert.Throws(() => GuardSchema.CanReorder(schema_0, command)); + } + + [Fact] + public void CanReorder_should_throw_exception_if_field_ids_do_not_covers_all_fields() + { + var command = new ReorderFields { FieldIds = new List { 1 } }; + + Assert.Throws(() => GuardSchema.CanReorder(schema_0, command)); + } + + [Fact] + public void CanReorder_should_not_throw_exception_if_field_ids_are_valid() + { + var command = new ReorderFields { FieldIds = new List { 1, 2 } }; + + GuardSchema.CanReorder(schema_0, command); + } + + [Fact] + public void CanDelete_should_not_throw_exception() + { + var command = new DeleteSchema(); + + GuardSchema.CanDelete(schema_0, command); + } + + private static StringFieldProperties ValidProperties() + { + return new StringFieldProperties { MinLength = 10, MaxLength = 20 }; + } + + private static StringFieldProperties InvalidProperties() + { + return new StringFieldProperties { MinLength = 20, MaxLength = 10 }; + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandMiddlewareTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandMiddlewareTests.cs new file mode 100644 index 000000000..1cd2a9a1d --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaCommandMiddlewareTests.cs @@ -0,0 +1,281 @@ +// ========================================================================== +// SchemaCommandMiddlewareTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using FakeItEasy; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Domain.Apps.Entities.TestHelpers; +using Squidex.Infrastructure; +using Squidex.Infrastructure.Commands; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas +{ + public class SchemaCommandMiddlewareTests : HandlerTestBase + { + private readonly IAppProvider appProvider = A.Fake(); + private readonly SchemaCommandMiddleware sut; + private readonly SchemaDomainObject schema; + private readonly FieldRegistry registry = new FieldRegistry(new TypeNameRegistry()); + private readonly string fieldName = "age"; + + protected override Guid Id + { + get { return SchemaId; } + } + + public SchemaCommandMiddlewareTests() + { + schema = new SchemaDomainObject(registry); + + sut = new SchemaCommandMiddleware(Handler, appProvider); + + A.CallTo(() => appProvider.GetSchemaAsync(AppId, SchemaName, false)) + .Returns((ISchemaEntity)null); + } + + [Fact] + public async Task Create_should_create_schema_domain_object() + { + var context = CreateContextForCommand(new CreateSchema { Name = SchemaName, SchemaId = SchemaId }); + + await TestCreate(schema, async _ => + { + await sut.HandleAsync(context); + }); + + Assert.Equal(SchemaId, context.Result>().IdOrValue); + + A.CallTo(() => appProvider.GetSchemaAsync(AppId, SchemaName, false)).MustHaveHappened(); + } + + [Fact] + public async Task UpdateSchema_should_update_domain_object() + { + CreateSchema(); + + var context = CreateContextForCommand(new UpdateSchema { Properties = new SchemaProperties() }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task ReorderSchema_should_update_domain_object() + { + CreateSchema(); + + var context = CreateContextForCommand(new ReorderFields { FieldIds = new List() }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task PublishSchema_should_update_domain_object() + { + CreateSchema(); + + var context = CreateContextForCommand(new PublishSchema()); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task UnpublishSchema_should_update_domain_object() + { + CreateSchema(); + PublishSchema(); + + var context = CreateContextForCommand(new UnpublishSchema()); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task ConfigureScripts_should_update_domain_object() + { + CreateSchema(); + + var context = CreateContextForCommand(new ConfigureScripts()); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task DeleteSchema_should_update_domain_object() + { + CreateSchema(); + + var context = CreateContextForCommand(new DeleteSchema()); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task Add_should_update_domain_object() + { + CreateSchema(); + + var context = CreateContextForCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + + Assert.Equal(1, context.Result>().IdOrValue); + } + + [Fact] + public async Task UpdateField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + var context = CreateContextForCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task LockField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + var context = CreateContextForCommand(new LockField { FieldId = 1 }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task HideField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + var context = CreateContextForCommand(new HideField { FieldId = 1 }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task ShowField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + HideField(); + + var context = CreateContextForCommand(new ShowField { FieldId = 1 }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task DisableField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + var context = CreateContextForCommand(new DisableField { FieldId = 1 }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task EnableField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + DisableField(); + + var context = CreateContextForCommand(new EnableField { FieldId = 1 }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task DeleteField_should_update_domain_object() + { + CreateSchema(); + CreateField(); + + var context = CreateContextForCommand(new DeleteField { FieldId = 1 }); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + private void CreateSchema() + { + schema.Create(CreateCommand(new CreateSchema { Name = SchemaName })); + } + + private void PublishSchema() + { + schema.Publish(CreateCommand(new PublishSchema())); + } + + private void CreateField() + { + schema.Add(CreateCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + } + + private void HideField() + { + schema.HideField(CreateCommand(new HideField { FieldId = 1 })); + } + + private void DisableField() + { + schema.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + } + } +} \ No newline at end of file diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaDomainObjectTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaDomainObjectTests.cs new file mode 100644 index 000000000..5275eafc5 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/SchemaDomainObjectTests.cs @@ -0,0 +1,663 @@ +// ========================================================================== +// SchemaDomainObjectTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Linq; +using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Domain.Apps.Entities.Schemas.Commands; +using Squidex.Domain.Apps.Entities.TestHelpers; +using Squidex.Domain.Apps.Events.Schemas; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Schemas +{ + public class SchemaDomainObjectTests : HandlerTestBase + { + private readonly string fieldName = "age"; + private readonly NamedId fieldId; + private readonly SchemaDomainObject sut; + + protected override Guid Id + { + get { return SchemaId; } + } + + public SchemaDomainObjectTests() + { + fieldId = new NamedId(1, fieldName); + + var fieldRegistry = new FieldRegistry(new TypeNameRegistry()); + + sut = new SchemaDomainObject(fieldRegistry); + } + + [Fact] + public void Create_should_throw_exception_if_created() + { + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName })); + + Assert.Throws(() => + { + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName })); + }); + } + + [Fact] + public void Create_should_create_schema_and_create_events() + { + var properties = new SchemaProperties(); + + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName, SchemaId = SchemaId, Properties = properties })); + + Assert.Equal(AppId, sut.State.AppId); + + Assert.Equal(SchemaName, sut.State.Name); + Assert.Equal(SchemaName, sut.State.SchemaDef.Name); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaCreated { Name = SchemaName, Properties = properties }) + ); + } + + [Fact] + public void Create_should_create_schema_with_initial_fields() + { + var properties = new SchemaProperties(); + + var fields = new List + { + new CreateSchemaField { Name = "field1", Properties = ValidProperties() }, + new CreateSchemaField { Name = "field2", Properties = ValidProperties() } + }; + + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName, Properties = properties, Fields = fields })); + + var @event = (SchemaCreated)sut.GetUncomittedEvents().Single().Payload; + + Assert.Equal(AppId, sut.State.AppId); + Assert.Equal(SchemaName, sut.State.Name); + Assert.Equal(SchemaName, sut.State.SchemaDef.Name); + + Assert.Equal(2, @event.Fields.Count); + } + + [Fact] + public void Update_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.Update(CreateCommand(new UpdateSchema { Properties = new SchemaProperties() })); + }); + } + + [Fact] + public void Update_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.Update(CreateCommand(new UpdateSchema { Properties = new SchemaProperties() })); + }); + } + + [Fact] + public void Update_should_refresh_properties_and_create_events() + { + var properties = new SchemaProperties(); + + CreateSchema(); + + sut.Update(CreateCommand(new UpdateSchema { Properties = properties })); + + Assert.Equal(properties, sut.State.SchemaDef.Properties); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaUpdated { Properties = properties }) + ); + } + + [Fact] + public void ConfigureScripts_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.ConfigureScripts(CreateCommand(new ConfigureScripts())); + }); + } + + [Fact] + public void ConfigureScripts_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.ConfigureScripts(CreateCommand(new ConfigureScripts())); + }); + } + + [Fact] + public void ConfigureScripts_should_create_events() + { + CreateSchema(); + + sut.ConfigureScripts(CreateCommand(new ConfigureScripts + { + ScriptQuery = "", + ScriptCreate = "", + ScriptUpdate = "", + ScriptDelete = "", + ScriptChange = "" + })); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new ScriptsConfigured + { + ScriptQuery = "", + ScriptCreate = "", + ScriptUpdate = "", + ScriptDelete = "", + ScriptChange = "" + }) + ); + } + + [Fact] + public void Reorder_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.Reorder(CreateCommand(new ReorderFields { FieldIds = new List() })); + }); + } + + [Fact] + public void Reorder_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.Reorder(CreateCommand(new ReorderFields { FieldIds = new List() })); + }); + } + + [Fact] + public void Reorder_should_refresh_properties_and_create_events() + { + var fieldIds = new List { 1, 2 }; + + CreateSchema(); + + sut.Add(CreateCommand(new AddField { Name = "field1", Properties = ValidProperties() })); + sut.Add(CreateCommand(new AddField { Name = "field2", Properties = ValidProperties() })); + + sut.ClearUncommittedEvents(); + + sut.Reorder(CreateCommand(new ReorderFields { FieldIds = fieldIds })); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaFieldsReordered { FieldIds = fieldIds }) + ); + } + + [Fact] + public void Publish_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.Publish(CreateCommand(new PublishSchema())); + }); + } + + [Fact] + public void Publish_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.Publish(CreateCommand(new PublishSchema())); + }); + } + + [Fact] + public void Publish_should_refresh_properties_and_create_events() + { + CreateSchema(); + + sut.Publish(CreateCommand(new PublishSchema())); + + Assert.True(sut.State.SchemaDef.IsPublished); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaPublished()) + ); + } + + [Fact] + public void Unpublish_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.Unpublish(CreateCommand(new UnpublishSchema())); + }); + } + + [Fact] + public void Unpublish_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.Unpublish(CreateCommand(new UnpublishSchema())); + }); + } + + [Fact] + public void Unpublish_should_refresh_properties_and_create_events() + { + CreateSchema(); + PublishSchema(); + + sut.Unpublish(CreateCommand(new UnpublishSchema())); + + Assert.False(sut.State.SchemaDef.IsPublished); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaUnpublished()) + ); + } + + [Fact] + public void Delete_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.Delete(CreateCommand(new DeleteSchema())); + }); + } + + [Fact] + public void Delete_should_throw_exception_if_already_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.Delete(CreateCommand(new DeleteSchema())); + }); + } + + [Fact] + public void Delete_should_refresh_properties_and_create_events() + { + CreateSchema(); + + sut.Delete(CreateCommand(new DeleteSchema())); + + Assert.True(sut.State.IsDeleted); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaDeleted()) + ); + } + + [Fact] + public void AddField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.Add(CreateCommand(new AddField { Name = fieldName, Properties = ValidProperties() })); + }); + } + + [Fact] + public void AddField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.Add(CreateCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + }); + } + + [Fact] + public void Add_should_update_schema_and_create_events() + { + var properties = new NumberFieldProperties(); + + CreateSchema(); + + sut.Add(CreateCommand(new AddField { Name = fieldName, Properties = properties })); + + Assert.Equal(properties, sut.State.SchemaDef.FieldsById[1].RawProperties); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldAdded { Name = fieldName, FieldId = fieldId, Properties = properties }) + ); + } + + [Fact] + public void UpdateField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + }); + } + + [Fact] + public void UpdateField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + }); + } + + [Fact] + public void UpdateField_should_update_schema_and_create_events() + { + var properties = new NumberFieldProperties(); + + CreateSchema(); + CreateField(); + + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = properties })); + + Assert.Equal(properties, sut.State.SchemaDef.FieldsById[1].RawProperties); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldUpdated { FieldId = fieldId, Properties = properties }) + ); + } + + [Fact] + public void LockField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.LockField(CreateCommand(new LockField { FieldId = 1 })); + }); + } + + [Fact] + public void LockField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.LockField(CreateCommand(new LockField { FieldId = 1 })); + }); + } + + [Fact] + public void LockField_should_update_schema_and_create_events() + { + CreateSchema(); + CreateField(); + + sut.LockField(CreateCommand(new LockField { FieldId = 1 })); + + Assert.False(sut.State.SchemaDef.FieldsById[1].IsDisabled); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldLocked { FieldId = fieldId }) + ); + } + + [Fact] + public void HideField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + }); + } + + [Fact] + public void HideField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + }); + } + + [Fact] + public void HideField_should_update_schema_and_create_events() + { + CreateSchema(); + CreateField(); + + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + + Assert.True(sut.State.SchemaDef.FieldsById[1].IsHidden); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldHidden { FieldId = fieldId }) + ); + } + + [Fact] + public void ShowField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.ShowField(CreateCommand(new ShowField { FieldId = 1 })); + }); + } + + [Fact] + public void ShowField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.ShowField(CreateCommand(new ShowField { FieldId = 1 })); + }); + } + + [Fact] + public void ShowField_should_update_schema_and_create_events() + { + CreateSchema(); + CreateField(); + + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + sut.ShowField(CreateCommand(new ShowField { FieldId = 1 })); + + Assert.False(sut.State.SchemaDef.FieldsById[1].IsHidden); + + sut.GetUncomittedEvents().Skip(1) + .ShouldHaveSameEvents( + CreateEvent(new FieldShown { FieldId = fieldId }) + ); + } + + [Fact] + public void DisableField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + }); + } + + [Fact] + public void DisableField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + }); + } + + [Fact] + public void DisableField_should_update_schema_and_create_events() + { + CreateSchema(); + CreateField(); + + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + + Assert.True(sut.State.SchemaDef.FieldsById[1].IsDisabled); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldDisabled { FieldId = fieldId }) + ); + } + + [Fact] + public void EnableField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.EnableField(CreateCommand(new EnableField { FieldId = 1 })); + }); + } + + [Fact] + public void EnableField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.EnableField(CreateCommand(new EnableField { FieldId = 1 })); + }); + } + + [Fact] + public void EnableField_should_update_schema_and_create_events() + { + CreateSchema(); + CreateField(); + + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + sut.EnableField(CreateCommand(new EnableField { FieldId = 1 })); + + Assert.False(sut.State.SchemaDef.FieldsById[1].IsDisabled); + + sut.GetUncomittedEvents().Skip(1) + .ShouldHaveSameEvents( + CreateEvent(new FieldEnabled { FieldId = fieldId }) + ); + } + + [Fact] + public void DeleteField_should_throw_exception_if_not_created() + { + Assert.Throws(() => + { + sut.DeleteField(CreateCommand(new DeleteField { FieldId = 1 })); + }); + } + + [Fact] + public void DeleteField_should_throw_exception_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => + { + sut.DeleteField(CreateCommand(new DeleteField { FieldId = 1 })); + }); + } + + [Fact] + public void DeleteField_should_update_schema_and_create_events() + { + CreateSchema(); + CreateField(); + + sut.DeleteField(CreateCommand(new DeleteField { FieldId = 1 })); + + Assert.False(sut.State.SchemaDef.FieldsById.ContainsKey(1)); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldDeleted { FieldId = fieldId }) + ); + } + + private void CreateField() + { + sut.Add(CreateCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + sut.ClearUncommittedEvents(); + } + + private void CreateSchema() + { + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName })); + sut.ClearUncommittedEvents(); + } + + private void PublishSchema() + { + sut.Publish(CreateCommand(new PublishSchema())); + sut.ClearUncommittedEvents(); + } + + private void DeleteSchema() + { + sut.Delete(CreateCommand(new DeleteSchema())); + sut.ClearUncommittedEvents(); + } + + private static StringFieldProperties ValidProperties() + { + return new StringFieldProperties { MinLength = 10, MaxLength = 20 }; + } + + private static StringFieldProperties InvalidProperties() + { + return new StringFieldProperties { MinLength = 20, MaxLength = 10 }; + } + } +} diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs b/tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs index c97d25f1c..80e4db5e7 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs @@ -8,9 +8,11 @@ using System; using System.Threading.Tasks; +using FakeItEasy; using Squidex.Domain.Apps.Events; using Squidex.Infrastructure; using Squidex.Infrastructure.Commands; +using Squidex.Infrastructure.States; #pragma warning disable IDE0019 // Use pattern matching @@ -74,6 +76,8 @@ namespace Squidex.Domain.Apps.Entities.TestHelpers protected Guid SchemaId { get; } = Guid.NewGuid(); + protected abstract Guid Id { get; } + protected string AppName { get; } = "my-app"; protected string SchemaName { get; } = "my-schema"; @@ -102,6 +106,7 @@ namespace Squidex.Domain.Apps.Entities.TestHelpers { handler.Init(domainObject); + await domainObject.ActivateAsync(Id.ToString(), A.Fake()); await action(domainObject); if (!handler.IsCreated && shouldCreate) @@ -114,6 +119,7 @@ namespace Squidex.Domain.Apps.Entities.TestHelpers { handler.Init(domainObject); + await domainObject.ActivateAsync(Id.ToString(), A.Fake()); await action(domainObject); if (!handler.IsUpdated && shouldUpdate)