diff --git a/global.json b/global.json index 3b8ca85e4..1aea5e477 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { - "projects": [ "src" ], + "projects": [ "src", "tests" ], "sdk": { - "version": "1.0.0-preview2-003133" + "version": "1.0.0-preview2-1-003177" } } diff --git a/src/Squidex.Core/Schemas/BooleanField.cs b/src/Squidex.Core/Schemas/BooleanField.cs new file mode 100644 index 000000000..2448a2770 --- /dev/null +++ b/src/Squidex.Core/Schemas/BooleanField.cs @@ -0,0 +1,41 @@ +// ========================================================================== +// BooleanField.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Globalization; +using Squidex.Core.Schemas.Validators; +using Squidex.Infrastructure; + +namespace Squidex.Core.Schemas +{ + public sealed class BooleanField : Field + { + public BooleanField(long id, string name, BooleanFieldProperties properties) + : base(id, name, properties) + { + } + + protected override IEnumerable CreateValidators() + { + if (Properties.IsRequired) + { + yield return new RequiredValidator(); + } + } + + protected override object ConvertValue(PropertyValue property) + { + return property.ToNullableBoolean(CultureInfo.InvariantCulture); + } + + protected override Field Clone() + { + return new BooleanField(Id, Name, Properties); + } + } +} diff --git a/src/Squidex.Core/Schemas/BooleanFieldEditor.cs b/src/Squidex.Core/Schemas/BooleanFieldEditor.cs new file mode 100644 index 000000000..fd6d7fe5f --- /dev/null +++ b/src/Squidex.Core/Schemas/BooleanFieldEditor.cs @@ -0,0 +1,16 @@ +// ========================================================================== +// BooleanFieldEditor.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +namespace Squidex.Core.Schemas +{ + public enum BooleanFieldEditor + { + Checkbox, + Toggle + } +} diff --git a/src/Squidex.Core/Schemas/BooleanFieldProperties.cs b/src/Squidex.Core/Schemas/BooleanFieldProperties.cs new file mode 100644 index 000000000..531524824 --- /dev/null +++ b/src/Squidex.Core/Schemas/BooleanFieldProperties.cs @@ -0,0 +1,50 @@ +// ========================================================================== +// BooleanFieldProperties.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using Squidex.Infrastructure; + +namespace Squidex.Core.Schemas +{ + [TypeName("BooleanField")] + public sealed class BooleanFieldProperties : FieldProperties + { + private BooleanFieldEditor editor; + private bool? defaultValue; + + public bool? DefaultValue + { + get { return defaultValue; } + set + { + ThrowIfFrozen(); + + defaultValue = value; + } + } + + public BooleanFieldEditor Editor + { + get { return editor; } + set + { + ThrowIfFrozen(); + + editor = value; + } + } + + protected override IEnumerable ValidateCore() + { + if (!Editor.IsEnumValue()) + { + yield return new ValidationError("Editor ist not a valid value", nameof(Editor)); + } + } + } +} diff --git a/src/Squidex.Core/Schemas/FieldRegistry.cs b/src/Squidex.Core/Schemas/FieldRegistry.cs index 7974e0cc9..7f964813a 100644 --- a/src/Squidex.Core/Schemas/FieldRegistry.cs +++ b/src/Squidex.Core/Schemas/FieldRegistry.cs @@ -51,6 +51,7 @@ namespace Squidex.Core.Schemas public FieldRegistry() { + Add((id, name, properties) => new BooleanField(id, name, (BooleanFieldProperties)properties)); Add((id, name, properties) => new NumberField(id, name, (NumberFieldProperties)properties)); Add((id, name, properties) => new StringField(id, name, (StringFieldProperties)properties)); } diff --git a/src/Squidex.Core/Schemas/Schema.cs b/src/Squidex.Core/Schemas/Schema.cs index da270cf7f..5d502d776 100644 --- a/src/Squidex.Core/Schemas/Schema.cs +++ b/src/Squidex.Core/Schemas/Schema.cs @@ -20,6 +20,7 @@ namespace Squidex.Core.Schemas public sealed class Schema { private readonly string name; + private readonly bool isPublished; private readonly SchemaProperties properties; private readonly ImmutableDictionary fieldsById; private readonly Dictionary fieldsByName; @@ -29,6 +30,11 @@ namespace Squidex.Core.Schemas get { return name; } } + public bool IsPublished + { + get { return isPublished; } + } + public ImmutableDictionary Fields { get { return fieldsById; } @@ -39,7 +45,7 @@ namespace Squidex.Core.Schemas get { return properties; } } - public Schema(string name, SchemaProperties properties, ImmutableDictionary fields) + public Schema(string name, SchemaProperties properties, bool isPublished, ImmutableDictionary fields) { Guard.NotNull(fields, nameof(fields)); Guard.NotNull(properties, nameof(properties)); @@ -48,6 +54,7 @@ namespace Squidex.Core.Schemas this.name = name; this.properties = properties; + this.isPublished = isPublished; fieldsById = fields; fieldsByName = fields.Values.ToDictionary(x => x.Name, StringComparer.OrdinalIgnoreCase); @@ -64,14 +71,14 @@ namespace Squidex.Core.Schemas throw new ValidationException("Cannot create a new schema", error); } - return new Schema(name, newProperties, ImmutableDictionary.Empty); + return new Schema(name, newProperties, false, ImmutableDictionary.Empty); } public Schema Update(SchemaProperties newProperties) { Guard.NotNull(newProperties, nameof(newProperties)); - return new Schema(name, newProperties, fieldsById); + return new Schema(name, newProperties, isPublished, fieldsById); } public Schema AddOrUpdateField(Field field) @@ -83,7 +90,7 @@ namespace Squidex.Core.Schemas throw new ValidationException($"A field with name '{field.Name}' already exists."); } - return new Schema(name, properties, fieldsById.SetItem(field.Id, field)); + return new Schema(name, properties, isPublished, fieldsById.SetItem(field.Id, field)); } public Schema UpdateField(long fieldId, FieldProperties newProperties) @@ -118,7 +125,27 @@ namespace Squidex.Core.Schemas public Schema DeleteField(long fieldId) { - return new Schema(name, properties, fieldsById.Remove(fieldId)); + return new Schema(name, properties, isPublished, fieldsById.Remove(fieldId)); + } + + public Schema Publish() + { + if (isPublished) + { + throw new DomainException("Schema is already published"); + } + + return new Schema(name, properties, true, fieldsById); + } + + public Schema Unpublish() + { + if (!isPublished) + { + throw new DomainException("Schema is not published"); + } + + return new Schema(name, properties, false, fieldsById); } public Schema UpdateField(long fieldId, Func updater) diff --git a/src/Squidex.Events/Schemas/SchemaPublished.cs b/src/Squidex.Events/Schemas/SchemaPublished.cs new file mode 100644 index 000000000..ce141fc07 --- /dev/null +++ b/src/Squidex.Events/Schemas/SchemaPublished.cs @@ -0,0 +1,18 @@ +// ========================================================================== +// SchemaPublished.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Squidex.Infrastructure; +using Squidex.Infrastructure.CQRS.Events; + +namespace Squidex.Events.Schemas +{ + [TypeName("SchemaPublished")] + public class SchemaPublished : IEvent + { + } +} diff --git a/src/Squidex.Events/Schemas/SchemaUnpublished.cs b/src/Squidex.Events/Schemas/SchemaUnpublished.cs new file mode 100644 index 000000000..6c621999b --- /dev/null +++ b/src/Squidex.Events/Schemas/SchemaUnpublished.cs @@ -0,0 +1,18 @@ +// ========================================================================== +// SchemaUnpublished.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Squidex.Infrastructure; +using Squidex.Infrastructure.CQRS.Events; + +namespace Squidex.Events.Schemas +{ + [TypeName("SchemaUnpublished")] + public class SchemaUnpublished : IEvent + { + } +} diff --git a/src/Squidex.Infrastructure/RefToken.cs b/src/Squidex.Infrastructure/RefToken.cs index 5a8214576..96848c1e2 100644 --- a/src/Squidex.Infrastructure/RefToken.cs +++ b/src/Squidex.Infrastructure/RefToken.cs @@ -58,7 +58,7 @@ namespace Squidex.Infrastructure public override int GetHashCode() { - return (Type.GetHashCode() * 397) ^ (Identifier.GetHashCode()); + return (Type.GetHashCode() * 397) ^ Identifier.GetHashCode(); } } } diff --git a/src/Squidex.Read/Schemas/Repositories/ISchemaEntity.cs b/src/Squidex.Read/Schemas/Repositories/ISchemaEntity.cs index 332aba541..55efd3565 100644 --- a/src/Squidex.Read/Schemas/Repositories/ISchemaEntity.cs +++ b/src/Squidex.Read/Schemas/Repositories/ISchemaEntity.cs @@ -10,5 +10,7 @@ namespace Squidex.Read.Schemas.Repositories public interface ISchemaEntity : IAppRefEntity, ITrackCreatedByEntity, ITrackLastModifiedByEntity { string Name { get; } + + bool IsPublished { get; } } } diff --git a/src/Squidex.Store.MongoDb/History/ParsedHistoryEvent.cs b/src/Squidex.Store.MongoDb/History/ParsedHistoryEvent.cs index 06282b7f0..2eaf3d279 100644 --- a/src/Squidex.Store.MongoDb/History/ParsedHistoryEvent.cs +++ b/src/Squidex.Store.MongoDb/History/ParsedHistoryEvent.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; using Squidex.Infrastructure; using Squidex.Read.History; +// ReSharper disable LoopCanBeConvertedToQuery namespace Squidex.Store.MongoDb.History { diff --git a/src/Squidex.Store.MongoDb/Schemas/MongoSchemaEntity.cs b/src/Squidex.Store.MongoDb/Schemas/MongoSchemaEntity.cs index 84bc0a5df..9f9c4ede0 100644 --- a/src/Squidex.Store.MongoDb/Schemas/MongoSchemaEntity.cs +++ b/src/Squidex.Store.MongoDb/Schemas/MongoSchemaEntity.cs @@ -45,6 +45,10 @@ namespace Squidex.Store.MongoDb.Schemas [BsonElement] public BsonDocument Schema { get; set; } + [BsonIgnoreIfDefault] + [BsonElement] + public bool IsPublished { get; set; } + Schema ISchemaEntityWithSchema.Schema { get { return schema.Value; } diff --git a/src/Squidex.Store.MongoDb/Schemas/MongoSchemaRepository.cs b/src/Squidex.Store.MongoDb/Schemas/MongoSchemaRepository.cs index 89e06540d..95434412d 100644 --- a/src/Squidex.Store.MongoDb/Schemas/MongoSchemaRepository.cs +++ b/src/Squidex.Store.MongoDb/Schemas/MongoSchemaRepository.cs @@ -128,6 +128,16 @@ namespace Squidex.Store.MongoDb.Schemas return UpdateSchema(headers, s => s.Update(@event.Properties)); } + protected Task On(SchemaPublished @event, EnvelopeHeaders headers) + { + return UpdateSchema(headers, s => s.Publish()); + } + + protected Task On(SchemaUnpublished @event, EnvelopeHeaders headers) + { + return UpdateSchema(headers, s => s.Publish()); + } + protected Task On(FieldAdded @event, EnvelopeHeaders headers) { var field = fieldRegistry.CreateField(@event.FieldId, @event.Name, @event.Properties); @@ -159,6 +169,8 @@ namespace Squidex.Store.MongoDb.Schemas currentSchema = updater(currentSchema); Serialize(entity, currentSchema); + + entity.IsPublished = currentSchema.IsPublished; } private void Serialize(MongoSchemaEntity entity, Schema schema) diff --git a/src/Squidex.Write/Schemas/Commands/PublishSchema.cs b/src/Squidex.Write/Schemas/Commands/PublishSchema.cs new file mode 100644 index 000000000..265be63d1 --- /dev/null +++ b/src/Squidex.Write/Schemas/Commands/PublishSchema.cs @@ -0,0 +1,14 @@ +// ========================================================================== +// PublishSchema.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +namespace Squidex.Write.Schemas.Commands +{ + public class PublishSchema : AppCommand + { + } +} diff --git a/src/Squidex.Write/Schemas/Commands/UnpublishSchema.cs b/src/Squidex.Write/Schemas/Commands/UnpublishSchema.cs new file mode 100644 index 000000000..d3d3649e2 --- /dev/null +++ b/src/Squidex.Write/Schemas/Commands/UnpublishSchema.cs @@ -0,0 +1,14 @@ +// ========================================================================== +// UnpublishShema.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +namespace Squidex.Write.Schemas.Commands +{ + public class UnpublishSchema : AppCommand + { + } +} diff --git a/src/Squidex.Write/Schemas/SchemaCommandHandler.cs b/src/Squidex.Write/Schemas/SchemaCommandHandler.cs index 5dd96a16a..7ed4cb9fb 100644 --- a/src/Squidex.Write/Schemas/SchemaCommandHandler.cs +++ b/src/Squidex.Write/Schemas/SchemaCommandHandler.cs @@ -99,6 +99,16 @@ namespace Squidex.Write.Schemas return handler.UpdateAsync(command, s => { s.UpdateField(command); }); } + protected Task On(PublishSchema command, CommandContext context) + { + return handler.UpdateAsync(command, s => { s.Publish(command); }); + } + + protected Task On(UnpublishSchema command, CommandContext context) + { + return handler.UpdateAsync(command, s => { s.Unpublish(command); }); + } + public Task HandleAsync(CommandContext context) { return context.IsHandled ? Task.FromResult(false) : this.DispatchActionAsync(context.Command, context); diff --git a/src/Squidex.Write/Schemas/SchemaDomainObject.cs b/src/Squidex.Write/Schemas/SchemaDomainObject.cs index 119ffc840..a82cd64d3 100644 --- a/src/Squidex.Write/Schemas/SchemaDomainObject.cs +++ b/src/Squidex.Write/Schemas/SchemaDomainObject.cs @@ -90,6 +90,16 @@ namespace Squidex.Write.Schemas schema = schema.DeleteField(@event.FieldId); } + protected void On(SchemaPublished @event) + { + schema = schema.Publish(); + } + + protected void On(SchemaUnpublished @event) + { + schema = schema.Unpublish(); + } + protected void On(SchemaDeleted @event) { isDeleted = true; @@ -194,6 +204,24 @@ namespace Squidex.Write.Schemas return this; } + public SchemaDomainObject Publish(PublishSchema command) + { + VerifyCreatedAndNotDeleted(); + + RaiseEvent(new SchemaPublished()); + + return this; + } + + public SchemaDomainObject Unpublish(UnpublishSchema command) + { + VerifyCreatedAndNotDeleted(); + + RaiseEvent(new SchemaUnpublished()); + + return this; + } + public SchemaDomainObject Delete(DeleteSchema command) { VerifyCreatedAndNotDeleted(); diff --git a/src/Squidex/Config/Identity/SwaggerIdentityUsage.cs b/src/Squidex/Config/Identity/SwaggerIdentityUsage.cs index 2dd974e2b..809a853e7 100644 --- a/src/Squidex/Config/Identity/SwaggerIdentityUsage.cs +++ b/src/Squidex/Config/Identity/SwaggerIdentityUsage.cs @@ -22,7 +22,9 @@ namespace Squidex.Config.Identity $ curl -X POST '{0}' -H 'Content-Type: application/x-www-form-urlencoded' - -d 'grant_type=client_credentials&client_id=[APP_NAME]:[CLIENT_NAME]&client_secret=[CLIENT_SECRET]'"; + -d 'grant_type=client_credentials& + client_id=[APP_NAME]:[CLIENT_NAME]& + client_secret=[CLIENT_SECRET]'"; public static SwaggerOwinSettings ConfigureIdentity(this SwaggerOwinSettings settings, MyUrlsOptions options) { diff --git a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs b/src/Squidex/Controllers/Api/Schemas/SchemasController.cs index 287cdc875..6071c1e8a 100644 --- a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs +++ b/src/Squidex/Controllers/Api/Schemas/SchemasController.cs @@ -127,7 +127,7 @@ namespace Squidex.Controllers.Api.Schemas } /// - /// Publishs a schema. + /// Publish a schema. /// /// The app where the schema is a part of. /// The name of the schema to publish. @@ -137,6 +137,7 @@ namespace Squidex.Controllers.Api.Schemas /// [HttpPut] [Route("apps/{app}/schemas/{name}/publish")] + [ProducesResponseType(typeof(ErrorDto), 400)] public async Task PublishSchema(string app, string name) { await CommandBus.PublishAsync(new PublishSchema()); @@ -145,7 +146,7 @@ namespace Squidex.Controllers.Api.Schemas } /// - /// Unpublishs a schema. + /// Unpublish a schema. /// /// The app where the schema is a part of. /// The name of the schema to unpublish. @@ -154,7 +155,8 @@ namespace Squidex.Controllers.Api.Schemas /// 204 => Schema has been deleted. /// [HttpPut] - [Route("apps/{app}/schemas/{name}/publish")] + [Route("apps/{app}/schemas/{name}/unpublish")] + [ProducesResponseType(typeof(ErrorDto), 400)] public async Task UnpublishSchema(string app, string name) { await CommandBus.PublishAsync(new UnpublishSchema()); diff --git a/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs b/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs new file mode 100644 index 000000000..79d971ec0 --- /dev/null +++ b/tests/Squidex.Core.Tests/Schemas/BooleanFieldPropertiesTests.cs @@ -0,0 +1,34 @@ +// ========================================================================== +// BooleanFieldPropertiesTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using FluentAssertions; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Core.Schemas +{ + public class BooleanFieldPropertiesTests + { + private readonly List errors = new List(); + + [Fact] + public void Should_add_error_if_editor_is_not_valid() + { + var sut = new BooleanFieldProperties { Editor = (BooleanFieldEditor)123 }; + + sut.Validate(errors); + + errors.ShouldBeEquivalentTo( + new List + { + new ValidationError("Editor ist not a valid value", "Editor") + }); + } + } +} diff --git a/tests/Squidex.Core.Tests/Schemas/BooleanFieldTests.cs b/tests/Squidex.Core.Tests/Schemas/BooleanFieldTests.cs new file mode 100644 index 000000000..e2a344f3a --- /dev/null +++ b/tests/Squidex.Core.Tests/Schemas/BooleanFieldTests.cs @@ -0,0 +1,66 @@ +// ========================================================================== +// BooleanFieldTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Threading.Tasks; +using FluentAssertions; +using Squidex.Infrastructure; +using Xunit; + +namespace Squidex.Core.Schemas +{ + public class BooleanFieldTests + { + private readonly List errors = new List(); + + [Fact] + public void Should_instantiate_field() + { + var sut = new BooleanField(1, "name", new BooleanFieldProperties()); + + Assert.Equal("name", sut.Name); + } + + [Fact] + public void Should_clone_object() + { + var sut = new BooleanField(1, "name", new BooleanFieldProperties()); + + Assert.NotEqual(sut, sut.Enable()); + } + + [Fact] + public async Task Should_add_errors_if_boolean_is_required() + { + var sut = new BooleanField(1, "name", new BooleanFieldProperties { Label = "Name", IsRequired = true }); + + await sut.ValidateAsync(CreateValue(null), errors); + + errors.ShouldBeEquivalentTo( + new[] { "Name is required" }); + } + + [Fact] + public async Task Should_add_errors_if_value_is_not_valid() + { + var sut = new BooleanField(1, "name", new BooleanFieldProperties { Label = "Name" }); + + await sut.ValidateAsync(CreateValue("Invalid"), errors); + + errors.ShouldBeEquivalentTo( + new[] { "Name is not a valid value" }); + } + + private static PropertyValue CreateValue(object v) + { + var bag = new PropertiesBag().Set("value", v); + + return bag["value"]; + } + } +} diff --git a/tests/Squidex.Core.Tests/Schemas/FieldRegistryTests.cs b/tests/Squidex.Core.Tests/Schemas/FieldRegistryTests.cs index c52572a55..41696f23a 100644 --- a/tests/Squidex.Core.Tests/Schemas/FieldRegistryTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/FieldRegistryTests.cs @@ -27,6 +27,7 @@ namespace Squidex.Core.Schemas static FieldRegistryTests() { + TypeNameRegistry.Map(typeof(BooleanFieldProperties), "BooleanField"); TypeNameRegistry.Map(typeof(NumberFieldProperties), "NumberField"); TypeNameRegistry.Map(typeof(StringFieldProperties), "StringField"); TypeNameRegistry.Map(typeof(InvalidProperties), "invalid"); diff --git a/tests/Squidex.Core.Tests/Schemas/SchemaTests.cs b/tests/Squidex.Core.Tests/Schemas/SchemaTests.cs index 4a4047a1c..4223576cd 100644 --- a/tests/Squidex.Core.Tests/Schemas/SchemaTests.cs +++ b/tests/Squidex.Core.Tests/Schemas/SchemaTests.cs @@ -267,6 +267,37 @@ namespace Squidex.Core.Schemas }); } + [Fact] + public void Should_publish_schema() + { + sut = sut.Publish(); + + Assert.True(sut.IsPublished); + } + + [Fact] + public void Should_throw_if_schema_is_already_published() + { + sut = sut.Publish(); + + Assert.Throws(() => sut.Publish()); + } + + [Fact] + public void Should_unpublish_schema() + { + sut = sut.Publish(); + sut = sut.Unpublish(); + + Assert.False(sut.IsPublished); + } + + [Fact] + public void Should_throw_if_schema_is_not_published() + { + Assert.Throws(() => sut.Unpublish()); + } + private NumberField AddField() { var field = new NumberField(1, "my-field", new NumberFieldProperties()); diff --git a/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs b/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs index 24451a7f7..51ad4c920 100644 --- a/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs +++ b/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs @@ -90,6 +90,35 @@ namespace Squidex.Write.Schemas }); } + [Fact] + public async Task PublishSchema_should_update_domain_object() + { + CreateSchema(); + + var command = new PublishSchema { AggregateId = Id }; + var context = new CommandContext(command); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + + [Fact] + public async Task UnpublishSchema_should_update_domain_object() + { + CreateSchema(); + PublishSchema(); + + var command = new UnpublishSchema { AggregateId = Id }; + var context = new CommandContext(command); + + await TestUpdate(schema, async _ => + { + await sut.HandleAsync(context); + }); + } + [Fact] public async Task DeleteSchema_should_update_domain_object() { @@ -215,6 +244,11 @@ namespace Squidex.Write.Schemas schema.Create(new CreateSchema { Name = schemaName }); } + private void PublishSchema() + { + schema.Publish(new PublishSchema()); + } + private void CreateField() { schema.AddField(new AddField { Name = fieldName, Properties = new NumberFieldProperties() }); diff --git a/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs b/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs index 145d40ccd..cc06c141e 100644 --- a/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs +++ b/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs @@ -108,6 +108,71 @@ namespace Squidex.Write.Schemas }); } + [Fact] + public void Publish_should_throw_if_not_created() + { + Assert.Throws(() => sut.Publish(new PublishSchema())); + } + + [Fact] + public void Publish_should_throw_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => sut.Publish(new PublishSchema())); + } + + [Fact] + public void Publish_should_refresh_properties_and_create_events() + { + CreateSchema(); + + sut.Publish(new PublishSchema()); + + Assert.True(sut.Schema.IsPublished); + + sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() + .ShouldBeEquivalentTo( + new IEvent[] + { + new SchemaPublished() + }); + } + + [Fact] + public void Unpublish_should_throw_if_not_created() + { + Assert.Throws(() => sut.Unpublish(new UnpublishSchema())); + } + + [Fact] + public void Unpublish_should_throw_if_schema_is_deleted() + { + CreateSchema(); + DeleteSchema(); + + Assert.Throws(() => sut.Unpublish(new UnpublishSchema())); + } + + [Fact] + public void Unpublish_should_refresh_properties_and_create_events() + { + CreateSchema(); + PublishSchema(); + + sut.Unpublish(new UnpublishSchema()); + + Assert.False(sut.Schema.IsPublished); + + sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() + .ShouldBeEquivalentTo( + new IEvent[] + { + new SchemaUnpublished() + }); + } + [Fact] public void Delete_should_throw_if_not_created() { @@ -442,6 +507,13 @@ namespace Squidex.Write.Schemas ((IAggregate)sut).ClearUncommittedEvents(); } + private void PublishSchema() + { + sut.Publish(new PublishSchema()); + + ((IAggregate)sut).ClearUncommittedEvents(); + } + private void DeleteSchema() { sut.Delete(new DeleteSchema());