mirror of https://github.com/Squidex/squidex.git
9 changed files with 376 additions and 14 deletions
@ -0,0 +1,180 @@ |
|||
// ==========================================================================
|
|||
// CachingAppProviderTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
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.Read.Apps.Repositories; |
|||
using Squidex.Read.Apps.Services.Implementations; |
|||
using Squidex.Read.MongoDb.Apps; |
|||
using Xunit; |
|||
// ReSharper disable ConvertToConstant.Local
|
|||
// ReSharper disable UnusedParameter.Local
|
|||
|
|||
namespace Squidex.Read.Apps |
|||
{ |
|||
public class CachingAppProviderTests |
|||
{ |
|||
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); |
|||
private readonly Mock<IAppRepository> repository = new Mock<IAppRepository>(); |
|||
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 |
|||
{ |
|||
} |
|||
|
|||
public CachingAppProviderTests() |
|||
{ |
|||
appV1 = new MongoAppEntity { Name = appName, Id = appId }; |
|||
appV2 = new MongoAppEntity { Name = appName, Id = appId }; |
|||
|
|||
sut = new CachingAppProvider(cache, repository.Object); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_also_retrieve_app_by_name_if_retrieved_by_id_before() |
|||
{ |
|||
repository.Setup(x => x.FindAppAsync(appId)).Returns(Task.FromResult<IAppEntity>(appV1)); |
|||
|
|||
await ProvideAppById(appV1); |
|||
await ProvideAppByName(appV1); |
|||
|
|||
repository.Verify(x => x.FindAppAsync(appId), Times.Once()); |
|||
repository.Verify(x => x.FindAppAsync(appName), 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<IAppEntity>(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<IAppEntity>(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<IAppEntity>(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<IAppEntity>(apps())); |
|||
|
|||
await ProvideAppByName(null); |
|||
await RaiseEvent(new AppCreated { Name = appName }); |
|||
await ProvideAppByName(appV1); |
|||
|
|||
repository.Verify(x => x.FindAppAsync(appName), Times.Exactly(2)); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(AppEvents))] |
|||
public async Task Should_clear_cache_for_id_after_update_event(IEvent @event) |
|||
{ |
|||
var apps = ProviderResults(appV1, appV2); |
|||
|
|||
repository.Setup(x => x.FindAppAsync(appId)).Returns(() => Task.FromResult<IAppEntity>(apps())); |
|||
|
|||
await ProvideAppById(appV1); |
|||
await RaiseEvent(@event); |
|||
await ProvideAppById(appV2); |
|||
|
|||
repository.Verify(x => x.FindAppAsync(appId), Times.Exactly(2)); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(AppEvents))] |
|||
public async Task Should_clear_cache_for_name_after_update_event(IEvent @event) |
|||
{ |
|||
var apps = ProviderResults(appV1, appV2); |
|||
|
|||
repository.Setup(x => x.FindAppAsync(appName)).Returns(() => Task.FromResult<IAppEntity>(apps())); |
|||
|
|||
await ProvideAppByName(appV1); |
|||
await RaiseEvent(@event); |
|||
await ProvideAppByName(appV2); |
|||
|
|||
repository.Verify(x => x.FindAppAsync(appName), Times.Exactly(2)); |
|||
} |
|||
|
|||
private async Task RaiseEvent(IEvent @event) |
|||
{ |
|||
await sut.On(new Envelope<IEvent>(@event).SetAggregateId(appId)); |
|||
} |
|||
|
|||
private async Task ProvideAppById(IAppEntity app) |
|||
{ |
|||
Assert.Equal(app, await sut.FindAppByIdAsync(appId)); |
|||
} |
|||
|
|||
private async Task ProvideAppByName(IAppEntity app) |
|||
{ |
|||
Assert.Equal(app, await sut.FindAppByNameAsync(appName)); |
|||
} |
|||
|
|||
private static Func<T> ProviderResults<T>(params T[] items) |
|||
{ |
|||
var index = 0; |
|||
|
|||
return () => items[index++]; |
|||
} |
|||
|
|||
public static IEnumerable<object[]> 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() }; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,179 @@ |
|||
// ==========================================================================
|
|||
// CachingSchemaProviderTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
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.Read.Schemas.Repositories; |
|||
using Squidex.Read.Schemas.Services.Implementations; |
|||
using Squidex.Read.MongoDb.Schemas; |
|||
using Xunit; |
|||
// ReSharper disable ConvertToConstant.Local
|
|||
// ReSharper disable UnusedParameter.Local
|
|||
|
|||
namespace Squidex.Read.Schemas |
|||
{ |
|||
public class CachingSchemaProviderTests |
|||
{ |
|||
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); |
|||
private readonly Mock<ISchemaRepository> repository = new Mock<ISchemaRepository>(); |
|||
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 |
|||
{ |
|||
} |
|||
|
|||
public CachingSchemaProviderTests() |
|||
{ |
|||
schemaV1 = new MongoSchemaEntity { Name = schemaName, Id = schemaId, AppId = appId }; |
|||
schemaV2 = new MongoSchemaEntity { Name = schemaName, Id = schemaId, AppId = appId }; |
|||
|
|||
sut = new CachingSchemaProvider(cache, repository.Object); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before() |
|||
{ |
|||
repository.Setup(x => x.FindSchemaAsync(schemaId)).Returns(Task.FromResult<ISchemaEntityWithSchema>(schemaV1)); |
|||
|
|||
await ProvideSchemaById(schemaV1); |
|||
await ProvideSchemaByName(schemaV1); |
|||
|
|||
repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Once()); |
|||
repository.Verify(x => x.FindSchemaAsync(appId, schemaName), 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<ISchemaEntityWithSchema>(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<ISchemaEntityWithSchema>(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<ISchemaEntityWithSchema>(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<ISchemaEntityWithSchema>(schemas())); |
|||
|
|||
await ProvideSchemaByName(null); |
|||
await RaiseEvent(new SchemaCreated { Name = schemaName }); |
|||
await ProvideSchemaByName(schemaV1); |
|||
|
|||
repository.Verify(x => x.FindSchemaAsync(appId, schemaName), Times.Exactly(2)); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(SchemaEvents))] |
|||
public async Task Should_clear_cache_for_id_after_update_event(IEvent @event) |
|||
{ |
|||
var schemas = ProviderResults(schemaV1, schemaV2); |
|||
|
|||
repository.Setup(x => x.FindSchemaAsync(schemaId)).Returns(() => Task.FromResult<ISchemaEntityWithSchema>(schemas())); |
|||
|
|||
await ProvideSchemaById(schemaV1); |
|||
await RaiseEvent(@event); |
|||
await ProvideSchemaById(schemaV2); |
|||
|
|||
repository.Verify(x => x.FindSchemaAsync(schemaId), Times.Exactly(2)); |
|||
} |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(SchemaEvents))] |
|||
public async Task Should_clear_cache_for_name_after_update_event(IEvent @event) |
|||
{ |
|||
var schemas = ProviderResults(schemaV1, schemaV2); |
|||
|
|||
repository.Setup(x => x.FindSchemaAsync(appId, schemaName)).Returns(() => Task.FromResult<ISchemaEntityWithSchema>(schemas())); |
|||
|
|||
await ProvideSchemaByName(schemaV1); |
|||
await RaiseEvent(@event); |
|||
await ProvideSchemaByName(schemaV2); |
|||
|
|||
repository.Verify(x => x.FindSchemaAsync(appId, schemaName), Times.Exactly(2)); |
|||
} |
|||
|
|||
private async Task RaiseEvent(IEvent @event) |
|||
{ |
|||
await sut.On(new Envelope<IEvent>(@event).SetAggregateId(schemaId).SetAppId(appId)); |
|||
} |
|||
|
|||
private async Task ProvideSchemaById(ISchemaEntityWithSchema schema) |
|||
{ |
|||
Assert.Equal(schema, await sut.FindSchemaByIdAsync(schemaId)); |
|||
} |
|||
|
|||
private async Task ProvideSchemaByName(ISchemaEntityWithSchema schema) |
|||
{ |
|||
Assert.Equal(schema, await sut.FindSchemaByNameAsync(appId, schemaName)); |
|||
} |
|||
|
|||
private static Func<T> ProviderResults<T>(params T[] items) |
|||
{ |
|||
var index = 0; |
|||
|
|||
return () => items[index++]; |
|||
} |
|||
|
|||
public static IEnumerable<object[]> 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() }; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue