// ========================================================================== // AggregateHandlerTests.cs // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== using System; using System.Collections.Generic; using System.Threading.Tasks; using FakeItEasy; using Squidex.Infrastructure.Commands.TestHelpers; using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.Log; using Squidex.Infrastructure.States; using Squidex.Infrastructure.Tasks; using Xunit; namespace Squidex.Infrastructure.Commands { public class AggregateHandlerTests { private readonly ISemanticLog log = A.Fake(); private readonly IServiceProvider serviceProvider = A.Fake(); private readonly IStore store = A.Fake(); private readonly IStateFactory stateFactory = A.Fake(); private readonly IPersistence persistence = A.Fake>(); private readonly Envelope event1 = new Envelope(new MyEvent()); private readonly Envelope event2 = new Envelope(new MyEvent()); private readonly CommandContext context; private readonly Guid domainObjectId = Guid.NewGuid(); private readonly MyDomainObject domainObject = new MyDomainObject(); private readonly AggregateHandler sut; public sealed class MyEvent : IEvent { } public AggregateHandlerTests() { context = new CommandContext(new MyCommand { AggregateId = domainObjectId }); A.CallTo(() => store.WithSnapshots(domainObjectId.ToString(), A>.Ignored)) .Returns(persistence); A.CallTo(() => stateFactory.CreateAsync(domainObjectId.ToString())) .Returns(Task.FromResult(domainObject)); A.CallTo(() => stateFactory.GetSingleAsync(domainObjectId.ToString())) .Returns(Task.FromResult(domainObject)); sut = new AggregateHandler(stateFactory, serviceProvider, log); domainObject.ActivateAsync(domainObjectId.ToString(), store).Wait(); } [Fact] public Task Create_with_task_should_throw_exception_if_not_aggregate_command() { return Assert.ThrowsAnyAsync(() => sut.CreateAsync(new CommandContext(A.Dummy()), x => TaskHelper.False)); } [Fact] public Task Create_synced_with_task_should_throw_exception_if_not_aggregate_command() { return Assert.ThrowsAnyAsync(() => sut.CreateSyncedAsync(new CommandContext(A.Dummy()), x => TaskHelper.False)); } [Fact] public async Task Create_with_task_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.CreateAsync(context, async x => { x.RaiseEvent(new MyEvent()); await Task.Yield(); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result>()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public async Task Create_synced_with_task_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.CreateSyncedAsync(context, async x => { x.RaiseEvent(new MyEvent()); await Task.Yield(); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result>()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public async Task Create_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.CreateAsync(context, x => { x.RaiseEvent(new MyEvent()); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result>()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public async Task Create_synced_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.CreateSyncedAsync(context, x => { x.RaiseEvent(new MyEvent()); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result>()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public Task Update_with_task_should_throw_exception_if_not_aggregate_command() { return Assert.ThrowsAnyAsync(() => sut.UpdateAsync(new CommandContext(A.Dummy()), x => TaskHelper.False)); } [Fact] public Task Update_synced_with_task_should_throw_exception_if_not_aggregate_command() { return Assert.ThrowsAnyAsync(() => sut.UpdateSyncedAsync(new CommandContext(A.Dummy()), x => TaskHelper.False)); } [Fact] public async Task Update_with_task_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.UpdateAsync(context, async x => { x.RaiseEvent(new MyEvent()); await Task.Yield(); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public async Task Update_synced_with_task_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.UpdateSyncedAsync(context, async x => { x.RaiseEvent(new MyEvent()); await Task.Yield(); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public async Task Update_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.UpdateAsync(context, x => { x.RaiseEvent(new MyEvent()); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } [Fact] public async Task Update_synced_should_create_domain_object_and_save() { MyDomainObject passedDomainObject = null; await sut.UpdateSyncedAsync(context, x => { x.RaiseEvent(new MyEvent()); passedDomainObject = x; }); Assert.Equal(domainObject, passedDomainObject); Assert.NotNull(context.Result()); A.CallTo(() => persistence.WriteEventsAsync(A>>.Ignored)) .MustHaveHappened(); } } }