예제 #1
0
        public async Task Should_not_call_script_engine_for_frontend_user()
        {
            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            var content = new ContentEntity {
                SchemaId = schemaWithScriptId
            };

            await sut.EnrichAsync(ctx, new[] { content }, schemaProvider);

            A.CallTo(() => scriptEngine.TransformAsync(A <ScriptVars> ._, A <string> ._, ScriptOptions()))
            .MustNotHaveHappened();
        }
예제 #2
0
        public async Task Should_get_next_statuses_for_draft()
        {
            var content = CreateContent(Status.Draft, 2);

            var expected = new[]
            {
                new StatusInfo(Status.Archived, StatusColors.Archived)
            };

            var result = await sut.GetNextsAsync(content, Mocks.FrontendUser("Developer"));

            result.Should().BeEquivalentTo(expected);
        }
예제 #3
0
        public async Task Should_limit_next_statuses_if_expression_does_not_evauate_to_true()
        {
            var content = CreateContent(Status.Draft, 4);

            var expected = new[]
            {
                new StatusInfo(Status.Archived, StatusColors.Archived)
            };

            var result = await sut.GetNextsAsync(content, Mocks.FrontendUser("Editor"));

            result.Should().BeEquivalentTo(expected);
        }
예제 #4
0
        protected Task <ExecutionResult> ExecuteAsync(ExecutionOptions options, string?permissionId = null)
        {
            var context = requestContext;

            if (permissionId != null)
            {
                var permission = Permissions.ForApp(permissionId, app.Name, schemaId.Name).Id;

                context = new Context(Mocks.FrontendUser(permission: permission), app);
            }

            return(ExcecuteAsync(options, context));
        }
예제 #5
0
        public async Task Should_not_compute_ui_tokens_for_frontend()
        {
            var source = new AssetEntity
            {
                AppId = appId
            };

            var result = await sut.EnrichAsync(new[] { source }, new Context(Mocks.FrontendUser(), Mocks.App(appId)), default);

            Assert.Null(result[0].EditToken);

            A.CallTo(() => urlGenerator.Root())
            .MustNotHaveHappened();
        }
예제 #6
0
        public async Task Should_enrich_with_schema_names()
        {
            var ctx = new Context(Mocks.FrontendUser(), requestContext.App);

            var source = PublishedContent();

            A.CallTo(() => contentWorkflow.GetInfoAsync(source))
            .Returns(new StatusInfo(Status.Published, StatusColors.Published));

            var result = await sut.EnrichAsync(source, ctx);

            Assert.Equal("my-schema", result.SchemaName);
            Assert.Equal("my-schema", result.SchemaDisplayName);
        }
예제 #7
0
        public void CheckPermission_should_not_throw_exception_if_content_is_from_another_user_but_user_has_permission()
        {
            var content = CreateContent(Status.Published);

            var permission = Permissions.ForApp(Permissions.AppContentsDelete, appId.Name, schemaId.Name).Id;

            var commandUser  = Mocks.FrontendUser(permission: permission);
            var commandActor = RefToken.User("456");
            var command      = CreateCommand(new DeleteContent {
                Actor = commandActor, User = commandUser
            });

            GuardContent.CheckPermission(content, command, Permissions.AppContentsDelete);
        }
예제 #8
0
        public GraphQLTestBase()
        {
            A.CallTo(() => userResolver.QueryManyAsync(A <string[]> ._, default))
            .ReturnsLazily(x =>
            {
                var ids = x.GetArgument <string[]>(0) !;

                var users = ids.Select(id => UserMocks.User(id, $"{id}@email.com", $"name_{id}"));

                return(Task.FromResult(users.ToDictionary(x => x.Id)));
            });

            requestContext = new Context(Mocks.FrontendUser(), TestApp.Default);
        }
        public async Task Should_limit_next_statuses_if_role_is_not_allowed()
        {
            var content = CreateContent(Status.Draft, 2);

            var expected = new[]
            {
                new StatusInfo(Status.Archived, StatusColors.Archived),
                new StatusInfo(Status.Published, StatusColors.Published)
            };

            var result = await sut.GetNextAsync(content, content.Status, Mocks.FrontendUser("Editor"));

            result.Should().BeEquivalentTo(expected);
        }
