mirror of https://github.com/Squidex/squidex.git
46 changed files with 868 additions and 115 deletions
@ -0,0 +1,23 @@ |
|||
// ==========================================================================
|
|||
// ContentCreated.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using Newtonsoft.Json.Linq; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
|
|||
namespace Squidex.Events.Contents |
|||
{ |
|||
[TypeName("ContentCreatedEvent")] |
|||
public class ContentCreated : IEvent |
|||
{ |
|||
public Guid SchemaId { get; set; } |
|||
|
|||
public JObject Data { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
// ==========================================================================
|
|||
// ContentDeleted.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
|
|||
namespace Squidex.Events.Contents |
|||
{ |
|||
[TypeName("ContentDeletedEvent")] |
|||
public class ContentDeleted : IEvent |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
// ==========================================================================
|
|||
// ContentUpdated.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using Newtonsoft.Json.Linq; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
|
|||
namespace Squidex.Events.Contents |
|||
{ |
|||
[TypeName("ContentUpdatedEvent")] |
|||
public class ContentUpdated : IEvent |
|||
{ |
|||
public JObject Data { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
// ==========================================================================
|
|||
// CreateContent.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
namespace Squidex.Write.Contents.Commands |
|||
{ |
|||
public class CreateContent : ContentDataCommand |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
// ==========================================================================
|
|||
// DeleteContent.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
namespace Squidex.Write.Contents.Commands |
|||
{ |
|||
public class DeleteContent : SchemaCommand |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
// ==========================================================================
|
|||
// UpdateContent.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
namespace Squidex.Write.Contents.Commands |
|||
{ |
|||
public class UpdateContent : ContentDataCommand |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,89 @@ |
|||
// ==========================================================================
|
|||
// ContentCommandHandler.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Commands; |
|||
using Squidex.Infrastructure.Dispatching; |
|||
using Squidex.Read.Apps.Services; |
|||
using Squidex.Read.Schemas.Services; |
|||
using Squidex.Write.Contents.Commands; |
|||
|
|||
namespace Squidex.Write.Contents |
|||
{ |
|||
public class ContentCommandHandler : ICommandHandler |
|||
{ |
|||
private readonly IAggregateHandler handler; |
|||
private readonly IAppProvider appProvider; |
|||
private readonly ISchemaProvider schemaProvider; |
|||
|
|||
public ContentCommandHandler( |
|||
IAggregateHandler handler, |
|||
IAppProvider appProvider, |
|||
ISchemaProvider schemaProvider) |
|||
{ |
|||
Guard.NotNull(handler, nameof(handler)); |
|||
Guard.NotNull(appProvider, nameof(appProvider)); |
|||
Guard.NotNull(schemaProvider, nameof(schemaProvider)); |
|||
|
|||
this.handler = handler; |
|||
this.appProvider = appProvider; |
|||
this.schemaProvider = schemaProvider; |
|||
} |
|||
|
|||
protected async Task On(CreateContent command, CommandContext context) |
|||
{ |
|||
await ValidateAsync(command, () => "Failed to create content"); |
|||
|
|||
await handler.CreateAsync<ContentDomainObject>(command, s => |
|||
{ |
|||
s.Create(command); |
|||
|
|||
context.Succeed(command.AggregateId); |
|||
}); |
|||
} |
|||
|
|||
protected async Task On(UpdateContent command, CommandContext context) |
|||
{ |
|||
await ValidateAsync(command, () => "Failed to update content"); |
|||
|
|||
await handler.UpdateAsync<ContentDomainObject>(command, s => s.Update(command)); |
|||
} |
|||
|
|||
protected Task On(DeleteContent command, CommandContext context) |
|||
{ |
|||
return handler.UpdateAsync<ContentDomainObject>(command, s => s.Delete(command)); |
|||
} |
|||
|
|||
public Task<bool> HandleAsync(CommandContext context) |
|||
{ |
|||
return context.IsHandled ? Task.FromResult(false) : this.DispatchActionAsync(context.Command, context); |
|||
} |
|||
|
|||
private async Task ValidateAsync(ContentDataCommand command, Func<string> message) |
|||
{ |
|||
Guard.Valid(command, nameof(command), message); |
|||
|
|||
var taskForApp = appProvider.FindAppByIdAsync(command.AppId); |
|||
var taskForSchema = schemaProvider.FindSchemaByIdAsync(command.SchemaId); |
|||
|
|||
await Task.WhenAll(taskForApp, taskForSchema); |
|||
|
|||
var errors = new List<ValidationError>(); |
|||
|
|||
await taskForSchema.Result.Schema.ValidateAsync(command.Data, errors, new HashSet<Language>(taskForApp.Result.Languages)); |
|||
|
|||
if (errors.Count > 0) |
|||
{ |
|||
throw new ValidationException(message(), errors); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
// ==========================================================================
|
|||
// ContentDataCommand.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Collections.Generic; |
|||
using Newtonsoft.Json.Linq; |
|||
using Squidex.Infrastructure; |
|||
|
|||
namespace Squidex.Write.Contents |
|||
{ |
|||
public class ContentDataCommand : SchemaCommand, IValidatable |
|||
{ |
|||
public JObject Data { get; set; } |
|||
|
|||
public void Validate(IList<ValidationError> errors) |
|||
{ |
|||
if (Data == null) |
|||
{ |
|||
errors.Add(new ValidationError("Data cannot be null", nameof(Data))); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,99 @@ |
|||
// ==========================================================================
|
|||
// ContentDomainObject.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using Squidex.Events.Contents; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
using Squidex.Infrastructure.Dispatching; |
|||
using Squidex.Infrastructure.Reflection; |
|||
using Squidex.Write.Contents.Commands; |
|||
|
|||
namespace Squidex.Write.Contents |
|||
{ |
|||
public class ContentDomainObject : DomainObject |
|||
{ |
|||
private bool isDeleted; |
|||
private bool isCreated; |
|||
|
|||
public bool IsDeleted |
|||
{ |
|||
get { return isDeleted; } |
|||
} |
|||
|
|||
public ContentDomainObject(Guid id, int version) |
|||
: base(id, version) |
|||
{ |
|||
} |
|||
|
|||
protected void On(ContentCreated @event) |
|||
{ |
|||
isCreated = true; |
|||
} |
|||
|
|||
protected void On(ContentDeleted @event) |
|||
{ |
|||
isDeleted = true; |
|||
} |
|||
|
|||
public ContentDomainObject Create(CreateContent command) |
|||
{ |
|||
Guard.Valid(command, nameof(command), () => "Cannot create content"); |
|||
|
|||
VerifyNotCreated(); |
|||
|
|||
RaiseEvent(SimpleMapper.Map(command, new ContentCreated())); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
public ContentDomainObject Update(UpdateContent command) |
|||
{ |
|||
Guard.Valid(command, nameof(command), () => "Cannot update content"); |
|||
|
|||
VerifyCreatedAndNotDeleted(); |
|||
|
|||
RaiseEvent(SimpleMapper.Map(command, new ContentUpdated())); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
public ContentDomainObject Delete(DeleteContent command) |
|||
{ |
|||
Guard.NotNull(command, nameof(command)); |
|||
|
|||
VerifyCreatedAndNotDeleted(); |
|||
|
|||
RaiseEvent(SimpleMapper.Map(command, new ContentDeleted())); |
|||
|
|||
return this; |
|||
} |
|||
|
|||
private void VerifyNotCreated() |
|||
{ |
|||
if (isCreated) |
|||
{ |
|||
throw new DomainException("Content has already been created."); |
|||
} |
|||
} |
|||
|
|||
private void VerifyCreatedAndNotDeleted() |
|||
{ |
|||
if (isDeleted || !isCreated) |
|||
{ |
|||
throw new DomainException("Content has already been deleted or not created yet."); |
|||
} |
|||
} |
|||
|
|||
protected override void DispatchEvent(Envelope<IEvent> @event) |
|||
{ |
|||
this.DispatchAction(@event.Payload); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
// ==========================================================================
|
|||
// ISchemaCommand.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Write |
|||
{ |
|||
public interface ISchemaCommand : IAppCommand |
|||
{ |
|||
Guid SchemaId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
// ==========================================================================
|
|||
// SchemaAggregateCommand.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
|
|||
namespace Squidex.Write |
|||
{ |
|||
public abstract class SchemaAggregateCommand : AppCommand, ISchemaCommand |
|||
{ |
|||
Guid ISchemaCommand.SchemaId |
|||
{ |
|||
get |
|||
{ |
|||
return AggregateId; |
|||
} |
|||
set |
|||
{ |
|||
AggregateId = value; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Squidex.Write |
|||
{ |
|||
public abstract class SchemaCommand : AppCommand, ISchemaCommand |
|||
{ |
|||
public Guid SchemaId { get; set; } |
|||
} |
|||
} |
|||
@ -1,69 +0,0 @@ |
|||
// ==========================================================================
|
|||
// EnrichWithSchemaAggregateIdHandler.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Commands; |
|||
using Squidex.Read.Schemas.Services; |
|||
using Squidex.Write; |
|||
using Squidex.Write.Schemas; |
|||
|
|||
// ReSharper disable InvertIf
|
|||
|
|||
namespace Squidex.Pipeline.CommandHandlers |
|||
{ |
|||
public sealed class EnrichWithSchemaAggregateIdHandler : ICommandHandler |
|||
{ |
|||
private readonly ISchemaProvider schemaProvider; |
|||
private readonly IActionContextAccessor actionContextAccessor; |
|||
|
|||
public EnrichWithSchemaAggregateIdHandler(ISchemaProvider schemaProvider, IActionContextAccessor actionContextAccessor) |
|||
{ |
|||
this.schemaProvider = schemaProvider; |
|||
|
|||
this.actionContextAccessor = actionContextAccessor; |
|||
} |
|||
|
|||
public async Task<bool> HandleAsync(CommandContext context) |
|||
{ |
|||
var aggregateCommand = context.Command as IAggregateCommand; |
|||
|
|||
if (aggregateCommand == null || aggregateCommand.AggregateId != Guid.Empty) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
var appCommand = context.Command as IAppCommand; |
|||
|
|||
if (appCommand == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
var routeValues = actionContextAccessor.ActionContext.RouteData.Values; |
|||
|
|||
if (routeValues.ContainsKey("name")) |
|||
{ |
|||
var schemaName = routeValues["name"].ToString(); |
|||
|
|||
var schema = await schemaProvider.ProvideSchemaByNameAsync(appCommand.AppId, schemaName); |
|||
|
|||
if (schema == null) |
|||
{ |
|||
throw new DomainObjectNotFoundException(schemaName, typeof(SchemaDomainObject)); |
|||
} |
|||
|
|||
aggregateCommand.AggregateId = schema.Id; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
// ==========================================================================
|
|||
// EnrichWithSchemaIdHandler.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc.Infrastructure; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Commands; |
|||
using Squidex.Read.Schemas.Services; |
|||
using Squidex.Write; |
|||
using Squidex.Write.Schemas; |
|||
|
|||
// ReSharper disable InvertIf
|
|||
|
|||
namespace Squidex.Pipeline.CommandHandlers |
|||
{ |
|||
public sealed class EnrichWithSchemaIdHandler : ICommandHandler |
|||
{ |
|||
private readonly ISchemaProvider schemaProvider; |
|||
private readonly IActionContextAccessor actionContextAccessor; |
|||
|
|||
public EnrichWithSchemaIdHandler(ISchemaProvider schemaProvider, IActionContextAccessor actionContextAccessor) |
|||
{ |
|||
this.schemaProvider = schemaProvider; |
|||
|
|||
this.actionContextAccessor = actionContextAccessor; |
|||
} |
|||
|
|||
public async Task<bool> HandleAsync(CommandContext context) |
|||
{ |
|||
var schemaCommand = context.Command as ISchemaCommand; |
|||
|
|||
if (schemaCommand != null) |
|||
{ |
|||
var routeValues = actionContextAccessor.ActionContext.RouteData.Values; |
|||
|
|||
if (routeValues.ContainsKey("name")) |
|||
{ |
|||
var schemaName = routeValues["name"].ToString(); |
|||
|
|||
var schema = await schemaProvider.FindSchemaByNameAsync(schemaCommand.AppId, schemaName); |
|||
|
|||
if (schema == null) |
|||
{ |
|||
throw new DomainObjectNotFoundException(schemaName, typeof(SchemaDomainObject)); |
|||
} |
|||
|
|||
schemaCommand.SchemaId = schema.Id; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
// ==========================================================================
|
|||
// ContentCommandHandlerTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Moq; |
|||
using Newtonsoft.Json.Linq; |
|||
using Squidex.Core.Schemas; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS.Commands; |
|||
using Squidex.Read.Apps; |
|||
using Squidex.Read.Apps.Services; |
|||
using Squidex.Read.Schemas.Repositories; |
|||
using Squidex.Read.Schemas.Services; |
|||
using Squidex.Write.Contents.Commands; |
|||
using Squidex.Write.Utils; |
|||
using Xunit; |
|||
|
|||
// ReSharper disable ConvertToConstant.Local
|
|||
|
|||
namespace Squidex.Write.Contents |
|||
{ |
|||
public class ContentCommandHandlerTests : HandlerTestBase<ContentDomainObject> |
|||
{ |
|||
private readonly ContentCommandHandler sut; |
|||
private readonly ContentDomainObject content; |
|||
private readonly Mock<ISchemaProvider> schemaProvider = new Mock<ISchemaProvider>(); |
|||
private readonly Mock<IAppProvider> appProvider = new Mock<IAppProvider>(); |
|||
private readonly Mock<ISchemaEntityWithSchema> schemaEntity = new Mock<ISchemaEntityWithSchema>(); |
|||
private readonly Mock<IAppEntity> appEntity = new Mock<IAppEntity>(); |
|||
private readonly Guid schemaId = Guid.NewGuid(); |
|||
private readonly Guid appId = Guid.NewGuid(); |
|||
private readonly JObject data = new JObject(new JProperty("field", 1)); |
|||
|
|||
public ContentCommandHandlerTests() |
|||
{ |
|||
var schema = |
|||
Schema.Create("my-schema", new SchemaProperties()) |
|||
.AddOrUpdateField(new NumberField(1, "field", new NumberFieldProperties { IsRequired = true })); |
|||
|
|||
content = new ContentDomainObject(Id, 0); |
|||
|
|||
sut = new ContentCommandHandler(Handler, appProvider.Object, schemaProvider.Object); |
|||
|
|||
appEntity.Setup(x => x.Languages).Returns(new[] { Language.GetLanguage("de") }); |
|||
appProvider.Setup(x => x.FindAppByIdAsync(appId)).Returns(Task.FromResult(appEntity.Object)); |
|||
|
|||
schemaEntity.Setup(x => x.Schema).Returns(schema); |
|||
schemaProvider.Setup(x => x.FindSchemaByIdAsync(schemaId)).Returns(Task.FromResult(schemaEntity.Object)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Create_should_throw_exception_if_data_is_not_valid() |
|||
{ |
|||
var command = new CreateContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = new JObject() }; |
|||
var context = new CommandContext(command); |
|||
|
|||
await TestCreate(content, async _ => |
|||
{ |
|||
await Assert.ThrowsAsync<ValidationException>(() => sut.HandleAsync(context)); |
|||
}, false); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Create_should_create_content() |
|||
{ |
|||
var command = new CreateContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = data }; |
|||
var context = new CommandContext(command); |
|||
|
|||
await TestCreate(content, async _ => |
|||
{ |
|||
await sut.HandleAsync(context); |
|||
}); |
|||
|
|||
Assert.Equal(Id, context.Result<Guid>()); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Update_should_throw_exception_if_data_is_not_valid() |
|||
{ |
|||
CreateContent(); |
|||
|
|||
var command = new UpdateContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = new JObject() }; |
|||
var context = new CommandContext(command); |
|||
|
|||
await TestUpdate(content, async _ => |
|||
{ |
|||
await Assert.ThrowsAsync<ValidationException>(() => sut.HandleAsync(context)); |
|||
}, false); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Update_should_update_domain_object() |
|||
{ |
|||
CreateContent(); |
|||
|
|||
var command = new UpdateContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = data }; |
|||
var context = new CommandContext(command); |
|||
|
|||
await TestUpdate(content, async _ => |
|||
{ |
|||
await sut.HandleAsync(context); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Delete_should_update_domain_object() |
|||
{ |
|||
CreateContent(); |
|||
|
|||
var command = new DeleteContent { AggregateId = Id }; |
|||
var context = new CommandContext(command); |
|||
|
|||
await TestUpdate(content, async _ => |
|||
{ |
|||
await sut.HandleAsync(context); |
|||
}); |
|||
} |
|||
|
|||
private void CreateContent() |
|||
{ |
|||
content.Create(new CreateContent { Data = data }); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,147 @@ |
|||
// ==========================================================================
|
|||
// ContentDomainObjectTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Linq; |
|||
using FluentAssertions; |
|||
using Newtonsoft.Json.Linq; |
|||
using Squidex.Events.Contents; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.CQRS; |
|||
using Squidex.Infrastructure.CQRS.Events; |
|||
using Squidex.Write.Contents.Commands; |
|||
using Xunit; |
|||
|
|||
// ReSharper disable ConvertToConstant.Local
|
|||
|
|||
namespace Squidex.Write.Contents |
|||
{ |
|||
[Collection("Content")] |
|||
public class ContentDomainObjectTests |
|||
{ |
|||
private readonly Guid appId = Guid.NewGuid(); |
|||
private readonly ContentDomainObject sut; |
|||
private readonly JObject data = new JObject(); |
|||
|
|||
public ContentDomainObjectTests() |
|||
{ |
|||
sut = new ContentDomainObject(Guid.NewGuid(), 0); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Create_should_throw_if_created() |
|||
{ |
|||
sut.Create(new CreateContent { Data = data }); |
|||
|
|||
Assert.Throws<DomainException>(() => sut.Create(new CreateContent { Data = data })); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Create_should_throw_if_command_is_not_valid() |
|||
{ |
|||
Assert.Throws<ValidationException>(() => sut.Create(new CreateContent())); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Create_should_create_events() |
|||
{ |
|||
sut.Create(new CreateContent { Data = data, AppId = appId }); |
|||
|
|||
sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() |
|||
.ShouldBeEquivalentTo( |
|||
new IEvent[] |
|||
{ |
|||
new ContentCreated { Data = data } |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_throw_if_not_created() |
|||
{ |
|||
Assert.Throws<DomainException>(() => sut.Update(new UpdateContent { Data = data })); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_throw_if_schema_is_deleted() |
|||
{ |
|||
CreateContent(); |
|||
DeleteContent(); |
|||
|
|||
Assert.Throws<ValidationException>(() => sut.Update(new UpdateContent())); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_throw_if_command_is_not_valid() |
|||
{ |
|||
CreateContent(); |
|||
|
|||
Assert.Throws<ValidationException>(() => sut.Update(new UpdateContent())); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_create_events() |
|||
{ |
|||
CreateContent(); |
|||
|
|||
sut.Update(new UpdateContent { Data = data }); |
|||
|
|||
sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() |
|||
.ShouldBeEquivalentTo( |
|||
new IEvent[] |
|||
{ |
|||
new ContentUpdated { Data = data } |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Delete_should_throw_if_not_created() |
|||
{ |
|||
Assert.Throws<DomainException>(() => sut.Delete(new DeleteContent())); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Delete_should_throw_if_already_deleted() |
|||
{ |
|||
CreateContent(); |
|||
DeleteContent(); |
|||
|
|||
Assert.Throws<DomainException>(() => sut.Delete(new DeleteContent())); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Delete_should_update_properties_create_events() |
|||
{ |
|||
CreateContent(); |
|||
|
|||
sut.Delete(new DeleteContent()); |
|||
|
|||
Assert.True(sut.IsDeleted); |
|||
|
|||
sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() |
|||
.ShouldBeEquivalentTo( |
|||
new IEvent[] |
|||
{ |
|||
new ContentDeleted() |
|||
}); |
|||
} |
|||
|
|||
private void CreateContent() |
|||
{ |
|||
sut.Create(new CreateContent { Data = data, AppId = appId }); |
|||
|
|||
((IAggregate)sut).ClearUncommittedEvents(); |
|||
} |
|||
|
|||
private void DeleteContent() |
|||
{ |
|||
sut.Delete(new DeleteContent()); |
|||
|
|||
((IAggregate)sut).ClearUncommittedEvents(); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue