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); }
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); }
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)); }
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); }
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(); }
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(); }
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); }
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(); }
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()); }
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(); }
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); }
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(); }
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;
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"]); }
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"]); }
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); }
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); }
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()); }
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(); }
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(); }
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); }
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")); }
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")); }
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); }
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()); }
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 }); }
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); }
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 }); }