예제 #10
0
        public GraphQLTestBase()
        {
            app = Mocks.App(appId, Language.DE, Language.GermanGermany);

            var schemaDef =
                new Schema("my-schema")
                .AddJson(1, "my-json", Partitioning.Invariant,
                         new JsonFieldProperties())
                .AddString(2, "my-string", Partitioning.Language,
                           new StringFieldProperties())
                .AddNumber(3, "my-number", Partitioning.Invariant,
                           new NumberFieldProperties())
                .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 = schemaId.Id
            })
                .AddReferences(9, "my-invalid", Partitioning.Invariant,
                               new ReferencesFieldProperties {
                SchemaId = Guid.NewGuid()
            })
                .AddGeolocation(10, "my-geolocation", Partitioning.Invariant,
                                new GeolocationFieldProperties())
                .AddTags(11, "my-tags", Partitioning.Invariant,
                         new TagsFieldProperties())
                .AddString(12, "my-localized", Partitioning.Language,
                           new StringFieldProperties())
                .AddArray(13, "my-array", Partitioning.Invariant, f => f
                          .AddBoolean(121, "nested-boolean")
                          .AddNumber(122, "nested-number")
                          .AddNumber(123, "nested_number"))
                .ConfigureScripts(new SchemaScripts {
                Query = "<query-script>"
            })
                .Publish();

            schema = Mocks.Schema(appId, schemaId, schemaDef);

            requestContext = new Context(Mocks.FrontendUser(), app);

            sut = CreateSut();
        }
예제 #11
0
        public ContentEnricherReferencesTests()
        {
            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId, Language.DE));

            var refSchemaDef =
                new Schema("my-ref")
                .AddString(1, "name", Partitioning.Invariant,
                           new StringFieldProperties {
                IsReferenceField = true
            })
                .AddNumber(2, "number", Partitioning.Invariant,
                           new NumberFieldProperties {
                IsReferenceField = true
            });

            var schemaDef =
                new Schema(schemaId.Name)
                .AddReferences(1, "ref1", Partitioning.Invariant, new ReferencesFieldProperties
            {
                ResolveReference = true,
                IsListField      = true,
                MinItems         = 1,
                MaxItems         = 1,
                SchemaId         = refSchemaId1.Id
            })
                .AddReferences(2, "ref2", Partitioning.Invariant, new ReferencesFieldProperties
            {
                ResolveReference = true,
                IsListField      = true,
                MinItems         = 1,
                MaxItems         = 1,
                SchemaId         = refSchemaId2.Id
            });

            void SetupSchema(NamedId <Guid> id, Schema def)
            {
                var schemaEntity = Mocks.Schema(appId, id, def);

                A.CallTo(() => contentQuery.GetSchemaOrThrowAsync(requestContext, id.Id.ToString()))
                .Returns(schemaEntity);
            }

            SetupSchema(schemaId, schemaDef);
            SetupSchema(refSchemaId1, refSchemaDef);
            SetupSchema(refSchemaId2, refSchemaDef);

            sut = new ContentEnricher(new Lazy <IContentQueryService>(() => contentQuery), contentWorkflow);
        }
예제 #12
0
        public ContentQueryParserTests()
        {
            var options = Options.Create(new ContentOptions { DefaultPageSize = 30 });

            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            var schemaDef =
                new Schema(schemaId.Name)
                    .AddString(1, "firstName", Partitioning.Invariant);

            schema = Mocks.Schema(appId, schemaId, schemaDef);

            var cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));

            sut = new ContentQueryParser(cache, JsonHelper.DefaultSerializer, options);
        }
예제 #13
0
        public async Task Should_not_enrich_references_if_disabled()
        {
            var contents = new[]
            {
                CreateContent(new[] { Guid.NewGuid() }, new Guid[0])
            };

            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId)).WithoutContentEnrichment(true);

            await sut.EnrichAsync(ctx, contents, schemaProvider);

            Assert.Null(contents[0].ReferenceData);

            A.CallTo(() => contentQuery.QueryAsync(A <Context> .Ignored, A <List <Guid> > .Ignored))
            .MustNotHaveHappened();
        }
예제 #14
0
        public async Task Should_not_enrich_references_if_disabled()
        {
            var contents = new[]
            {
                CreateContent(new[] { DomainId.NewGuid() }, Array.Empty <DomainId>())
            };

            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId)).WithoutContentEnrichment(true);

            await sut.EnrichAsync(ctx, contents, schemaProvider);

            Assert.Null(contents[0].ReferenceData);

            A.CallTo(() => assetQuery.QueryAsync(A <Context> ._, null, A <Q> ._))
            .MustNotHaveHappened();
        }
예제 #15
0
        public async Task Should_not_call_script_engine_for_frontend_user()
        {
            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            var(provider, schemaId) = CreateSchema(
                query: "my-query");

            var content = new ContentEntity {
                Data = new ContentData(), SchemaId = schemaId
            };

            await sut.EnrichAsync(ctx, new[] { content }, provider, default);

            A.CallTo(() => scriptEngine.TransformAsync(A <ScriptVars> ._, A <string> ._, ScriptOptions(), A <CancellationToken> ._))
            .MustNotHaveHappened();
        }
