예제 #1
0
        public async Task Should_generate_etag_from_ids_and_versions()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            await sut.OnActionExecutionAsync(executingContext, () =>
            {
                cachingManager.AddDependency(id1, 12);
                cachingManager.AddDependency(id2, 12);
                cachingManager.AddDependency(12);

                return(Task.FromResult(executedContext));
            });

            Assert.True(httpContext.Response.Headers[HeaderNames.ETag].ToString().Length > 20);
        }
예제 #2
0
        public void CanDelete_should_not_throw_exception_if_comment_from_same_user()
        {
            var commentId = DomainId.NewGuid();
            var command   = new DeleteComment {
                CommentId = commentId, Actor = user1
            };

            var events = new List <Envelope <CommentsEvent> >
            {
                Envelope.Create <CommentsEvent>(new CommentCreated {
                    CommentId = commentId, Actor = user1
                }).To <CommentsEvent>()
            };

            GuardComments.CanDelete(command, commentsId, events);
        }
예제 #3
0
        public void CanUpdate_should_throw_exception_if_comment_from_another_user()
        {
            var commentId = DomainId.NewGuid();
            var command   = new UpdateComment {
                CommentId = commentId, Actor = user2, Text = "text2"
            };

            var events = new List <Envelope <CommentsEvent> >
            {
                Envelope.Create <CommentsEvent>(new CommentCreated {
                    CommentId = commentId, Actor = user1
                }).To <CommentsEvent>()
            };

            Assert.Throws <DomainException>(() => GuardComments.CanUpdate(command, commentsId, events));
        }
예제 #4
0
        public void CanUpdate_should_not_throw_exception_if_comment_is_own_notification()
        {
            var commentId = DomainId.NewGuid();
            var command   = new UpdateComment {
                CommentId = commentId, Actor = user1, Text = "text2"
            };

            var events = new List <Envelope <CommentsEvent> >
            {
                Envelope.Create <CommentsEvent>(new CommentCreated {
                    CommentId = commentId, Actor = user1
                }).To <CommentsEvent>()
            };

            GuardComments.CanUpdate(command, user1.Identifier, events);
        }
예제 #5
0
        public async Task Should_not_enrich_references_if_not_api_user()
        {
            var contents = new[]
            {
                CreateContent(new[] { DomainId.NewGuid() }, Array.Empty <DomainId>())
            };

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

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

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

            A.CallTo(() => contentQuery.QueryAsync(A <Context> ._, A <Q> ._))
            .MustNotHaveHappened();
        }
예제 #6
0
        public async Task Should_not_repair_updated_asset_if_found()
        {
            var @event = new AssetUpdated {
                AppId = appId, AssetId = DomainId.NewGuid(), FileVersion = 3
            };

            SetupEvent(@event);

            A.CallTo(() => assetFileStore.GetFileSizeAsync(appId.Id, @event.AssetId, 3, default))
            .Returns(100);

            await sut.RepairAsync();

            A.CallTo(() => assetFileStore.UploadAsync(appId.Id, @event.AssetId, 3, A <Stream> ._, default))
            .MustNotHaveHappened();
        }
예제 #7
0
        public void Should_return_ids_from_nested_field(NestedField field)
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            var arrayField = Fields.Array(1, "my-array", Partitioning.Invariant, field);

            var value =
                JsonValue.Array(
                    JsonValue.Object()
                    .Add(field.Name, CreateValue(id1, id2)));

            var result = arrayField.GetReferencedIds(value).ToArray();

            Assert.Equal(new[] { id1, id2 }, result);
        }
예제 #8
0
        public async Task Should_not_enrich_references_if_disabled()
        {
            var contents = new[]
            {
                CreateContent(new[] { DomainId.NewGuid() }, new DomainId[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(() => assetQuery.QueryAsync(A <Context> ._, null, A <Q> ._))
            .MustNotHaveHappened();
        }
예제 #9
0
        public async Task Should_provide_empty_events_if_nothing_loaded()
        {
            var key = DomainId.NewGuid();

            var bulk = sut.WithBatchContext(None.Type);

            await bulk.LoadAsync(new[] { key });

            var persistedEvents = Save.Events();
            var persistence     = bulk.WithEventSourcing(None.Type, key, persistedEvents.Write);

            await persistence.ReadAsync();

            Assert.Empty(persistedEvents.ToArray());
            Assert.Empty(persistedEvents.ToArray());
        }
예제 #10
0
        public async Task Should_repair_created_asset_if_not_found()
        {
            var @event = new AssetCreated {
                AppId = appId, AssetId = DomainId.NewGuid()
            };

            SetupEvent(@event);

            A.CallTo(() => assetFileStore.GetFileSizeAsync(appId.Id, @event.AssetId, 0, default))
            .Throws(new AssetNotFoundException("file"));

            await sut.RepairAsync();

            A.CallTo(() => assetFileStore.UploadAsync(appId.Id, @event.AssetId, 0, A <Stream> ._, default))
            .MustHaveHappened();
        }
예제 #11
0
        public async Task Should_query_contents_with_matching_permissions()
        {
            var requestContext = CreateContext(allowSchema: false);

            var ids = Enumerable.Range(0, 5).Select(x => DomainId.NewGuid()).ToList();

            var q = Q.Empty.WithIds(ids);

            A.CallTo(() => contentRepository.QueryAsync(requestContext.App,
                                                        A <List <ISchemaEntity> > .That.Matches(x => x.Count == 0), q, SearchScope.All,
                                                        A <CancellationToken> ._))
            .Returns(ResultList.Create(0, ids.Select(CreateContent)));

            var result = await sut.QueryAsync(requestContext, q, ct);

            Assert.Empty(result);
        }
예제 #12
0
        public async Task Should_delete_asset()
        {
            SetupContext(Permissions.AppAssetsDelete);

            var id = DomainId.NewGuid();

            var command = BulkCommand(BulkUpdateAssetType.Delete, id);

            var result = await PublishAsync(command);

            Assert.Single(result);
            Assert.Single(result, x => x.JobIndex == 0 && x.Id == id && x.Exception == null);

            A.CallTo(() => commandBus.PublishAsync(
                         A <DeleteAsset> .That.Matches(x => x.AssetId == id)))
            .MustHaveHappened();
        }
예제 #13
0
        public async Task Should_create_client()
        {
            var command = new CreateApp {
                AppId = DomainId.NewGuid(), Name = "my-app"
            };

            var context =
                new CommandContext(command, commandBus)
                .Complete();

            var sut = new AlwaysCreateClientCommandMiddleware();

            await sut.HandleAsync(context);

            A.CallTo(() => commandBus.PublishAsync(A <AttachClient> .That.Matches(x => x.Id == "default")))
            .MustHaveHappened();
        }
        public async Task Should_upsert_content_with_with_resolved_ids()
        {
            var requestContext = SetupContext(Permissions.AppContentsUpsert);

            var(_, data, query) = CreateTestData(true);

            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            A.CallTo(() => contentQuery.QueryAsync(requestContext, A <string> ._, A <Q> .That.Matches(x => x.JsonQuery == query)))
            .Returns(ResultList.CreateFrom(2,
                                           CreateContent(id1),
                                           CreateContent(id2)));

            var command = BulkCommand(BulkUpdateType.Upsert, query: query, data: data);

            command.Jobs ![0].ExpectedCount = 2;
예제 #15
0
        public async Task Should_not_append_surrogate_keys_if_maximum_is_overriden()
        {
            var id1 = DomainId.NewGuid().ToString();
            var id2 = DomainId.NewGuid().ToString();

            httpContext.Request.Headers[CachingManager.SurrogateKeySizeHeader] = "20";

            await sut.OnActionExecutionAsync(executingContext, () =>
            {
                cachingManager.AddDependency(id1, 12);
                cachingManager.AddDependency(id2, 12);

                return(Task.FromResult(executedContext));
            });

            Assert.Equal(StringValues.Empty, httpContext.Response.Headers["Surrogate-Key"]);
        }
예제 #16
0
        public async Task Should_append_surrogate_keys_if_just_enough_space_for_one()
        {
            var id1 = DomainId.NewGuid().ToString();
            var id2 = DomainId.NewGuid().ToString();

            cachingOptions.MaxSurrogateKeysSize = 36;

            await sut.OnActionExecutionAsync(executingContext, () =>
            {
                cachingManager.AddDependency(id1, 12);
                cachingManager.AddDependency(id2, 12);

                return(Task.FromResult(executedContext));
            });

            Assert.Equal($"{id1}", httpContext.Response.Headers["Surrogate-Key"]);
        }
예제 #17
0
        public void Should_get_ids_from_name_data()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            var input =
                new ContentData()
                .AddField("assets1",
                          new ContentFieldData()
                          .AddInvariant(JsonValue.Array(id1.ToString(), id2.ToString())));

            var ids = new HashSet <DomainId>();

            input.AddReferencedIds(schema, ids, components);

            Assert.Equal(new[] { id1, id2 }, ids);
        }
예제 #18
0
        public async Task Should_not_reserve_name_if_already_used()
        {
            var ids = new Dictionary <string, DomainId>
            {
                ["name1"] = DomainId.NewGuid()
            };

            A.CallTo(() => schemaRepository.QueryIdsAsync(appId, default))
            .Returns(ids);

            var token1 = await sut.ReserveAsync(DomainId.NewGuid(), "name1");

            var token2 = await sut.ReserveAsync(DomainId.NewGuid(), "name2");

            Assert.Null(token1);
            Assert.NotNull(token2);
        }
예제 #19
0
        public void Should_handle_domain_id_as_string()
        {
            var id = DomainId.NewGuid();

            var vars = new ScriptVars
            {
                ["value"] = id
            };

            const string script = @"
                return value;
            ";

            var result = sut.Execute(vars, script);

            Assert.Equal(id.ToString(), result.ToString());
        }
예제 #20
0
        public async Task Should_only_query_first_assets()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            var contents = new[]
            {
                CreateContent(new[] { id1, id2 }, Array.Empty <DomainId>())
            };

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

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

            A.CallTo(() => assetQuery.QueryAsync(A <Context> .That.Matches(x => !x.ShouldEnrichAsset()), null, A <Q> .That.HasIds(id1)))
            .MustHaveHappened();
        }
예제 #21
0
        public async Task Should_add_rule_to_index_on_create()
        {
            var ruleId = DomainId.NewGuid();

            var command = new CreateRule {
                RuleId = ruleId, AppId = appId
            };

            var context =
                new CommandContext(command, commandBus)
                .Complete();

            await sut.HandleAsync(context);

            A.CallTo(() => cache.AddAsync(ruleId))
            .MustHaveHappened();
        }
예제 #22
0
        public void Should_get_limited_ids_from_name_data()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

            var input =
                new NamedContentData()
                .AddField("assets",
                          new ContentFieldData()
                          .AddJsonValue(JsonValue.Array(id1.ToString(), id2.ToString())));

            var ids = new HashSet <DomainId>();

            input.AddReferencedIds(schema, ids, 1);

            Assert.Equal(new[] { id1 }, ids);
        }
예제 #23
0
        public void Should_cleanup_deleted_ids()
        {
            var id1 = DomainId.NewGuid();
            var id2 = DomainId.NewGuid();

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

            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)))));

            var cleaner = ValueReferencesConverter.CleanReferences(new HashSet <DomainId> {
                id2
            });
            var cleanNested = ValueConverters.ForNested(cleaner);

            var converter = FieldConverters.ForValues(cleaner, cleanNested);

            var actual = source.ConvertName2Name(schema, converter);

            Assert.Equal(expected, actual);
        }
        public async Task Should_provide_all_permissions()
        {
            A.CallTo(() => appProvider.GetSchemasAsync(A <DomainId> ._))
            .Returns(new List <ISchemaEntity>
            {
                Mocks.Schema(appId, NamedId.Of(DomainId.NewGuid(), "schema1")),
                Mocks.Schema(appId, NamedId.Of(DomainId.NewGuid(), "schema2"))
            });

            var result = await sut.GetPermissionsAsync(app);

            Assert.True(result.Contains("*"));
            Assert.True(result.Contains("clients.read"));
            Assert.True(result.Contains("schemas.*.update"));
            Assert.True(result.Contains("schemas.schema1.update"));
            Assert.True(result.Contains("schemas.schema2.update"));
        }
예제 #25
0
        public void CanUpdate_should_throw_exception_if_text_not_defined()
        {
            var commentId = DomainId.NewGuid();
            var command   = new UpdateComment {
                CommentId = commentId, Actor = user1
            };

            var events = new List <Envelope <CommentsEvent> >
            {
                Envelope.Create <CommentsEvent>(new CommentCreated {
                    CommentId = commentId, Actor = user1
                }).To <CommentsEvent>()
            };

            ValidationAssert.Throws(() => GuardComments.CanUpdate(commentsId, events, command),
                                    new ValidationError("Text is required.", "Text"));
        }
예제 #26
0
        public async Task Should_get_comments_from_grain()
        {
            var commentsId = DomainId.NewGuid();
            var comments   = new CommentsResult();

            var grain = A.Fake <ICommentsGrain>();

            A.CallTo(() => grain.GetCommentsAsync(11))
            .Returns(comments);

            A.CallTo(() => grainFactory.GetGrain <ICommentsGrain>(commentsId.ToString(), null))
            .Returns(grain);

            var result = await sut.GetCommentsAsync(commentsId, 11);

            Assert.Same(comments, result);
        }
예제 #27
0
        public async Task QueryAll_should_return_contents(int isFrontend, int unpublished, SearchScope scope)
        {
            var ctx =
                CreateContext(isFrontend: isFrontend == 1, allowSchema: true)
                .WithUnpublished(unpublished == 1);

            var ids = Enumerable.Range(0, 5).Select(x => DomainId.NewGuid()).ToList();

            var q = Q.Empty.WithIds(ids);

            A.CallTo(() => contentRepository.QueryAsync(ctx.App, A <List <ISchemaEntity> > .That.Matches(x => x.Count == 1), q, scope))
            .Returns(ResultList.Create(5, ids.Select(CreateContent)));

            var result = await sut.QueryAsync(ctx, q);

            Assert.Equal(ids, result.Select(x => x.Id).ToList());
        }
