diff --git a/Fody.2.3.24.nupkg b/Fody.2.3.24.nupkg new file mode 100644 index 000000000..ca315c314 Binary files /dev/null and b/Fody.2.3.24.nupkg differ diff --git a/libs/fody/2.3.24/fody.2.3.24.nupkg b/libs/fody/2.3.24/fody.2.3.24.nupkg new file mode 100644 index 000000000..ca315c314 Binary files /dev/null and b/libs/fody/2.3.24/fody.2.3.24.nupkg differ diff --git a/libs/fody/2.3.24/fody.2.3.24.nupkg.sha512 b/libs/fody/2.3.24/fody.2.3.24.nupkg.sha512 new file mode 100644 index 000000000..e2af0e784 --- /dev/null +++ b/libs/fody/2.3.24/fody.2.3.24.nupkg.sha512 @@ -0,0 +1 @@ +tTFEibLh222u4a7SJ+I4zCkfPRBRF4mHF446OSRQtILNZ2tH0Te/rSM7MCt1FzvLAy5KeNlZHfwdlS+AJZDa6w== \ No newline at end of file diff --git a/libs/fody/2.3.24/fody.nuspec b/libs/fody/2.3.24/fody.nuspec new file mode 100644 index 000000000..caafd3029 --- /dev/null +++ b/libs/fody/2.3.24/fody.nuspec @@ -0,0 +1,17 @@ + + + + Fody + 2.3.24 + Simon Cropp + Simon Cropp + false + true + http://www.opensource.org/licenses/mit-license.php + http://github.com/Fody/Fody + https://raw.github.com/Fody/Fody/master/package_icon.png + Extensible tool for weaving .net assemblies. + + ILWeaving, Fody, Cecil, AOP + + \ No newline at end of file diff --git a/src/Squidex.Domain.Apps.Core.Model/FodyWeavers.xml b/src/Squidex.Domain.Apps.Core.Model/FodyWeavers.xml new file mode 100644 index 000000000..0444e1d26 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/Squidex.Infrastructure/Freezable.cs b/src/Squidex.Domain.Apps.Core.Model/Freezable.cs similarity index 63% rename from src/Squidex.Infrastructure/Freezable.cs rename to src/Squidex.Domain.Apps.Core.Model/Freezable.cs index a71d35175..26bfddb5e 100644 --- a/src/Squidex.Infrastructure/Freezable.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Freezable.cs @@ -6,16 +6,22 @@ // ========================================================================== using System; +using Squidex.Infrastructure; -namespace Squidex.Infrastructure +namespace Squidex.Domain.Apps.Core { - public abstract class Freezable + public abstract class Freezable : IFreezable { - public bool IsFrozen { get; private set; } + private bool isFrozen; - protected void ThrowIfFrozen() + public bool IsFrozen { - if (IsFrozen) + get { return isFrozen; } + } + + protected void CheckIfFrozen() + { + if (isFrozen) { throw new InvalidOperationException("Object is frozen"); } @@ -23,7 +29,7 @@ namespace Squidex.Infrastructure public void Freeze() { - IsFrozen = true; + isFrozen = true; } } } diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AlgoliaAction.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AlgoliaAction.cs index e8040e57d..33295be4a 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AlgoliaAction.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AlgoliaAction.cs @@ -12,51 +12,11 @@ namespace Squidex.Domain.Apps.Core.Rules.Actions [TypeName(nameof(AlgoliaAction))] public sealed class AlgoliaAction : RuleAction { - private string appId; - private string apiKey; - private string indexName; + public string AppId { get; set; } - public string AppId - { - get - { - return appId; - } - set - { - ThrowIfFrozen(); - - appId = value; - } - } - - public string ApiKey - { - get - { - return apiKey; - } - set - { - ThrowIfFrozen(); + public string ApiKey { get; set; } - apiKey = value; - } - } - - public string IndexName - { - get - { - return indexName; - } - set - { - ThrowIfFrozen(); - - indexName = value; - } - } + public string IndexName { get; set; } public override T Accept(IRuleActionVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs new file mode 100644 index 000000000..fc9178243 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/AzureQueueAction.cs @@ -0,0 +1,24 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Infrastructure; + +namespace Squidex.Domain.Apps.Core.Rules.Actions +{ + [TypeName(nameof(AzureQueueAction))] + public sealed class AzureQueueAction : RuleAction + { + public string ConnectionString { get; set; } + + public string Queue { get; set; } + + public override T Accept(IRuleActionVisitor visitor) + { + return visitor.Visit(this); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/SlackAction.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/SlackAction.cs index 3e39a2ff7..b669fe104 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/SlackAction.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/SlackAction.cs @@ -13,36 +13,9 @@ namespace Squidex.Domain.Apps.Core.Rules.Actions [TypeName(nameof(SlackAction))] public sealed class SlackAction : RuleAction { - private Uri webhookUrl; - private string text; + public Uri WebhookUrl { get; set; } - public Uri WebhookUrl - { - get - { - return webhookUrl; - } - set - { - ThrowIfFrozen(); - - webhookUrl = value; - } - } - - public string Text - { - get - { - return text; - } - set - { - ThrowIfFrozen(); - - text = value; - } - } + public string Text { get; set; } public override T Accept(IRuleActionVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/WebhookAction.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/WebhookAction.cs index 849c87a6e..30a6c0707 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/WebhookAction.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Actions/WebhookAction.cs @@ -13,36 +13,9 @@ namespace Squidex.Domain.Apps.Core.Rules.Actions [TypeName(nameof(WebhookAction))] public sealed class WebhookAction : RuleAction { - private Uri url; - private string sharedSecret; + public Uri Url { get; set; } - public Uri Url - { - get - { - return url; - } - set - { - ThrowIfFrozen(); - - url = value; - } - } - - public string SharedSecret - { - get - { - return sharedSecret; - } - set - { - ThrowIfFrozen(); - - sharedSecret = value; - } - } + public string SharedSecret { get; set; } public override T Accept(IRuleActionVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs index ae9543b0a..b90f8b872 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/IRuleActionVisitor.cs @@ -13,6 +13,8 @@ namespace Squidex.Domain.Apps.Core.Rules { T Visit(AlgoliaAction action); + T Visit(AzureQueueAction action); + T Visit(SlackAction action); T Visit(WebhookAction action); diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs index 02fb9e85d..caaf409d0 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/RuleAction.cs @@ -5,8 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure; - namespace Squidex.Domain.Apps.Core.Rules { public abstract class RuleAction : Freezable diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs index 1640b81ab..95c1deb0f 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/RuleTrigger.cs @@ -5,8 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure; - namespace Squidex.Domain.Apps.Core.Rules { public abstract class RuleTrigger : Freezable diff --git a/src/Squidex.Domain.Apps.Core.Model/Rules/Triggers/ContentChangedTrigger.cs b/src/Squidex.Domain.Apps.Core.Model/Rules/Triggers/ContentChangedTrigger.cs index 2ad2d5110..b390fba25 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Rules/Triggers/ContentChangedTrigger.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Rules/Triggers/ContentChangedTrigger.cs @@ -13,21 +13,7 @@ namespace Squidex.Domain.Apps.Core.Rules.Triggers [TypeName(nameof(ContentChangedTrigger))] public sealed class ContentChangedTrigger : RuleTrigger { - private ImmutableList schemas; - - public ImmutableList Schemas - { - get - { - return schemas; - } - set - { - ThrowIfFrozen(); - - schemas = value; - } - } + public ImmutableList Schemas { get; set; } public override T Accept(IRuleTriggerVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs index 022890352..d3ed6270a 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/AssetsFieldProperties.cs @@ -13,186 +13,29 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(AssetsField))] public sealed class AssetsFieldProperties : FieldProperties { - private bool mustBeImage; - private int? minItems; - private int? maxItems; - private int? minWidth; - private int? maxWidth; - private int? minHeight; - private int? maxHeight; - private int? minSize; - private int? maxSize; - private int? aspectWidth; - private int? aspectHeight; - private ImmutableList allowedExtensions; + public bool MustBeImage { get; set; } - public bool MustBeImage - { - get - { - return mustBeImage; - } - set - { - ThrowIfFrozen(); + public int? MinItems { get; set; } - mustBeImage = value; - } - } + public int? MaxItems { get; set; } - public int? MinItems - { - get - { - return minItems; - } - set - { - ThrowIfFrozen(); + public int? MinWidth { get; set; } - minItems = value; - } - } + public int? MaxWidth { get; set; } - public int? MaxItems - { - get - { - return maxItems; - } - set - { - ThrowIfFrozen(); + public int? MinHeight { get; set; } - maxItems = value; - } - } + public int? MaxHeight { get; set; } - public int? MinWidth - { - get - { - return minWidth; - } - set - { - ThrowIfFrozen(); + public int? MinSize { get; set; } - minWidth = value; - } - } + public int? MaxSize { get; set; } - public int? MaxWidth - { - get - { - return maxWidth; - } - set - { - ThrowIfFrozen(); + public int? AspectWidth { get; set; } - maxWidth = value; - } - } + public int? AspectHeight { get; set; } - public int? MinHeight - { - get - { - return minHeight; - } - set - { - ThrowIfFrozen(); - - minHeight = value; - } - } - - public int? MaxHeight - { - get - { - return maxHeight; - } - set - { - ThrowIfFrozen(); - - maxHeight = value; - } - } - - public int? MinSize - { - get - { - return minSize; - } - set - { - ThrowIfFrozen(); - - minSize = value; - } - } - - public int? MaxSize - { - get - { - return maxSize; - } - set - { - ThrowIfFrozen(); - - maxSize = value; - } - } - - public int? AspectWidth - { - get - { - return aspectWidth; - } - set - { - ThrowIfFrozen(); - - aspectWidth = value; - } - } - - public int? AspectHeight - { - get - { - return aspectHeight; - } - set - { - ThrowIfFrozen(); - - aspectHeight = value; - } - } - - public ImmutableList AllowedExtensions - { - get - { - return allowedExtensions; - } - set - { - ThrowIfFrozen(); - - allowedExtensions = value; - } - } + public ImmutableList AllowedExtensions { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/BooleanFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/BooleanFieldProperties.cs index 06c2f2fe8..2785eceba 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/BooleanFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/BooleanFieldProperties.cs @@ -12,36 +12,9 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(BooleanField))] public sealed class BooleanFieldProperties : FieldProperties { - private BooleanFieldEditor editor; - private bool? defaultValue; + public bool? DefaultValue { get; set; } - public bool? DefaultValue - { - get - { - return defaultValue; - } - set - { - ThrowIfFrozen(); - - defaultValue = value; - } - } - - public BooleanFieldEditor Editor - { - get - { - return editor; - } - set - { - ThrowIfFrozen(); - - editor = value; - } - } + public BooleanFieldEditor Editor { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/DateTimeFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/DateTimeFieldProperties.cs index 6456e9604..8dcdd85d5 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/DateTimeFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/DateTimeFieldProperties.cs @@ -13,81 +13,15 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(DateTimeField))] public sealed class DateTimeFieldProperties : FieldProperties { - private DateTimeFieldEditor editor; - private DateTimeCalculatedDefaultValue? calculatedDefaultValue; - private Instant? maxValue; - private Instant? minValue; - private Instant? defaultValue; + public Instant? MaxValue { get; set; } - public Instant? MaxValue - { - get - { - return maxValue; - } - set - { - ThrowIfFrozen(); - - maxValue = value; - } - } - - public Instant? MinValue - { - get - { - return minValue; - } - set - { - ThrowIfFrozen(); - - minValue = value; - } - } - - public Instant? DefaultValue - { - get - { - return defaultValue; - } - set - { - ThrowIfFrozen(); - - defaultValue = value; - } - } - - public DateTimeCalculatedDefaultValue? CalculatedDefaultValue - { - get - { - return calculatedDefaultValue; - } - set - { - ThrowIfFrozen(); + public Instant? MinValue { get; set; } - calculatedDefaultValue = value; - } - } + public Instant? DefaultValue { get; set; } - public DateTimeFieldEditor Editor - { - get - { - return editor; - } - set - { - ThrowIfFrozen(); + public DateTimeCalculatedDefaultValue? CalculatedDefaultValue { get; set; } - editor = value; - } - } + public DateTimeFieldEditor Editor { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldProperties.cs index 3c0fc63f2..3820bd6c5 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldProperties.cs @@ -9,51 +9,11 @@ namespace Squidex.Domain.Apps.Core.Schemas { public abstract class FieldProperties : NamedElementPropertiesBase { - private bool isRequired; - private bool isListField; - private string placeholder; + public bool IsRequired { get; set; } - public bool IsRequired - { - get - { - return isRequired; - } - set - { - ThrowIfFrozen(); + public bool IsListField { get; set; } - isRequired = value; - } - } - - public bool IsListField - { - get - { - return isListField; - } - set - { - ThrowIfFrozen(); - - isListField = value; - } - } - - public string Placeholder - { - get - { - return placeholder; - } - set - { - ThrowIfFrozen(); - - placeholder = value; - } - } + public string Placeholder { get; set; } public abstract T Accept(IFieldPropertiesVisitor visitor); diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/GeolocationFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/GeolocationFieldProperties.cs index 985f75b5a..4cc7b239b 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/GeolocationFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/GeolocationFieldProperties.cs @@ -12,21 +12,7 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(GeolocationField))] public sealed class GeolocationFieldProperties : FieldProperties { - private GeolocationFieldEditor editor; - - public GeolocationFieldEditor Editor - { - get - { - return editor; - } - set - { - ThrowIfFrozen(); - - editor = value; - } - } + public GeolocationFieldEditor Editor { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/NamedElementPropertiesBase.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/NamedElementPropertiesBase.cs index f4f1b7497..9b3b92aba 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/NamedElementPropertiesBase.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/NamedElementPropertiesBase.cs @@ -5,41 +5,12 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using Squidex.Infrastructure; - namespace Squidex.Domain.Apps.Core.Schemas { public abstract class NamedElementPropertiesBase : Freezable { - private string label; - private string hints; - - public string Label - { - get - { - return label; - } - set - { - ThrowIfFrozen(); - - label = value; - } - } - - public string Hints - { - get - { - return hints; - } - set - { - ThrowIfFrozen(); + public string Label { get; set; } - hints = value; - } - } + public string Hints { get; set; } } } \ No newline at end of file diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/NumberFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/NumberFieldProperties.cs index cf6107222..8b0b02ec7 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/NumberFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/NumberFieldProperties.cs @@ -13,81 +13,15 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(NumberField))] public sealed class NumberFieldProperties : FieldProperties { - private double? maxValue; - private double? minValue; - private double? defaultValue; - private ImmutableList allowedValues; - private NumberFieldEditor editor; + public double? MaxValue { get; set; } - public double? MaxValue - { - get - { - return maxValue; - } - set - { - ThrowIfFrozen(); - - maxValue = value; - } - } - - public double? MinValue - { - get - { - return minValue; - } - set - { - ThrowIfFrozen(); - - minValue = value; - } - } - - public double? DefaultValue - { - get - { - return defaultValue; - } - set - { - ThrowIfFrozen(); - - defaultValue = value; - } - } - - public ImmutableList AllowedValues - { - get - { - return allowedValues; - } - set - { - ThrowIfFrozen(); + public double? MinValue { get; set; } - allowedValues = value; - } - } + public double? DefaultValue { get; set; } - public NumberFieldEditor Editor - { - get - { - return editor; - } - set - { - ThrowIfFrozen(); + public ImmutableList AllowedValues { get; set; } - editor = value; - } - } + public NumberFieldEditor Editor { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs index 368ec7a2b..cc3740bda 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs @@ -13,51 +13,11 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(ReferencesField))] public sealed class ReferencesFieldProperties : FieldProperties { - private int? minItems; - private int? maxItems; - private Guid schemaId; + public int? MinItems { get; set; } - public int? MinItems - { - get - { - return minItems; - } - set - { - ThrowIfFrozen(); - - minItems = value; - } - } - - public int? MaxItems - { - get - { - return maxItems; - } - set - { - ThrowIfFrozen(); + public int? MaxItems { get; set; } - maxItems = value; - } - } - - public Guid SchemaId - { - get - { - return schemaId; - } - set - { - ThrowIfFrozen(); - - schemaId = value; - } - } + public Guid SchemaId { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs index 1129c646b..1c0313c9e 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs @@ -13,111 +13,19 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(StringField))] public sealed class StringFieldProperties : FieldProperties { - private int? minLength; - private int? maxLength; - private string pattern; - private string patternMessage; - private string defaultValue; - private ImmutableList allowedValues; - private StringFieldEditor editor; + public int? MinLength { get; set; } - public int? MinLength - { - get - { - return minLength; - } - set - { - ThrowIfFrozen(); - - minLength = value; - } - } - - public int? MaxLength - { - get - { - return maxLength; - } - set - { - ThrowIfFrozen(); - - maxLength = value; - } - } - - public string DefaultValue - { - get - { - return defaultValue; - } - set - { - ThrowIfFrozen(); - - defaultValue = value; - } - } + public int? MaxLength { get; set; } - public string Pattern - { - get - { - return pattern; - } - set - { - ThrowIfFrozen(); - - pattern = value; - } - } + public string DefaultValue { get; set; } - public string PatternMessage - { - get - { - return patternMessage; - } - set - { - ThrowIfFrozen(); + public string Pattern { get; set; } - patternMessage = value; - } - } + public string PatternMessage { get; set; } - public ImmutableList AllowedValues - { - get - { - return allowedValues; - } - set - { - ThrowIfFrozen(); + public ImmutableList AllowedValues { get; set; } - allowedValues = value; - } - } - - public StringFieldEditor Editor - { - get - { - return editor; - } - set - { - ThrowIfFrozen(); - - editor = value; - } - } + public StringFieldEditor Editor { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Schemas/TagsFieldProperties.cs b/src/Squidex.Domain.Apps.Core.Model/Schemas/TagsFieldProperties.cs index ab4e3b305..a87e2fd44 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Schemas/TagsFieldProperties.cs +++ b/src/Squidex.Domain.Apps.Core.Model/Schemas/TagsFieldProperties.cs @@ -12,36 +12,9 @@ namespace Squidex.Domain.Apps.Core.Schemas [TypeName(nameof(TagsField))] public sealed class TagsFieldProperties : FieldProperties { - private int? minItems; - private int? maxItems; + public int? MinItems { get; set; } - public int? MinItems - { - get - { - return minItems; - } - set - { - ThrowIfFrozen(); - - minItems = value; - } - } - - public int? MaxItems - { - get - { - return maxItems; - } - set - { - ThrowIfFrozen(); - - maxItems = value; - } - } + public int? MaxItems { get; set; } public override T Accept(IFieldPropertiesVisitor visitor) { diff --git a/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj b/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj index 701e56aa9..91ab5c926 100644 --- a/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj +++ b/src/Squidex.Domain.Apps.Core.Model/Squidex.Domain.Apps.Core.Model.csproj @@ -8,6 +8,8 @@ True + + diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs new file mode 100644 index 000000000..92e28ba1b --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/AzureQueueActionHandler.cs @@ -0,0 +1,72 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using Microsoft.WindowsAzure.Storage; +using Microsoft.WindowsAzure.Storage.Queue; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Squidex.Domain.Apps.Core.Rules; +using Squidex.Domain.Apps.Core.Rules.Actions; +using Squidex.Domain.Apps.Events; +using Squidex.Infrastructure; +using Squidex.Infrastructure.EventSourcing; + +namespace Squidex.Domain.Apps.Core.HandleRules.Actions +{ + public sealed class AzureQueueActionHandler : RuleActionHandler + { + private readonly ConcurrentDictionary<(string ConnectionString, string QueueName), CloudQueue> queues = new ConcurrentDictionary<(string ConnectionString, string QueueName), CloudQueue>(); + private readonly RuleEventFormatter formatter; + + public AzureQueueActionHandler(RuleEventFormatter formatter) + { + Guard.NotNull(formatter, nameof(formatter)); + + this.formatter = formatter; + } + + protected override (string Description, RuleJobData Data) CreateJob(Envelope @event, string eventName, AzureQueueAction action) + { + var body = formatter.ToRouteData(@event, eventName); + + var ruleDescription = $"Send event to azure queue '{action.Queue}'"; + var ruleData = new RuleJobData + { + ["QueueConnectionString"] = action.ConnectionString, + ["QueueName"] = action.Queue, + ["MessageBody"] = body + }; + + return (ruleDescription, ruleData); + } + + public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job) + { + var queueConnectionString = job["QueueConnectionString"].Value(); + var queueName = job["QueueName"].Value(); + + var queue = queues.GetOrAdd((queueConnectionString, queueName), s => + { + var storageAccount = CloudStorageAccount.Parse(queueConnectionString); + + var queueClient = storageAccount.CreateCloudQueueClient(); + var queueRef = queueClient.GetQueueReference(queueName); + + return queueRef; + }); + + var messageBody = job["MessageBody"].ToString(Formatting.Indented); + + await queue.AddMessageAsync(new CloudQueueMessage(messageBody)); + + return ("Completed", null); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs index 9899c5a2e..dc10c3afd 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/SlackActionHandler.cs @@ -49,31 +49,30 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions private JObject CreatePayload(Envelope @event, string text) { - return new JObject( - new JProperty("text", formatter.FormatString(text, @event))); + return new JObject(new JProperty("text", formatter.FormatString(text, @event))); } public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job) { var requestBody = job["RequestBody"].ToString(Formatting.Indented); - var request = BuildRequest(job, requestBody); + var requestMsg = BuildRequest(job, requestBody); HttpResponseMessage response = null; try { - response = await Client.SendAsync(request); + response = await Client.SendAsync(requestMsg); var responseString = await response.Content.ReadAsStringAsync(); - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, responseString, TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, responseString, TimeSpan.Zero, false); return (requestDump, null); } catch (Exception ex) { - if (request != null) + if (requestMsg != null) { - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, ex.ToString(), TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, ex.ToString(), TimeSpan.Zero, false); return (requestDump, ex); } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs index 88baca09f..bb0d00cbd 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/Actions/WebhookActionHandler.cs @@ -35,11 +35,11 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions protected override (string Description, RuleJobData Data) CreateJob(Envelope @event, string eventName, WebhookAction action) { - var body = CreatePayload(@event, eventName); + var body = formatter.ToRouteData(@event, eventName); var signature = $"{body.ToString(Formatting.Indented)}{action.SharedSecret}".Sha256Base64(); - var ruleDescription = $"Send event to webhook {action.Url}"; + var ruleDescription = $"Send event to webhook '{action.Url}'"; var ruleData = new RuleJobData { ["RequestUrl"] = action.Url, @@ -50,18 +50,10 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions return (ruleDescription, ruleData); } - private JObject CreatePayload(Envelope @event, string eventName) - { - return new JObject( - new JProperty("type", eventName), - new JProperty("payload", formatter.ToRouteData(@event.Payload)), - new JProperty("timestamp", @event.Headers.Timestamp().ToString())); - } - public override async Task<(string Dump, Exception Exception)> ExecuteJobAsync(RuleJobData job) { var requestBody = job["RequestBody"].ToString(Formatting.Indented); - var request = BuildRequest(job, requestBody); + var requestMsg = BuildRequest(job, requestBody); HttpResponseMessage response = null; @@ -69,19 +61,19 @@ namespace Squidex.Domain.Apps.Core.HandleRules.Actions { using (var client = new HttpClient { Timeout = Timeout }) { - response = await client.SendAsync(request); + response = await client.SendAsync(requestMsg); var responseString = await response.Content.ReadAsStringAsync(); - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, responseString, TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, responseString, TimeSpan.Zero, false); return (requestDump, null); } } catch (Exception ex) { - if (request != null) + if (requestMsg != null) { - var requestDump = DumpFormatter.BuildDump(request, response, requestBody, ex.ToString(), TimeSpan.Zero, false); + var requestDump = DumpFormatter.BuildDump(requestMsg, response, requestBody, ex.ToString(), TimeSpan.Zero, false); return (requestDump, ex); } diff --git a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs index 9b0d70043..0e64960f9 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs +++ b/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleEventFormatter.cs @@ -43,6 +43,14 @@ namespace Squidex.Domain.Apps.Core.HandleRules return JToken.FromObject(value, serializer); } + public virtual JToken ToRouteData(Envelope @event, string eventName) + { + return new JObject( + new JProperty("type", eventName), + new JProperty("payload", JToken.FromObject(@event.Payload, serializer)), + new JProperty("timestamp", @event.Headers.Timestamp().ToString())); + } + public virtual string FormatString(string text, Envelope @event) { var sb = new StringBuilder(text); diff --git a/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj b/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj index 631f0b094..8a5057653 100644 --- a/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj +++ b/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj @@ -23,6 +23,7 @@ + ..\..\Squidex.ruleset diff --git a/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs b/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs index b2801f751..7cb300d54 100644 --- a/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs +++ b/src/Squidex.Domain.Apps.Entities/Rules/Guards/RuleActionValidator.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Collections.Generic; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules.Actions; @@ -46,6 +47,27 @@ namespace Squidex.Domain.Apps.Entities.Rules.Guards return Task.FromResult>(errors); } + public Task> Visit(AzureQueueAction action) + { + var errors = new List(); + + if (string.IsNullOrWhiteSpace(action.ConnectionString)) + { + errors.Add(new ValidationError("Connection string must be defined.", nameof(action.ConnectionString))); + } + + if (string.IsNullOrWhiteSpace(action.Queue)) + { + errors.Add(new ValidationError("Queue must be defined.", nameof(action.Queue))); + } + else if (!Regex.IsMatch(action.Queue, "^[a-z][a-z0-9]{2,}(\\-[a-z0-9]+)*$")) + { + errors.Add(new ValidationError("Queue must be valid azure queue name.", nameof(action.Queue))); + } + + return Task.FromResult>(errors); + } + public Task> Visit(SlackAction action) { var errors = new List(); diff --git a/src/Squidex.Infrastructure/IFreezable.cs b/src/Squidex.Infrastructure/IFreezable.cs new file mode 100644 index 000000000..c7095fccd --- /dev/null +++ b/src/Squidex.Infrastructure/IFreezable.cs @@ -0,0 +1,14 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Infrastructure +{ + public interface IFreezable + { + void Freeze(); + } +} diff --git a/src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs b/src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs new file mode 100644 index 000000000..bfcafb1ac --- /dev/null +++ b/src/Squidex/Areas/Api/Controllers/Rules/Models/Actions/AzureQueueActionDto.cs @@ -0,0 +1,36 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.ComponentModel.DataAnnotations; +using NJsonSchema.Annotations; +using Squidex.Domain.Apps.Core.Rules; +using Squidex.Domain.Apps.Core.Rules.Actions; +using Squidex.Infrastructure.Reflection; + +namespace Squidex.Areas.Api.Controllers.Rules.Models.Actions +{ + [JsonSchema("AzureQueue")] + public class AzureQueueActionDto : RuleActionDto + { + /// + /// The connection string to the storage account. + /// + [Required] + public string ConnectionString { get; set; } + + /// + /// The queue name. + /// + [Required] + public string Queue { get; set; } + + public override RuleAction ToAction() + { + return SimpleMapper.Map(this, new AzureQueueAction()); + } + } +} diff --git a/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs b/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs index 1d3ab43b2..6fee353e9 100644 --- a/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs +++ b/src/Squidex/Areas/Api/Controllers/Rules/Models/Converters/RuleActionDtoFactory.cs @@ -30,6 +30,11 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models.Converters return SimpleMapper.Map(action, new AlgoliaActionDto()); } + public RuleActionDto Visit(AzureQueueAction action) + { + return SimpleMapper.Map(action, new AzureQueueActionDto()); + } + public RuleActionDto Visit(SlackAction action) { return SimpleMapper.Map(action, new SlackActionDto()); diff --git a/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs b/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs index 21b9cc39b..7a6643d18 100644 --- a/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionDto.cs @@ -14,6 +14,7 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models { [JsonConverter(typeof(JsonInheritanceConverter), "actionType")] [KnownType(typeof(AlgoliaActionDto))] + [KnownType(typeof(AzureQueueActionDto))] [KnownType(typeof(SlackActionDto))] [KnownType(typeof(WebhookActionDto))] public abstract class RuleActionDto diff --git a/src/Squidex/Config/Domain/ReadServices.cs b/src/Squidex/Config/Domain/ReadServices.cs index 1a24fedd5..d6e8e4979 100644 --- a/src/Squidex/Config/Domain/ReadServices.cs +++ b/src/Squidex/Config/Domain/ReadServices.cs @@ -98,6 +98,9 @@ namespace Squidex.Config.Domain services.AddSingletonAs() .As(); + services.AddSingletonAs() + .As(); + services.AddSingletonAs() .As(); diff --git a/src/Squidex/app/features/rules/declarations.ts b/src/Squidex/app/features/rules/declarations.ts index 815788500..e4ead5d30 100644 --- a/src/Squidex/app/features/rules/declarations.ts +++ b/src/Squidex/app/features/rules/declarations.ts @@ -6,6 +6,7 @@ */ export * from './pages/rules/actions/algolia-action.component'; +export * from './pages/rules/actions/azure-queue-action.component'; export * from './pages/rules/actions/slack-action.component'; export * from './pages/rules/actions/webhook-action.component'; export * from './pages/rules/triggers/content-changed-trigger.component'; diff --git a/src/Squidex/app/features/rules/module.ts b/src/Squidex/app/features/rules/module.ts index d9630a213..6a95936fb 100644 --- a/src/Squidex/app/features/rules/module.ts +++ b/src/Squidex/app/features/rules/module.ts @@ -16,6 +16,7 @@ import { import { AlgoliaActionComponent, + AzureQueueActionComponent, ContentChangedTriggerComponent, RuleEventsPageComponent, RulesPageComponent, @@ -52,6 +53,7 @@ const routes: Routes = [ ], declarations: [ AlgoliaActionComponent, + AzureQueueActionComponent, ContentChangedTriggerComponent, RuleEventsPageComponent, RulesPageComponent, diff --git a/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html index f7e39f603..8e9594229 100644 --- a/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html +++ b/src/Squidex/app/features/rules/pages/rules/actions/algolia-action.component.html @@ -1,8 +1,8 @@
- + -
+
@@ -14,9 +14,9 @@
- + -
+
@@ -28,9 +28,9 @@
- + -
+
diff --git a/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html new file mode 100644 index 000000000..0a5a6831d --- /dev/null +++ b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.html @@ -0,0 +1,29 @@ + +
+ + +
+ + + + + + The connection string to the storage account. + +
+
+ +
+ + +
+ + + + + + The name of the queue. + +
+
+ \ No newline at end of file diff --git a/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss new file mode 100644 index 000000000..fbb752506 --- /dev/null +++ b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.scss @@ -0,0 +1,2 @@ +@import '_vars'; +@import '_mixins'; \ No newline at end of file diff --git a/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts new file mode 100644 index 000000000..0556f59a1 --- /dev/null +++ b/src/Squidex/app/features/rules/pages/rules/actions/azure-queue-action.component.ts @@ -0,0 +1,61 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { FormBuilder, Validators } from '@angular/forms'; + +import { ValidatorsEx } from 'shared'; + +@Component({ + selector: 'sqx-azure-queue-action', + styleUrls: ['./azure-queue-action.component.scss'], + templateUrl: './azure-queue-action.component.html' +}) +export class AzureQueueActionComponent implements OnInit { + @Input() + public action: any; + + @Output() + public actionChanged = new EventEmitter(); + + public actionFormSubmitted = false; + public actionForm = + this.formBuilder.group({ + connectionString: ['', + [ + Validators.required + ]], + queue: ['squidex', + [ + Validators.required, + ValidatorsEx.pattern('[a-z][a-z0-9]{2,}(\-[a-z0-9]+)*', 'Name must be a valid azure queue name.') + ]] + }); + + constructor( + private readonly formBuilder: FormBuilder + ) { + } + + public ngOnInit() { + this.action = Object.assign({}, { connectionString: '', queue: 'squidex' }, this.action || {}); + + this.actionFormSubmitted = false; + this.actionForm.reset(); + this.actionForm.setValue(this.action); + } + + public save() { + this.actionFormSubmitted = true; + + if (this.actionForm.valid) { + const action = this.actionForm.value; + + this.actionChanged.emit(action); + } + } +} \ No newline at end of file diff --git a/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html index 4a278f6aa..37c237b09 100644 --- a/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html +++ b/src/Squidex/app/features/rules/pages/rules/actions/slack-action.component.html @@ -1,8 +1,8 @@
- + -
+
@@ -14,9 +14,9 @@
- + -
+
diff --git a/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html b/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html index b643d8cef..f85e3b298 100644 --- a/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html +++ b/src/Squidex/app/features/rules/pages/rules/actions/webhook-action.component.html @@ -1,8 +1,8 @@
- + -
+
@@ -14,9 +14,9 @@
- + -
+
diff --git a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html index cb1d67acf..77cad1927 100644 --- a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html +++ b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.html @@ -68,6 +68,12 @@ (actionChanged)="selectAction($event)">
+
+ + +
+
+
+ + + + icon-action-AzureQueue +
+
+ + +
+
+ liga: + +
+
diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.eot b/src/Squidex/app/theme/icomoon/fonts/icomoon.eot index 1430ee463..af30e1e79 100644 Binary files a/src/Squidex/app/theme/icomoon/fonts/icomoon.eot and b/src/Squidex/app/theme/icomoon/fonts/icomoon.eot differ diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.svg b/src/Squidex/app/theme/icomoon/fonts/icomoon.svg index 068a00b7a..b87ca2593 100644 --- a/src/Squidex/app/theme/icomoon/fonts/icomoon.svg +++ b/src/Squidex/app/theme/icomoon/fonts/icomoon.svg @@ -71,7 +71,7 @@ - + diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.ttf b/src/Squidex/app/theme/icomoon/fonts/icomoon.ttf index e279c01a1..7bcee5687 100644 Binary files a/src/Squidex/app/theme/icomoon/fonts/icomoon.ttf and b/src/Squidex/app/theme/icomoon/fonts/icomoon.ttf differ diff --git a/src/Squidex/app/theme/icomoon/fonts/icomoon.woff b/src/Squidex/app/theme/icomoon/fonts/icomoon.woff index d2f1d0936..0eb4b5199 100644 Binary files a/src/Squidex/app/theme/icomoon/fonts/icomoon.woff and b/src/Squidex/app/theme/icomoon/fonts/icomoon.woff differ diff --git a/src/Squidex/app/theme/icomoon/selection.json b/src/Squidex/app/theme/icomoon/selection.json index 4392c15c9..af9b52817 100644 --- a/src/Squidex/app/theme/icomoon/selection.json +++ b/src/Squidex/app/theme/icomoon/selection.json @@ -2121,7 +2121,7 @@ "id": 1, "prevSize": 32, "code": 59712, - "name": "microsoft" + "name": "microsoft, action-AzureQueue" }, "setIdx": 2, "setId": 1, diff --git a/src/Squidex/app/theme/icomoon/style.css b/src/Squidex/app/theme/icomoon/style.css index 5a9cd9d98..435cb8160 100644 --- a/src/Squidex/app/theme/icomoon/style.css +++ b/src/Squidex/app/theme/icomoon/style.css @@ -1,10 +1,10 @@ @font-face { font-family: 'icomoon'; - src: url('fonts/icomoon.eot?fb43dg'); - src: url('fonts/icomoon.eot?fb43dg#iefix') format('embedded-opentype'), - url('fonts/icomoon.ttf?fb43dg') format('truetype'), - url('fonts/icomoon.woff?fb43dg') format('woff'), - url('fonts/icomoon.svg?fb43dg#icomoon') format('svg'); + src: url('fonts/icomoon.eot?knmn0p'); + src: url('fonts/icomoon.eot?knmn0p#iefix') format('embedded-opentype'), + url('fonts/icomoon.ttf?knmn0p') format('truetype'), + url('fonts/icomoon.woff?knmn0p') format('woff'), + url('fonts/icomoon.svg?knmn0p#icomoon') format('svg'); font-weight: normal; font-style: normal; } @@ -265,6 +265,9 @@ .icon-microsoft:before { content: "\e940"; } +.icon-action-AzureQueue:before { + content: "\e940"; +} .icon-pause:before { content: "\e92f"; } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs index 1eee35983..fe0dfac5a 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Rules/RuleTests.cs @@ -6,6 +6,8 @@ // ========================================================================== using System; +using System.Collections.Generic; +using System.Linq; using FluentAssertions; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -21,6 +23,21 @@ namespace Squidex.Domain.Apps.Core.Model.Rules public class RuleTests { private readonly JsonSerializer serializer = TestData.DefaultSerializer(); + + public static readonly List Actions = + typeof(Rule).Assembly.GetTypes() + .Where(x => x.BaseType == typeof(RuleAction)) + .Select(Activator.CreateInstance) + .Select(x => new object[] { x }) + .ToList(); + + public static readonly List Triggers = + typeof(Rule).Assembly.GetTypes() + .Where(x => x.BaseType == typeof(RuleTrigger)) + .Select(Activator.CreateInstance) + .Select(x => new object[] { x }) + .ToList(); + private readonly Rule rule_0 = new Rule(new ContentChangedTrigger(), new WebhookAction()); public sealed class OtherTrigger : RuleTrigger @@ -117,16 +134,18 @@ namespace Squidex.Domain.Apps.Core.Model.Rules appClients.ShouldBeEquivalentTo(rule_0); } - [Fact] - public void Should_freeze_webhook_action() + [Theory] + [MemberData(nameof(Actions))] + public void Should_freeze_actions(RuleAction action) { - TestData.TestFreeze(new WebhookAction()); + TestData.TestFreeze(action); } - [Fact] - public void Should_freeze_contentchanged_trigger() + [Theory] + [MemberData(nameof(Triggers))] + public void Should_freeze_triggers(RuleTrigger trigger) { - TestData.TestFreeze(new ContentChangedTrigger()); + TestData.TestFreeze(trigger); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaFieldTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaFieldTests.cs index 4f267a407..4360b5673 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaFieldTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaFieldTests.cs @@ -6,6 +6,8 @@ // ========================================================================== using System; +using System.Collections.Generic; +using System.Linq; using Squidex.Domain.Apps.Core.Schemas; using Xunit; @@ -15,6 +17,13 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas { public class SchemaFieldTests { + public static readonly List FieldProperties = + typeof(Schema).Assembly.GetTypes() + .Where(x => x.BaseType == typeof(FieldProperties)) + .Select(Activator.CreateInstance) + .Select(x => new object[] { x }) + .ToList(); + private readonly NumberField field_0 = new NumberField(1, "my-field", Partitioning.Invariant); [Fact] @@ -97,58 +106,11 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas Assert.Throws(() => field_0.Update(new StringFieldProperties())); } - [Fact] - public void Should_freeze_asset_field_properties() - { - TestData.TestFreeze(new AssetsFieldProperties()); - } - - [Fact] - public void Should_freeze_boolean_field_properties() - { - TestData.TestFreeze(new BooleanFieldProperties()); - } - - [Fact] - public void Should_freeze_datetime_field_properties() - { - TestData.TestFreeze(new DateTimeFieldProperties()); - } - - [Fact] - public void Should_freeze_geolocation_field_properties() - { - TestData.TestFreeze(new GeolocationFieldProperties()); - } - - [Fact] - public void Should_freeze_json_field_properties() - { - TestData.TestFreeze(new JsonFieldProperties()); - } - - [Fact] - public void Should_freeze_number_field_properties() - { - TestData.TestFreeze(new NumberFieldProperties()); - } - - [Fact] - public void Should_freeze_references_field_properties() - { - TestData.TestFreeze(new ReferencesFieldProperties()); - } - - [Fact] - public void Should_freeze_string_field_properties() - { - TestData.TestFreeze(new StringFieldProperties()); - } - - [Fact] - public void Should_freeze_tags_field_properties() + [Theory] + [MemberData(nameof(FieldProperties))] + public void Should_freeze_field_properties(FieldProperties action) { - TestData.TestFreeze(new TagsFieldProperties()); + TestData.TestFreeze(action); } } } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs index 65f272f9e..ef38ea0c5 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Schemas/SchemaTests.cs @@ -26,7 +26,6 @@ namespace Squidex.Domain.Apps.Core.Model.Schemas [Fact] public void Should_instantiate_schema() { - Assert.True(schema_0.Properties.IsFrozen); Assert.Equal("my-schema", schema_0.Name); } diff --git a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs index a4bc9a133..988a2d483 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs @@ -101,7 +101,7 @@ namespace Squidex.Domain.Apps.Core return schema; } - public static void TestFreeze(Freezable freezable) + public static void TestFreeze(IFreezable freezable) { var sut = new AssetsFieldProperties(); diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Actions/AzureQueueActionTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Actions/AzureQueueActionTests.cs new file mode 100644 index 000000000..1569a7ada --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Actions/AzureQueueActionTests.cs @@ -0,0 +1,56 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Threading.Tasks; +using Squidex.Domain.Apps.Core.Rules.Actions; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Rules.Guards.Actions +{ + public sealed class AzureQueueActionTests + { + [Fact] + public async Task Should_add_error_if_connection_string_is_null() + { + var action = new AzureQueueAction { ConnectionString = null, Queue = "squidex" }; + + var errors = await RuleActionValidator.ValidateAsync(action); + + Assert.NotEmpty(errors); + } + + [Fact] + public async Task Should_add_error_if_queue_is_null() + { + var action = new AzureQueueAction { ConnectionString = "connection", Queue = null }; + + var errors = await RuleActionValidator.ValidateAsync(action); + + Assert.NotEmpty(errors); + } + + [Fact] + public async Task Should_add_error_if_queue_is_invalid() + { + var action = new AzureQueueAction { ConnectionString = "connection", Queue = "Squidex" }; + + var errors = await RuleActionValidator.ValidateAsync(action); + + Assert.NotEmpty(errors); + } + + [Fact] + public async Task Should_not_add_error_if_values_are_valid() + { + var action = new AzureQueueAction { ConnectionString = "connection", Queue = "squidex" }; + + var errors = await RuleActionValidator.ValidateAsync(action); + + Assert.Empty(errors); + } + } +}