From b82ec725a675187a3c6fb7d922e0181978721a95 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sat, 11 Feb 2017 21:16:32 +0100 Subject: [PATCH] Tests fixed --- Squidex.sln | 2 - .../RedisExternalSystem.cs | 2 +- .../CQRS/Commands/ICommand.cs | 1 + .../CQRS/Events/EventReceiver.cs | 11 +- src/Squidex.Infrastructure/Language.cs | 5 + src/Squidex.Infrastructure/NamedId.cs | 4 +- .../Apps/MongoAppRepository_EventHandling.cs | 8 +- .../MongoSchemaRepository_EventHandling.cs | 11 +- .../Apps/AppHistoryEventsCreator.cs | 17 +- .../Apps/Repositories/IAppRepository.cs | 3 +- .../Apps/Services/IAppProvider.cs | 3 +- .../Implementations/CachingAppProvider.cs | 55 +-- .../History/HistoryEventToStore.cs | 4 +- .../Schemas/Repositories/ISchemaRepository.cs | 3 +- .../Schemas/Services/ISchemaProvider.cs | 5 +- .../Implementations/CachingSchemaProvider.cs | 64 +--- src/Squidex.Write/Apps/AppDomainObject.cs | 12 +- .../Contents/ContentDomainObject.cs | 2 +- src/Squidex.Write/SchemaAggregateCommand.cs | 2 +- .../Schemas/SchemaDomainObject.cs | 12 +- src/Squidex.Write/SquidexCommand.cs | 3 +- .../Config/Domain/StoreMongoDbModule.cs | 4 +- src/Squidex/Config/Domain/Usages.cs | 8 +- .../contents/contents-page.component.html | 2 +- .../pages/schemas/schemas-page.component.html | 2 +- src/Squidex/appsettings.json | 4 +- .../DefaultDomainObjectRepositoryTests.cs | 24 +- .../EnrichWithTimestampHandlerTests.cs | 4 +- .../CQRS/EnvelopeExtensionsTests.cs | 11 - .../Events/EnrichWithActorProcessorTests.cs | 55 --- .../CQRS/Events/EventReceiverTests.cs | 150 ++++---- .../CQRS/Replay/ReplayGeneratorTests.cs | 82 ---- .../LanguageTests.cs | 22 +- .../NamedIdTest.cs | 148 ++++++++ .../PropertiesBagTests.cs | 4 +- .../RefTokenTests.cs | 37 +- .../TestHelpers/JsonHelper.cs | 40 ++ .../Apps/CachingAppProviderTests.cs | 114 ++---- .../Schemas/CachingSchemaProviderTests.cs | 114 ++---- .../Apps/AppCommandHandlerTests.cs | 67 ++-- .../Apps/AppDomainObjectTests.cs | 336 +++++++++++------ .../Contents/ContentCommandHandlerTests.cs | 49 +-- .../Contents/ContentDomainObjectTests.cs | 186 +++++---- .../EnrichWithAppIdProcessorTests.cs | 71 ---- .../EnrichWithSchemaIdProcessorTests.cs | 74 ---- .../Schemas/SchemaCommandHandlerTests.cs | 59 ++- .../Schemas/SchemaDomainObjectTests.cs | 356 +++++++++++------- .../TestHelpers/AssertHelper.cs | 31 ++ .../{Utils => TestHelpers}/HandlerTestBase.cs | 71 +++- 49 files changed, 1171 insertions(+), 1183 deletions(-) delete mode 100644 tests/Squidex.Infrastructure.Tests/CQRS/Events/EnrichWithActorProcessorTests.cs delete mode 100644 tests/Squidex.Infrastructure.Tests/CQRS/Replay/ReplayGeneratorTests.cs create mode 100644 tests/Squidex.Infrastructure.Tests/NamedIdTest.cs create mode 100644 tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs delete mode 100644 tests/Squidex.Write.Tests/EnrichWithAppIdProcessorTests.cs delete mode 100644 tests/Squidex.Write.Tests/EnrichWithSchemaIdProcessorTests.cs create mode 100644 tests/Squidex.Write.Tests/TestHelpers/AssertHelper.cs rename tests/Squidex.Write.Tests/{Utils => TestHelpers}/HandlerTestBase.cs (55%) diff --git a/Squidex.sln b/Squidex.sln index fbf5f53e3..133daf848 100644 --- a/Squidex.sln +++ b/Squidex.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{24A3171D-2905-49C9-8A49-A473799014E8}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4B5539DB-F68E-4DBA-B22A-72B9FE7FE2D8}" ProjectSection(SolutionItems) = preProject global.json = global.json diff --git a/src/Squidex.Infrastructure.Redis/RedisExternalSystem.cs b/src/Squidex.Infrastructure.Redis/RedisExternalSystem.cs index 161bf942c..545bdd99a 100644 --- a/src/Squidex.Infrastructure.Redis/RedisExternalSystem.cs +++ b/src/Squidex.Infrastructure.Redis/RedisExternalSystem.cs @@ -11,7 +11,7 @@ using StackExchange.Redis; namespace Squidex.Infrastructure.Redis { - public class RedisExternalSystem + public sealed class RedisExternalSystem : IExternalSystem { private readonly IConnectionMultiplexer redis; diff --git a/src/Squidex.Infrastructure/CQRS/Commands/ICommand.cs b/src/Squidex.Infrastructure/CQRS/Commands/ICommand.cs index 0ec0c1dde..c1834662e 100644 --- a/src/Squidex.Infrastructure/CQRS/Commands/ICommand.cs +++ b/src/Squidex.Infrastructure/CQRS/Commands/ICommand.cs @@ -5,6 +5,7 @@ // Copyright (c) Squidex Group // All rights reserved. // ========================================================================== + namespace Squidex.Infrastructure.CQRS.Commands { public interface ICommand diff --git a/src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs b/src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs index 645e08689..98cb5481d 100644 --- a/src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs +++ b/src/Squidex.Infrastructure/CQRS/Events/EventReceiver.cs @@ -46,7 +46,14 @@ namespace Squidex.Infrastructure.CQRS.Events { if (disposing) { - timer?.Dispose(); + try + { + timer?.Dispose(); + } + catch (Exception ex) + { + logger.LogCritical(InfrastructureErrors.EventHandlingFailed, ex, "Event stream {0} has been aborted"); + } } } @@ -98,6 +105,8 @@ namespace Squidex.Infrastructure.CQRS.Events try { await consumer.On(@event, eventNumber); + + logger.LogDebug("[{0}]: Handled event {1} ({2})", consumer, @event.Payload, @event.Headers.EventId()); } catch (Exception ex) { diff --git a/src/Squidex.Infrastructure/Language.cs b/src/Squidex.Infrastructure/Language.cs index cae71c3d9..b0ad82847 100644 --- a/src/Squidex.Infrastructure/Language.cs +++ b/src/Squidex.Infrastructure/Language.cs @@ -112,5 +112,10 @@ namespace Squidex.Infrastructure return null; } + + public override string ToString() + { + return EnglishName; + } } } \ No newline at end of file diff --git a/src/Squidex.Infrastructure/NamedId.cs b/src/Squidex.Infrastructure/NamedId.cs index 8d7cba263..182bbacc1 100644 --- a/src/Squidex.Infrastructure/NamedId.cs +++ b/src/Squidex.Infrastructure/NamedId.cs @@ -38,12 +38,12 @@ namespace Squidex.Infrastructure public bool Equals(NamedId other) { - return other != null && (ReferenceEquals(this, other) || Id.Equals(other.Id)); + return other != null && (ReferenceEquals(this, other) || (Id.Equals(other.Id) && Name.Equals(other.Name))); } public override int GetHashCode() { - return Id.GetHashCode(); + return (Id.GetHashCode() * 397) ^ Name.GetHashCode(); } } } diff --git a/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs b/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs index 68b68ae5a..de55df60f 100644 --- a/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs +++ b/src/Squidex.Read.MongoDb/Apps/MongoAppRepository_EventHandling.cs @@ -21,7 +21,7 @@ namespace Squidex.Read.MongoDb.Apps { public partial class MongoAppRepository { - public event Action AppSaved; + public event Action> AppSaved; public Task On(Envelope @event) { @@ -35,7 +35,7 @@ namespace Squidex.Read.MongoDb.Apps SimpleMapper.Map(@event, a); }); - AppSaved?.Invoke(headers.AggregateId()); + AppSaved?.Invoke(@event.AppId); } protected Task On(AppContributorAssigned @event, EnvelopeHeaders headers) @@ -104,11 +104,11 @@ namespace Squidex.Read.MongoDb.Apps }); } - public async Task UpdateAsync(SquidexEvent @event, EnvelopeHeaders headers, Action updater) + public async Task UpdateAsync(AppEvent @event, EnvelopeHeaders headers, Action updater) { await Collection.UpdateAsync(@event, headers, updater); - AppSaved?.Invoke(headers.AggregateId()); + AppSaved?.Invoke(@event.AppId); } } } diff --git a/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs b/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs index a29b4b68a..e78b8fa9d 100644 --- a/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs +++ b/src/Squidex.Read.MongoDb/Schemas/MongoSchemaRepository_EventHandling.cs @@ -12,6 +12,7 @@ using Squidex.Core.Schemas; using Squidex.Events; using Squidex.Events.Schemas; using Squidex.Events.Schemas.Utils; +using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; using Squidex.Infrastructure.CQRS.Events; using Squidex.Infrastructure.Dispatching; @@ -22,7 +23,7 @@ namespace Squidex.Read.MongoDb.Schemas { public partial class MongoSchemaRepository { - public event Action SchemaSaved; + public event Action, NamedId> SchemaSaved; public Task On(Envelope @event) { @@ -35,7 +36,7 @@ namespace Squidex.Read.MongoDb.Schemas await Collection.CreateAsync(@event, headers, s => { UpdateSchema(s, schema); SimpleMapper.Map(@event, s); }); - SchemaSaved?.Invoke(headers.AggregateId()); + SchemaSaved?.Invoke(@event.AppId, @event.SchemaId); } protected Task On(FieldDeleted @event, EnvelopeHeaders headers) @@ -92,14 +93,14 @@ namespace Squidex.Read.MongoDb.Schemas { await Collection.UpdateAsync(@event, headers, s => s.IsDeleted = true); - SchemaSaved?.Invoke(headers.AggregateId()); + SchemaSaved?.Invoke(@event.AppId, @event.SchemaId); } - private async Task UpdateSchema(SquidexEvent @event, EnvelopeHeaders headers, Func updater) + private async Task UpdateSchema(SchemaEvent @event, EnvelopeHeaders headers, Func updater) { await Collection.UpdateAsync(@event, headers, e => UpdateSchema(e, updater)); - SchemaSaved?.Invoke(headers.AggregateId()); + SchemaSaved?.Invoke(@event.AppId, @event.SchemaId); } private void UpdateSchema(MongoSchemaEntity entity, Func updater) diff --git a/src/Squidex.Read/Apps/AppHistoryEventsCreator.cs b/src/Squidex.Read/Apps/AppHistoryEventsCreator.cs index 3f9d16065..13f65f455 100644 --- a/src/Squidex.Read/Apps/AppHistoryEventsCreator.cs +++ b/src/Squidex.Read/Apps/AppHistoryEventsCreator.cs @@ -61,8 +61,7 @@ namespace Squidex.Read.Apps return Task.FromResult( ForEvent(@event, channel) - .AddParameter("Contributor", @event.ContributorId) - .AddParameter("Permission", @event.Permission.ToString())); + .AddParameter("Contributor", @event.ContributorId).AddParameter("Permission", @event.Permission)); } protected Task On(AppClientAttached @event, EnvelopeHeaders headers) @@ -89,8 +88,7 @@ namespace Squidex.Read.Apps return Task.FromResult( ForEvent(@event, channel) - .AddParameter("Id", @event.Id) - .AddParameter("Name", !string.IsNullOrWhiteSpace(@event.Name) ? @event.Name : @event.Id)); + .AddParameter("Id", @event.Id).AddParameter("Name", ClientName(@event))); } protected Task On(AppLanguageAdded @event, EnvelopeHeaders headers) @@ -99,7 +97,7 @@ namespace Squidex.Read.Apps return Task.FromResult( ForEvent(@event, channel) - .AddParameter("Language", @event.Language.EnglishName)); + .AddParameter("Language", @event.Language)); } protected Task On(AppLanguageRemoved @event, EnvelopeHeaders headers) @@ -108,7 +106,7 @@ namespace Squidex.Read.Apps return Task.FromResult( ForEvent(@event, channel) - .AddParameter("Language", @event.Language.EnglishName)); + .AddParameter("Language", @event.Language)); } protected Task On(AppMasterLanguageSet @event, EnvelopeHeaders headers) @@ -117,12 +115,17 @@ namespace Squidex.Read.Apps return Task.FromResult( ForEvent(@event, channel) - .AddParameter("Language", @event.Language.EnglishName)); + .AddParameter("Language", @event.Language)); } protected override Task CreateEventCoreAsync(Envelope @event) { return this.DispatchFuncAsync(@event.Payload, @event.Headers, (HistoryEventToStore)null); } + + private static string ClientName(AppClientRenamed @event) + { + return !string.IsNullOrWhiteSpace(@event.Name) ? @event.Name : @event.Id; + } } } \ No newline at end of file diff --git a/src/Squidex.Read/Apps/Repositories/IAppRepository.cs b/src/Squidex.Read/Apps/Repositories/IAppRepository.cs index 232d3d6b2..4ab28435f 100644 --- a/src/Squidex.Read/Apps/Repositories/IAppRepository.cs +++ b/src/Squidex.Read/Apps/Repositories/IAppRepository.cs @@ -9,12 +9,13 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Squidex.Infrastructure; namespace Squidex.Read.Apps.Repositories { public interface IAppRepository { - event Action AppSaved; + event Action> AppSaved; Task> QueryAllAsync(string subjectId); diff --git a/src/Squidex.Read/Apps/Services/IAppProvider.cs b/src/Squidex.Read/Apps/Services/IAppProvider.cs index 9c85dfec9..b861ae4e6 100644 --- a/src/Squidex.Read/Apps/Services/IAppProvider.cs +++ b/src/Squidex.Read/Apps/Services/IAppProvider.cs @@ -8,6 +8,7 @@ using System; using System.Threading.Tasks; +using Squidex.Infrastructure; namespace Squidex.Read.Apps.Services { @@ -17,6 +18,6 @@ namespace Squidex.Read.Apps.Services Task FindAppByNameAsync(string name); - void Remove(Guid id); + void Remove(NamedId id); } } diff --git a/src/Squidex.Read/Apps/Services/Implementations/CachingAppProvider.cs b/src/Squidex.Read/Apps/Services/Implementations/CachingAppProvider.cs index d4baeae8d..ee1e90829 100644 --- a/src/Squidex.Read/Apps/Services/Implementations/CachingAppProvider.cs +++ b/src/Squidex.Read/Apps/Services/Implementations/CachingAppProvider.cs @@ -22,13 +22,6 @@ namespace Squidex.Read.Apps.Services.Implementations private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(30); private readonly IAppRepository repository; - private sealed class CacheItem - { - public IAppEntity Entity; - - public string Name; - } - public CachingAppProvider(IMemoryCache cache, IAppRepository repository) : base(cache) { @@ -40,23 +33,22 @@ namespace Squidex.Read.Apps.Services.Implementations public async Task FindAppByIdAsync(Guid appId) { var cacheKey = BuildIdCacheKey(appId); - var cacheItem = Cache.Get(cacheKey); - if (cacheItem == null) + IAppEntity result; + + if (!Cache.TryGetValue(cacheKey, out result)) { - var entity = await repository.FindAppAsync(appId); - - cacheItem = new CacheItem { Entity = entity, Name = entity.Name }; + result = await repository.FindAppAsync(appId); - Cache.Set(cacheKey, cacheItem, CacheDuration); + Cache.Set(cacheKey, result, CacheDuration); - if (cacheItem.Entity != null) + if (result != null) { - Cache.Set(BuildNameCacheKey(cacheItem.Name), cacheItem, CacheDuration); + Cache.Set(BuildNameCacheKey(result.Name), result, CacheDuration); } } - return cacheItem.Entity; + return result; } public async Task FindAppByNameAsync(string name) @@ -64,37 +56,28 @@ namespace Squidex.Read.Apps.Services.Implementations Guard.NotNullOrEmpty(name, nameof(name)); var cacheKey = BuildNameCacheKey(name); - var cacheItem = Cache.Get(cacheKey); - if (cacheItem == null) - { - var entity = await repository.FindAppAsync(name); + IAppEntity result; - cacheItem = new CacheItem { Entity = entity, Name = name }; + if (!Cache.TryGetValue(cacheKey, out result)) + { + result = await repository.FindAppAsync(name); - Cache.Set(cacheKey, cacheItem, CacheDuration); + Cache.Set(cacheKey, result, CacheDuration); - if (cacheItem.Entity != null) + if (result != null) { - Cache.Set(BuildIdCacheKey(cacheItem.Entity.Id), cacheItem, CacheDuration); + Cache.Set(BuildIdCacheKey(result.Id), result, CacheDuration); } } - return cacheItem.Entity; + return result; } - public void Remove(Guid id) + public void Remove(NamedId id) { - var cacheKey = BuildIdCacheKey(id); - - var cacheItem = Cache.Get(cacheKey); - - if (cacheItem?.Name != null) - { - Cache.Remove(BuildNameCacheKey(cacheItem.Name)); - } - - Cache.Remove(cacheKey); + Cache.Remove(BuildIdCacheKey(id.Id)); + Cache.Remove(BuildNameCacheKey(id.Name)); } private static string BuildNameCacheKey(string name) diff --git a/src/Squidex.Read/History/HistoryEventToStore.cs b/src/Squidex.Read/History/HistoryEventToStore.cs index fc5c13c5e..065e4b37e 100644 --- a/src/Squidex.Read/History/HistoryEventToStore.cs +++ b/src/Squidex.Read/History/HistoryEventToStore.cs @@ -34,9 +34,9 @@ namespace Squidex.Read.History Message = message; } - public HistoryEventToStore AddParameter(string key, string value) + public HistoryEventToStore AddParameter(string key, object value) { - parameters[key] = value; + parameters[key] = value.ToString(); return this; } diff --git a/src/Squidex.Read/Schemas/Repositories/ISchemaRepository.cs b/src/Squidex.Read/Schemas/Repositories/ISchemaRepository.cs index ef86664aa..b7a73a821 100644 --- a/src/Squidex.Read/Schemas/Repositories/ISchemaRepository.cs +++ b/src/Squidex.Read/Schemas/Repositories/ISchemaRepository.cs @@ -9,12 +9,13 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Squidex.Infrastructure; namespace Squidex.Read.Schemas.Repositories { public interface ISchemaRepository { - event Action SchemaSaved; + event Action, NamedId> SchemaSaved; Task> QueryAllAsync(Guid appId); diff --git a/src/Squidex.Read/Schemas/Services/ISchemaProvider.cs b/src/Squidex.Read/Schemas/Services/ISchemaProvider.cs index 178b4ef09..02dfcf03b 100644 --- a/src/Squidex.Read/Schemas/Services/ISchemaProvider.cs +++ b/src/Squidex.Read/Schemas/Services/ISchemaProvider.cs @@ -8,6 +8,7 @@ using System; using System.Threading.Tasks; +using Squidex.Infrastructure; namespace Squidex.Read.Schemas.Services { @@ -16,7 +17,7 @@ namespace Squidex.Read.Schemas.Services Task FindSchemaByIdAsync(Guid id); Task FindSchemaByNameAsync(Guid appId, string name); - - void Remove(Guid id); + + void Remove(NamedId appId, NamedId schemaId); } } diff --git a/src/Squidex.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs b/src/Squidex.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs index 93d1508b5..e2a2c8bff 100644 --- a/src/Squidex.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs +++ b/src/Squidex.Read/Schemas/Services/Implementations/CachingSchemaProvider.cs @@ -23,15 +23,6 @@ namespace Squidex.Read.Schemas.Services.Implementations private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(10); private readonly ISchemaRepository repository; - private sealed class CacheItem - { - public ISchemaEntityWithSchema Entity; - - public Guid AppId; - - public string Name; - } - public CachingSchemaProvider(IMemoryCache cache, ISchemaRepository repository) : base(cache) { @@ -43,30 +34,22 @@ namespace Squidex.Read.Schemas.Services.Implementations public async Task FindSchemaByIdAsync(Guid id) { var cacheKey = BuildIdCacheKey(id); - var cacheItem = Cache.Get(cacheKey); - if (cacheItem == null) - { - var entity = await repository.FindSchemaAsync(id); + ISchemaEntityWithSchema result; - if (entity == null) - { - cacheItem = new CacheItem(); - } - else - { - cacheItem = new CacheItem { Entity = entity, Name = entity.Name, AppId = entity.AppId }; - } + if (!Cache.TryGetValue(cacheKey, out result)) + { + result = await repository.FindSchemaAsync(id); - Cache.Set(cacheKey, cacheItem, CacheDuration); + Cache.Set(cacheKey, result, CacheDuration); - if (cacheItem.Entity != null) + if (result != null) { - Cache.Set(BuildNameCacheKey(cacheItem.Entity.AppId, cacheItem.Entity.Name), cacheItem, CacheDuration); + Cache.Set(BuildNameCacheKey(result.AppId, result.Name), result, CacheDuration); } } - return cacheItem.Entity; + return result; } public async Task FindSchemaByNameAsync(Guid appId, string name) @@ -74,37 +57,28 @@ namespace Squidex.Read.Schemas.Services.Implementations Guard.NotNullOrEmpty(name, nameof(name)); var cacheKey = BuildNameCacheKey(appId, name); - var cacheItem = Cache.Get(cacheKey); - if (cacheItem == null) - { - var entity = await repository.FindSchemaAsync(appId, name); + ISchemaEntityWithSchema result; - cacheItem = new CacheItem { Entity = entity, Name = name, AppId = appId }; + if (!Cache.TryGetValue(cacheKey, out result)) + { + result = await repository.FindSchemaAsync(appId, name); - Cache.Set(cacheKey, cacheItem, CacheDuration); + Cache.Set(cacheKey, result, CacheDuration); - if (cacheItem.Entity != null) + if (result != null) { - Cache.Set(BuildIdCacheKey(cacheItem.Entity.Id), cacheItem, CacheDuration); + Cache.Set(BuildIdCacheKey(result.Id), result, CacheDuration); } } - return cacheItem.Entity; + return result; } - public void Remove(Guid id) + public void Remove(NamedId appId, NamedId schemaId) { - var cacheKey = BuildIdCacheKey(id); - - var cacheItem = Cache.Get(cacheKey); - - if (cacheItem?.Name != null) - { - Cache.Remove(BuildNameCacheKey(cacheItem.AppId, cacheItem.Name)); - } - - Cache.Remove(cacheKey); + Cache.Remove(BuildIdCacheKey(schemaId.Id)); + Cache.Remove(BuildNameCacheKey(appId.Id, schemaId.Name)); } private static string BuildNameCacheKey(Guid appId, string name) diff --git a/src/Squidex.Write/Apps/AppDomainObject.cs b/src/Squidex.Write/Apps/AppDomainObject.cs index 7e94400d4..9fe4a8ef2 100644 --- a/src/Squidex.Write/Apps/AppDomainObject.cs +++ b/src/Squidex.Write/Apps/AppDomainObject.cs @@ -9,10 +9,10 @@ using System; using System.Collections.Generic; using Squidex.Core.Apps; +using Squidex.Events; using Squidex.Events.Apps; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.CQRS.Events; using Squidex.Infrastructure.Dispatching; using Squidex.Infrastructure.Reflection; @@ -200,6 +200,16 @@ namespace Squidex.Write.Apps return this; } + protected void RaiseEvent(AppEvent @event) + { + if (@event.AppId == null) + { + @event.AppId = new NamedId(Id, name); + } + + base.RaiseEvent(Envelope.Create(@event)); + } + private static AppLanguageAdded CreateInitialLanguage(NamedId id) { return new AppLanguageAdded { AppId = id, Language = DefaultLanguage }; diff --git a/src/Squidex.Write/Contents/ContentDomainObject.cs b/src/Squidex.Write/Contents/ContentDomainObject.cs index 2d52668f6..269fef8ee 100644 --- a/src/Squidex.Write/Contents/ContentDomainObject.cs +++ b/src/Squidex.Write/Contents/ContentDomainObject.cs @@ -135,7 +135,7 @@ namespace Squidex.Write.Contents if (!newData.Equals(data)) { - RaiseEvent(new ContentUpdated { Data = newData }); + RaiseEvent(SimpleMapper.Map(command, new ContentUpdated { Data = newData })); } return this; diff --git a/src/Squidex.Write/SchemaAggregateCommand.cs b/src/Squidex.Write/SchemaAggregateCommand.cs index 0168fa358..755be469a 100644 --- a/src/Squidex.Write/SchemaAggregateCommand.cs +++ b/src/Squidex.Write/SchemaAggregateCommand.cs @@ -15,7 +15,7 @@ namespace Squidex.Write { Guid IAggregateCommand.AggregateId { - get { return AppId.Id; } + get { return SchemaId.Id; } } } } diff --git a/src/Squidex.Write/Schemas/SchemaDomainObject.cs b/src/Squidex.Write/Schemas/SchemaDomainObject.cs index 5e84f3185..44fb38f83 100644 --- a/src/Squidex.Write/Schemas/SchemaDomainObject.cs +++ b/src/Squidex.Write/Schemas/SchemaDomainObject.cs @@ -134,7 +134,7 @@ namespace Squidex.Write.Schemas VerifyNotCreated(); - RaiseEvent(SimpleMapper.Map(command, new SchemaCreated())); + RaiseEvent(SimpleMapper.Map(command, new SchemaCreated { SchemaId = new NamedId(Id, command.Name) })); return this; } @@ -211,7 +211,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new SchemaPublished()); + RaiseEvent(SimpleMapper.Map(command, new SchemaPublished())); return this; } @@ -222,7 +222,7 @@ namespace Squidex.Write.Schemas VerifyCreatedAndNotDeleted(); - RaiseEvent(new SchemaUnpublished()); + RaiseEvent(SimpleMapper.Map(command, new SchemaUnpublished())); return this; } @@ -230,14 +230,16 @@ namespace Squidex.Write.Schemas public SchemaDomainObject Delete(DeleteSchema command) { VerifyCreatedAndNotDeleted(); - - RaiseEvent(new SchemaDeleted()); + + RaiseEvent(SimpleMapper.Map(command, new SchemaDeleted())); return this; } protected void RaiseEvent(FieldCommand fieldCommand, FieldEvent @event) { + SimpleMapper.Map(fieldCommand, @event); + Field field; if (schema.Fields.TryGetValue(fieldCommand.FieldId, out field)) diff --git a/src/Squidex.Write/SquidexCommand.cs b/src/Squidex.Write/SquidexCommand.cs index abb221411..ae3637166 100644 --- a/src/Squidex.Write/SquidexCommand.cs +++ b/src/Squidex.Write/SquidexCommand.cs @@ -7,10 +7,11 @@ // ========================================================================== using Squidex.Infrastructure; +using Squidex.Infrastructure.CQRS.Commands; namespace Squidex.Write { - public abstract class SquidexCommand + public abstract class SquidexCommand : ICommand { public RefToken Actor { get; set; } } diff --git a/src/Squidex/Config/Domain/StoreMongoDbModule.cs b/src/Squidex/Config/Domain/StoreMongoDbModule.cs index d23761c32..c78beded1 100644 --- a/src/Squidex/Config/Domain/StoreMongoDbModule.cs +++ b/src/Squidex/Config/Domain/StoreMongoDbModule.cs @@ -126,7 +126,7 @@ namespace Squidex.Config.Domain c.Resolve())) .As() .SingleInstance(); - /* + builder.Register(c => new MongoDbConsumerWrapper( c.ResolveNamed(MongoDatabaseName), @@ -146,7 +146,7 @@ namespace Squidex.Config.Domain c.ResolveNamed(MongoDatabaseName), c.Resolve())) .As() - .SingleInstance();*/ + .SingleInstance(); } } } diff --git a/src/Squidex/Config/Domain/Usages.cs b/src/Squidex/Config/Domain/Usages.cs index 661c15793..083b37ca5 100644 --- a/src/Squidex/Config/Domain/Usages.cs +++ b/src/Squidex/Config/Domain/Usages.cs @@ -33,16 +33,16 @@ namespace Squidex.Config.Domain var appProvider = app.ApplicationServices.GetRequiredService(); - app.ApplicationServices.GetRequiredService().AppSaved += id => + app.ApplicationServices.GetRequiredService().AppSaved += appId => { - appProvider.Remove(id); + appProvider.Remove(appId); }; var schemaProvider = app.ApplicationServices.GetRequiredService(); - app.ApplicationServices.GetRequiredService().SchemaSaved += id => + app.ApplicationServices.GetRequiredService().SchemaSaved += (appId, schemaId) => { - schemaProvider.Remove(id); + schemaProvider.Remove(appId, schemaId); }; return app; diff --git a/src/Squidex/app/features/content/pages/contents/contents-page.component.html b/src/Squidex/app/features/content/pages/contents/contents-page.component.html index 596b05621..842b8a575 100644 --- a/src/Squidex/app/features/content/pages/contents/contents-page.component.html +++ b/src/Squidex/app/features/content/pages/contents/contents-page.component.html @@ -5,7 +5,7 @@
- +
diff --git a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html index 068f69953..f17f76336 100644 --- a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html +++ b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html @@ -12,7 +12,7 @@
- +
diff --git a/src/Squidex/appsettings.json b/src/Squidex/appsettings.json index 6625280db..ad31902ba 100644 --- a/src/Squidex/appsettings.json +++ b/src/Squidex/appsettings.json @@ -4,9 +4,9 @@ "baseUrl": "http://localhost:5000" }, "clusterer": { - "type": "none", + "type": "redis", "redis": { - "connectionString": "redis://localhost:6379" + "connectionString": "localhost:6379" } }, "eventStore": { diff --git a/tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs b/tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs index 1eae11b4d..997a3050c 100644 --- a/tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs +++ b/tests/Squidex.Infrastructure.Tests/CQRS/Commands/DefaultDomainObjectRepositoryTests.cs @@ -24,7 +24,6 @@ namespace Squidex.Infrastructure.CQRS.Commands { private readonly Mock factory = new Mock(); private readonly Mock eventStore = new Mock(); - private readonly Mock eventPublisher = new Mock(); private readonly Mock streamNameResolver = new Mock(); private readonly Mock eventDataFormatter = new Mock(new TypeNameRegistry(), null); private readonly string streamName = Guid.NewGuid().ToString(); @@ -40,7 +39,7 @@ namespace Squidex.Infrastructure.CQRS.Commands factory.Setup(x => x.CreateNew(typeof(MyDomainObject), aggregateId)).Returns(domainObject); - sut = new DefaultDomainObjectRepository(factory.Object, eventStore.Object, eventPublisher.Object, streamNameResolver.Object, eventDataFormatter.Object); + sut = new DefaultDomainObjectRepository(factory.Object, eventStore.Object, streamNameResolver.Object, eventDataFormatter.Object); } public sealed class MyEvent : IEvent @@ -74,7 +73,7 @@ namespace Squidex.Infrastructure.CQRS.Commands [Fact] public async Task Should_throw_exception_when_event_store_returns_no_events() { - eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(Observable.Empty()); + eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(Observable.Empty()); await Assert.ThrowsAsync(() => sut.GetByIdAsync(aggregateId)); } @@ -88,7 +87,13 @@ namespace Squidex.Infrastructure.CQRS.Commands var event1 = new MyEvent(); var event2 = new MyEvent(); - eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(new[] { eventData1, eventData2 }.ToObservable()); + var events = new[] + { + new StoredEvent(0, eventData1), + new StoredEvent(1, eventData2) + }; + + eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(events.ToObservable()); eventDataFormatter.Setup(x => x.Parse(eventData1)).Returns(new Envelope(event1)); eventDataFormatter.Setup(x => x.Parse(eventData2)).Returns(new Envelope(event2)); @@ -107,7 +112,13 @@ namespace Squidex.Infrastructure.CQRS.Commands var event1 = new MyEvent(); var event2 = new MyEvent(); - eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(new[] { eventData1, eventData2 }.ToObservable()); + var events = new[] + { + new StoredEvent(0, eventData1), + new StoredEvent(1, eventData2) + }; + + eventStore.Setup(x => x.GetEventsAsync(streamName)).Returns(events.ToObservable()); eventDataFormatter.Setup(x => x.Parse(eventData1)).Returns(new Envelope(event1)); eventDataFormatter.Setup(x => x.Parse(eventData2)).Returns(new Envelope(event2)); @@ -137,9 +148,6 @@ namespace Squidex.Infrastructure.CQRS.Commands await sut.SaveAsync(domainObject, domainObject.GetUncomittedEvents(), commitId); - eventPublisher.Verify(x => x.Publish(eventData1)); - eventPublisher.Verify(x => x.Publish(eventData2)); - eventStore.VerifyAll(); } diff --git a/tests/Squidex.Infrastructure.Tests/CQRS/Commands/EnrichWithTimestampHandlerTests.cs b/tests/Squidex.Infrastructure.Tests/CQRS/Commands/EnrichWithTimestampHandlerTests.cs index 1d56e3018..b38f504ca 100644 --- a/tests/Squidex.Infrastructure.Tests/CQRS/Commands/EnrichWithTimestampHandlerTests.cs +++ b/tests/Squidex.Infrastructure.Tests/CQRS/Commands/EnrichWithTimestampHandlerTests.cs @@ -14,11 +14,11 @@ namespace Squidex.Infrastructure.CQRS.Commands { public sealed class EnrichWithTimestampHandlerTests { - private sealed class MyNormalCommand : AggregateCommand + private sealed class MyNormalCommand : ICommand { } - private sealed class MyTimestampCommand : AggregateCommand, ITimestampCommand + private sealed class MyTimestampCommand : ITimestampCommand { public DateTime Timestamp { get; set; } } diff --git a/tests/Squidex.Infrastructure.Tests/CQRS/EnvelopeExtensionsTests.cs b/tests/Squidex.Infrastructure.Tests/CQRS/EnvelopeExtensionsTests.cs index 046cf1f6d..1e20276fa 100644 --- a/tests/Squidex.Infrastructure.Tests/CQRS/EnvelopeExtensionsTests.cs +++ b/tests/Squidex.Infrastructure.Tests/CQRS/EnvelopeExtensionsTests.cs @@ -62,17 +62,6 @@ namespace Squidex.Infrastructure.CQRS Assert.Equal(commitId, sut.Headers["AggregateId"].ToGuid(culture)); } - [Fact] - public void Should_set_and_get_actor() - { - var actor = new RefToken("subject", "123"); - - sut.SetActor(actor); - - Assert.Equal(actor, sut.Headers.Actor()); - Assert.Equal(actor, RefToken.Parse(sut.Headers["Actor"].ToString())); - } - [Fact] public void Should_set_and_get_event_number() { diff --git a/tests/Squidex.Infrastructure.Tests/CQRS/Events/EnrichWithActorProcessorTests.cs b/tests/Squidex.Infrastructure.Tests/CQRS/Events/EnrichWithActorProcessorTests.cs deleted file mode 100644 index eb0597b5e..000000000 --- a/tests/Squidex.Infrastructure.Tests/CQRS/Events/EnrichWithActorProcessorTests.cs +++ /dev/null @@ -1,55 +0,0 @@ -// ========================================================================== -// EnrichWithUserProcessorTests.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System.Threading.Tasks; -using Squidex.Infrastructure.CQRS.Commands; -using Xunit; - -namespace Squidex.Infrastructure.CQRS.Events -{ - public class EnrichWithActorProcessorTests - { - public sealed class MyActorCommand : IActorCommand - { - public RefToken Actor { get; set; } - } - - public sealed class MyNormalCommand : ICommand - { - } - - public sealed class MyEvent : IEvent - { - } - - private readonly EnrichWithActorProcessor sut = new EnrichWithActorProcessor(); - - [Fact] - public async Task Should_not_do_anything_if_not_actor_command() - { - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, null, new MyNormalCommand()); - - Assert.False(envelope.Headers.Contains("User")); - } - - [Fact] - public async Task Should_attach_user_to_event_envelope() - { - var actorToken = new RefToken("subject", "123"); - var actorCommand = new MyActorCommand { Actor = actorToken }; - - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, null, actorCommand); - - Assert.Equal(actorToken, envelope.Headers.Actor()); - } - } -} diff --git a/tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs b/tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs index 5b92b3c2a..8e00a241c 100644 --- a/tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs +++ b/tests/Squidex.Infrastructure.Tests/CQRS/Events/EventReceiverTests.cs @@ -8,6 +8,8 @@ using System; using System.Collections.Generic; +using System.Reactive.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Moq; using Xunit; @@ -41,128 +43,118 @@ namespace Squidex.Infrastructure.CQRS.Events return null; } } - - private readonly Mock liveConsumer1 = new Mock(); - private readonly Mock liveConsumer2 = new Mock(); - private readonly Mock catchConsumer1 = new Mock(); - private readonly Mock catchConsumer2 = new Mock(); - private readonly Mock eventStream = new Mock(); + + private readonly Mock eventConsumer = new Mock(); + private readonly Mock eventNotifier = new Mock(); + private readonly Mock eventStore = new Mock(); private readonly Mock formatter = new Mock(new TypeNameRegistry(), null); - private readonly EventData eventData = new EventData(); - private readonly Envelope envelope = new Envelope(new MyEvent()); + private readonly EventData eventData1 = new EventData(); + private readonly EventData eventData2 = new EventData(); + private readonly EventData eventData3 = new EventData(); + private readonly EventData eventData4 = new EventData(); + private readonly Envelope envelope1 = new Envelope(new MyEvent()); + private readonly Envelope envelope2 = new Envelope(new MyEvent()); + private readonly Envelope envelope3 = new Envelope(new MyEvent()); + private readonly Envelope envelope4 = new Envelope(new MyEvent()); + private readonly EventReceiver sut; private readonly MyLogger logger = new MyLogger(); + private readonly StoredEvent[][] events; public EventReceiverTests() { - formatter.Setup(x => x.Parse(eventData)).Returns(envelope); - - eventStream.Setup(x => x.Connect("squidex", It.IsAny>())).Callback( - new Action>((queue, callback) => + events = new [] + { + new [] { - callback(eventData); - })); - } + new StoredEvent(3, eventData1), + new StoredEvent(4, eventData1) + }, + new[] + { + new StoredEvent(5, eventData1), + new StoredEvent(6, eventData1) + } + }; - [Fact] - public void Should_only_connect_once() - { - var sut = CreateSut(true); - sut.Subscribe(); - sut.Subscribe(); + formatter.Setup(x => x.Parse(eventData1)).Returns(envelope1); + formatter.Setup(x => x.Parse(eventData2)).Returns(envelope2); + formatter.Setup(x => x.Parse(eventData3)).Returns(envelope3); + formatter.Setup(x => x.Parse(eventData4)).Returns(envelope4); - eventStream.Verify(x => x.Connect("squidex", It.IsAny>()), Times.Once()); + sut = new EventReceiver(formatter.Object, eventStore.Object, eventNotifier.Object, logger); } [Fact] - public void Should_invoke_live_consumers() + public void Should_only_connect_once() { - var sut = CreateSut(false); - - sut.Subscribe(); + sut.Subscribe(eventConsumer.Object); + sut.Subscribe(eventConsumer.Object); - catchConsumer1.Verify(x => x.On(It.IsAny>()), Times.Never()); - catchConsumer2.Verify(x => x.On(It.IsAny>()), Times.Never()); - - liveConsumer1.Verify(x => x.On(envelope), Times.Once()); - liveConsumer2.Verify(x => x.On(envelope), Times.Once()); - - Assert.Equal(1, logger.LogCount.Count); - Assert.Equal(1, logger.LogCount[LogLevel.Debug]); + eventConsumer.Verify(x => x.GetLastHandledEventNumber(), Times.Once()); } [Fact] - public void Should_invoke_catch_consumers() + public void Should_subscribe_to_consumers_and_handle_events() { - var sut = CreateSut(true); + eventConsumer.Setup(x => x.GetLastHandledEventNumber()).Returns(Task.FromResult(2L)); + eventConsumer.Setup(x => x.On(It.IsAny>(), It.IsAny())).Returns(Task.FromResult(true)); - sut.Subscribe(); + eventStore.Setup(x => x.GetEventsAsync(2)).Returns(events[0].ToObservable()); + eventStore.Setup(x => x.GetEventsAsync(4)).Returns(events[1].ToObservable()); - liveConsumer1.Verify(x => x.On(It.IsAny>()), Times.Never()); - liveConsumer2.Verify(x => x.On(It.IsAny>()), Times.Never()); + eventStore.Setup(x => x.GetEventsAsync(It.Is(l => l != 2 && l != 4))).Returns(Observable.Empty()); - catchConsumer1.Verify(x => x.On(envelope), Times.Once()); - catchConsumer2.Verify(x => x.On(envelope), Times.Once()); + sut.Subscribe(eventConsumer.Object, 20); + + Task.Delay(400).ContinueWith(x => sut.Dispose()).Wait(); Assert.Equal(1, logger.LogCount.Count); - Assert.Equal(1, logger.LogCount[LogLevel.Debug]); + Assert.Equal(4, logger.LogCount[LogLevel.Debug]); + + eventConsumer.Verify(x => x.On(It.IsAny>(), It.IsAny()), Times.Exactly(4)); } [Fact] - public void Should_log_if_parsing_event_failed() + public void Should_abort_if_handling_failed() { - formatter.Setup(x => x.Parse(eventData)).Throws(new InvalidOperationException()); + eventConsumer.Setup(x => x.GetLastHandledEventNumber()).Returns(Task.FromResult(2L)); + eventConsumer.Setup(x => x.On(It.IsAny>(), It.IsAny())).Throws(); - var sut = CreateSut(true); + eventStore.Setup(x => x.GetEventsAsync(2)).Returns(events[0].ToObservable()); + eventStore.Setup(x => x.GetEventsAsync(It.Is(l => l != 2 && l != 4))).Returns(Observable.Empty()); - sut.Subscribe(); + sut.Subscribe(eventConsumer.Object, 20); - catchConsumer1.Verify(x => x.On(It.IsAny>()), Times.Never()); - catchConsumer2.Verify(x => x.On(It.IsAny>()), Times.Never()); + Task.Delay(400).ContinueWith(x => sut.Dispose()).Wait(); - liveConsumer1.Verify(x => x.On(It.IsAny>()), Times.Never()); - liveConsumer2.Verify(x => x.On(It.IsAny>()), Times.Never()); - - Assert.Equal(1, logger.LogCount.Count); + Assert.Equal(2, logger.LogCount.Count); Assert.Equal(1, logger.LogCount[LogLevel.Error]); + Assert.Equal(1, logger.LogCount[LogLevel.Critical]); + + eventConsumer.Verify(x => x.On(It.IsAny>(), It.IsAny()), Times.Exactly(1)); + eventStore.Verify(x => x.GetEventsAsync(It.IsAny()), Times.Exactly(1)); } [Fact] - public void Should_log_if_handling_failed() + public void Should_abort_if_serialization_failed() { - catchConsumer1.Setup(x => x.On(envelope)).Throws(new InvalidOperationException()); + eventConsumer.Setup(x => x.GetLastHandledEventNumber()).Returns(Task.FromResult(2L)); + eventConsumer.Setup(x => x.On(It.IsAny>(), It.IsAny())).Throws(); - var sut = CreateSut(true); + eventStore.Setup(x => x.GetEventsAsync(2)).Returns(events[0].ToObservable()); + eventStore.Setup(x => x.GetEventsAsync(It.Is(l => l != 2 && l != 4))).Returns(Observable.Empty()); - sut.Subscribe(); + sut.Subscribe(eventConsumer.Object, 20); - catchConsumer1.Verify(x => x.On(envelope), Times.Once()); - catchConsumer2.Verify(x => x.On(envelope), Times.Once()); - - liveConsumer1.Verify(x => x.On(It.IsAny>()), Times.Never()); - liveConsumer2.Verify(x => x.On(It.IsAny>()), Times.Never()); + Task.Delay(400).ContinueWith(x => sut.Dispose()).Wait(); Assert.Equal(2, logger.LogCount.Count); - Assert.Equal(1, logger.LogCount[LogLevel.Debug]); Assert.Equal(1, logger.LogCount[LogLevel.Error]); - } + Assert.Equal(1, logger.LogCount[LogLevel.Critical]); - private EventReceiver CreateSut(bool canCatch) - { - return new EventReceiver( - logger, - eventStream.Object, - new[] - { - liveConsumer1.Object, - liveConsumer2.Object - }, - new[] - { - catchConsumer1.Object, - catchConsumer2.Object - }, - formatter.Object, canCatch); + eventConsumer.Verify(x => x.On(It.IsAny>(), It.IsAny()), Times.Exactly(1)); + eventStore.Verify(x => x.GetEventsAsync(It.IsAny()), Times.Exactly(1)); } } } diff --git a/tests/Squidex.Infrastructure.Tests/CQRS/Replay/ReplayGeneratorTests.cs b/tests/Squidex.Infrastructure.Tests/CQRS/Replay/ReplayGeneratorTests.cs deleted file mode 100644 index 3b159775f..000000000 --- a/tests/Squidex.Infrastructure.Tests/CQRS/Replay/ReplayGeneratorTests.cs +++ /dev/null @@ -1,82 +0,0 @@ -// ========================================================================== -// ReplayGeneratorTests.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System; -using System.Reactive.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Moq; -using Squidex.Infrastructure.CQRS.Events; -using Xunit; - -namespace Squidex.Infrastructure.CQRS.Replay -{ - public class ReplayGeneratorTests - { - private readonly Mock eventStore = new Mock(); - private readonly Mock eventPublisher = new Mock(); - private readonly Mock store1 = new Mock(); - private readonly Mock store2 = new Mock(); - private readonly Mock> logger = new Mock>(); - private readonly ReplayGenerator sut; - - public ReplayGeneratorTests() - { - sut = new ReplayGenerator(logger.Object, eventStore.Object, eventPublisher.Object, new[] { store1.Object, store2.Object }); - } - - [Fact] - public async Task Should_clear_stores_and_replay_events() - { - var event1 = new EventData(); - var event2 = new EventData(); - var event3 = new EventData(); - - eventStore.Setup(x => x.GetEventsAsync()).Returns(new[] { event1, event2, event3 }.ToObservable()); - - await sut.ReplayAllAsync(); - - store1.Verify(x => x.ClearAsync(), Times.Once()); - store2.Verify(x => x.ClearAsync(), Times.Once()); - - eventPublisher.Verify(x => x.Publish(event1)); - eventPublisher.Verify(x => x.Publish(event2)); - eventPublisher.Verify(x => x.Publish(event3)); - } - - [Fact] - public async Task Should_not_publish_if_clearing_failed() - { - var event1 = new EventData(); - var event2 = new EventData(); - var event3 = new EventData(); - - store1.Setup(x => x.ClearAsync()).Throws(new InvalidOperationException()); - - eventStore.Setup(x => x.GetEventsAsync()).Returns(new[] { event1, event2, event3 }.ToObservable()); - - await sut.ReplayAllAsync(); - - store1.Verify(x => x.ClearAsync(), Times.Once()); - store2.Verify(x => x.ClearAsync(), Times.Never()); - - eventStore.Verify(x => x.GetEventsAsync(), Times.Never()); - eventPublisher.Verify(x => x.Publish(It.IsAny()), Times.Never()); - } - - [Fact] - public async Task Should_not_throw_if_process_throws() - { - eventStore.Setup(x => x.GetEventsAsync()).Throws(new InvalidOperationException()); - - await sut.ReplayAllAsync(); - - eventPublisher.Verify(x => x.Publish(It.IsAny()), Times.Never()); - } - } -} diff --git a/tests/Squidex.Infrastructure.Tests/LanguageTests.cs b/tests/Squidex.Infrastructure.Tests/LanguageTests.cs index 4e02ebc2b..be10d78c4 100644 --- a/tests/Squidex.Infrastructure.Tests/LanguageTests.cs +++ b/tests/Squidex.Infrastructure.Tests/LanguageTests.cs @@ -8,22 +8,14 @@ using System; using System.Linq; -using Newtonsoft.Json; using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.TestHelpers; using Xunit; namespace Squidex.Infrastructure { public class LanguageTests { - private static readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); - - static LanguageTests() - { - serializerSettings.Converters.Add(new LanguageConverter()); - serializerSettings.NullValueHandling = NullValueHandling.Include; - } - [Theory] [InlineData("")] [InlineData(" ")] @@ -53,21 +45,13 @@ namespace Squidex.Infrastructure [Fact] public void Should_serialize_and_deserialize_null_language() { - var input = Tuple.Create(null); - var json = JsonConvert.SerializeObject(input, serializerSettings); - var output = JsonConvert.DeserializeObject>(json, serializerSettings); - - Assert.Equal(output.Item1, input.Item1); + JsonHelper.SerializeAndDeserialize(null, new LanguageConverter()); } [Fact] public void Should_serialize_and_deserialize_valid_language() { - var input = Tuple.Create(Language.DE); - var json = JsonConvert.SerializeObject(input, serializerSettings); - var output = JsonConvert.DeserializeObject>(json, serializerSettings); - - Assert.Equal(output.Item1, input.Item1); + Language.DE.SerializeAndDeserialize(new LanguageConverter()); } [Theory] diff --git a/tests/Squidex.Infrastructure.Tests/NamedIdTest.cs b/tests/Squidex.Infrastructure.Tests/NamedIdTest.cs new file mode 100644 index 000000000..88ec83c87 --- /dev/null +++ b/tests/Squidex.Infrastructure.Tests/NamedIdTest.cs @@ -0,0 +1,148 @@ +// ========================================================================== +// NamedIdTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.TestHelpers; +using Xunit; + +// ReSharper disable RedundantCast + +namespace Squidex.Infrastructure +{ + public class NamedIdTests + { + [Fact] + public void Should_instantiate_token() + { + var id = Guid.NewGuid(); + + var namedId = new NamedId(id, "my-name"); + + Assert.Equal(id, namedId.Id); + Assert.Equal("my-name", namedId.Name); + } + + [Fact] + public void Should_convert_named_id_to_string() + { + var id = Guid.NewGuid(); + + var namedId = new NamedId(id, "my-name"); + + Assert.Equal($"{id},my-name", namedId.ToString()); + } + + [Fact] + public void Should_make_correct_equal_comparisons() + { + var id1 = Guid.NewGuid(); + var id2 = Guid.NewGuid(); + + var token1a = new NamedId(id1, "my-name1"); + var token1b = new NamedId(id1, "my-name1"); + var token1c = new NamedId(id1, "my-name2"); + var token2a = new NamedId(id2, "my-name1"); + + Assert.True(token1a.Equals(token1b)); + + Assert.False(token1a.Equals(token2a)); + Assert.False(token1a.Equals(token1c)); + } + + [Fact] + public void Should_make_correct_object_equal_comparisons() + { + var id1 = Guid.NewGuid(); + var id2 = Guid.NewGuid(); + + object token1a = new NamedId(id1, "my-name1"); + object token1b = new NamedId(id1, "my-name1"); + object token1c = new NamedId(id1, "my-name2"); + object token2a = new NamedId(id2, "my-name1"); + + Assert.True(token1a.Equals(token1b)); + + Assert.False(token1a.Equals(token2a)); + Assert.False(token1a.Equals(token1c)); + } + + [Fact] + public void Should_provide_correct_hash_codes() + { + var id1 = Guid.NewGuid(); + var id2 = Guid.NewGuid(); + + object token1a = new NamedId(id1, "my-name1"); + object token1b = new NamedId(id1, "my-name1"); + object token1c = new NamedId(id1, "my-name2"); + object token2a = new NamedId(id2, "my-name1"); + + Assert.Equal(token1a.GetHashCode(), token1b.GetHashCode()); + + Assert.NotEqual(token1a.GetHashCode(), token2a.GetHashCode()); + Assert.NotEqual(token1a.GetHashCode(), token1c.GetHashCode()); + } + + [Fact] + public void Should_serialize_and_deserialize_null_guid_token() + { + JsonHelper.SerializeAndDeserialize>(null, new NamedGuidIdConverter()); + } + + [Fact] + public void Should_serialize_and_deserialize_valid_guid_token() + { + new NamedId(Guid.NewGuid(), "my-name").SerializeAndDeserialize(new NamedGuidIdConverter()); + } + + [Fact] + public void Should_serialize_and_deserialize_null_long_token() + { + JsonHelper.SerializeAndDeserialize>(null, new NamedLongIdConverter()); + } + + [Fact] + public void Should_serialize_and_deserialize_valid_long_token() + { + new NamedId(123, "my-name").SerializeAndDeserialize(new NamedLongIdConverter()); + } + + [Fact] + public void Should_serialize_and_deserialize_null_string_token() + { + JsonHelper.SerializeAndDeserialize>(null, new NamedStringIdConverter()); + } + + [Fact] + public void Should_serialize_and_deserialize_valid_string_token() + { + new NamedId(Guid.NewGuid().ToString(), "my-name").SerializeAndDeserialize(new NamedStringIdConverter()); + } + + [Fact] + public void Should_throw_if_string_id_is_not_valid() + { + JsonHelper.DoesNotDeserialize>("123", new NamedStringIdConverter()); + } + + [Fact] + public void Should_throw_if_long_id_is_not_valid() + { + JsonHelper.DoesNotDeserialize>("123", new NamedLongIdConverter()); + JsonHelper.DoesNotDeserialize>("invalid-long,name", new NamedLongIdConverter()); + } + + [Fact] + public void Should_throw_if_guid_id_is_not_valid() + { + JsonHelper.DoesNotDeserialize>("123", new NamedGuidIdConverter()); + JsonHelper.DoesNotDeserialize>("invalid-guid,name", new NamedGuidIdConverter()); + } + } +} diff --git a/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs b/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs index 887b24fa4..564224b53 100644 --- a/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs +++ b/tests/Squidex.Infrastructure.Tests/PropertiesBagTests.cs @@ -39,9 +39,9 @@ namespace Squidex.Infrastructure serializerSettings.Converters.Add(new PropertiesBagConverter()); var content = JsonConvert.SerializeObject(bag, serializerSettings); - var response = JsonConvert.DeserializeObject(content, serializerSettings); + var output = JsonConvert.DeserializeObject(content, serializerSettings); - Assert.Equal(bag.Count, response.Count); + Assert.Equal(bag.Count, output.Count); } [Fact] diff --git a/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs b/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs index a227d3ab3..4f5aed92e 100644 --- a/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs +++ b/tests/Squidex.Infrastructure.Tests/RefTokenTests.cs @@ -7,8 +7,8 @@ // ========================================================================== using System; -using Newtonsoft.Json; using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.TestHelpers; using Xunit; // ReSharper disable RedundantCast @@ -17,14 +17,6 @@ namespace Squidex.Infrastructure { public class RefTokenTests { - private static readonly JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); - - static RefTokenTests() - { - serializerSettings.Converters.Add(new RefTokenConverter()); - serializerSettings.NullValueHandling = NullValueHandling.Include; - } - [Theory] [InlineData("")] [InlineData(" ")] @@ -84,24 +76,23 @@ namespace Squidex.Infrastructure { var token1a = RefToken.Parse("client:client1"); var token1b = RefToken.Parse("client:client1"); - var token2 = RefToken.Parse("client:client2"); + var token2a = RefToken.Parse("client:client2"); Assert.True(token1a.Equals(token1b)); - Assert.False(token1a.Equals(token2)); + Assert.False(token1a.Equals(token2a)); } [Fact] public void Should_make_correct_object_equal_comparisons() { - var token1a = RefToken.Parse("client:client1"); - + object token1a = RefToken.Parse("client:client1"); object token1b = RefToken.Parse("client:client1"); - object token2 = RefToken.Parse("client:client2"); + object token2a = RefToken.Parse("client:client2"); Assert.True(token1a.Equals(token1b)); - Assert.False(token1a.Equals(token2)); + Assert.False(token1a.Equals(token2a)); } [Fact] @@ -109,31 +100,23 @@ namespace Squidex.Infrastructure { var token1a = RefToken.Parse("client:client1"); var token1b = RefToken.Parse("client:client1"); - var token2 = RefToken.Parse("client:client2"); + var token2a = RefToken.Parse("client:client2"); Assert.Equal(token1a.GetHashCode(), token1b.GetHashCode()); - Assert.NotEqual(token1a.GetHashCode(), token2.GetHashCode()); + Assert.NotEqual(token1a.GetHashCode(), token2a.GetHashCode()); } [Fact] public void Should_serialize_and_deserialize_null_token() { - var input = Tuple.Create(null); - var json = JsonConvert.SerializeObject(input, serializerSettings); - var output = JsonConvert.DeserializeObject>(json, serializerSettings); - - Assert.Equal(output.Item1, input.Item1); + JsonHelper.SerializeAndDeserialize(null, new RefTokenConverter()); } [Fact] public void Should_serialize_and_deserialize_valid_token() { - var input = Tuple.Create(RefToken.Parse("client:client1")); - var json = JsonConvert.SerializeObject(input, serializerSettings); - var output = JsonConvert.DeserializeObject>(json, serializerSettings); - - Assert.Equal(output.Item1, input.Item1); + RefToken.Parse("client:client1").SerializeAndDeserialize(new RefTokenConverter()); } } } diff --git a/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs b/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs new file mode 100644 index 000000000..a1f0799be --- /dev/null +++ b/tests/Squidex.Infrastructure.Tests/TestHelpers/JsonHelper.cs @@ -0,0 +1,40 @@ +// ========================================================================== +// JsonHelper.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using Newtonsoft.Json; +using Xunit; + +namespace Squidex.Infrastructure.TestHelpers +{ + public static class JsonHelper + { + public static void SerializeAndDeserialize(this T value, JsonConverter converter) where T : class + { + var serializerSettings = new JsonSerializerSettings(); + + serializerSettings.Converters.Add(converter); + serializerSettings.NullValueHandling = NullValueHandling.Include; + + var result = JsonConvert.SerializeObject(Tuple.Create(value), serializerSettings); + var output = JsonConvert.DeserializeObject>(result, serializerSettings); + + Assert.Equal(value, output.Item1); + } + + public static void DoesNotDeserialize(string value, JsonConverter converter) where T : class + { + var serializerSettings = new JsonSerializerSettings(); + + serializerSettings.Converters.Add(converter); + serializerSettings.NullValueHandling = NullValueHandling.Include; + + Assert.Throws(() => JsonConvert.DeserializeObject>($"{{ \"Item1\": \"{value}\" }}")); + } + } +} diff --git a/tests/Squidex.Read.Tests/Apps/CachingAppProviderTests.cs b/tests/Squidex.Read.Tests/Apps/CachingAppProviderTests.cs index 7af890482..58bd97232 100644 --- a/tests/Squidex.Read.Tests/Apps/CachingAppProviderTests.cs +++ b/tests/Squidex.Read.Tests/Apps/CachingAppProviderTests.cs @@ -7,14 +7,11 @@ // ========================================================================== using System; -using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using Moq; -using Squidex.Events.Apps; -using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Events; +using Squidex.Infrastructure; using Squidex.Read.Apps.Repositories; using Squidex.Read.Apps.Services.Implementations; using Squidex.Read.MongoDb.Apps; @@ -32,17 +29,12 @@ namespace Squidex.Read.Apps private readonly CachingAppProvider sut; private readonly MongoAppEntity appV1; private readonly MongoAppEntity appV2; - private readonly Guid appId = Guid.NewGuid(); - private readonly string appName = "my-app"; - - private sealed class MyEvent : IEvent - { - } + private readonly NamedId appId = new NamedId(Guid.NewGuid(), "my-app"); public CachingAppProviderTests() { - appV1 = new MongoAppEntity { Name = appName, Id = appId }; - appV2 = new MongoAppEntity { Name = appName, Id = appId }; + appV1 = new MongoAppEntity { Name = appId.Name, Id = appId.Id }; + appV2 = new MongoAppEntity { Name = appId.Name, Id = appId.Id }; sut = new CachingAppProvider(cache, repository.Object); } @@ -50,110 +42,67 @@ namespace Squidex.Read.Apps [Fact] public async Task Should_also_retrieve_app_by_name_if_retrieved_by_id_before() { - repository.Setup(x => x.FindAppAsync(appId)).Returns(Task.FromResult(appV1)); + repository.Setup(x => x.FindAppAsync(appId.Id)).Returns(Task.FromResult(appV1)); await ProvideAppById(appV1); await ProvideAppByName(appV1); - repository.Verify(x => x.FindAppAsync(appId), Times.Once()); - repository.Verify(x => x.FindAppAsync(appName), Times.Never()); + repository.Verify(x => x.FindAppAsync(appId.Id), Times.Once()); + repository.Verify(x => x.FindAppAsync(appId.Name), Times.Never()); } [Fact] public async Task Should_also_retrieve_app_by_id_if_retrieved_by_name_before() { - repository.Setup(x => x.FindAppAsync(appName)).Returns(Task.FromResult(appV1)); + repository.Setup(x => x.FindAppAsync(appId.Name)).Returns(Task.FromResult(appV1)); await ProvideAppByName(appV1); await ProvideAppById(appV1); - repository.Verify(x => x.FindAppAsync(appName), Times.Once()); - repository.Verify(x => x.FindAppAsync(appId), Times.Never()); - } - - [Fact] - public async Task Should_ignore_other_events() - { - repository.Setup(x => x.FindAppAsync(appId)).Returns(Task.FromResult(appV1)); - - await ProvideAppById(appV1); - await RaiseEvent(new MyEvent()); - await ProvideAppById(appV1); - - repository.Verify(x => x.FindAppAsync(appId), Times.Once()); - } - - [Fact] - public async Task Should_retrieve_by_id_after_created_event() - { - var apps = ProviderResults(null, appV1); - - repository.Setup(x => x.FindAppAsync(appId)).Returns(() => Task.FromResult(apps())); - - await ProvideAppById(null); - await RaiseEvent(new AppCreated { Name = appName }); - await ProvideAppById(appV1); - - repository.Verify(x => x.FindAppAsync(appId), Times.Exactly(2)); - } - - [Fact] - public async Task Should_retrieve_by_name_after_created_event() - { - var apps = ProviderResults(null, appV1); - - repository.Setup(x => x.FindAppAsync(appName)).Returns(() => Task.FromResult(apps())); - - await ProvideAppByName(null); - await RaiseEvent(new AppCreated { Name = appName }); - await ProvideAppByName(appV1); - - repository.Verify(x => x.FindAppAsync(appName), Times.Exactly(2)); + repository.Verify(x => x.FindAppAsync(appId.Name), Times.Once()); + repository.Verify(x => x.FindAppAsync(appId.Id), Times.Never()); } [Theory] - [MemberData(nameof(AppEvents))] - public async Task Should_clear_cache_for_id_after_update_event(IEvent @event) + public async Task Should_clear_cache_for_id_after_update_event() { var apps = ProviderResults(appV1, appV2); - repository.Setup(x => x.FindAppAsync(appId)).Returns(() => Task.FromResult(apps())); + repository.Setup(x => x.FindAppAsync(appId.Id)).Returns(() => Task.FromResult(apps())); await ProvideAppById(appV1); - await RaiseEvent(@event); + + sut.Remove(appId); + await ProvideAppById(appV2); - repository.Verify(x => x.FindAppAsync(appId), Times.Exactly(2)); + repository.Verify(x => x.FindAppAsync(appId.Id), Times.Exactly(2)); } [Theory] - [MemberData(nameof(AppEvents))] - public async Task Should_clear_cache_for_name_after_update_event(IEvent @event) + public async Task Should_clear_cache_for_name_after_update_event() { var apps = ProviderResults(appV1, appV2); - repository.Setup(x => x.FindAppAsync(appName)).Returns(() => Task.FromResult(apps())); + repository.Setup(x => x.FindAppAsync(appId.Name)).Returns(() => Task.FromResult(apps())); await ProvideAppByName(appV1); - await RaiseEvent(@event); - await ProvideAppByName(appV2); - repository.Verify(x => x.FindAppAsync(appName), Times.Exactly(2)); - } + sut.Remove(appId); - private async Task RaiseEvent(IEvent @event) - { - await sut.On(new Envelope(@event).SetAggregateId(appId)); + await ProvideAppByName(appV2); + + repository.Verify(x => x.FindAppAsync(appId.Name), Times.Exactly(2)); } private async Task ProvideAppById(IAppEntity app) { - Assert.Equal(app, await sut.FindAppByIdAsync(appId)); + Assert.Equal(app, await sut.FindAppByIdAsync(appId.Id)); } private async Task ProvideAppByName(IAppEntity app) { - Assert.Equal(app, await sut.FindAppByNameAsync(appName)); + Assert.Equal(app, await sut.FindAppByNameAsync(appId.Name)); } private static Func ProviderResults(params T[] items) @@ -162,20 +111,5 @@ namespace Squidex.Read.Apps return () => items[index++]; } - - public static IEnumerable AppEvents - { - get - { - yield return new object[] { new AppContributorAssigned() }; - yield return new object[] { new AppContributorRemoved() }; - yield return new object[] { new AppClientAttached() }; - yield return new object[] { new AppClientRevoked() }; - yield return new object[] { new AppClientRenamed() }; - yield return new object[] { new AppLanguageAdded() }; - yield return new object[] { new AppLanguageRemoved() }; - yield return new object[] { new AppMasterLanguageSet() }; - } - } } } diff --git a/tests/Squidex.Read.Tests/Schemas/CachingSchemaProviderTests.cs b/tests/Squidex.Read.Tests/Schemas/CachingSchemaProviderTests.cs index 0c334c211..706625b7d 100644 --- a/tests/Squidex.Read.Tests/Schemas/CachingSchemaProviderTests.cs +++ b/tests/Squidex.Read.Tests/Schemas/CachingSchemaProviderTests.cs @@ -7,15 +7,11 @@ // ========================================================================== using System; -using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using Moq; -using Squidex.Events; -using Squidex.Events.Schemas; -using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Events; +using Squidex.Infrastructure; using Squidex.Read.Schemas.Repositories; using Squidex.Read.Schemas.Services.Implementations; using Squidex.Read.MongoDb.Schemas; @@ -33,18 +29,13 @@ namespace Squidex.Read.Schemas private readonly CachingSchemaProvider sut; private readonly MongoSchemaEntity schemaV1; private readonly MongoSchemaEntity schemaV2; - private readonly Guid schemaId = Guid.NewGuid(); - private readonly Guid appId = Guid.NewGuid(); - private readonly string schemaName = "my-schema"; - - private sealed class MyEvent : IEvent - { - } + private readonly NamedId schemaId = new NamedId(Guid.NewGuid(), "my-schema"); + private readonly NamedId appId = new NamedId(Guid.NewGuid(), "my-app"); public CachingSchemaProviderTests() { - schemaV1 = new MongoSchemaEntity { Name = schemaName, Id = schemaId, AppId = appId }; - schemaV2 = new MongoSchemaEntity { Name = schemaName, Id = schemaId, AppId = appId }; + schemaV1 = new MongoSchemaEntity { Name = schemaId.Name, Id = schemaId.Id, AppId = appId.Id }; + schemaV2 = new MongoSchemaEntity { Name = schemaId.Name, Id = schemaId.Id, AppId = appId.Id }; sut = new CachingSchemaProvider(cache, repository.Object); } @@ -52,110 +43,67 @@ namespace Squidex.Read.Schemas [Fact] public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before() { - repository.Setup(x => x.FindSchemaAsync(schemaId)).Returns(Task.FromResult(schemaV1)); + repository.Setup(x => x.FindSchemaAsync(schemaId.Id)).Returns(Task.FromResult(schemaV1)); await ProvideSchemaById(schemaV1); await ProvideSchemaByName(schemaV1); - repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Once()); - repository.Verify(x => x.FindSchemaAsync(appId, schemaName), Times.Never()); + repository.Verify(x => x.FindSchemaAsync(schemaId.Id), Times.Once()); + repository.Verify(x => x.FindSchemaAsync(appId.Id, schemaId.Name), Times.Never()); } [Fact] public async Task Should_also_retrieve_schema_by_id_if_retrieved_by_name_before() { - repository.Setup(x => x.FindSchemaAsync(appId, schemaName)).Returns(Task.FromResult(schemaV1)); + repository.Setup(x => x.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(Task.FromResult(schemaV1)); await ProvideSchemaByName(schemaV1); await ProvideSchemaById(schemaV1); - repository.Verify(x => x.FindSchemaAsync(appId, schemaName), Times.Once()); - repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Never()); - } - - [Fact] - public async Task Should_ignore_other_events() - { - repository.Setup(x => x.FindSchemaAsync(schemaId)).Returns(Task.FromResult(schemaV1)); - - await ProvideSchemaById(schemaV1); - await RaiseEvent(new MyEvent()); - await ProvideSchemaById(schemaV1); - - repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Once()); - } - - [Fact] - public async Task Should_retrieve_by_id_after_created_event() - { - var schemas = ProviderResults(null, schemaV1); - - repository.Setup(x => x.FindSchemaAsync(schemaId)).Returns(() => Task.FromResult(schemas())); - - await ProvideSchemaById(null); - await RaiseEvent(new SchemaCreated { Name = schemaName }); - await ProvideSchemaById(schemaV1); - - repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Exactly(2)); - } - - [Fact] - public async Task Should_retrieve_by_name_after_created_event() - { - var schemas = ProviderResults(null, schemaV1); - - repository.Setup(x => x.FindSchemaAsync(appId, schemaName)).Returns(() => Task.FromResult(schemas())); - - await ProvideSchemaByName(null); - await RaiseEvent(new SchemaCreated { Name = schemaName }); - await ProvideSchemaByName(schemaV1); - - repository.Verify(x => x.FindSchemaAsync(appId, schemaName), Times.Exactly(2)); + repository.Verify(x => x.FindSchemaAsync(appId.Id, schemaId.Name), Times.Once()); + repository.Verify(x => x.FindSchemaAsync(schemaId.Id), Times.Never()); } [Theory] - [MemberData(nameof(SchemaEvents))] - public async Task Should_clear_cache_for_id_after_update_event(IEvent @event) + public async Task Should_clear_cache_for_id_after_update_event() { var schemas = ProviderResults(schemaV1, schemaV2); - repository.Setup(x => x.FindSchemaAsync(schemaId)).Returns(() => Task.FromResult(schemas())); + repository.Setup(x => x.FindSchemaAsync(schemaId.Id)).Returns(() => Task.FromResult(schemas())); await ProvideSchemaById(schemaV1); - await RaiseEvent(@event); + + sut.Remove(appId, schemaId); + await ProvideSchemaById(schemaV2); - repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Exactly(2)); + repository.Verify(x => x.FindSchemaAsync(schemaId.Id), Times.Exactly(2)); } [Theory] - [MemberData(nameof(SchemaEvents))] - public async Task Should_clear_cache_for_name_after_update_event(IEvent @event) + public async Task Should_clear_cache_for_name_after_update_event() { var schemas = ProviderResults(schemaV1, schemaV2); - repository.Setup(x => x.FindSchemaAsync(appId, schemaName)).Returns(() => Task.FromResult(schemas())); + repository.Setup(x => x.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(() => Task.FromResult(schemas())); await ProvideSchemaByName(schemaV1); - await RaiseEvent(@event); - await ProvideSchemaByName(schemaV2); - repository.Verify(x => x.FindSchemaAsync(appId, schemaName), Times.Exactly(2)); - } + sut.Remove(appId, schemaId); - private async Task RaiseEvent(IEvent @event) - { - await sut.On(new Envelope(@event).SetAggregateId(schemaId).SetAppId(appId)); + await ProvideSchemaByName(schemaV2); + + repository.Verify(x => x.FindSchemaAsync(appId.Id, schemaId.Name), Times.Exactly(2)); } private async Task ProvideSchemaById(ISchemaEntityWithSchema schema) { - Assert.Equal(schema, await sut.FindSchemaByIdAsync(schemaId)); + Assert.Equal(schema, await sut.FindSchemaByIdAsync(schemaId.Id)); } private async Task ProvideSchemaByName(ISchemaEntityWithSchema schema) { - Assert.Equal(schema, await sut.FindSchemaByNameAsync(appId, schemaName)); + Assert.Equal(schema, await sut.FindSchemaByNameAsync(appId.Id, schemaId.Name)); } private static Func ProviderResults(params T[] items) @@ -164,17 +112,5 @@ namespace Squidex.Read.Schemas return () => items[index++]; } - - public static IEnumerable SchemaEvents - { - get - { - yield return new object[] { new SchemaDeleted() }; - yield return new object[] { new SchemaPublished() }; - yield return new object[] { new SchemaUnpublished() }; - yield return new object[] { new SchemaUpdated() }; - yield return new object[] { new FieldAdded() }; - } - } } } diff --git a/tests/Squidex.Write.Tests/Apps/AppCommandHandlerTests.cs b/tests/Squidex.Write.Tests/Apps/AppCommandHandlerTests.cs index 2d47dfb41..7be4cf8ad 100644 --- a/tests/Squidex.Write.Tests/Apps/AppCommandHandlerTests.cs +++ b/tests/Squidex.Write.Tests/Apps/AppCommandHandlerTests.cs @@ -11,13 +11,12 @@ using System.Threading.Tasks; using FluentAssertions; using Moq; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Commands; using Squidex.Read.Apps; using Squidex.Read.Apps.Repositories; using Squidex.Read.Users; using Squidex.Read.Users.Repositories; using Squidex.Write.Apps.Commands; -using Squidex.Write.Utils; +using Squidex.Write.TestHelpers; using Xunit; // ReSharper disable ImplicitlyCapturedClosure @@ -32,17 +31,15 @@ namespace Squidex.Write.Apps private readonly Mock userRepository = new Mock(); private readonly AppCommandHandler sut; private readonly AppDomainObject app; - private readonly RefToken subjectId = new RefToken("subject", Guid.NewGuid().ToString()); private readonly DateTime expiresUtc = DateTime.UtcNow.AddYears(1); private readonly Language language = Language.DE; private readonly string contributorId = Guid.NewGuid().ToString(); private readonly string clientSecret = Guid.NewGuid().ToString(); private readonly string clientName = "client"; - private readonly string appName = "my-app"; public AppCommandHandlerTests() { - app = new AppDomainObject(Id, 0); + app = new AppDomainObject(AppId, 0); sut = new AppCommandHandler(Handler, appRepository.Object, userRepository.Object, keyGenerator.Object); } @@ -50,10 +47,9 @@ namespace Squidex.Write.Apps [Fact] public async Task Create_should_throw_if_a_name_with_same_name_already_exists() { - var command = new CreateApp { Name = appName, AggregateId = Id, Actor = subjectId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new CreateApp { Name = AppName, AggregateId = AppId }); - appRepository.Setup(x => x.FindAppAsync(appName)).Returns(Task.FromResult(new Mock().Object)).Verifiable(); + appRepository.Setup(x => x.FindAppAsync(AppName)).Returns(Task.FromResult(new Mock().Object)).Verifiable(); await TestCreate(app, async _ => { @@ -66,17 +62,16 @@ namespace Squidex.Write.Apps [Fact] public async Task Create_should_create_app_if_name_is_free() { - var command = new CreateApp { Name = appName, AggregateId = Id, Actor = subjectId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new CreateApp { Name = AppName, AggregateId = AppId }); - appRepository.Setup(x => x.FindAppAsync(appName)).Returns(Task.FromResult(null)).Verifiable(); + appRepository.Setup(x => x.FindAppAsync(AppName)).Returns(Task.FromResult(null)).Verifiable(); await TestCreate(app, async _ => { await sut.HandleAsync(context); }); - Assert.Equal(command.AggregateId, context.Result()); + Assert.Equal(AppId, context.Result()); } [Fact] @@ -84,10 +79,9 @@ namespace Squidex.Write.Apps { CreateApp(); - var command = new AssignContributor { AggregateId = Id, ContributorId = contributorId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new AssignContributor { ContributorId = contributorId }); - userRepository.Setup(x => x.FindUserByIdAsync(command.ContributorId)).Returns(Task.FromResult(null)); + userRepository.Setup(x => x.FindUserByIdAsync(contributorId)).Returns(Task.FromResult(null)); await TestUpdate(app, async _ => { @@ -100,10 +94,9 @@ namespace Squidex.Write.Apps { CreateApp(); - var command = new AssignContributor { AggregateId = Id, ContributorId = null }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new AssignContributor { ContributorId = null }); - userRepository.Setup(x => x.FindUserByIdAsync(command.ContributorId)).Returns(Task.FromResult(null)); + userRepository.Setup(x => x.FindUserByIdAsync(contributorId)).Returns(Task.FromResult(null)); await TestUpdate(app, async _ => { @@ -116,10 +109,9 @@ namespace Squidex.Write.Apps { CreateApp(); - var command = new AssignContributor { AggregateId = Id, ContributorId = contributorId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new AssignContributor { ContributorId = contributorId }); - userRepository.Setup(x => x.FindUserByIdAsync(command.ContributorId)).Returns(Task.FromResult(new Mock().Object)); + userRepository.Setup(x => x.FindUserByIdAsync(contributorId)).Returns(Task.FromResult(new Mock().Object)); await TestUpdate(app, async _ => { @@ -131,10 +123,9 @@ namespace Squidex.Write.Apps public async Task RemoveContributor_should_update_domain_object() { CreateApp() - .AssignContributor(new AssignContributor { ContributorId = contributorId }); + .AssignContributor(CreateCommand(new AssignContributor { ContributorId = contributorId })); - var command = new RemoveContributor { AggregateId = Id, ContributorId = contributorId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new RemoveContributor { ContributorId = contributorId }); await TestUpdate(app, async _ => { @@ -151,8 +142,7 @@ namespace Squidex.Write.Apps var timestamp = DateTime.Today; - var command = new AttachClient { Id = clientName, AggregateId = Id, Timestamp = timestamp }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new AttachClient { Id = clientName, Timestamp = timestamp }); await TestUpdate(app, async _ => { @@ -169,10 +159,9 @@ namespace Squidex.Write.Apps public async Task RenameClient_should_update_domain_object() { CreateApp() - .AttachClient(new AttachClient { Id = clientName }, clientSecret, expiresUtc); + .AttachClient(CreateCommand(new AttachClient { Id = clientName }), clientSecret, expiresUtc); - var command = new RenameClient { AggregateId = Id, Id = clientName, Name = "New Name" }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new RenameClient { Id = clientName, Name = "New Name" }); await TestUpdate(app, async _ => { @@ -184,10 +173,9 @@ namespace Squidex.Write.Apps public async Task RevokeClient_should_update_domain_object() { CreateApp() - .AttachClient(new AttachClient { Id = clientName }, clientSecret, expiresUtc); + .AttachClient(CreateCommand(new AttachClient { Id = clientName }), clientSecret, expiresUtc); - var command = new RevokeClient { AggregateId = Id, Id = clientName }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new RevokeClient { Id = clientName }); await TestUpdate(app, async _ => { @@ -200,8 +188,7 @@ namespace Squidex.Write.Apps { CreateApp(); - var command = new AddLanguage { AggregateId = Id, Language = language }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new AddLanguage { Language = language }); await TestUpdate(app, async _ => { @@ -213,10 +200,9 @@ namespace Squidex.Write.Apps public async Task RemoveLanguage_should_update_domain_object() { CreateApp() - .AddLanguage(new AddLanguage { AggregateId = Id, Language = language }); + .AddLanguage(CreateCommand(new AddLanguage { Language = language })); - var command = new RemoveLanguage { AggregateId = Id, Language = language }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new RemoveLanguage { Language = language }); await TestUpdate(app, async _ => { @@ -228,10 +214,9 @@ namespace Squidex.Write.Apps public async Task SetMasterLanguage_should_update_domain_object() { CreateApp() - .AddLanguage(new AddLanguage { AggregateId = Id, Language = language }); + .AddLanguage(CreateCommand(new AddLanguage { Language = language })); - var command = new SetMasterLanguage { AggregateId = Id, Language = language }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new SetMasterLanguage { Language = language }); await TestUpdate(app, async _ => { @@ -241,7 +226,7 @@ namespace Squidex.Write.Apps private AppDomainObject CreateApp() { - app.Create(new CreateApp { Name = appName, Actor = subjectId }); + app.Create(CreateCommand(new CreateApp { Name = AppName })); return app; } diff --git a/tests/Squidex.Write.Tests/Apps/AppDomainObjectTests.cs b/tests/Squidex.Write.Tests/Apps/AppDomainObjectTests.cs index 9e2c38f2b..c0bacd689 100644 --- a/tests/Squidex.Write.Tests/Apps/AppDomainObjectTests.cs +++ b/tests/Squidex.Write.Tests/Apps/AppDomainObjectTests.cs @@ -8,24 +8,21 @@ using System; using System.Linq; -using FluentAssertions; using Squidex.Core.Apps; using Squidex.Events.Apps; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Events; using Squidex.Write.Apps.Commands; +using Squidex.Write.TestHelpers; using Xunit; // ReSharper disable ConvertToConstant.Local namespace Squidex.Write.Apps { - public class AppDomainObjectTests + public class AppDomainObjectTests : HandlerTestBase { - private const string TestName = "app"; private readonly AppDomainObject sut; - private readonly RefToken user = new RefToken("subject", Guid.NewGuid().ToString()); private readonly DateTime expiresUtc = DateTime.UtcNow.AddYears(1); private readonly string contributorId = Guid.NewGuid().ToString(); private readonly string clientSecret = Guid.NewGuid().ToString(); @@ -34,7 +31,7 @@ namespace Squidex.Write.Apps public AppDomainObjectTests() { - sut = new AppDomainObject(Guid.NewGuid(), 0); + sut = new AppDomainObject(AppId, 0); } [Fact] @@ -42,43 +39,53 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.Create(new CreateApp { Name = TestName })); + Assert.Throws(() => + { + sut.Create(CreateCommand(new CreateApp { Name = AppName })); + }); } [Fact] public void Create_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.Create(new CreateApp())); + Assert.Throws(() => + { + sut.Create(CreateCommand(new CreateApp())); + }); } [Fact] public void Create_should_specify_name_and_owner() { - sut.Create(new CreateApp { Name = TestName, Actor = user }); + sut.Create(CreateCommand(new CreateApp { Name = AppName, Actor = User, AggregateId = AppId })); - Assert.Equal(TestName, sut.Name); + Assert.Equal(AppName, sut.Name); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppCreated { Name = TestName }, - new AppContributorAssigned { ContributorId = user.Identifier, Permission = PermissionLevel.Owner }, - new AppLanguageAdded { Language = Language.EN }, - new AppMasterLanguageSet { Language = Language.EN } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppCreated { Name = AppName }), + CreateEvent(new AppContributorAssigned { ContributorId = User.Identifier, Permission = PermissionLevel.Owner }), + CreateEvent(new AppLanguageAdded { Language = Language.EN }), + CreateEvent(new AppMasterLanguageSet { Language = Language.EN }) + ); } [Fact] public void AssignContributor_should_throw_if_not_created() { - Assert.Throws(() => sut.AssignContributor(new AssignContributor { ContributorId = contributorId })); + Assert.Throws(() => + { + sut.AssignContributor(CreateCommand(new AssignContributor { ContributorId = contributorId })); + }); } [Fact] public void AssignContributor_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.AssignContributor(new AssignContributor())); + Assert.Throws(() => + { + sut.AssignContributor(CreateCommand(new AssignContributor())); + }); } [Fact] @@ -86,16 +93,22 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.AssignContributor(new AssignContributor { ContributorId = user.Identifier, Permission = PermissionLevel.Editor })); + Assert.Throws(() => + { + sut.AssignContributor(CreateCommand(new AssignContributor { ContributorId = User.Identifier, Permission = PermissionLevel.Editor })); + }); } [Fact] public void AssignContributor_should_throw_if_user_already_contributor() { CreateApp(); - sut.AssignContributor(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor }); + sut.AssignContributor(CreateCommand(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor })); - Assert.Throws(() => sut.AssignContributor(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor })); + Assert.Throws(() => + { + sut.AssignContributor(CreateCommand(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor })); + }); } [Fact] @@ -103,26 +116,30 @@ namespace Squidex.Write.Apps { CreateApp(); - sut.AssignContributor(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor }); + sut.AssignContributor(CreateCommand(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppContributorAssigned { ContributorId = contributorId, Permission = PermissionLevel.Editor } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppContributorAssigned { ContributorId = contributorId, Permission = PermissionLevel.Editor }) + ); } [Fact] public void RemoveContributor_should_throw_if_not_created() { - Assert.Throws(() => sut.RemoveContributor(new RemoveContributor { ContributorId = contributorId })); + Assert.Throws(() => + { + sut.RemoveContributor(CreateCommand(new RemoveContributor { ContributorId = contributorId })); + }); } [Fact] public void RemoveContributor_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.RemoveContributor(new RemoveContributor())); + Assert.Throws(() => + { + sut.RemoveContributor(CreateCommand(new RemoveContributor())); + }); } [Fact] @@ -130,7 +147,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RemoveContributor(new RemoveContributor { ContributorId = user.Identifier })); + Assert.Throws(() => + { + sut.RemoveContributor(CreateCommand(new RemoveContributor { ContributorId = User.Identifier })); + }); } [Fact] @@ -138,7 +158,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RemoveContributor(new RemoveContributor { ContributorId = "not-found" })); + Assert.Throws(() => + { + sut.RemoveContributor(CreateCommand(new RemoveContributor { ContributorId = "not-found" })); + }); } [Fact] @@ -146,21 +169,22 @@ namespace Squidex.Write.Apps { CreateApp(); - sut.AssignContributor(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor }); - sut.RemoveContributor(new RemoveContributor { ContributorId = contributorId }); - - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppContributorRemoved { ContributorId = contributorId } - }); + sut.AssignContributor(CreateCommand(new AssignContributor { ContributorId = contributorId, Permission = PermissionLevel.Editor })); + sut.RemoveContributor(CreateCommand(new RemoveContributor { ContributorId = contributorId })); + + sut.GetUncomittedEvents().Skip(1) + .ShouldHaveSameEvents( + CreateEvent(new AppContributorRemoved { ContributorId = contributorId }) + ); } [Fact] public void AttachClient_should_throw_if_not_created() { - Assert.Throws(() => sut.AttachClient(new AttachClient { Id = clientId }, clientSecret, expiresUtc)); + Assert.Throws(() => + { + sut.AttachClient(CreateCommand(new AttachClient { Id = clientId }), clientSecret, expiresUtc); + }); } [Fact] @@ -168,8 +192,15 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.AttachClient(new AttachClient(), clientSecret, expiresUtc)); - Assert.Throws(() => sut.AttachClient(new AttachClient { Id = string.Empty }, clientSecret, expiresUtc)); + Assert.Throws(() => + { + sut.AttachClient(CreateCommand(new AttachClient()), clientSecret, expiresUtc); + }); + + Assert.Throws(() => + { + sut.AttachClient(CreateCommand(new AttachClient { Id = string.Empty }), clientSecret, expiresUtc); + }); } [Fact] @@ -177,9 +208,12 @@ namespace Squidex.Write.Apps { CreateApp(); - sut.AttachClient(new AttachClient { Id = clientId }, clientSecret, expiresUtc); + sut.AttachClient(CreateCommand(new AttachClient { Id = clientId }), clientSecret, expiresUtc); - Assert.Throws(() => sut.AttachClient(new AttachClient { Id = clientId }, clientSecret, expiresUtc)); + Assert.Throws(() => + { + sut.AttachClient(CreateCommand(new AttachClient { Id = clientId }), clientSecret, expiresUtc); + }); } [Fact] @@ -189,20 +223,21 @@ namespace Squidex.Write.Apps CreateApp(); - sut.AttachClient(new AttachClient { Id = clientId, Timestamp = now }, clientSecret, expiresUtc); + sut.AttachClient(CreateCommand(new AttachClient { Id = clientId, Timestamp = now }), clientSecret, expiresUtc); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppClientAttached { Id = clientId, Secret = clientSecret, ExpiresUtc = expiresUtc } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppClientAttached { Id = clientId, Secret = clientSecret, ExpiresUtc = expiresUtc }) + ); } [Fact] public void RevokeClient_should_throw_if_not_created() { - Assert.Throws(() => sut.RevokeClient(new RevokeClient { Id = "not-found" })); + Assert.Throws(() => + { + sut.RevokeClient(CreateCommand(new RevokeClient { Id = "not-found" })); + }); } [Fact] @@ -210,8 +245,15 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RevokeClient(new RevokeClient())); - Assert.Throws(() => sut.RevokeClient(new RevokeClient { Id = string.Empty })); + Assert.Throws(() => + { + sut.RevokeClient(CreateCommand(new RevokeClient())); + }); + + Assert.Throws(() => + { + sut.RevokeClient(CreateCommand(new RevokeClient { Id = string.Empty })); + }); } [Fact] @@ -219,29 +261,33 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RevokeClient(new RevokeClient { Id = "not-found" })); + Assert.Throws(() => + { + sut.RevokeClient(CreateCommand(new RevokeClient { Id = "not-found" })); + }); } [Fact] public void RevokeClient_should_create_events() { CreateApp(); + CreateClient(); - sut.AttachClient(new AttachClient { Id = clientId }, clientSecret, expiresUtc); - sut.RevokeClient(new RevokeClient { Id = clientId }); + sut.RevokeClient(CreateCommand(new RevokeClient { Id = clientId })); - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppClientRevoked { Id = clientSecret } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppClientRevoked { Id = clientId }) + ); } [Fact] public void RenameClient_should_throw_if_not_created() { - Assert.Throws(() => sut.RenameClient(new RenameClient { Id = "not-found", Name = clientNewName })); + Assert.Throws(() => + { + sut.RenameClient(CreateCommand(new RenameClient { Id = "not-found", Name = clientNewName })); + }); } [Fact] @@ -249,8 +295,15 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RenameClient(new RenameClient())); - Assert.Throws(() => sut.RenameClient(new RenameClient { Id = string.Empty })); + Assert.Throws(() => + { + sut.RenameClient(CreateCommand(new RenameClient())); + }); + + Assert.Throws(() => + { + sut.RenameClient(CreateCommand(new RenameClient { Id = string.Empty })); + }); } [Fact] @@ -258,40 +311,47 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RenameClient(new RenameClient { Id = "not-found", Name = clientNewName })); + Assert.Throws(() => + { + sut.RenameClient(CreateCommand(new RenameClient { Id = "not-found", Name = clientNewName })); + }); } [Fact] public void RenameClient_should_throw_if_same_client_name() { CreateApp(); + CreateClient(); - sut.AttachClient(new AttachClient { Id = clientId }, clientSecret, expiresUtc); - sut.RenameClient(new RenameClient { Id = clientId, Name = clientNewName }); + sut.RenameClient(CreateCommand(new RenameClient { Id = clientId, Name = clientNewName })); - Assert.Throws(() => sut.RenameClient(new RenameClient { Id = clientId, Name = clientNewName })); + Assert.Throws(() => + { + sut.RenameClient(CreateCommand(new RenameClient { Id = clientId, Name = clientNewName })); + }); } [Fact] public void RenameClient_should_create_events() { CreateApp(); + CreateClient(); - sut.AttachClient(new AttachClient { Id = clientId }, clientSecret, expiresUtc); - sut.RenameClient(new RenameClient { Id = clientId, Name = clientNewName }); + sut.RenameClient(CreateCommand(new RenameClient { Id = clientId, Name = clientNewName })); - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppClientRenamed { Id = clientId, Name = clientNewName } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppClientRenamed { Id = clientId, Name = clientNewName }) + ); } [Fact] public void AddLanguage_should_throw_if_not_created() { - Assert.Throws(() => sut.AddLanguage(new AddLanguage { Language = Language.DE })); + Assert.Throws(() => + { + sut.AddLanguage(CreateCommand(new AddLanguage { Language = Language.DE })); + }); } [Fact] @@ -299,7 +359,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.AddLanguage(new AddLanguage())); + Assert.Throws(() => + { + sut.AddLanguage(CreateCommand(new AddLanguage())); + }); } [Fact] @@ -307,7 +370,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.AddLanguage(new AddLanguage { Language = Language.EN })); + Assert.Throws(() => + { + sut.AddLanguage(CreateCommand(new AddLanguage { Language = Language.EN })); + }); } [Fact] @@ -315,20 +381,21 @@ namespace Squidex.Write.Apps { CreateApp(); - sut.AddLanguage(new AddLanguage { Language = Language.DE }); + sut.AddLanguage(CreateCommand(new AddLanguage { Language = Language.DE })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppLanguageAdded { Language = Language.DE } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppLanguageAdded { Language = Language.DE }) + ); } [Fact] public void RemoveLanguage_should_throw_if_not_created() { - Assert.Throws(() => sut.RemoveLanguage(new RemoveLanguage { Language = Language.EN })); + Assert.Throws(() => + { + sut.RemoveLanguage(CreateCommand(new RemoveLanguage { Language = Language.EN })); + }); } [Fact] @@ -336,7 +403,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RemoveLanguage(new RemoveLanguage())); + Assert.Throws(() => + { + sut.RemoveLanguage(CreateCommand(new RemoveLanguage())); + }); } [Fact] @@ -344,7 +414,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RemoveLanguage(new RemoveLanguage { Language = Language.DE })); + Assert.Throws(() => + { + sut.RemoveLanguage(CreateCommand(new RemoveLanguage { Language = Language.DE })); + }); } [Fact] @@ -352,29 +425,33 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.RemoveLanguage(new RemoveLanguage { Language = Language.EN })); + Assert.Throws(() => + { + sut.RemoveLanguage(CreateCommand(new RemoveLanguage { Language = Language.EN })); + }); } [Fact] public void RemoveLanguage_should_create_events() { CreateApp(); + CreateLanguage(); + + sut.RemoveLanguage(CreateCommand(new RemoveLanguage { Language = Language.DE })); - sut.AddLanguage(new AddLanguage { Language = Language.DE }); - sut.RemoveLanguage(new RemoveLanguage { Language = Language.DE }); - - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppLanguageRemoved { Language = Language.DE } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppLanguageRemoved { Language = Language.DE }) + ); } [Fact] public void SetMasterLanguage_should_throw_if_not_created() { - Assert.Throws(() => sut.SetMasterLanguage(new SetMasterLanguage { Language = Language.EN })); + Assert.Throws(() => + { + sut.SetMasterLanguage(CreateCommand(new SetMasterLanguage { Language = Language.EN })); + }); } [Fact] @@ -382,7 +459,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.SetMasterLanguage(new SetMasterLanguage())); + Assert.Throws(() => + { + sut.SetMasterLanguage(CreateCommand(new SetMasterLanguage())); + }); } [Fact] @@ -390,7 +470,10 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.SetMasterLanguage(new SetMasterLanguage { Language = Language.DE })); + Assert.Throws(() => + { + sut.SetMasterLanguage(CreateCommand(new SetMasterLanguage { Language = Language.DE })); + }); } [Fact] @@ -398,28 +481,43 @@ namespace Squidex.Write.Apps { CreateApp(); - Assert.Throws(() => sut.SetMasterLanguage(new SetMasterLanguage { Language = Language.EN })); + Assert.Throws(() => + { + sut.SetMasterLanguage(CreateCommand(new SetMasterLanguage { Language = Language.EN })); + }); } [Fact] public void SetMasterLanguage_should_create_events() { CreateApp(); + CreateLanguage(); - sut.AddLanguage(new AddLanguage { Language = Language.DE }); - sut.SetMasterLanguage(new SetMasterLanguage { Language = Language.DE }); + sut.SetMasterLanguage(CreateCommand(new SetMasterLanguage { Language = Language.DE })); - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new AppMasterLanguageSet { Language = Language.DE } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new AppMasterLanguageSet { Language = Language.DE }) + ); } private void CreateApp() { - sut.Create(new CreateApp { Name = TestName, Actor = user }); + sut.Create(CreateCommand(new CreateApp { Name = AppName })); + + ((IAggregate)sut).ClearUncommittedEvents(); + } + + private void CreateClient() + { + sut.AttachClient(CreateCommand(new AttachClient { Id = clientId }), clientSecret, expiresUtc); + + ((IAggregate)sut).ClearUncommittedEvents(); + } + + private void CreateLanguage() + { + sut.AddLanguage(CreateCommand(new AddLanguage { Language = Language.DE })); ((IAggregate)sut).ClearUncommittedEvents(); } diff --git a/tests/Squidex.Write.Tests/Contents/ContentCommandHandlerTests.cs b/tests/Squidex.Write.Tests/Contents/ContentCommandHandlerTests.cs index 832183af3..9f329362f 100644 --- a/tests/Squidex.Write.Tests/Contents/ContentCommandHandlerTests.cs +++ b/tests/Squidex.Write.Tests/Contents/ContentCommandHandlerTests.cs @@ -12,13 +12,12 @@ using Moq; using Squidex.Core.Contents; 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; using Squidex.Read.Schemas.Services; using Squidex.Write.Contents.Commands; -using Squidex.Write.Utils; +using Squidex.Write.TestHelpers; using Xunit; // ReSharper disable ConvertToConstant.Local @@ -33,33 +32,31 @@ namespace Squidex.Write.Contents private readonly Mock appProvider = new Mock(); private readonly Mock schemaEntity = new Mock(); private readonly Mock appEntity = new Mock(); - private readonly Guid schemaId = Guid.NewGuid(); - private readonly Guid appId = Guid.NewGuid(); private readonly ContentData data = new ContentData().AddField("my-field", new ContentFieldData().SetValue(1)); + private readonly Guid contentId = Guid.NewGuid(); public ContentCommandHandlerTests() { - var schema = + var schema = Schema.Create("my-schema", new SchemaProperties()) - .AddOrUpdateField(new NumberField(1, "my-field", + .AddOrUpdateField(new NumberField(1, "my-field", new NumberFieldProperties { IsRequired = true })); - content = new ContentDomainObject(Id, 0); + content = new ContentDomainObject(contentId, 0); sut = new ContentCommandHandler(Handler, appProvider.Object, schemaProvider.Object); appEntity.Setup(x => x.Languages).Returns(new[] { Language.DE }); - appProvider.Setup(x => x.FindAppByIdAsync(appId)).Returns(Task.FromResult(appEntity.Object)); + 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)); + 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 ContentData() }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new CreateContent { ContentId = contentId, Data = new ContentData() }); await TestCreate(content, async _ => { @@ -70,15 +67,14 @@ namespace Squidex.Write.Contents [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); + var context = CreateContextForCommand(new CreateContent { ContentId = contentId, Data = data }); await TestCreate(content, async _ => { await sut.HandleAsync(context); }); - Assert.Equal(Id, context.Result()); + Assert.Equal(contentId, context.Result()); } [Fact] @@ -86,8 +82,7 @@ namespace Squidex.Write.Contents { CreateContent(); - var command = new UpdateContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = new ContentData() }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new UpdateContent { ContentId = contentId, Data = new ContentData() }); await TestUpdate(content, async _ => { @@ -100,8 +95,7 @@ namespace Squidex.Write.Contents { CreateContent(); - var command = new UpdateContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = data }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new UpdateContent { ContentId = contentId, Data = data }); await TestUpdate(content, async _ => { @@ -114,8 +108,7 @@ namespace Squidex.Write.Contents { CreateContent(); - var command = new PatchContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = new ContentData() }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new PatchContent { ContentId = contentId, Data = new ContentData() }); await TestUpdate(content, async _ => { @@ -126,10 +119,11 @@ namespace Squidex.Write.Contents [Fact] public async Task Patch_should_update_domain_object() { + var otherContent = new ContentData().AddField("my-field", new ContentFieldData().SetValue(3)); + CreateContent(); - var command = new PatchContent { AggregateId = Id, AppId = appId, SchemaId = schemaId, Data = data }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new PatchContent { ContentId = contentId, Data = otherContent }); await TestUpdate(content, async _ => { @@ -142,8 +136,7 @@ namespace Squidex.Write.Contents { CreateContent(); - var command = new PublishContent { AggregateId = Id, AppId = appId, SchemaId = schemaId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new PublishContent { ContentId = contentId }); await TestUpdate(content, async _ => { @@ -156,8 +149,7 @@ namespace Squidex.Write.Contents { CreateContent(); - var command = new UnpublishContent { AggregateId = Id, AppId = appId, SchemaId = schemaId }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new UnpublishContent { ContentId = contentId }); await TestUpdate(content, async _ => { @@ -170,12 +162,11 @@ namespace Squidex.Write.Contents { CreateContent(); - var command = new DeleteContent { AggregateId = Id }; - var context = new CommandContext(command); + var command = CreateContextForCommand(new DeleteContent { ContentId = contentId }); await TestUpdate(content, async _ => { - await sut.HandleAsync(context); + await sut.HandleAsync(command); }); } diff --git a/tests/Squidex.Write.Tests/Contents/ContentDomainObjectTests.cs b/tests/Squidex.Write.Tests/Contents/ContentDomainObjectTests.cs index 6f8d81972..ea2e8c1da 100644 --- a/tests/Squidex.Write.Tests/Contents/ContentDomainObjectTests.cs +++ b/tests/Squidex.Write.Tests/Contents/ContentDomainObjectTests.cs @@ -7,23 +7,21 @@ // ========================================================================== using System; -using System.Linq; using FluentAssertions; using Squidex.Core.Contents; using Squidex.Events.Contents; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Events; using Squidex.Write.Contents.Commands; +using Squidex.Write.TestHelpers; using Xunit; // ReSharper disable ConvertToConstant.Local namespace Squidex.Write.Contents { - public class ContentDomainObjectTests + public class ContentDomainObjectTests : HandlerTestBase { - private readonly Guid appId = Guid.NewGuid(); private readonly ContentDomainObject sut; private readonly ContentData data = new ContentData() @@ -36,9 +34,11 @@ namespace Squidex.Write.Contents new ContentFieldData() .AddValue("iv", 2)); + public Guid ContentId { get; } = Guid.NewGuid(); + public ContentDomainObjectTests() { - sut = new ContentDomainObject(Guid.NewGuid(), 0); + sut = new ContentDomainObject(ContentId, 0); } [Fact] @@ -46,32 +46,39 @@ namespace Squidex.Write.Contents { sut.Create(new CreateContent { Data = data }); - Assert.Throws(() => sut.Create(new CreateContent { Data = data })); + Assert.Throws(() => + { + sut.Create(CreateContentCommand(new CreateContent { Data = data })); + }); } [Fact] public void Create_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.Create(new CreateContent())); + Assert.Throws(() => + { + sut.Create(CreateContentCommand(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 } - }); + sut.Create(CreateContentCommand(new CreateContent { Data = data })); + + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateContentEvent(new ContentCreated { Data = data }) + ); } [Fact] public void Update_should_throw_if_not_created() { - Assert.Throws(() => sut.Update(new UpdateContent { Data = data })); + Assert.Throws(() => + { + sut.Update(CreateContentCommand(new UpdateContent { Data = data })); + }); } [Fact] @@ -80,7 +87,10 @@ namespace Squidex.Write.Contents CreateContent(); DeleteContent(); - Assert.Throws(() => sut.Update(new UpdateContent())); + Assert.Throws(() => + { + sut.Update(CreateContentCommand(new UpdateContent())); + }); } [Fact] @@ -88,7 +98,10 @@ namespace Squidex.Write.Contents { CreateContent(); - Assert.Throws(() => sut.Update(new UpdateContent())); + Assert.Throws(() => + { + sut.Update(CreateContentCommand(new UpdateContent())); + }); } [Fact] @@ -97,14 +110,12 @@ namespace Squidex.Write.Contents CreateContent(); UpdateContent(); - sut.Update(new UpdateContent { Data = otherData }); + sut.Update(CreateContentCommand(new UpdateContent { Data = otherData })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new ContentUpdated { Data = otherData } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateContentEvent(new ContentUpdated { Data = otherData }) + ); } [Fact] @@ -113,15 +124,18 @@ namespace Squidex.Write.Contents CreateContent(); UpdateContent(); - sut.Update(new UpdateContent { Data = data }); + sut.Update(CreateContentCommand(new UpdateContent { Data = data })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray().ShouldBeEquivalentTo(new IEvent[0]); + sut.GetUncomittedEvents().Should().BeEmpty(); } [Fact] public void Patch_should_throw_if_not_created() { - Assert.Throws(() => sut.Patch(new PatchContent { Data = data })); + Assert.Throws(() => + { + sut.Patch(CreateContentCommand(new PatchContent { Data = data })); + }); } [Fact] @@ -130,7 +144,10 @@ namespace Squidex.Write.Contents CreateContent(); DeleteContent(); - Assert.Throws(() => sut.Patch(new PatchContent())); + Assert.Throws(() => + { + sut.Patch(CreateContentCommand(new PatchContent())); + }); } [Fact] @@ -138,7 +155,10 @@ namespace Squidex.Write.Contents { CreateContent(); - Assert.Throws(() => sut.Patch(new PatchContent())); + Assert.Throws(() => + { + sut.Patch(CreateContentCommand(new PatchContent())); + }); } [Fact] @@ -147,31 +167,32 @@ namespace Squidex.Write.Contents CreateContent(); UpdateContent(); - sut.Patch(new PatchContent { Data = otherData }); + sut.Patch(CreateContentCommand(new PatchContent { Data = otherData })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new ContentUpdated { Data = data.MergeInto(otherData) } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateContentEvent(new ContentUpdated { Data = otherData }) + ); } - + [Fact] public void Patch_should_not_create_event_for_same_data() { CreateContent(); UpdateContent(); - sut.Patch(new PatchContent { Data = data }); + sut.Patch(CreateContentCommand(new PatchContent { Data = data })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray().Should().BeEmpty(); + sut.GetUncomittedEvents().Should().BeEmpty(); } [Fact] public void Publish_should_throw_if_not_created() { - Assert.Throws(() => sut.Publish(new PublishContent())); + Assert.Throws(() => + { + sut.Publish(CreateContentCommand(new PublishContent())); + }); } [Fact] @@ -180,7 +201,10 @@ namespace Squidex.Write.Contents CreateContent(); DeleteContent(); - Assert.Throws(() => sut.Publish(new PublishContent())); + Assert.Throws(() => + { + sut.Publish(CreateContentCommand(new PublishContent())); + }); } [Fact] @@ -188,22 +212,23 @@ namespace Squidex.Write.Contents { CreateContent(); - sut.Publish(new PublishContent()); + sut.Publish(CreateContentCommand(new PublishContent())); Assert.True(sut.IsPublished); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new ContentPublished() - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateContentEvent(new ContentPublished()) + ); } [Fact] public void Unpublish_should_throw_if_not_created() { - Assert.Throws(() => sut.Unpublish(new UnpublishContent())); + Assert.Throws(() => + { + sut.Unpublish(CreateContentCommand(new UnpublishContent())); + }); } [Fact] @@ -212,7 +237,10 @@ namespace Squidex.Write.Contents CreateContent(); DeleteContent(); - Assert.Throws(() => sut.Unpublish(new UnpublishContent())); + Assert.Throws(() => + { + sut.Unpublish(CreateContentCommand(new UnpublishContent())); + }); } [Fact] @@ -221,22 +249,23 @@ namespace Squidex.Write.Contents CreateContent(); PublishContent(); - sut.Unpublish(new UnpublishContent()); + sut.Unpublish(CreateContentCommand(new UnpublishContent())); Assert.False(sut.IsPublished); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new ContentUnpublished() - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateContentEvent(new ContentUnpublished()) + ); } [Fact] public void Delete_should_throw_if_not_created() { - Assert.Throws(() => sut.Delete(new DeleteContent())); + Assert.Throws(() => + { + sut.Delete(CreateContentCommand(new DeleteContent())); + }); } [Fact] @@ -245,7 +274,10 @@ namespace Squidex.Write.Contents CreateContent(); DeleteContent(); - Assert.Throws(() => sut.Delete(new DeleteContent())); + Assert.Throws(() => + { + sut.Delete(CreateContentCommand(new DeleteContent())); + }); } [Fact] @@ -253,44 +285,56 @@ namespace Squidex.Write.Contents { CreateContent(); - sut.Delete(new DeleteContent()); + sut.Delete(CreateContentCommand(new DeleteContent())); Assert.True(sut.IsDeleted); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new ContentDeleted() - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateContentEvent(new ContentDeleted()) + ); } private void CreateContent() { - sut.Create(new CreateContent { Data = data, AppId = appId }); + sut.Create(CreateContentCommand(new CreateContent { Data = data })); ((IAggregate)sut).ClearUncommittedEvents(); } private void UpdateContent() { - sut.Update(new UpdateContent { Data = data, AppId = appId }); + sut.Update(CreateContentCommand(new UpdateContent { Data = data })); ((IAggregate)sut).ClearUncommittedEvents(); } private void PublishContent() { - sut.Publish(new PublishContent()); + sut.Publish(CreateContentCommand(new PublishContent())); ((IAggregate)sut).ClearUncommittedEvents(); } private void DeleteContent() { - sut.Delete(new DeleteContent()); + sut.Delete(CreateContentCommand(new DeleteContent())); ((IAggregate)sut).ClearUncommittedEvents(); } + + protected T CreateContentEvent(T @event) where T : ContentEvent + { + @event.ContentId = ContentId; + + return CreateEvent(@event); + } + + protected T CreateContentCommand(T command) where T : ContentCommand + { + command.ContentId = ContentId; + + return CreateCommand(command); + } } } diff --git a/tests/Squidex.Write.Tests/EnrichWithAppIdProcessorTests.cs b/tests/Squidex.Write.Tests/EnrichWithAppIdProcessorTests.cs deleted file mode 100644 index ee609dc30..000000000 --- a/tests/Squidex.Write.Tests/EnrichWithAppIdProcessorTests.cs +++ /dev/null @@ -1,71 +0,0 @@ -// ========================================================================== -// EnrichWithAppIdProcessorTests.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System; -using System.Threading.Tasks; -using Squidex.Events; -using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Commands; -using Squidex.Infrastructure.CQRS.Events; -using Squidex.Write.Apps; -using Xunit; - -namespace Squidex.Write -{ - public class EnrichWithAppIdProcessorTests - { - public sealed class MyAppCommand : AppAggregateCommand - { - } - - public sealed class MyNormalCommand : ICommand - { - } - - public sealed class MyEvent : IEvent - { - } - - private readonly EnrichWithAppIdProcessor sut = new EnrichWithAppIdProcessor(); - - [Fact] - public async Task Should_not_do_anything_if_not_app_command() - { - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, null, new MyNormalCommand()); - - Assert.False(envelope.Headers.Contains("AppId")); - } - - [Fact] - public async Task Should_attach_app_id_from_domain_object() - { - var appId = Guid.NewGuid(); - - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, new AppDomainObject(appId, 1), new MyNormalCommand()); - - Assert.Equal(appId, envelope.Headers.AppId()); - } - - [Fact] - public async Task Should_attach_app_id_to_event_envelope() - { - var appId = Guid.NewGuid(); - var appCommand = new MyAppCommand { AggregateId = appId }; - - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, null, appCommand); - - Assert.Equal(appId, envelope.Headers.AppId()); - } - } -} diff --git a/tests/Squidex.Write.Tests/EnrichWithSchemaIdProcessorTests.cs b/tests/Squidex.Write.Tests/EnrichWithSchemaIdProcessorTests.cs deleted file mode 100644 index 7b10382aa..000000000 --- a/tests/Squidex.Write.Tests/EnrichWithSchemaIdProcessorTests.cs +++ /dev/null @@ -1,74 +0,0 @@ -// ========================================================================== -// EnrichWithSchemaIdProcessorTests.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System; -using System.Threading.Tasks; -using Squidex.Core.Schemas; -using Squidex.Events; -using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Commands; -using Squidex.Infrastructure.CQRS.Events; -using Squidex.Write.Schemas; -using Xunit; - -namespace Squidex.Write -{ - public class EnrichWithSchemaIdProcessorTests - { - public sealed class MySchemaCommand : SchemaAggregateCommand - { - } - - public sealed class MyNormalCommand : ICommand - { - } - - public sealed class MyEvent : IEvent - { - } - - private readonly FieldRegistry registry = new FieldRegistry(new TypeNameRegistry()); - private readonly EnrichWithSchemaIdProcessor sut = new EnrichWithSchemaIdProcessor(); - - [Fact] - public async Task Should_not_do_anything_if_not_app_command() - { - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, null, new MyNormalCommand()); - - Assert.False(envelope.Headers.Contains("SchemaId")); - } - - [Fact] - public async Task Should_attach_app_id_from_domain_object() - { - var appId = Guid.NewGuid(); - - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, new SchemaDomainObject(appId, 1, registry), new MyNormalCommand()); - - Assert.Equal(appId, envelope.Headers.SchemaId()); - } - - [Fact] - public async Task Should_attach_app_id_to_event_envelope() - { - var appId = Guid.NewGuid(); - var appCommand = new MySchemaCommand { AggregateId = appId }; - - var envelope = new Envelope(new MyEvent()); - - await sut.ProcessEventAsync(envelope, null, appCommand); - - Assert.Equal(appId, envelope.Headers.SchemaId()); - } - } -} diff --git a/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs b/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs index c32e12098..b1d977fa2 100644 --- a/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs +++ b/tests/Squidex.Write.Tests/Schemas/SchemaCommandHandlerTests.cs @@ -6,16 +6,14 @@ // All rights reserved. // ========================================================================== -using System; using System.Threading.Tasks; using Moq; using Squidex.Core.Schemas; using Squidex.Infrastructure; -using Squidex.Infrastructure.CQRS.Commands; using Squidex.Read.Schemas; using Squidex.Read.Schemas.Services; using Squidex.Write.Schemas.Commands; -using Squidex.Write.Utils; +using Squidex.Write.TestHelpers; using Xunit; // ReSharper disable ConvertToConstant.Local @@ -28,13 +26,11 @@ namespace Squidex.Write.Schemas private readonly SchemaCommandHandler sut; private readonly SchemaDomainObject schema; private readonly FieldRegistry registry = new FieldRegistry(new TypeNameRegistry()); - private readonly Guid appId = Guid.NewGuid(); private readonly string fieldName = "age"; - private readonly string schemaName = "users"; public SchemaCommandHandlerTests() { - schema = new SchemaDomainObject(Id, 0, registry); + schema = new SchemaDomainObject(SchemaId, 0, registry); sut = new SchemaCommandHandler(Handler, schemaProvider.Object); } @@ -42,10 +38,9 @@ namespace Squidex.Write.Schemas [Fact] public async Task Create_should_throw_if_a_name_with_same_name_already_exists() { - var command = new CreateSchema { Name = schemaName, AppId = appId, AggregateId = Id }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new CreateSchema { Name = SchemaName, SchemaId = SchemaId }); - schemaProvider.Setup(x => x.FindSchemaByNameAsync(appId, schemaName)).Returns(Task.FromResult(new Mock().Object)).Verifiable(); + schemaProvider.Setup(x => x.FindSchemaByNameAsync(AppId, SchemaName)).Returns(Task.FromResult(new Mock().Object)).Verifiable(); await TestCreate(schema, async _ => { @@ -58,17 +53,16 @@ namespace Squidex.Write.Schemas [Fact] public async Task Create_should_create_schema_if_name_is_free() { - var command = new CreateSchema { Name = schemaName, AppId = appId, AggregateId = Id }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new CreateSchema { Name = SchemaName, SchemaId = SchemaId }); - schemaProvider.Setup(x => x.FindSchemaByNameAsync(Id, schemaName)).Returns(Task.FromResult(null)).Verifiable(); + schemaProvider.Setup(x => x.FindSchemaByNameAsync(AppId, SchemaName)).Returns(Task.FromResult(null)).Verifiable(); await TestCreate(schema, async _ => { await sut.HandleAsync(context); }); - Assert.Equal(command.Name, context.Result()); + Assert.Equal(SchemaName, context.Result()); } [Fact] @@ -76,8 +70,7 @@ namespace Squidex.Write.Schemas { CreateSchema(); - var command = new UpdateSchema { AggregateId = Id, Properties = new SchemaProperties() }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new UpdateSchema { Properties = new SchemaProperties() }); await TestUpdate(schema, async _ => { @@ -90,8 +83,7 @@ namespace Squidex.Write.Schemas { CreateSchema(); - var command = new PublishSchema { AggregateId = Id }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new PublishSchema()); await TestUpdate(schema, async _ => { @@ -105,8 +97,7 @@ namespace Squidex.Write.Schemas CreateSchema(); PublishSchema(); - var command = new UnpublishSchema { AggregateId = Id }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new UnpublishSchema()); await TestUpdate(schema, async _ => { @@ -119,8 +110,7 @@ namespace Squidex.Write.Schemas { CreateSchema(); - var command = new DeleteSchema { AggregateId = Id }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new DeleteSchema()); await TestUpdate(schema, async _ => { @@ -133,8 +123,7 @@ namespace Squidex.Write.Schemas { CreateSchema(); - var command = new AddField { AggregateId = Id, Name = fieldName, Properties = new NumberFieldProperties() }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() }); await TestUpdate(schema, async _ => { @@ -150,8 +139,7 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - var command = new UpdateField { AggregateId = Id, FieldId = 1, Properties = new NumberFieldProperties() }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() }); await TestUpdate(schema, async _ => { @@ -165,8 +153,7 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - var command = new HideField { AggregateId = Id, FieldId = 1 }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new HideField { FieldId = 1 }); await TestUpdate(schema, async _ => { @@ -180,8 +167,7 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - var command = new ShowField { AggregateId = Id, FieldId = 1 }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new ShowField { FieldId = 1 }); await TestUpdate(schema, async _ => { @@ -195,8 +181,7 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - var command = new DisableField { AggregateId = Id, FieldId = 1 }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new DisableField { FieldId = 1 }); await TestUpdate(schema, async _ => { @@ -210,8 +195,7 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - var command = new EnableField { AggregateId = Id, FieldId = 1 }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new EnableField { FieldId = 1 }); await TestUpdate(schema, async _ => { @@ -225,8 +209,7 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - var command = new DeleteField { AggregateId = Id, FieldId = 1 }; - var context = new CommandContext(command); + var context = CreateContextForCommand(new DeleteField { FieldId = 1 }); await TestUpdate(schema, async _ => { @@ -236,17 +219,17 @@ namespace Squidex.Write.Schemas private void CreateSchema() { - schema.Create(new CreateSchema { Name = schemaName }); + schema.Create(CreateCommand(new CreateSchema { Name = SchemaName })); } private void PublishSchema() { - schema.Publish(new PublishSchema()); + schema.Publish(CreateCommand(new PublishSchema())); } private void CreateField() { - schema.AddField(new AddField { Name = fieldName, Properties = new NumberFieldProperties() }); + schema.AddField(CreateCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); } } } diff --git a/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs b/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs index f72cf444e..022ade096 100644 --- a/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs +++ b/tests/Squidex.Write.Tests/Schemas/SchemaDomainObjectTests.cs @@ -6,47 +6,52 @@ // All rights reserved. // ========================================================================== -using System; using System.Linq; -using FluentAssertions; using Squidex.Core.Schemas; using Squidex.Events.Schemas; using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; -using Squidex.Infrastructure.CQRS.Events; using Squidex.Write.Schemas.Commands; +using Squidex.Write.TestHelpers; using Xunit; // ReSharper disable ConvertToConstant.Local namespace Squidex.Write.Schemas { - public class SchemaDomainObjectTests + public class SchemaDomainObjectTests : HandlerTestBase { - private readonly Guid appId = Guid.NewGuid(); private readonly string fieldName = "age"; - private readonly string appName = "schema"; + private readonly NamedId fieldId; private readonly SchemaDomainObject sut; - + public SchemaDomainObjectTests() { + fieldId = new NamedId(1, fieldName); + var fieldRegistry = new FieldRegistry(new TypeNameRegistry()); - sut = new SchemaDomainObject(Guid.NewGuid(), 0, fieldRegistry); + sut = new SchemaDomainObject(SchemaId, 0, fieldRegistry); } [Fact] public void Create_should_throw_if_created() { - sut.Create(new CreateSchema { Name = appName }); + sut.Create(new CreateSchema { Name = SchemaName }); - Assert.Throws(() => sut.Create(new CreateSchema { Name = appName })); + Assert.Throws(() => + { + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName })); + }); } [Fact] public void Create_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.Create(new CreateSchema())); + Assert.Throws(() => + { + sut.Create(CreateCommand(new CreateSchema())); + }); } [Fact] @@ -54,22 +59,22 @@ namespace Squidex.Write.Schemas { var properties = new SchemaProperties(); - sut.Create(new CreateSchema { Name = appName, AppId = appId, Properties = properties }); - - Assert.Equal("schema", sut.Schema.Name); + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName, Properties = properties })); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new SchemaCreated { Name = appName, Properties = properties } - }); - } + Assert.Equal(SchemaName, sut.Schema.Name); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaCreated { Name = SchemaName, Properties = properties }) + ); + } [Fact] public void Update_should_throw_if_not_created() { - Assert.Throws(() => sut.Update(new UpdateSchema { Properties = new SchemaProperties() })); + Assert.Throws(() => + { + sut.Update(CreateCommand(new UpdateSchema { Properties = new SchemaProperties() })); + }); } [Fact] @@ -78,7 +83,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.Update(new UpdateSchema())); + Assert.Throws(() => + { + sut.Update(CreateCommand(new UpdateSchema())); + }); } [Fact] @@ -86,7 +94,10 @@ namespace Squidex.Write.Schemas { CreateSchema(); - Assert.Throws(() => sut.Update(new UpdateSchema())); + Assert.Throws(() => + { + sut.Update(CreateCommand(new UpdateSchema())); + }); } [Fact] @@ -96,22 +107,23 @@ namespace Squidex.Write.Schemas CreateSchema(); - sut.Update(new UpdateSchema { Properties = properties }); - + sut.Update(CreateCommand(new UpdateSchema { Properties = properties })); + Assert.Equal(properties, sut.Schema.Properties); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new SchemaUpdated { Properties = properties } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaUpdated { Properties = properties }) + ); } [Fact] public void Publish_should_throw_if_not_created() { - Assert.Throws(() => sut.Publish(new PublishSchema())); + Assert.Throws(() => + { + sut.Publish(CreateCommand(new PublishSchema())); + }); } [Fact] @@ -120,7 +132,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.Publish(new PublishSchema())); + Assert.Throws(() => + { + sut.Publish(CreateCommand(new PublishSchema())); + }); } [Fact] @@ -128,22 +143,23 @@ namespace Squidex.Write.Schemas { CreateSchema(); - sut.Publish(new PublishSchema()); + sut.Publish(CreateCommand(new PublishSchema())); Assert.True(sut.Schema.IsPublished); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new SchemaPublished() - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaPublished()) + ); } - + [Fact] public void Unpublish_should_throw_if_not_created() { - Assert.Throws(() => sut.Unpublish(new UnpublishSchema())); + Assert.Throws(() => + { + sut.Unpublish(CreateCommand(new UnpublishSchema())); + }); } [Fact] @@ -152,7 +168,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.Unpublish(new UnpublishSchema())); + Assert.Throws(() => + { + sut.Unpublish(CreateCommand(new UnpublishSchema())); + }); } [Fact] @@ -161,22 +180,23 @@ namespace Squidex.Write.Schemas CreateSchema(); PublishSchema(); - sut.Unpublish(new UnpublishSchema()); + sut.Unpublish(CreateCommand(new UnpublishSchema())); Assert.False(sut.Schema.IsPublished); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new SchemaUnpublished() - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaUnpublished()) + ); } - + [Fact] public void Delete_should_throw_if_not_created() { - Assert.Throws(() => sut.Delete(new DeleteSchema())); + Assert.Throws(() => + { + sut.Delete(CreateCommand(new DeleteSchema())); + }); } [Fact] @@ -185,7 +205,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.Delete(new DeleteSchema())); + Assert.Throws(() => + { + sut.Delete(CreateCommand(new DeleteSchema())); + }); } [Fact] @@ -193,28 +216,32 @@ namespace Squidex.Write.Schemas { CreateSchema(); - sut.Delete(new DeleteSchema()); + sut.Delete(CreateCommand(new DeleteSchema())); Assert.True(sut.IsDeleted); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new SchemaDeleted() - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new SchemaDeleted()) + ); } - + [Fact] public void AddField_should_throw_if_not_created() { - Assert.Throws(() => sut.AddField(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + Assert.Throws(() => + { + sut.AddField(CreateCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + }); } [Fact] public void AddField_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.AddField(new AddField())); + Assert.Throws(() => + { + sut.AddField(CreateCommand(new AddField())); + }); } [Fact] @@ -223,7 +250,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.AddField(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + Assert.Throws(() => + { + sut.AddField(CreateCommand(new AddField { Name = fieldName, Properties = new NumberFieldProperties() })); + }); } [Fact] @@ -233,28 +263,32 @@ namespace Squidex.Write.Schemas CreateSchema(); - sut.AddField(new AddField { Name = fieldName, Properties = properties }); + sut.AddField(CreateCommand(new AddField { Name = fieldName, Properties = properties })); Assert.Equal(properties, sut.Schema.Fields[1].RawProperties); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldAdded { Name = fieldName, FieldId = 1, Properties = properties } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldAdded { Name = fieldName, FieldId = fieldId, Properties = properties }) + ); } - + [Fact] public void UpdateField_should_throw_if_not_created() { - Assert.Throws(() => sut.UpdateField(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + Assert.Throws(() => + { + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + }); } [Fact] public void UpdateField_should_throw_if_command_is_not_valid() { - Assert.Throws(() => sut.UpdateField(new UpdateField())); + Assert.Throws(() => + { + sut.UpdateField(CreateCommand(new UpdateField())); + }); } [Fact] @@ -262,7 +296,10 @@ namespace Squidex.Write.Schemas { CreateSchema(); - Assert.Throws(() => sut.UpdateField(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + Assert.Throws(() => + { + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + }); } [Fact] @@ -271,7 +308,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.UpdateField(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + Assert.Throws(() => + { + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = new NumberFieldProperties() })); + }); } [Fact] @@ -282,22 +322,23 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - sut.UpdateField(new UpdateField { FieldId = 1, Properties = properties }); + sut.UpdateField(CreateCommand(new UpdateField { FieldId = 1, Properties = properties })); Assert.Equal(properties, sut.Schema.Fields[1].RawProperties); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldUpdated { FieldId = 1, Properties = properties } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldUpdated { FieldId = fieldId, Properties = properties }) + ); } [Fact] public void HideField_should_throw_if_not_created() { - Assert.Throws(() => sut.HideField(new HideField { FieldId = 1 })); + Assert.Throws(() => + { + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + }); } [Fact] @@ -305,7 +346,10 @@ namespace Squidex.Write.Schemas { CreateSchema(); - Assert.Throws(() => sut.HideField(new HideField { FieldId = 2 })); + Assert.Throws(() => + { + sut.HideField(CreateCommand(new HideField { FieldId = 2 })); + }); } [Fact] @@ -314,7 +358,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.HideField(new HideField { FieldId = 1 })); + Assert.Throws(() => + { + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + }); } [Fact] @@ -323,22 +370,23 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - sut.HideField(new HideField { FieldId = 1 }); + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); Assert.True(sut.Schema.Fields[1].IsHidden); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldHidden { FieldId = 1 } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldHidden { FieldId = fieldId }) + ); } - + [Fact] public void ShowField_should_throw_if_not_created() { - Assert.Throws(() => sut.ShowField(new ShowField { FieldId = 1 })); + Assert.Throws(() => + { + sut.ShowField(CreateCommand(new ShowField { FieldId = 1 })); + }); } [Fact] @@ -346,7 +394,10 @@ namespace Squidex.Write.Schemas { CreateSchema(); - Assert.Throws(() => sut.ShowField(new ShowField { FieldId = 2 })); + Assert.Throws(() => + { + sut.ShowField(CreateCommand(new ShowField { FieldId = 2 })); + }); } [Fact] @@ -355,7 +406,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.ShowField(new ShowField { FieldId = 1 })); + Assert.Throws(() => + { + sut.ShowField(CreateCommand(new ShowField { FieldId = 1 })); + }); } [Fact] @@ -364,23 +418,24 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - sut.HideField(new HideField { FieldId = 1 }); - sut.ShowField(new ShowField { FieldId = 1 }); + sut.HideField(CreateCommand(new HideField { FieldId = 1 })); + sut.ShowField(CreateCommand(new ShowField { FieldId = 1 })); Assert.False(sut.Schema.Fields[1].IsHidden); - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldShown { FieldId = 1 } - }); + sut.GetUncomittedEvents().Skip(1) + .ShouldHaveSameEvents( + CreateEvent(new FieldShown { FieldId = fieldId }) + ); } - + [Fact] public void DisableField_should_throw_if_not_created() { - Assert.Throws(() => sut.DisableField(new DisableField { FieldId = 1 })); + Assert.Throws(() => + { + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + }); } [Fact] @@ -388,7 +443,10 @@ namespace Squidex.Write.Schemas { CreateSchema(); - Assert.Throws(() => sut.DisableField(new DisableField { FieldId = 2 })); + Assert.Throws(() => + { + sut.DisableField(CreateCommand(new DisableField { FieldId = 2 })); + }); } [Fact] @@ -397,7 +455,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.DisableField(new DisableField { FieldId = 1 })); + Assert.Throws(() => + { + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + }); } [Fact] @@ -405,23 +466,24 @@ namespace Squidex.Write.Schemas { CreateSchema(); CreateField(); - - sut.DisableField(new DisableField { FieldId = 1 }); + + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); Assert.True(sut.Schema.Fields[1].IsDisabled); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldDisabled { FieldId = 1 } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldDisabled { FieldId = fieldId }) + ); } - + [Fact] public void EnableField_should_throw_if_not_created() { - Assert.Throws(() => sut.EnableField(new EnableField { FieldId = 1 })); + Assert.Throws(() => + { + sut.EnableField(CreateCommand(new EnableField { FieldId = 1 })); + }); } [Fact] @@ -429,7 +491,10 @@ namespace Squidex.Write.Schemas { CreateSchema(); - Assert.Throws(() => sut.EnableField(new EnableField { FieldId = 2 })); + Assert.Throws(() => + { + sut.EnableField(CreateCommand(new EnableField { FieldId = 2 })); + }); } [Fact] @@ -438,7 +503,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.EnableField(new EnableField { FieldId = 1 })); + Assert.Throws(() => + { + sut.EnableField(CreateCommand(new EnableField { FieldId = 1 })); + }); } [Fact] @@ -447,23 +515,24 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - sut.DisableField(new DisableField { FieldId = 1 }); - sut.EnableField(new EnableField { FieldId = 1 }); + sut.DisableField(CreateCommand(new DisableField { FieldId = 1 })); + sut.EnableField(CreateCommand(new EnableField { FieldId = 1 })); Assert.False(sut.Schema.Fields[1].IsDisabled); - sut.GetUncomittedEvents().Select(x => x.Payload).Skip(1).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldEnabled { FieldId = 1 } - }); + sut.GetUncomittedEvents().Skip(1) + .ShouldHaveSameEvents( + CreateEvent(new FieldEnabled { FieldId = fieldId }) + ); } - + [Fact] public void DeleteField_should_throw_if_not_created() { - Assert.Throws(() => sut.DeleteField(new DeleteField { FieldId = 1 })); + Assert.Throws(() => + { + sut.DeleteField(CreateCommand(new DeleteField { FieldId = 1 })); + }); } [Fact] @@ -472,7 +541,10 @@ namespace Squidex.Write.Schemas CreateSchema(); DeleteSchema(); - Assert.Throws(() => sut.DeleteField(new DeleteField { FieldId = 1 })); + Assert.Throws(() => + { + sut.DeleteField(CreateCommand(new DeleteField { FieldId = 1 })); + }); } [Fact] @@ -481,16 +553,14 @@ namespace Squidex.Write.Schemas CreateSchema(); CreateField(); - sut.DeleteField(new DeleteField { FieldId = 1 }); + sut.DeleteField(CreateCommand(new DeleteField { FieldId = 1 })); Assert.False(sut.Schema.Fields.ContainsKey(1)); - sut.GetUncomittedEvents().Select(x => x.Payload).ToArray() - .ShouldBeEquivalentTo( - new IEvent[] - { - new FieldDeleted { FieldId = 1 } - }); + sut.GetUncomittedEvents() + .ShouldHaveSameEvents( + CreateEvent(new FieldDeleted { FieldId = fieldId }) + ); } private void CreateField() @@ -502,21 +572,21 @@ namespace Squidex.Write.Schemas private void CreateSchema() { - sut.Create(new CreateSchema { Name = appName, AppId = appId }); + sut.Create(CreateCommand(new CreateSchema { Name = SchemaName })); ((IAggregate)sut).ClearUncommittedEvents(); } private void PublishSchema() { - sut.Publish(new PublishSchema()); + sut.Publish(CreateCommand(new PublishSchema())); ((IAggregate)sut).ClearUncommittedEvents(); } private void DeleteSchema() { - sut.Delete(new DeleteSchema()); + sut.Delete(CreateCommand(new DeleteSchema())); ((IAggregate)sut).ClearUncommittedEvents(); } diff --git a/tests/Squidex.Write.Tests/TestHelpers/AssertHelper.cs b/tests/Squidex.Write.Tests/TestHelpers/AssertHelper.cs new file mode 100644 index 000000000..27dacb7e1 --- /dev/null +++ b/tests/Squidex.Write.Tests/TestHelpers/AssertHelper.cs @@ -0,0 +1,31 @@ +// ========================================================================== +// AssertHelper.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Squidex.Infrastructure.CQRS; +using Squidex.Infrastructure.CQRS.Events; + +namespace Squidex.Write.TestHelpers +{ + public static class AssertHelper + { + public static void ShouldHaveSameEvents(this IEnumerable> events, params IEvent[] others) + { + var source = events.Select(x => x.Payload).ToArray(); + + source.Should().HaveSameCount(others); + + for (var i = 0; i < source.Length; i++) + { + ((object)source[i]).ShouldBeEquivalentTo(others[i], o => o.IncludingAllDeclaredProperties()); + } + } + } +} diff --git a/tests/Squidex.Write.Tests/Utils/HandlerTestBase.cs b/tests/Squidex.Write.Tests/TestHelpers/HandlerTestBase.cs similarity index 55% rename from tests/Squidex.Write.Tests/Utils/HandlerTestBase.cs rename to tests/Squidex.Write.Tests/TestHelpers/HandlerTestBase.cs index 5d78fc0ac..a8ff8db5e 100644 --- a/tests/Squidex.Write.Tests/Utils/HandlerTestBase.cs +++ b/tests/Squidex.Write.Tests/TestHelpers/HandlerTestBase.cs @@ -8,10 +8,12 @@ using System; using System.Threading.Tasks; +using Squidex.Events; +using Squidex.Infrastructure; using Squidex.Infrastructure.CQRS; using Squidex.Infrastructure.CQRS.Commands; -namespace Squidex.Write.Utils +namespace Squidex.Write.TestHelpers { public abstract class HandlerTestBase where T : DomainObject { @@ -46,11 +48,25 @@ namespace Squidex.Write.Utils } private readonly MockupHandler handler = new MockupHandler(); - private readonly Guid id = Guid.NewGuid(); - protected Guid Id + protected RefToken User { get; } = new RefToken("subject", Guid.NewGuid().ToString()); + + protected Guid AppId { get; } = Guid.NewGuid(); + + protected Guid SchemaId { get; } = Guid.NewGuid(); + + protected string AppName { get; } = "my-app"; + + protected string SchemaName { get; } = "my-schema"; + + protected NamedId AppNamedId { - get { return id; } + get { return new NamedId(AppId, AppName); } + } + + protected NamedId SchemaNamedId + { + get { return new NamedId(SchemaId, SchemaName); } } protected IAggregateHandler Handler @@ -58,6 +74,11 @@ namespace Squidex.Write.Utils get { return handler; } } + protected CommandContext CreateContextForCommand(TCommand command) where TCommand : SquidexCommand + { + return new CommandContext(CreateCommand(command)); + } + public async Task TestCreate(T domainObject, Func action, bool shouldCreate = true) { handler.Init(domainObject); @@ -81,5 +102,47 @@ namespace Squidex.Write.Utils throw new InvalidOperationException("Create not called"); } } + + protected virtual TCommand CreateCommand(TCommand command) where TCommand : SquidexCommand + { + command.Actor = User; + + var appCommand = command as AppCommand; + + if (appCommand != null) + { + appCommand.AppId = AppNamedId; + } + + var schemaCommand = command as SchemaCommand; + + if (schemaCommand != null) + { + schemaCommand.SchemaId = SchemaNamedId; + } + + return command; + } + + protected virtual TEvent CreateEvent(TEvent @event) where TEvent : SquidexEvent + { + @event.Actor = User; + + var appEvent = @event as AppEvent; + + if (appEvent != null) + { + appEvent.AppId = AppNamedId; + } + + var schemaEvent = @event as SchemaEvent; + + if (schemaEvent != null) + { + schemaEvent.SchemaId = SchemaNamedId; + } + + return @event; + } } }