예제 #28
0
 private ContentEntity CreateContent(DomainId[] ref1, DomainId[] ref2)
 {
     return(new ContentEntity
     {
         Id = DomainId.NewGuid(),
         Data =
             new ContentData()
             .AddField("ref1",
                       new ContentFieldData()
                       .AddInvariant(JsonValue.Array(ref1.Select(x => x.ToString()))))
             .AddField("ref2",
                       new ContentFieldData()
                       .AddInvariant(JsonValue.Array(ref2.Select(x => x.ToString())))),
         SchemaId = schemaId, AppId = appId,
         Version = 0
     });
 }
예제 #29
0
        private static (DomainId, RootField <ComponentFieldProperties>) Field(ComponentFieldProperties properties, bool isRequired = false)
        {
            var schema =
                new Schema("my-component")
                .AddNumber(1, "component-field", Partitioning.Invariant,
                           new NumberFieldProperties {
                IsRequired = isRequired
            });

            var id = DomainId.NewGuid();

            var field =
                Fields.Component(1, "my-component", Partitioning.Invariant, properties)
                .SetResolvedSchema(id, schema);

            return(id, field);
        }
예제 #30
0
        public async Task Should_read_from_preloaded_events()
        {
            var event1_1 = new MyEvent {
                MyProperty = "event1_1"
            };
            var event1_2 = new MyEvent {
                MyProperty = "event1_2"
            };
            var event2_1 = new MyEvent {
                MyProperty = "event2_1"
            };
            var event2_2 = new MyEvent {
                MyProperty = "event2_2"
            };

            var key1 = DomainId.NewGuid();
            var key2 = DomainId.NewGuid();

            var bulk = sut.WithBatchContext(None.Type);

            SetupEventStore(new Dictionary <DomainId, List <MyEvent> >
            {
                [key1] = new List <MyEvent> {
                    event1_1, event1_2
                },
                [key2] = new List <MyEvent> {
                    event2_1, event2_2
                }
            });

            await bulk.LoadAsync(new[] { key1, key2 });

            var persistedEvents1 = Save.Events();
            var persistence1     = bulk.WithEventSourcing(None.Type, key1, persistedEvents1.Write);

            await persistence1.ReadAsync();

            var persistedEvents2 = Save.Events();
            var persistence2     = bulk.WithEventSourcing(None.Type, key2, persistedEvents2.Write);

            await persistence2.ReadAsync();

            Assert.Equal(persistedEvents1.ToArray(), new[] { event1_1, event1_2 });
            Assert.Equal(persistedEvents2.ToArray(), new[] { event2_1, event2_2 });
        }