mirror of https://github.com/Squidex/squidex.git
9 changed files with 365 additions and 24 deletions
@ -0,0 +1,129 @@ |
|||||
|
// ==========================================================================
|
||||
|
// CommandsHandlerTests.cs
|
||||
|
// PinkParrot Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) PinkParrot Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Moq; |
||||
|
using PinkParrot.Infrastructure.CQRS.Events; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace PinkParrot.Infrastructure.CQRS.Commands |
||||
|
{ |
||||
|
public class CommandsHandlerTests |
||||
|
{ |
||||
|
private readonly Mock<IDomainObjectFactory> domainObjectFactory = new Mock<IDomainObjectFactory>(); |
||||
|
private readonly Mock<IDomainObjectRepository> domainObjectRepository = new Mock<IDomainObjectRepository>(); |
||||
|
private readonly TestCommandHandler sut; |
||||
|
private readonly Guid id = Guid.NewGuid(); |
||||
|
|
||||
|
private sealed class TestCommand : AggregateCommand |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
private sealed class TestDomainObject : DomainObject |
||||
|
{ |
||||
|
public TestDomainObject(Guid id, int version) : base(id, version) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected override void DispatchEvent(Envelope<IEvent> @event) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private sealed class TestCommandHandler : CommandHandler<TestDomainObject> |
||||
|
{ |
||||
|
public TestCommandHandler(IDomainObjectFactory domainObjectFactory, IDomainObjectRepository domainObjectRepository) |
||||
|
: base(domainObjectFactory, domainObjectRepository) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public override Task<bool> HandleAsync(CommandContext context) |
||||
|
{ |
||||
|
throw new NotImplementedException(); |
||||
|
} |
||||
|
|
||||
|
public IDomainObjectFactory TestFactory |
||||
|
{ |
||||
|
get { return Factory; } |
||||
|
} |
||||
|
|
||||
|
public IDomainObjectRepository TestRepository |
||||
|
{ |
||||
|
get { return Repository; } |
||||
|
} |
||||
|
|
||||
|
public Task CreateTestAsync(IAggregateCommand command, Action<TestDomainObject> creator) |
||||
|
{ |
||||
|
return CreateAsync(command, creator); |
||||
|
} |
||||
|
|
||||
|
public Task UpdateTestAsync(IAggregateCommand command, Action<TestDomainObject> updater) |
||||
|
{ |
||||
|
return UpdateAsync(command, updater); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public CommandsHandlerTests() |
||||
|
{ |
||||
|
sut = new TestCommandHandler(domainObjectFactory.Object, domainObjectRepository.Object); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_provide_factory() |
||||
|
{ |
||||
|
Assert.Equal(domainObjectFactory.Object, sut.TestFactory); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_provide_repository() |
||||
|
{ |
||||
|
Assert.Equal(domainObjectRepository.Object, sut.TestRepository); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_retrieve_from_repository_and_update() |
||||
|
{ |
||||
|
var command = new TestCommand { AggregateId = id }; |
||||
|
|
||||
|
var domainObject = new TestDomainObject(id, 123); |
||||
|
|
||||
|
domainObjectRepository.Setup(x => x.GetByIdAsync<TestDomainObject>(id, int.MaxValue)).Returns(Task.FromResult(domainObject)).Verifiable(); |
||||
|
domainObjectRepository.Setup(x => x.SaveAsync(domainObject, It.IsAny<Guid>())).Returns(Task.FromResult(true)).Verifiable(); |
||||
|
|
||||
|
var isCalled = false; |
||||
|
|
||||
|
await sut.UpdateTestAsync(command, x => isCalled = true); |
||||
|
|
||||
|
domainObjectRepository.VerifyAll(); |
||||
|
|
||||
|
Assert.True(isCalled); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_create_with_factory_and_update() |
||||
|
{ |
||||
|
var command = new TestCommand { AggregateId = id }; |
||||
|
|
||||
|
var domainObject = new TestDomainObject(id, 123); |
||||
|
|
||||
|
domainObjectFactory.Setup(x => x.CreateNew(typeof(TestDomainObject), id)).Returns(domainObject).Verifiable(); |
||||
|
domainObjectRepository.Setup(x => x.SaveAsync(domainObject, It.IsAny<Guid>())).Returns(Task.FromResult(true)).Verifiable(); |
||||
|
|
||||
|
var isCalled = false; |
||||
|
|
||||
|
await sut.CreateTestAsync(command, x => isCalled = true); |
||||
|
|
||||
|
domainObjectFactory.VerifyAll(); |
||||
|
domainObjectRepository.VerifyAll(); |
||||
|
|
||||
|
Assert.True(isCalled); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,116 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace PinkParrot.Infrastructure.CQRS.Commands |
||||
|
{ |
||||
|
public class InMemoryCommandBusTests |
||||
|
{ |
||||
|
private readonly TestCommand command = new TestCommand(); |
||||
|
|
||||
|
private sealed class TestCommand : ICommand |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
private sealed class HandledHandler : ICommandHandler |
||||
|
{ |
||||
|
public ICommand LastCommand; |
||||
|
|
||||
|
public Task<bool> HandleAsync(CommandContext context) |
||||
|
{ |
||||
|
LastCommand = context.Command; |
||||
|
|
||||
|
return Task.FromResult(true); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private sealed class NonHandledHandler : ICommandHandler |
||||
|
{ |
||||
|
public ICommand LastCommand; |
||||
|
|
||||
|
public Task<bool> HandleAsync(CommandContext context) |
||||
|
{ |
||||
|
LastCommand = context.Command; |
||||
|
|
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private sealed class ThrowHandledHandler : ICommandHandler |
||||
|
{ |
||||
|
public ICommand LastCommand; |
||||
|
|
||||
|
public Task<bool> HandleAsync(CommandContext context) |
||||
|
{ |
||||
|
LastCommand = context.Command; |
||||
|
|
||||
|
throw new InvalidOperationException(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private sealed class AfterThrowHandler : ICommandHandler |
||||
|
{ |
||||
|
public Exception LastException; |
||||
|
|
||||
|
public Task<bool> HandleAsync(CommandContext context) |
||||
|
{ |
||||
|
LastException = context.Exception; |
||||
|
|
||||
|
return Task.FromResult(false); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_not_set_handled_if_no_handler_registered() |
||||
|
{ |
||||
|
var sut = new InMemoryCommandBus(new ICommandHandler[0]); |
||||
|
var ctx = await sut.PublishAsync(command); |
||||
|
|
||||
|
Assert.False(ctx.IsHandled); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_not_set_succeeded_if_handler_returns_false() |
||||
|
{ |
||||
|
var handler = new NonHandledHandler(); |
||||
|
|
||||
|
var sut = new InMemoryCommandBus(new ICommandHandler[] { handler }); |
||||
|
var ctx = await sut.PublishAsync(command); |
||||
|
|
||||
|
Assert.Equal(command, handler.LastCommand); |
||||
|
Assert.False(ctx.IsSucceeded); |
||||
|
Assert.False(ctx.IsHandled); |
||||
|
Assert.Null(ctx.Exception); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_set_succeeded_if_handler_returns_true() |
||||
|
{ |
||||
|
var handler = new HandledHandler(); |
||||
|
|
||||
|
var sut = new InMemoryCommandBus(new ICommandHandler[] { handler }); |
||||
|
var ctx = await sut.PublishAsync(command); |
||||
|
|
||||
|
Assert.Equal(command, handler.LastCommand); |
||||
|
Assert.True(ctx.IsSucceeded); |
||||
|
Assert.True(ctx.IsHandled); |
||||
|
Assert.Null(ctx.Exception); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_throw_and_call_all_handlers_if_first_handler_fails() |
||||
|
{ |
||||
|
var handler1 = new ThrowHandledHandler(); |
||||
|
var handler2 = new AfterThrowHandler(); |
||||
|
|
||||
|
var sut = new InMemoryCommandBus(new ICommandHandler[] { handler1, handler2 }); |
||||
|
|
||||
|
await Assert.ThrowsAsync<InvalidOperationException>(async () => await sut.PublishAsync(command)); |
||||
|
|
||||
|
Assert.Equal(command, handler1.LastCommand); |
||||
|
Assert.IsType<InvalidOperationException>(handler2.LastException); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using NodaTime; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace PinkParrot.Infrastructure.CQRS |
||||
|
{ |
||||
|
public class EnvelopeExtensionsTests |
||||
|
{ |
||||
|
private readonly Envelope<string> sut = new Envelope<string>(string.Empty); |
||||
|
private readonly CultureInfo culture = CultureInfo.InvariantCulture; |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_set_and_get_timestamp() |
||||
|
{ |
||||
|
var timestamp = SystemClock.Instance.GetCurrentInstant(); |
||||
|
|
||||
|
sut.SetTimestamp(timestamp); |
||||
|
|
||||
|
Assert.Equal(timestamp, sut.Headers.Timestamp()); |
||||
|
Assert.Equal(timestamp, sut.Headers["Timestamp"].ToInstant(culture)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_set_and_get_commit_id() |
||||
|
{ |
||||
|
var commitId = Guid.NewGuid(); |
||||
|
|
||||
|
sut.SetCommitId(commitId); |
||||
|
|
||||
|
Assert.Equal(commitId, sut.Headers.CommitId()); |
||||
|
Assert.Equal(commitId, sut.Headers["CommitId"].ToGuid(culture)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_set_and_get_event_id() |
||||
|
{ |
||||
|
var commitId = Guid.NewGuid(); |
||||
|
|
||||
|
sut.SetEventId(commitId); |
||||
|
|
||||
|
Assert.Equal(commitId, sut.Headers.EventId()); |
||||
|
Assert.Equal(commitId, sut.Headers["EventId"].ToGuid(culture)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_set_and_get_aggregate_id() |
||||
|
{ |
||||
|
var commitId = Guid.NewGuid(); |
||||
|
|
||||
|
sut.SetAggregateId(commitId); |
||||
|
|
||||
|
Assert.Equal(commitId, sut.Headers.AggregateId()); |
||||
|
Assert.Equal(commitId, sut.Headers["AggregateId"].ToGuid(culture)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_set_and_get_app_id() |
||||
|
{ |
||||
|
var commitId = Guid.NewGuid(); |
||||
|
|
||||
|
sut.SetAppId(commitId); |
||||
|
|
||||
|
Assert.Equal(commitId, sut.Headers.AppId()); |
||||
|
Assert.Equal(commitId, sut.Headers["AppId"].ToGuid(culture)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_set_and_get_event_number() |
||||
|
{ |
||||
|
const int eventNumber = 123; |
||||
|
|
||||
|
sut.SetEventNumber(eventNumber); |
||||
|
|
||||
|
Assert.Equal(eventNumber, sut.Headers.EventNumber()); |
||||
|
Assert.Equal(eventNumber, sut.Headers["EventNumber"].ToInt32(culture)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue