From 0d96fe0a730639ff3a591521bed51742b953894d Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Sep 2017 14:28:00 +0200 Subject: [PATCH 1/6] Register Noop Event --- src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs | 1 + src/Squidex/Config/Domain/Serializers.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs b/src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs index be6c125f0..c70e89334 100644 --- a/src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs +++ b/src/Squidex.Infrastructure/CQRS/Events/NoopEvent.cs @@ -8,6 +8,7 @@ namespace Squidex.Infrastructure.CQRS.Events { + [TypeName(nameof(NoopEvent))] public sealed class NoopEvent : IEvent { } diff --git a/src/Squidex/Config/Domain/Serializers.cs b/src/Squidex/Config/Domain/Serializers.cs index 59f8c9e5d..2aed9636a 100644 --- a/src/Squidex/Config/Domain/Serializers.cs +++ b/src/Squidex/Config/Domain/Serializers.cs @@ -15,6 +15,7 @@ using NodaTime.Serialization.JsonNet; using Squidex.Domain.Apps.Events; using Squidex.Infrastructure; using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Config.Domain { @@ -51,6 +52,7 @@ namespace Squidex.Config.Domain static Serializers() { TypeNameRegistry.Map(typeof(SquidexEvent).GetTypeInfo().Assembly); + TypeNameRegistry.Map(typeof(NoopEvent).GetTypeInfo().Assembly); } private static JsonSerializerSettings CreateSettings() From 8fb79b882bd72879755901623f64e3e8fbd7597f Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Sep 2017 14:42:01 +0200 Subject: [PATCH 2/6] Stylecop warning fixed. --- src/Squidex/Config/Domain/Serializers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Squidex/Config/Domain/Serializers.cs b/src/Squidex/Config/Domain/Serializers.cs index 2aed9636a..aba7c3559 100644 --- a/src/Squidex/Config/Domain/Serializers.cs +++ b/src/Squidex/Config/Domain/Serializers.cs @@ -14,8 +14,8 @@ using NodaTime; using NodaTime.Serialization.JsonNet; using Squidex.Domain.Apps.Events; using Squidex.Infrastructure; -using Squidex.Infrastructure.Json; using Squidex.Infrastructure.CQRS.Events; +using Squidex.Infrastructure.Json; namespace Squidex.Config.Domain { From 1e118610f7b14da232aac284a2bc5206d34238be Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Sep 2017 16:06:18 +0200 Subject: [PATCH 3/6] Field brought back. --- .../schemas/pages/schema/schema-page.component.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts index f38b8cc3f..44affcfc2 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts @@ -156,6 +156,16 @@ export class SchemaPageComponent extends AppComponentBase implements OnInit { }); } + public showField(field: FieldDto) { + this.appNameOnce() + .switchMap(app => this.schemasService.showField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + .subscribe(() => { + this.updateSchema(this.schema.updateField(field.show(), this.authService.user!.token)); + }, error => { + this.notifyError(error); + }); + } + public hideField(field: FieldDto) { this.appNameOnce() .switchMap(app => this.schemasService.hideField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) From a63c27ca13007e5c53b5c313ef267d30d01b74b4 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Sep 2017 16:25:29 +0200 Subject: [PATCH 4/6] Also apply default value when field value is an empty string. Closes #109 --- .../ContentEnricher.cs | 2 +- .../Schemas/FieldProperties.cs | 6 ++ .../Schemas/StringFieldProperties.cs | 6 ++ .../ContentEnrichmentTests.cs | 62 ++++++++++++------- 4 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/Squidex.Domain.Apps.Core/ContentEnricher.cs b/src/Squidex.Domain.Apps.Core/ContentEnricher.cs index 2d633ad13..6b0247080 100644 --- a/src/Squidex.Domain.Apps.Core/ContentEnricher.cs +++ b/src/Squidex.Domain.Apps.Core/ContentEnricher.cs @@ -64,7 +64,7 @@ namespace Squidex.Domain.Apps.Core var key = partitionItem.Key; - if (!fieldData.TryGetValue(key, out var value) || value == null || value.Type == JTokenType.Null) + if (!fieldData.TryGetValue(key, out var value) || field.RawProperties.ShouldApplyDefaultValue(value)) { fieldData.AddValue(key, defaultValue); } diff --git a/src/Squidex.Domain.Apps.Core/Schemas/FieldProperties.cs b/src/Squidex.Domain.Apps.Core/Schemas/FieldProperties.cs index 262d8453f..f9785bbbf 100644 --- a/src/Squidex.Domain.Apps.Core/Schemas/FieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core/Schemas/FieldProperties.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using Newtonsoft.Json.Linq; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json; namespace Squidex.Domain.Apps.Core.Schemas { @@ -62,6 +63,11 @@ namespace Squidex.Domain.Apps.Core.Schemas public abstract JToken GetDefaultValue(); + public virtual bool ShouldApplyDefaultValue(JToken value) + { + return value.IsNull(); + } + public void Validate(IList errors) { foreach (var error in ValidateCore()) diff --git a/src/Squidex.Domain.Apps.Core/Schemas/StringFieldProperties.cs b/src/Squidex.Domain.Apps.Core/Schemas/StringFieldProperties.cs index eb70680ac..fe038910d 100644 --- a/src/Squidex.Domain.Apps.Core/Schemas/StringFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core/Schemas/StringFieldProperties.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using Newtonsoft.Json.Linq; using Squidex.Infrastructure; +using Squidex.Infrastructure.Json; namespace Squidex.Domain.Apps.Core.Schemas { @@ -127,6 +128,11 @@ namespace Squidex.Domain.Apps.Core.Schemas return DefaultValue; } + public override bool ShouldApplyDefaultValue(JToken value) + { + return value.IsNull() || (value is JValue jValue && Equals(jValue.Value, string.Empty)); + } + protected override IEnumerable ValidateCore() { if (!Editor.IsEnumValue()) diff --git a/tests/Squidex.Domain.Apps.Core.Tests/ContentEnrichmentTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/ContentEnrichmentTests.cs index 35ed1e728..c50f0bc42 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/ContentEnrichmentTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/ContentEnrichmentTests.cs @@ -18,32 +18,30 @@ namespace Squidex.Domain.Apps.Core { public class ContentEnrichmentTests { + private static readonly Instant Now = Instant.FromUnixTimeSeconds(SystemClock.Instance.GetCurrentInstant().ToUnixTimeSeconds()); private readonly LanguagesConfig languagesConfig = LanguagesConfig.Create(Language.DE, Language.EN); + private readonly Schema schema = + Schema.Create("my-schema", new SchemaProperties()) + .AddOrUpdateField(new JsonField(1, "my-json", Partitioning.Invariant, + new JsonFieldProperties())) + .AddOrUpdateField(new StringField(2, "my-string", Partitioning.Language, + new StringFieldProperties { DefaultValue = "en-string" })) + .AddOrUpdateField(new NumberField(3, "my-number", Partitioning.Invariant, + new NumberFieldProperties { DefaultValue = 123 })) + .AddOrUpdateField(new AssetsField(4, "my-assets", Partitioning.Invariant, + new AssetsFieldProperties())) + .AddOrUpdateField(new BooleanField(5, "my-boolean", Partitioning.Invariant, + new BooleanFieldProperties { DefaultValue = true })) + .AddOrUpdateField(new DateTimeField(6, "my-datetime", Partitioning.Invariant, + new DateTimeFieldProperties { DefaultValue = Now })) + .AddOrUpdateField(new ReferencesField(7, "my-references", Partitioning.Invariant, + new ReferencesFieldProperties { SchemaId = Guid.NewGuid() })) + .AddOrUpdateField(new GeolocationField(8, "my-geolocation", Partitioning.Invariant, + new GeolocationFieldProperties())); [Fact] private void Should_enrich_with_default_values() { - var now = Instant.FromUnixTimeSeconds(SystemClock.Instance.GetCurrentInstant().ToUnixTimeSeconds()); - - var schema = - Schema.Create("my-schema", new SchemaProperties()) - .AddOrUpdateField(new JsonField(1, "my-json", Partitioning.Invariant, - new JsonFieldProperties())) - .AddOrUpdateField(new StringField(2, "my-string", Partitioning.Language, - new StringFieldProperties { DefaultValue = "en-string" })) - .AddOrUpdateField(new NumberField(3, "my-number", Partitioning.Invariant, - new NumberFieldProperties { DefaultValue = 123 })) - .AddOrUpdateField(new AssetsField(4, "my-assets", Partitioning.Invariant, - new AssetsFieldProperties())) - .AddOrUpdateField(new BooleanField(5, "my-boolean", Partitioning.Invariant, - new BooleanFieldProperties { DefaultValue = true })) - .AddOrUpdateField(new DateTimeField(6, "my-datetime", Partitioning.Invariant, - new DateTimeFieldProperties { DefaultValue = now })) - .AddOrUpdateField(new ReferencesField(7, "my-references", Partitioning.Invariant, - new ReferencesFieldProperties { SchemaId = Guid.NewGuid() })) - .AddOrUpdateField(new GeolocationField(8, "my-geolocation", Partitioning.Invariant, - new GeolocationFieldProperties())); - var data = new NamedContentData() .AddField("my-string", @@ -60,9 +58,29 @@ namespace Squidex.Domain.Apps.Core Assert.Equal("de-string", (string)data["my-string"]["de"]); Assert.Equal("en-string", (string)data["my-string"]["en"]); - Assert.Equal(now, InstantPattern.General.Parse((string)data["my-datetime"]["iv"]).Value); + Assert.Equal(Now, InstantPattern.General.Parse((string)data["my-datetime"]["iv"]).Value); Assert.Equal(true, (bool)data["my-boolean"]["iv"]); } + + [Fact] + private void Should_also_enrich_with_default_values_when_string_is_empty() + { + var now = Instant.FromUnixTimeSeconds(SystemClock.Instance.GetCurrentInstant().ToUnixTimeSeconds()); + + var data = + new NamedContentData() + .AddField("my-string", + new ContentFieldData() + .AddValue("de", string.Empty)) + .AddField("my-number", + new ContentFieldData() + .AddValue("iv", 456)); + + data.Enrich(schema, languagesConfig.ToResolver()); + + Assert.Equal("en-string", (string)data["my-string"]["de"]); + Assert.Equal("en-string", (string)data["my-string"]["en"]); + } } } From 56aa831ed98e41ae88d9e2568f0c26ed4fb7d781 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Sep 2017 20:11:55 +0200 Subject: [PATCH 5/6] Link to docs fixed. --- src/Squidex/Docs/schemabody.md | 2 +- src/Squidex/Docs/schemaquery.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Squidex/Docs/schemabody.md b/src/Squidex/Docs/schemabody.md index bf97dd0de..57a6e9d40 100644 --- a/src/Squidex/Docs/schemabody.md +++ b/src/Squidex/Docs/schemabody.md @@ -4,4 +4,4 @@ Please note that each field is an object with one entry per language. If the field is not localizable you must use iv (Invariant Language) as a key. When you change the field to be localizable the value will become the value for the master language, depending what the master language is at this point of time. -Read more about it at: https://docs.squidex.io/04-guides/01-api.html \ No newline at end of file +Read more about it at: https://docs.squidex.io/04-guides/02-api.html \ No newline at end of file diff --git a/src/Squidex/Docs/schemaquery.md b/src/Squidex/Docs/schemaquery.md index aa78298b9..1642bd400 100644 --- a/src/Squidex/Docs/schemaquery.md +++ b/src/Squidex/Docs/schemaquery.md @@ -8,4 +8,4 @@ We support the following query options. * **$filter**: The $filter query option allows clients to filter a collection of resources that are addressed by a request URL. * **$orderby**: The $orderby query option allows clients to request resources in a particular order. -Read more about it at: https://docs.squidex.io/04-guides/01-api.html +Read more about it at: https://docs.squidex.io/04-guides/02-api.html From fd5d8754fc5163bc1c54044f58cdc4b700aac5a2 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Thu, 14 Sep 2017 20:56:43 +0200 Subject: [PATCH 6/6] Event name fix --- src/Squidex.Domain.Apps.Events/Webhooks/WebhookDeleted.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Squidex.Domain.Apps.Events/Webhooks/WebhookDeleted.cs b/src/Squidex.Domain.Apps.Events/Webhooks/WebhookDeleted.cs index a01d60dc3..a04e86ab6 100644 --- a/src/Squidex.Domain.Apps.Events/Webhooks/WebhookDeleted.cs +++ b/src/Squidex.Domain.Apps.Events/Webhooks/WebhookDeleted.cs @@ -6,12 +6,11 @@ // All rights reserved. // ========================================================================== -using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS.Events; namespace Squidex.Domain.Apps.Events.Webhooks { - [EventType(nameof(WebhookUpdated), 2)] + [EventType(nameof(WebhookDeleted), 2)] public sealed class WebhookDeleted : WebhookEvent { }