예제 #16
0
        public ContentQueryParserTests()
        {
            var options = Options.Create(new ContentOptions {
                DefaultPageSize = 30
            });

            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            var schemaDef =
                new Schema(schemaId.Name)
                .AddString(1, "firstName", Partitioning.Invariant)
                .AddGeolocation(2, "geo", Partitioning.Invariant);

            schema = Mocks.Schema(appId, schemaId, schemaDef);

            var cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));

            sut = new ContentQueryParser(appProvider, textIndex, options, cache, TestUtils.DefaultSerializer);
        }
예제 #17
0
        public AssetQueryServiceTests()
        {
            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            SetupEnricher();

            A.CallTo(() => queryParser.ParseAsync(requestContext, A <Q> ._))
            .ReturnsLazily(c => Task.FromResult(c.GetArgument <Q>(1) !));

            var options = Options.Create(new AssetOptions());

            sut = new AssetQueryService(
                assetEnricher,
                assetRepository,
                assetLoader,
                assetFolderRepository,
                options,
                queryParser);
        }
예제 #18
0
        public async Task Should_cleanup_references()
        {
            var id1 = Guid.NewGuid();
            var id2 = Guid.NewGuid();

            var source = BuildTestData(id1, id2);

            var content = CreateContent(source);

            var expected =
                new NamedContentData()
                .AddField("references",
                          new ContentFieldData()
                          .AddJsonValue(JsonValue.Array(id2)))
                .AddField("assets",
                          new ContentFieldData()
                          .AddJsonValue(JsonValue.Array()))
                .AddField("array",
                          new ContentFieldData()
                          .AddJsonValue(
                              JsonValue.Array(
                                  JsonValue.Object()
                                  .Add("nested", JsonValue.Array(id2)))));

            A.CallTo(() => assetRepository.QueryIdsAsync(appId.Id, A <HashSet <Guid> > .That.Is(id1, id2)))
            .Returns(new List <Guid> {
                id2
            });

            A.CallTo(() => contentRepository.QueryIdsAsync(appId.Id, A <HashSet <Guid> > .That.Is(id1, id2)))
            .Returns(new List <(Guid, Guid)> {
                (id2, id2)
            });

            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            await sut.EnrichAsync(ctx, Enumerable.Repeat(content, 1), schemaProvider);

            Assert.Equal(expected, content.Data);
            Assert.Equal(expected, content.DataDraft);
        }
예제 #19
0
        public async Task Should_cleanup_references()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            var source = BuildTestData(id1, id2);

            var content = CreateContent(source);

            var expected =
                new ContentData()
                .AddField("references",
                          new ContentFieldData()
                          .AddInvariant(JsonValue.Array(id2)))
                .AddField("assets",
                          new ContentFieldData()
                          .AddInvariant(JsonValue.Array()))
                .AddField("array",
                          new ContentFieldData()
                          .AddInvariant(
                              JsonValue.Array(
                                  JsonValue.Object()
                                  .Add("nested", JsonValue.Array(id2)))));

            A.CallTo(() => assetRepository.QueryIdsAsync(appId.Id, A <HashSet <DomainId> > .That.Is(id1, id2), A <CancellationToken> ._))
            .Returns(new List <DomainId> {
                id2
            });

            A.CallTo(() => contentRepository.QueryIdsAsync(appId.Id, A <HashSet <DomainId> > .That.Is(id1, id2), SearchScope.All, A <CancellationToken> ._))
            .Returns(new List <(DomainId, DomainId, Status)> {
                (id2, id2, Status.Published)
            });

            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            await sut.EnrichAsync(ctx, Enumerable.Repeat(content, 1), schemaProvider, default);

            Assert.Equal(expected, content.Data);
        }
예제 #20
0
        public ResolveAssetsTests()
        {
            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId, Language.DE));

            var schemaDef =
                new Schema(schemaId.Name)
                .AddAssets(1, "asset1", Partitioning.Invariant, new AssetsFieldProperties
            {
                ResolveFirst = true,
                MinItems     = 2,
                MaxItems     = 3
            })
                .AddAssets(2, "asset2", Partitioning.Language, new AssetsFieldProperties
            {
                ResolveFirst = true,
                MinItems     = 1,
                MaxItems     = 1
            })
                .SetFieldsInLists("asset1", "asset2");

            A.CallTo(() => urlGenerator.AssetContent(appId, A <string> ._))
            .ReturnsLazily(ctx => $"url/to/{ctx.GetArgument<string>(1)}");

            schemaProvider = x =>
            {
                if (x == schemaId.Id)
                {
                    return(Task.FromResult(Mocks.Schema(appId, schemaId, schemaDef)));
                }
                else
                {
                    throw new DomainObjectNotFoundException(x.ToString());
                }
            };

            sut = new ResolveAssets(urlGenerator, assetQuery, requestCache);
        }
