public async Task Should_create_events_from_snapshots_with_schema_ids()
        {
            var trigger = new ContentChangedTriggerV2
            {
                Schemas = ReadonlyList.Create(
                    new ContentChangedTriggerSchemaV2
                {
                    SchemaId = schemaMatch.Id
                })
            };

            var ctx = Context(trigger);

            A.CallTo(() => contentRepository.StreamAll(ctx.AppId.Id, A <HashSet <DomainId> > .That.Is(schemaMatch.Id), default))
            .Returns(new List <ContentEntity>
            {
                new ContentEntity {
                    SchemaId = schemaMatch
                },
                new ContentEntity {
                    SchemaId = schemaMatch
                }
            }.ToAsyncEnumerable());

            var result = await sut.CreateSnapshotEventsAsync(ctx, default).ToListAsync();

            var typed = result.OfType <EnrichedContentEvent>().ToList();

            Assert.Equal(2, typed.Count);
            Assert.Equal(2, typed.Count(x => x.Type == EnrichedContentEventType.Created));
        }
        private void TestForTrigger(bool handleAll, NamedId <DomainId>?schemaId, string?condition, Action <RuleContext> action)
        {
            var trigger = new ContentChangedTriggerV2 {
                HandleAll = handleAll
            };

            if (schemaId != null)
            {
                trigger = trigger with
                {
                    Schemas = ReadonlyList.Create(
                        new ContentChangedTriggerSchemaV2
                    {
                        SchemaId  = schemaId.Id,
                        Condition = condition
                    })
                };
            }

            action(Context(trigger));

            if (string.IsNullOrWhiteSpace(condition))
            {
                A.CallTo(() => scriptEngine.Evaluate(A <ScriptVars> ._, A <string> ._, default))
                .MustNotHaveHappened();
            }
            else
            {
                A.CallTo(() => scriptEngine.Evaluate(A <ScriptVars> ._, condition, default))
                .MustHaveHappened();
            }
        }
예제 #3
0
        static TestSchemas()
        {
            Ref1 = Mocks.Schema(TestApp.DefaultId, Ref1Id,
                                new Schema(Ref1Id.Name)
                                .Publish()
                                .AddString(1, "schemaRef1Field", Partitioning.Invariant));

            Ref2 = Mocks.Schema(TestApp.DefaultId, Ref2Id,
                                new Schema(Ref2Id.Name)
                                .Publish()
                                .AddString(1, "schemaRef2Field", Partitioning.Invariant));

            Default = Mocks.Schema(TestApp.DefaultId, DefaultId,
                                   new Schema(DefaultId.Name)
                                   .Publish()
                                   .AddJson(1, "my-json", Partitioning.Invariant,
                                            new JsonFieldProperties())
                                   .AddString(2, "my-string", Partitioning.Invariant,
                                              new StringFieldProperties())
                                   .AddString(3, "my-localized-string", Partitioning.Language,
                                              new StringFieldProperties())
                                   .AddNumber(4, "my-number", Partitioning.Invariant,
                                              new NumberFieldProperties())
                                   .AddAssets(5, "my-assets", Partitioning.Invariant,
                                              new AssetsFieldProperties())
                                   .AddBoolean(6, "my-boolean", Partitioning.Invariant,
                                               new BooleanFieldProperties())
                                   .AddDateTime(7, "my-datetime", Partitioning.Invariant,
                                                new DateTimeFieldProperties())
                                   .AddReferences(8, "my-references", Partitioning.Invariant,
                                                  new ReferencesFieldProperties {
                SchemaId = Ref1Id.Id
            })
                                   .AddReferences(9, "my-union", Partitioning.Invariant,
                                                  new ReferencesFieldProperties())
                                   .AddGeolocation(10, "my-geolocation", Partitioning.Invariant,
                                                   new GeolocationFieldProperties())
                                   .AddComponent(11, "my-component", Partitioning.Invariant,
                                                 new ComponentFieldProperties {
                SchemaId = Ref1Id.Id
            })
                                   .AddComponents(12, "my-components", Partitioning.Invariant,
                                                  new ComponentsFieldProperties {
                SchemaIds = ReadonlyList.Create(Ref1.Id, Ref2.Id)
            })
                                   .AddTags(13, "my-tags", Partitioning.Invariant,
                                            new TagsFieldProperties())
                                   .AddArray(100, "my-array", Partitioning.Invariant, f => f
                                             .AddBoolean(121, "nested-boolean",
                                                         new BooleanFieldProperties())
                                             .AddNumber(122, "nested-number",
                                                        new NumberFieldProperties()))
                                   .SetScripts(new SchemaScripts {
                Query = "<query-script>"
            }));
        }
