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