예제 #21
0
        public ResolveAssetsTests()
        {
            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId, Language.DE));

            var schemaDef =
                new Schema(schemaId.Name)
                .AddAssets(1, "asset1", Partitioning.Invariant, new AssetsFieldProperties
            {
                ResolveImage = true,
                MinItems     = 2,
                MaxItems     = 3
            })
                .AddAssets(2, "asset2", Partitioning.Language, new AssetsFieldProperties
            {
                ResolveImage = true,
                MinItems     = 1,
                MaxItems     = 1
            })
                .SetFieldsInLists("asset1", "asset2");

            A.CallTo(() => assetUrlGenerator.GenerateUrl(A <string> .Ignored))
            .ReturnsLazily(new Func <string, string>(id => $"url/to/{id}"));

            schemaProvider = x =>
            {
                if (x == schemaId.Id)
                {
                    return(Task.FromResult(Mocks.Schema(appId, schemaId, schemaDef)));
                }
                else
                {
                    throw new DomainObjectNotFoundException(x.ToString(), typeof(ISchemaEntity));
                }
            };

            sut = new ResolveAssets(assetUrlGenerator, assetQuery, requestCache);
        }
예제 #22
0
        public ContentEnricherAssetsTests()
        {
            requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId, Language.DE));

            var schemaDef =
                new Schema(schemaId.Name)
                .AddAssets(1, "asset1", Partitioning.Invariant, new AssetsFieldProperties
            {
                ResolveImage = true,
                MinItems     = 2,
                MaxItems     = 3,
                IsListField  = true
            })
                .AddAssets(2, "asset2", Partitioning.Language, new AssetsFieldProperties
            {
                ResolveImage = true,
                MinItems     = 1,
                MaxItems     = 1,
                IsListField  = true,
            });

            A.CallTo(() => assetUrlGenerator.GenerateUrl(A <string> .Ignored))
            .ReturnsLazily(new Func <string, string>(id => $"url/to/{id}"));

            void SetupSchema(NamedId <Guid> id, Schema def)
            {
                var schemaEntity = Mocks.Schema(appId, id, def);

                A.CallTo(() => contentQuery.GetSchemaOrThrowAsync(requestContext, id.Id.ToString()))
                .Returns(schemaEntity);
            }

            SetupSchema(schemaId, schemaDef);

            sut = new ContentEnricher(assetQuery, assetUrlGenerator, new Lazy <IContentQueryService>(() => contentQuery), contentWorkflow);
        }
예제 #23
0
        public async Task Should_cleanup_references_when_everything_deleted()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            var source = BuildTestData(id1, id2);

            var content = CreateContent(source);

            var expected =
                new NamedContentData()
                .AddField("references",
                          new ContentFieldData()
                          .AddJsonValue(JsonValue.Array()))
                .AddField("assets",
                          new ContentFieldData()
                          .AddJsonValue(JsonValue.Array()))
                .AddField("array",
                          new ContentFieldData()
                          .AddJsonValue(
                              JsonValue.Array(
                                  JsonValue.Object()
                                  .Add("nested", JsonValue.Array()))));

            A.CallTo(() => assetRepository.QueryIdsAsync(appId.Id, A <HashSet <DomainId> > .That.Is(id1, id2)))
            .Returns(new List <DomainId>());

            A.CallTo(() => contentRepository.QueryIdsAsync(appId.Id, A <HashSet <DomainId> > .That.Is(id1, id2), SearchScope.All))
            .Returns(new List <(DomainId, DomainId, Status)>());

            var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId));

            await sut.EnrichAsync(ctx, Enumerable.Repeat(content, 1), schemaProvider);

            Assert.Equal(expected, content.Data);
        }