예제 #4
0
        public async Task Should_not_add_error_if_value_has_not_duplicates()
        {
            var sut = Field(new ArrayFieldProperties {
                UniqueFields = ReadonlyList.Create("myString")
            });

            await sut.ValidateAsync(CreateValue(Object("myString", "1"), Object("myString", "2")), errors);

            Assert.Empty(errors);
        }
예제 #5
0
        public void Should_not_add_error_if_inline_editing_is_allowed_for_editor(NumberFieldEditor editor)
        {
            var sut = new NumberFieldProperties {
                InlineEditable = true, Editor = editor, AllowedValues = ReadonlyList.Create(1.0)
            };

            var errors = FieldPropertiesValidator.Validate(sut).ToList();

            Assert.Empty(errors);
        }
예제 #6
0
        public async Task Should_add_error_if_value_has_no_discriminator()
        {
            var(_, sut, components) = Field(new ComponentFieldProperties {
                SchemaIds = ReadonlyList.Create(schemaId1, schemaId2)
            });

            await sut.ValidateAsync(CreateValue(null, "field", 1), errors, components : components);

            errors.Should().BeEquivalentTo(
                new[] { "Invalid component. No 'schemaId' field found." });
        }
예제 #7
0
        public async Task Should_add_error_if_value_has_duplicates()
        {
            var(id, sut, components) = Field(new ComponentsFieldProperties {
                UniqueFields = ReadonlyList.Create("componentField")
            });

            await sut.ValidateAsync(CreateValue(2, id.ToString(), "componentField", 1), errors, components : components);

            errors.Should().BeEquivalentTo(
                new[] { "Must not contain items with duplicate 'componentField' fields." });
        }
예제 #8
0
        public async Task Should_add_error_if_value_contains_an_not_allowed_values()
        {
            var sut = Field(new TagsFieldProperties {
                AllowedValues = ReadonlyList.Create("tag-2", "tag-3")
            });

            await sut.ValidateAsync(CreateValue("tag-1", "tag-2", null), errors);

            errors.Should().BeEquivalentTo(
                new[] { "[1]: Not an allowed value." });
        }
예제 #9
0
        public async Task Should_add_error_if_string_not_allowed()
        {
            var sut = Field(new StringFieldProperties {
                AllowedValues = ReadonlyList.Create("Foo")
            });

            await sut.ValidateAsync(CreateValue("Bar"), errors);

            errors.Should().BeEquivalentTo(
                new[] { "Not an allowed value." });
        }
예제 #10
0
        public async Task Should_add_error_if_value_has_duplicates()
        {
            var sut = Field(new ArrayFieldProperties {
                UniqueFields = ReadonlyList.Create("myString")
            });

            await sut.ValidateAsync(CreateValue(Object("myString", "1"), Object("myString", "1")), errors);

            errors.Should().BeEquivalentTo(
                new[] { "Must not contain items with duplicate 'myString' fields." });
        }
예제 #11
0
        public async Task Should_add_error_if_number_is_not_allowed()
        {
            var sut = Field(new NumberFieldProperties {
                AllowedValues = ReadonlyList.Create(10d)
            });

            await sut.ValidateAsync(CreateValue(20), errors);

            errors.Should().BeEquivalentTo(
                new[] { "Not an allowed value." });
        }
예제 #12
0
 public LanguageConfig ToSource()
 {
     if (!IsOptional && (Fallback == null || Fallback.Length == 0))
     {
         return(LanguageConfig.Default);
     }
     else
     {
         return(new LanguageConfig(IsOptional, ReadonlyList.Create(Fallback)));
     }
 }
예제 #13
0
        public void Should_add_error_if_inline_editing_is_not_allowed_for_editor(StringFieldEditor editor)
        {
            var sut = new StringFieldProperties {
                InlineEditable = true, Editor = editor, AllowedValues = ReadonlyList.Create("Value")
            };

            var errors = FieldPropertiesValidator.Validate(sut).ToList();

            errors.Should().BeEquivalentTo(
                new List <ValidationError>
            {
                new ValidationError("Inline editing is only allowed for dropdowns, slugs and input fields.", "InlineEditable", "Editor")
            });
        }
예제 #14
0
        public void Should_update_language()
        {
            var config_1 = config_0.Set(Language.IT);
            var config_2 = config_1.Set(Language.IT, true, Language.EN);

            config_2.Languages.Should().BeEquivalentTo(
                new Dictionary <string, LanguageConfig>
            {
                [Language.EN] = new LanguageConfig(),
                [Language.IT] = new LanguageConfig(true, ReadonlyList.Create(Language.EN))
            });

            Assert.Equal(Language.EN, config_2.Master);
        }
예제 #15
0
        public void Should_add_error_if_inline_editing_is_not_allowed_for_editor(NumberFieldEditor editor)
        {
            var sut = new NumberFieldProperties {
                InlineEditable = true, Editor = editor, AllowedValues = ReadonlyList.Create(1.0)
            };

            var errors = FieldPropertiesValidator.Validate(sut).ToList();

            errors.Should().BeEquivalentTo(
                new List <ValidationError>
            {
                new ValidationError("Inline editing is not allowed for Radio editor.", "InlineEditable", "Editor")
            });
        }
예제 #16
0
        public void CanUpdateSettings_should_not_throw_exception_if_setting_is_valid()
        {
            var command = new UpdateAppSettings
            {
                Settings = new AppSettings
                {
                    Patterns = ReadonlyList.Create(
                        new Pattern("name", "[a-z]")),
                    Editors = ReadonlyList.Create(
                        new Editor("name", "url/to/editor"))
                }
            };

            GuardApp.CanUpdateSettings(command);
        }
예제 #17
0
        public async Task Should_add_error_if_image_has_invalid_extension()
        {
            var sut = Validator(new AssetsFieldProperties {
                AllowedExtensions = ReadonlyList.Create("mp4")
            });

            await sut.ValidateAsync(CreateValue(Document.AssetId, Image1.AssetId), errors);

            errors.Should().BeEquivalentTo(
                new[]
            {
                "[1]: Must be an allowed extension.",
                "[2]: Must be an allowed extension."
            });
        }
예제 #18
0
        public void Should_eliminate_invalid_fallbacks_and_self()
        {
            var config_1 = config_0.Set(Language.IT);
            var config_2 = config_1.Set(Language.IT);
            var config_3 = config_2.Set(Language.IT, true, Language.EN, Language.IT, Language.DE);

            config_3.Languages.Should().BeEquivalentTo(
                new Dictionary <string, LanguageConfig>
            {
                [Language.EN] = new LanguageConfig(),
                [Language.IT] = new LanguageConfig(true, ReadonlyList.Create(Language.EN))
            });

            Assert.Equal(Language.EN, config_2.Master);
        }
예제 #19
0
        public async Task Should_not_add_error_if_schemas_ids_are_valid()
        {
            A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A <DomainId> ._, false, default))
            .Returns(Mocks.Schema(appId, schemaId));

            var trigger = new ContentChangedTriggerV2
            {
                Schemas = ReadonlyList.Create(new ContentChangedTriggerSchemaV2 {
                    SchemaId = schemaId.Id
                })
            };

            var errors = await RuleTriggerValidator.ValidateAsync(appId.Id, trigger, appProvider);

            Assert.Empty(errors);
        }
예제 #20
0
        public async Task Should_add_error_if_schema_id_is_not_defined()
        {
            var trigger = new ContentChangedTriggerV2
            {
                Schemas = ReadonlyList.Create(new ContentChangedTriggerSchemaV2())
            };

            var errors = await RuleTriggerValidator.ValidateAsync(appId.Id, trigger, appProvider);

            errors.Should().BeEquivalentTo(
                new List <ValidationError>
            {
                new ValidationError("Schema ID is required.", "Schemas")
            });

            A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A <DomainId> ._, false, default))
            .MustNotHaveHappened();
        }
예제 #21
0
        public DynamicContentWorkflowTests()
        {
            app = Mocks.App(appId);

            var simpleWorkflow = new Workflow(
                Status.Draft,
                new Dictionary <Status, WorkflowStep>
            {
                [Status.Draft] =
                    new WorkflowStep(
                        new Dictionary <Status, WorkflowTransition>
                {
                    [Status.Published] = WorkflowTransition.Always
                }.ToReadonlyDictionary(),
                        StatusColors.Draft),
                [Status.Published] =
                    new WorkflowStep(
                        new Dictionary <Status, WorkflowTransition>
                {
                    [Status.Draft] = WorkflowTransition.Always
                }.ToReadonlyDictionary(),
                        StatusColors.Published)
            }.ToReadonlyDictionary(),
                ReadonlyList.Create(simpleSchemaId.Id));

            var workflows = Workflows.Empty.Set(workflow).Set(DomainId.NewGuid(), simpleWorkflow);

            A.CallTo(() => appProvider.GetAppAsync(appId.Id, false, default))
            .Returns(app);

            A.CallTo(() => app.Workflows)
            .Returns(workflows);

            var scriptEngine = new JintScriptEngine(new MemoryCache(Options.Create(new MemoryCacheOptions())),
                                                    Options.Create(new JintScriptOptions
            {
                TimeoutScript    = TimeSpan.FromSeconds(2),
                TimeoutExecution = TimeSpan.FromSeconds(10)
            }));

            sut = new DynamicContentWorkflow(scriptEngine, appProvider);
        }
예제 #22
0
        public void Should_compare_two_tags_fields_as_equal()
        {
            var lhs = new TagsFieldProperties
            {
                DefaultValues = new LocalizedValue <ReadonlyList <string>?>(new Dictionary <string, ReadonlyList <string>?>
                {
                    ["iv"] = ReadonlyList.Create("A", "B", "C")
                })
            };

            var rhs = new TagsFieldProperties
            {
                DefaultValues = new LocalizedValue <ReadonlyList <string>?>(new Dictionary <string, ReadonlyList <string>?>
                {
                    ["iv"] = ReadonlyList.Create("A", "B", "C")
                })
            };

            Assert.Equal(lhs, rhs);
        }
예제 #23
0
        public async Task Should_add_error_if_schemas_ids_are_not_valid()
        {
            A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, default))
            .Returns(Task.FromResult <ISchemaEntity?>(null));

            var trigger = new ContentChangedTriggerV2
            {
                Schemas = ReadonlyList.Create(new ContentChangedTriggerSchemaV2 {
                    SchemaId = schemaId.Id
                })
            };

            var errors = await RuleTriggerValidator.ValidateAsync(appId.Id, trigger, appProvider);

            errors.Should().BeEquivalentTo(
                new List <ValidationError>
            {
                new ValidationError($"Schema {schemaId.Id} does not exist.", "Schemas")
            });
        }
예제 #24
0
        public void Should_serialize_and_deserialize()
        {
            var workflow = new Workflow(
                Status.Draft,
                new Dictionary <Status, WorkflowStep>
            {
                [Status.Draft] = new WorkflowStep(
                    new Dictionary <Status, WorkflowTransition>
                {
                    [Status.Published] = WorkflowTransition.When("Expression", "Role1", "Role2")
                }.ToReadonlyDictionary(),
                    "#00ff00",
                    NoUpdate.When("Expression", "Role1", "Role2"))
            }.ToReadonlyDictionary(),
                ReadonlyList.Create(DomainId.NewGuid()), "MyName");

            var serialized = workflow.SerializeAndDeserialize();

            Assert.Equal(workflow, serialized);
        }
예제 #25
0
        public void Should_create_initial_config_0_with_multiple_languages()
        {
            var config =
                LanguagesConfig.English
                .Set(Language.DE)
                .Set(Language.ES, true)
                .Set(Language.IT, true, Language.ES)
                .MakeMaster(Language.DE);

            config.Languages.Should().BeEquivalentTo(
                new Dictionary <string, LanguageConfig>
            {
                [Language.EN] = new LanguageConfig(),
                [Language.DE] = new LanguageConfig(),
                [Language.ES] = new LanguageConfig(true),
                [Language.IT] = new LanguageConfig(true, ReadonlyList.Create(Language.ES))
            });

            Assert.Equal(Language.DE, config.Master);
        }
예제 #26
0
        public static Schema MixedSchema(SchemaType type = SchemaType.Default)
        {
            var componentId = DomainId.NewGuid();

            var schema = new Schema("user", type: type)
                         .Publish()
                         .AddArray(101, "root-array", Partitioning.Language, f => f
                                   .AddAssets(201, "nested-assets")
                                   .AddBoolean(202, "nested-boolean")
                                   .AddDateTime(203, "nested-datetime")
                                   .AddGeolocation(204, "nested-geolocation")
                                   .AddJson(205, "nested-json")
                                   .AddJson(211, "nested-json2")
                                   .AddNumber(206, "nested-number")
                                   .AddReferences(207, "nested-references")
                                   .AddString(208, "nested-string")
                                   .AddTags(209, "nested-tags")
                                   .AddUI(210, "nested-ui"))
                         .AddAssets(102, "root-assets", Partitioning.Invariant,
                                    new AssetsFieldProperties())
                         .AddBoolean(103, "root-boolean", Partitioning.Invariant,
                                     new BooleanFieldProperties())
                         .AddDateTime(104, "root-datetime", Partitioning.Invariant,
                                      new DateTimeFieldProperties {
                Editor = DateTimeFieldEditor.DateTime
            })
                         .AddDateTime(105, "root-date", Partitioning.Invariant,
                                      new DateTimeFieldProperties {
                Editor = DateTimeFieldEditor.Date
            })
                         .AddGeolocation(106, "root-geolocation", Partitioning.Invariant,
                                         new GeolocationFieldProperties())
                         .AddJson(107, "root-json", Partitioning.Invariant,
                                  new JsonFieldProperties())
                         .AddNumber(108, "root-number", Partitioning.Invariant,
                                    new NumberFieldProperties {
                MinValue = 1, MaxValue = 10
            })
                         .AddReferences(109, "root-references", Partitioning.Invariant,
                                        new ReferencesFieldProperties())
                         .AddString(110, "root-string1", Partitioning.Invariant,
                                    new StringFieldProperties {
                Label = "My String1", IsRequired = true, AllowedValues = ReadonlyList.Create("a", "b")
            })
                         .AddString(111, "root-string2", Partitioning.Invariant,
                                    new StringFieldProperties {
                Hints = "My String1"
            })
                         .AddTags(112, "root-tags", Partitioning.Language,
                                  new TagsFieldProperties())
                         .AddUI(113, "root-ui", Partitioning.Language,
                                new UIFieldProperties())
                         .AddComponent(114, "root-component", Partitioning.Language,
                                       new ComponentFieldProperties {
                SchemaId = componentId
            })
                         .AddComponents(115, "root-components", Partitioning.Language,
                                        new ComponentsFieldProperties {
                SchemaId = componentId
            })
                         .Update(new SchemaProperties {
                Hints = "The User"
            })
                         .HideField(104)
                         .HideField(211, 101)
                         .DisableField(109)
                         .DisableField(212, 101)
                         .LockField(105);

            return(schema);
        }