예제 #24
0
        public GraphQLTestBase()
        {
            app = Mocks.App(appId, Language.DE, Language.GermanGermany);

            var schemaDef =
                new Schema(schemaId.Name)
                .Publish()
                .AddNumber(16, "2_numbers", Partitioning.Invariant,
                           new NumberFieldProperties())
                .AddNumber(17, "2-numbers", Partitioning.Invariant,
                           new NumberFieldProperties())
                .AddNumber(18, "content", Partitioning.Invariant,
                           new NumberFieldProperties())
                .AddJson(1, "my-json", Partitioning.Invariant,
                         new JsonFieldProperties())
                .AddString(2, "my-string", Partitioning.Language,
                           new StringFieldProperties())
                .AddString(3, "my-string2", Partitioning.Invariant,
                           new StringFieldProperties())
                .AddString(4, "my-localized", Partitioning.Language,
                           new StringFieldProperties())
                .AddNumber(5, "my-number", Partitioning.Invariant,
                           new NumberFieldProperties())
                .AddNumber(6, "my_number", Partitioning.Invariant,
                           new NumberFieldProperties())
                .AddAssets(7, "my-assets", Partitioning.Invariant,
                           new AssetsFieldProperties())
                .AddBoolean(8, "my-boolean", Partitioning.Invariant,
                            new BooleanFieldProperties())
                .AddDateTime(9, "my-datetime", Partitioning.Invariant,
                             new DateTimeFieldProperties())
                .AddReferences(10, "my-references", Partitioning.Invariant,
                               new ReferencesFieldProperties {
                SchemaId = schemaRefId1.Id
            })
                .AddReferences(11, "my-union", Partitioning.Invariant,
                               new ReferencesFieldProperties())
                .AddReferences(12, "my-invalid", Partitioning.Invariant,
                               new ReferencesFieldProperties {
                SchemaId = DomainId.NewGuid()
            })
                .AddGeolocation(13, "my-geolocation", Partitioning.Invariant,
                                new GeolocationFieldProperties())
                .AddTags(14, "my-tags", Partitioning.Invariant,
                         new TagsFieldProperties())
                .AddArray(15, "my-array", Partitioning.Invariant, f => f
                          .AddBoolean(121, "nested-boolean")
                          .AddNumber(122, "nested-number")
                          .AddNumber(123, "nested_number"))
                .SetScripts(new SchemaScripts {
                Query = "<query-script>"
            });

            schema = Mocks.Schema(appId, schemaId, schemaDef);

            var schemaRef1Def =
                new Schema(schemaRefId1.Name)
                .Publish()
                .AddString(1, "ref1-field", Partitioning.Invariant);

            schemaRef1 = Mocks.Schema(appId, schemaRefId1, schemaRef1Def);

            var schemaRef2Def =
                new Schema(schemaRefId2.Name)
                .Publish()
                .AddString(1, "ref2-field", Partitioning.Invariant);

            schemaRef2 = Mocks.Schema(appId, schemaRefId2, schemaRef2Def);

            var schemaInvalidNameDef =
                new Schema(schemaInvalidNameId.Name)
                .Publish()
                .AddString(1, "my-field", Partitioning.Invariant);

            schemaInvalidName = Mocks.Schema(appId, schemaInvalidNameId, schemaInvalidNameDef);

            requestContext = new Context(Mocks.FrontendUser(), app);

            sut = CreateSut();
        }
        public async Task Should_not_allow_transition_if_data_not_valid()
        {
            var content = CreateContent(Status.Draft, 4);

            var result = await sut.CanMoveToAsync(content, content.Status, Status.Published, Mocks.FrontendUser("Editor"));

            Assert.False(result);
        }
        public async Task Should_allow_transition_if_role_is_allowed()
        {
            var content = CreateContent(Status.Draft, 2);

            var result = await sut.CanMoveToAsync(content, content.Status, Status.Published, Mocks.FrontendUser("Editor"));

            Assert.True(result);
        }
        public async Task Should_check_is_valid_next()
        {
            var content = CreateContent(Status.Draft, 2);

            var result = await sut.CanMoveToAsync(content, content.Status, Status.Published, Mocks.FrontendUser("Editor"));

            Assert.True(result);
        }
        public async Task Should_not_allow_publish_on_create_if_role_not_allowed()
        {
            var content = CreateContent(Status.Draft, 2);

            var result = await sut.CanPublishOnCreateAsync(Mocks.Schema(appId, schemaId), content.Data, Mocks.FrontendUser("Developer"));

            Assert.False(result);
        }
        public async Task Should_not_allow_publish_on_create_if_data_is_invalid()
        {
            var content = CreateContent(Status.Draft, 4);

            var result = await sut.CanPublishOnCreateAsync(Mocks.Schema(appId, schemaId), content.Data, Mocks.FrontendUser("Editor"));

            Assert.False(result);
        }
        public async Task Should_allow_publish_on_create()
        {
            var content = CreateContent(Status.Draft, 2);

            var result = await sut.CanPublishOnCreateAsync(Mocks.Schema(appId, schemaId), content.Data, Mocks.FrontendUser("Editor"));

            Assert.True(result);
        }