Browse Source

Fake it easy for read models.

pull/95/head
Sebastian Stehle 8 years ago
parent
commit
01c493825b
  1. 57
      tests/Squidex.Domain.Apps.Read.Tests/Apps/CachingAppProviderTests.cs
  2. 8
      tests/Squidex.Domain.Apps.Read.Tests/Apps/ConfigAppLimitsProviderTests.cs
  3. 97
      tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs
  4. 61
      tests/Squidex.Domain.Apps.Read.Tests/Contents/ODataQueryTests.cs
  5. 61
      tests/Squidex.Domain.Apps.Read.Tests/Schemas/CachingSchemaProviderTests.cs

57
tests/Squidex.Domain.Apps.Read.Tests/Apps/CachingAppProviderTests.cs

@ -8,9 +8,9 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Moq;
using Squidex.Domain.Apps.Events.Apps; using Squidex.Domain.Apps.Events.Apps;
using Squidex.Domain.Apps.Read.Apps.Repositories; using Squidex.Domain.Apps.Read.Apps.Repositories;
using Squidex.Domain.Apps.Read.Apps.Services.Implementations; using Squidex.Domain.Apps.Read.Apps.Services.Implementations;
@ -26,27 +26,21 @@ namespace Squidex.Domain.Apps.Read.Apps
public class CachingAppProviderTests public class CachingAppProviderTests
{ {
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly Mock<IAppRepository> repository = new Mock<IAppRepository>(); private readonly IAppRepository repository = A.Fake<IAppRepository>();
private readonly CachingAppProvider sut; private readonly CachingAppProvider sut;
private readonly IAppEntity appV1; private readonly IAppEntity appV1 = A.Dummy<IAppEntity>();
private readonly IAppEntity appV2; private readonly IAppEntity appV2 = A.Dummy<IAppEntity>();
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app"); private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
public CachingAppProviderTests() public CachingAppProviderTests()
{ {
var appV1Mock = new Mock<IAppEntity>(); A.CallTo(() => appV1.Id).Returns(appId.Id);
var appV2Mock = new Mock<IAppEntity>(); A.CallTo(() => appV1.Name).Returns(appId.Name);
appV1Mock.Setup(x => x.Id).Returns(appId.Id); A.CallTo(() => appV2.Id).Returns(appId.Id);
appV1Mock.Setup(x => x.Name).Returns(appId.Name); A.CallTo(() => appV2.Name).Returns(appId.Name);
appV2Mock.Setup(x => x.Id).Returns(appId.Id); sut = new CachingAppProvider(cache, repository);
appV2Mock.Setup(x => x.Name).Returns(appId.Name);
appV1 = appV1Mock.Object;
appV2 = appV2Mock.Object;
sut = new CachingAppProvider(cache, repository.Object);
} }
[Fact] [Fact]
@ -70,33 +64,32 @@ namespace Squidex.Domain.Apps.Read.Apps
[Fact] [Fact]
public async Task Should_also_retrieve_app_by_name_if_retrieved_by_id_before() public async Task Should_also_retrieve_app_by_name_if_retrieved_by_id_before()
{ {
repository.Setup(x => x.FindAppAsync(appId.Id)).Returns(Task.FromResult(appV1)); A.CallTo(() => repository.FindAppAsync(appId.Id)).Returns(Task.FromResult(appV1));
await ProvideAppById(appV1); await ProvideAppById(appV1);
await ProvideAppByName(appV1); await ProvideAppByName(appV1);
repository.Verify(x => x.FindAppAsync(appId.Id), Times.Once()); A.CallTo(() => repository.FindAppAsync(appId.Id)).MustHaveHappened();
repository.Verify(x => x.FindAppAsync(appId.Name), Times.Never()); A.CallTo(() => repository.FindAppAsync(appId.Name)).MustNotHaveHappened();
} }
[Fact] [Fact]
public async Task Should_also_retrieve_app_by_id_if_retrieved_by_name_before() public async Task Should_also_retrieve_app_by_id_if_retrieved_by_name_before()
{ {
repository.Setup(x => x.FindAppAsync(appId.Name)).Returns(Task.FromResult(appV1)); A.CallTo(() => repository.FindAppAsync(appId.Name)).Returns(Task.FromResult(appV1));
await ProvideAppByName(appV1); await ProvideAppByName(appV1);
await ProvideAppById(appV1); await ProvideAppById(appV1);
repository.Verify(x => x.FindAppAsync(appId.Name), Times.Once()); A.CallTo(() => repository.FindAppAsync(appId.Id)).MustNotHaveHappened();
repository.Verify(x => x.FindAppAsync(appId.Id), Times.Never()); A.CallTo(() => repository.FindAppAsync(appId.Name)).MustHaveHappened();
} }
[Fact] [Fact]
public async Task Should_clear_cache_for_id_after_update_event() public async Task Should_clear_cache_for_id_after_update_event()
{ {
var apps = ProviderResults(appV1, appV2); A.CallTo(() => repository.FindAppAsync(appId.Id)).Returns(appV2);
A.CallTo(() => repository.FindAppAsync(appId.Id)).Returns(appV1).Once();
repository.Setup(x => x.FindAppAsync(appId.Id)).Returns(() => Task.FromResult(apps()));
await ProvideAppById(appV1); await ProvideAppById(appV1);
@ -104,15 +97,14 @@ namespace Squidex.Domain.Apps.Read.Apps
await ProvideAppById(appV2); await ProvideAppById(appV2);
repository.Verify(x => x.FindAppAsync(appId.Id), Times.Exactly(2)); A.CallTo(() => repository.FindAppAsync(appId.Id)).MustHaveHappened(Repeated.Exactly.Times(2));
} }
[Fact] [Fact]
public async Task Should_clear_cache_for_name_after_update_event() public async Task Should_clear_cache_for_name_after_update_event()
{ {
var apps = ProviderResults(appV1, appV2); A.CallTo(() => repository.FindAppAsync(appId.Name)).Returns(appV2);
A.CallTo(() => repository.FindAppAsync(appId.Name)).Returns(appV1).Once();
repository.Setup(x => x.FindAppAsync(appId.Name)).Returns(() => Task.FromResult(apps()));
await ProvideAppByName(appV1); await ProvideAppByName(appV1);
@ -120,7 +112,7 @@ namespace Squidex.Domain.Apps.Read.Apps
await ProvideAppByName(appV2); await ProvideAppByName(appV2);
repository.Verify(x => x.FindAppAsync(appId.Name), Times.Exactly(2)); A.CallTo(() => repository.FindAppAsync(appId.Name)).MustHaveHappened(Repeated.Exactly.Times(2));
} }
private async Task ProvideAppById(IAppEntity app) private async Task ProvideAppById(IAppEntity app)
@ -132,12 +124,5 @@ namespace Squidex.Domain.Apps.Read.Apps
{ {
Assert.Equal(app, await sut.FindAppByNameAsync(appId.Name)); Assert.Equal(app, await sut.FindAppByNameAsync(appId.Name));
} }
private static Func<T> ProviderResults<T>(params T[] items)
{
var index = 0;
return () => items[index++];
}
} }
} }

8
tests/Squidex.Domain.Apps.Read.Tests/Apps/ConfigAppLimitsProviderTests.cs

@ -7,8 +7,8 @@
// ========================================================================== // ==========================================================================
using System.Linq; using System.Linq;
using FakeItEasy;
using FluentAssertions; using FluentAssertions;
using Moq;
using Squidex.Domain.Apps.Read.Apps.Services.Implementations; using Squidex.Domain.Apps.Read.Apps.Services.Implementations;
using Xunit; using Xunit;
@ -112,11 +112,11 @@ namespace Squidex.Domain.Apps.Read.Apps
private static IAppEntity CreateApp(string plan) private static IAppEntity CreateApp(string plan)
{ {
var app = new Mock<IAppEntity>(); var app = A.Dummy<IAppEntity>();
app.Setup(x => x.PlanId).Returns(plan); A.CallTo(() => app.PlanId).Returns(plan);
return app.Object; return app;
} }
} }
} }

97
tests/Squidex.Domain.Apps.Read.Tests/Contents/GraphQLTests.cs

@ -9,9 +9,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Moq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core;
@ -59,32 +59,29 @@ namespace Squidex.Domain.Apps.Read.Contents
.AddOrUpdateField(new GeolocationField(9, "my-geolocation", Partitioning.Invariant, .AddOrUpdateField(new GeolocationField(9, "my-geolocation", Partitioning.Invariant,
new GeolocationFieldProperties())); new GeolocationFieldProperties()));
private readonly Mock<ISchemaRepository> schemaRepository = new Mock<ISchemaRepository>(); private readonly ISchemaRepository schemaRepository = A.Fake<ISchemaRepository>();
private readonly Mock<IContentRepository> contentRepository = new Mock<IContentRepository>(); private readonly ISchemaEntity schemaEntity = A.Fake<ISchemaEntity>();
private readonly Mock<IAssetRepository> assetRepository = new Mock<IAssetRepository>(); private readonly IContentRepository contentRepository = A.Fake<IContentRepository>();
private readonly IAppEntity app; private readonly IAssetRepository assetRepository = A.Fake<IAssetRepository>();
private readonly IAppEntity appEntity = A.Dummy<IAppEntity>();
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly IGraphQLService sut; private readonly IGraphQLService sut;
public GraphQLTests() public GraphQLTests()
{ {
var appEntity = new Mock<IAppEntity>(); A.CallTo(() => appEntity.Id).Returns(appId);
appEntity.Setup(x => x.Id).Returns(appId); A.CallTo(() => appEntity.PartitionResolver).Returns(x => InvariantPartitioning.Instance);
appEntity.Setup(x => x.PartitionResolver).Returns(x => InvariantPartitioning.Instance);
app = appEntity.Object; A.CallTo(() => schemaEntity.Id).Returns(schemaId);
A.CallTo(() => schemaEntity.Name).Returns(schema.Name);
A.CallTo(() => schemaEntity.Schema).Returns(schema);
A.CallTo(() => schemaEntity.IsPublished).Returns(true);
var schemaEntity = new Mock<ISchemaEntity>(); var schemas = new List<ISchemaEntity> { schemaEntity };
schemaEntity.Setup(x => x.Id).Returns(schemaId);
schemaEntity.Setup(x => x.Name).Returns(schema.Name);
schemaEntity.Setup(x => x.Schema).Returns(schema);
schemaEntity.Setup(x => x.IsPublished).Returns(true);
var schemas = new List<ISchemaEntity> { schemaEntity.Object }; A.CallTo(() => schemaRepository.QueryAllAsync(appId)).Returns(Task.FromResult<IReadOnlyList<ISchemaEntity>>(schemas));
schemaRepository.Setup(x => x.QueryAllAsync(appId)).Returns(Task.FromResult<IReadOnlyList<ISchemaEntity>>(schemas)); sut = new CachingGraphQLService(cache, schemaRepository, assetRepository, contentRepository, new FakeUrlGenerator());
sut = new CachingGraphQLService(cache, schemaRepository.Object, assetRepository.Object, contentRepository.Object, new FakeUrlGenerator());
} }
[Fact] [Fact]
@ -115,11 +112,10 @@ namespace Squidex.Domain.Apps.Read.Contents
var assets = new List<IAssetEntity> { assetEntity }; var assets = new List<IAssetEntity> { assetEntity };
assetRepository.Setup(x => x.QueryAsync(app.Id, null, null, "my-query", 30, 5)) A.CallTo(() => assetRepository.QueryAsync(appEntity.Id, null, null, "my-query", 30, 5))
.Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(assets)) .Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(assets));
.Verifiable();
var result = await sut.QueryAsync(app, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -150,8 +146,6 @@ namespace Squidex.Domain.Apps.Read.Contents
}; };
AssertJson(expected, new { data = result.Data }); AssertJson(expected, new { data = result.Data });
assetRepository.VerifyAll();
} }
[Fact] [Fact]
@ -181,11 +175,10 @@ namespace Squidex.Domain.Apps.Read.Contents
}} }}
}}"; }}";
assetRepository.Setup(x => x.FindAssetAsync(assetId)) A.CallTo(() => assetRepository.FindAssetAsync(assetId))
.Returns(Task.FromResult(assetEntity)) .Returns(Task.FromResult(assetEntity));
.Verifiable();
var result = await sut.QueryAsync(app, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -213,8 +206,6 @@ namespace Squidex.Domain.Apps.Read.Contents
}; };
AssertJson(expected, new { data = result.Data }); AssertJson(expected, new { data = result.Data });
assetRepository.VerifyAll();
} }
[Fact] [Fact]
@ -257,11 +248,10 @@ namespace Squidex.Domain.Apps.Read.Contents
var contents = new List<IContentEntity> { contentEntity }; var contents = new List<IContentEntity> { contentEntity };
contentRepository.Setup(x => x.QueryAsync(app, schemaId, false, null, "?$top=30&$skip=5")) A.CallTo(() => contentRepository.QueryAsync(appEntity, schemaId, false, null, "?$top=30&$skip=5"))
.Returns(Task.FromResult<IReadOnlyList<IContentEntity>>(contents)) .Returns(Task.FromResult<IReadOnlyList<IContentEntity>>(contents));
.Verifiable();
var result = await sut.QueryAsync(app, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -318,8 +308,6 @@ namespace Squidex.Domain.Apps.Read.Contents
}; };
AssertJson(expected, new { data = result.Data }); AssertJson(expected, new { data = result.Data });
contentRepository.VerifyAll();
} }
[Fact] [Fact]
@ -361,11 +349,10 @@ namespace Squidex.Domain.Apps.Read.Contents
}} }}
}}"; }}";
contentRepository.Setup(x => x.FindContentAsync(app, schemaId, contentId)) A.CallTo(() => contentRepository.FindContentAsync(appEntity, schemaId, contentId))
.Returns(Task.FromResult(contentEntity)) .Returns(Task.FromResult(contentEntity));
.Verifiable();
var result = await sut.QueryAsync(app, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -419,8 +406,6 @@ namespace Squidex.Domain.Apps.Read.Contents
}; };
AssertJson(expected, new { data = result.Data }); AssertJson(expected, new { data = result.Data });
contentRepository.VerifyAll();
} }
[Fact] [Fact]
@ -448,15 +433,13 @@ namespace Squidex.Domain.Apps.Read.Contents
var refContents = new List<IContentEntity> { contentRefEntity }; var refContents = new List<IContentEntity> { contentRefEntity };
contentRepository.Setup(x => x.FindContentAsync(app, schemaId, contentId)) A.CallTo(() => contentRepository.FindContentAsync(appEntity, schemaId, contentId))
.Returns(Task.FromResult(contentEntity)) .Returns(Task.FromResult(contentEntity));
.Verifiable();
contentRepository.Setup(x => x.QueryAsync(app, schemaId, false, new HashSet<Guid> {contentRefId }, null)) A.CallTo(() => contentRepository.QueryAsync(appEntity, schemaId, false, A<HashSet<Guid>>.That.Matches(x => x.Contains(contentRefId)), null))
.Returns(Task.FromResult<IReadOnlyList<IContentEntity>>(refContents)) .Returns(Task.FromResult<IReadOnlyList<IContentEntity>>(refContents));
.Verifiable();
var result = await sut.QueryAsync(app, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -483,8 +466,6 @@ namespace Squidex.Domain.Apps.Read.Contents
}; };
AssertJson(expected, new { data = result.Data }); AssertJson(expected, new { data = result.Data });
contentRepository.VerifyAll();
} }
[Fact] [Fact]
@ -512,15 +493,13 @@ namespace Squidex.Domain.Apps.Read.Contents
var refAssets = new List<IAssetEntity> { assetRefEntity }; var refAssets = new List<IAssetEntity> { assetRefEntity };
contentRepository.Setup(x => x.FindContentAsync(app, schemaId, contentId)) A.CallTo(() => contentRepository.FindContentAsync(appEntity, schemaId, contentId))
.Returns(Task.FromResult(contentEntity)) .Returns(Task.FromResult(contentEntity));
.Verifiable();
assetRepository.Setup(x => x.QueryAsync(app.Id, null, new HashSet<Guid> { assetRefId }, null, int.MaxValue, 0)) A.CallTo(() => assetRepository.QueryAsync(appEntity.Id, null, A<HashSet<Guid>>.That.Matches(x => x.Contains(assetRefId)), null, int.MaxValue, 0))
.Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(refAssets)) .Returns(Task.FromResult<IReadOnlyList<IAssetEntity>>(refAssets));
.Verifiable();
var result = await sut.QueryAsync(app, new GraphQLQuery { Query = query }); var result = await sut.QueryAsync(appEntity, new GraphQLQuery { Query = query });
var expected = new var expected = new
{ {
@ -547,8 +526,6 @@ namespace Squidex.Domain.Apps.Read.Contents
}; };
AssertJson(expected, new { data = result.Data }); AssertJson(expected, new { data = result.Data });
contentRepository.VerifyAll();
} }
private static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId) private static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId)

61
tests/Squidex.Domain.Apps.Read.Tests/Contents/ODataQueryTests.cs

@ -8,12 +8,12 @@
using System; using System;
using System.Collections.Immutable; using System.Collections.Immutable;
using FakeItEasy;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.OData.Edm; using Microsoft.OData.Edm;
using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization;
using MongoDB.Driver; using MongoDB.Driver;
using Moq;
using Squidex.Domain.Apps.Core; using Squidex.Domain.Apps.Core;
using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Domain.Apps.Read.Apps; using Squidex.Domain.Apps.Read.Apps;
@ -62,17 +62,17 @@ namespace Squidex.Domain.Apps.Read.Contents
{ {
var builder = new EdmModelBuilder(new MemoryCache(Options.Create(new MemoryCacheOptions()))); var builder = new EdmModelBuilder(new MemoryCache(Options.Create(new MemoryCacheOptions())));
var schemaEntity = new Mock<ISchemaEntity>(); var schemaEntity = A.Dummy<ISchemaEntity>();
schemaEntity.Setup(x => x.Id).Returns(Guid.NewGuid()); A.CallTo(() => schemaEntity.Id).Returns(Guid.NewGuid());
schemaEntity.Setup(x => x.Version).Returns(3); A.CallTo(() => schemaEntity.Version).Returns(3);
schemaEntity.Setup(x => x.Schema).Returns(schema); A.CallTo(() => schemaEntity.Schema).Returns(schema);
var appEntity = new Mock<IAppEntity>(); var appEntity = A.Dummy<IAppEntity>();
appEntity.Setup(x => x.Id).Returns(Guid.NewGuid()); A.CallTo(() => appEntity.Id).Returns(Guid.NewGuid());
appEntity.Setup(x => x.Version).Returns(3); A.CallTo(() => appEntity.Version).Returns(3);
appEntity.Setup(x => x.PartitionResolver).Returns(languagesConfig.ToResolver()); A.CallTo(() => appEntity.PartitionResolver).Returns(languagesConfig.ToResolver());
edmModel = builder.BuildEdmModel(schemaEntity.Object, appEntity.Object); edmModel = builder.BuildEdmModel(schemaEntity, appEntity);
} }
[Fact] [Fact]
@ -294,55 +294,55 @@ namespace Squidex.Domain.Apps.Read.Contents
public void Should_set_top() public void Should_set_top()
{ {
var parser = edmModel.ParseQuery("$top=3"); var parser = edmModel.ParseQuery("$top=3");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = A.Fake<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Take(parser); cursor.Take(parser);
cursor.Verify(x => x.Limit(3)); A.CallTo(() => cursor.Limit(3)).MustHaveHappened();
} }
[Fact] [Fact]
public void Should_set_max_top_if_larger() public void Should_set_max_top_if_larger()
{ {
var parser = edmModel.ParseQuery("$top=300"); var parser = edmModel.ParseQuery("$top=300");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = A.Fake<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Take(parser); cursor.Take(parser);
cursor.Verify(x => x.Limit(200)); A.CallTo(() => cursor.Limit(200)).MustHaveHappened();
} }
[Fact] [Fact]
public void Should_set_default_top() public void Should_set_default_top()
{ {
var parser = edmModel.ParseQuery(""); var parser = edmModel.ParseQuery("");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = A.Fake<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Take(parser); cursor.Take(parser);
cursor.Verify(x => x.Limit(20)); A.CallTo(() => cursor.Limit(20)).MustHaveHappened();
} }
[Fact] [Fact]
public void Should_set_skip() public void Should_set_skip()
{ {
var parser = edmModel.ParseQuery("$skip=3"); var parser = edmModel.ParseQuery("$skip=3");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = A.Fake<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Skip(parser); cursor.Skip(parser);
cursor.Verify(x => x.Skip(3)); A.CallTo(() => cursor.Skip(3)).MustHaveHappened();
} }
[Fact] [Fact]
public void Should_not_set_skip() public void Should_not_set_skip()
{ {
var parser = edmModel.ParseQuery(""); var parser = edmModel.ParseQuery("");
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = A.Fake<IFindFluent<MongoContentEntity, MongoContentEntity>>();
cursor.Object.Take(parser); cursor.Take(parser);
cursor.Verify(x => x.Skip(It.IsAny<int>()), Times.Never); A.CallTo(() => cursor.Skip(A<int>.Ignored)).MustNotHaveHappened();
} }
private static string C(string value) private static string C(string value)
@ -353,16 +353,17 @@ namespace Squidex.Domain.Apps.Read.Contents
private string S(string value) private string S(string value)
{ {
var parser = edmModel.ParseQuery(value); var parser = edmModel.ParseQuery(value);
var cursor = new Mock<IFindFluent<MongoContentEntity, MongoContentEntity>>(); var cursor = A.Fake<IFindFluent<MongoContentEntity, MongoContentEntity>>();
var i = string.Empty; var i = string.Empty;
cursor.Setup(x => x.Sort(It.IsAny<SortDefinition<MongoContentEntity>>())).Callback(new Action<SortDefinition<MongoContentEntity>>(s => A.CallTo(() => cursor.Sort(A<SortDefinition<MongoContentEntity>>.Ignored))
.Invokes((SortDefinition<MongoContentEntity> sortDefinition) =>
{ {
i = s.Render(serializer, registry).ToString(); i = sortDefinition.Render(serializer, registry).ToString();
})); });
cursor.Object.Sort(parser, schema); cursor.Sort(parser, schema);
return i; return i;
} }

61
tests/Squidex.Domain.Apps.Read.Tests/Schemas/CachingSchemaProviderTests.cs

@ -8,9 +8,9 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using FakeItEasy;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Moq;
using Squidex.Domain.Apps.Events.Schemas; using Squidex.Domain.Apps.Events.Schemas;
using Squidex.Domain.Apps.Read.Schemas.Repositories; using Squidex.Domain.Apps.Read.Schemas.Repositories;
using Squidex.Domain.Apps.Read.Schemas.Services.Implementations; using Squidex.Domain.Apps.Read.Schemas.Services.Implementations;
@ -26,30 +26,24 @@ namespace Squidex.Domain.Apps.Read.Schemas
public class CachingSchemaProviderTests public class CachingSchemaProviderTests
{ {
private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions())); private readonly IMemoryCache cache = new MemoryCache(Options.Create(new MemoryCacheOptions()));
private readonly Mock<ISchemaRepository> repository = new Mock<ISchemaRepository>(); private readonly ISchemaRepository repository = A.Fake<ISchemaRepository>();
private readonly CachingSchemaProvider sut; private readonly CachingSchemaProvider sut;
private readonly ISchemaEntity schemaV1; private readonly ISchemaEntity schemaV1 = A.Dummy<ISchemaEntity>();
private readonly ISchemaEntity schemaV2; private readonly ISchemaEntity schemaV2 = A.Dummy<ISchemaEntity>();
private readonly NamedId<Guid> schemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema"); private readonly NamedId<Guid> schemaId = new NamedId<Guid>(Guid.NewGuid(), "my-schema");
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app"); private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
public CachingSchemaProviderTests() public CachingSchemaProviderTests()
{ {
var schemaV1Mock = new Mock<ISchemaEntity>(); A.CallTo(() => schemaV1.Id).Returns(schemaId.Id);
var schemaV2Mock = new Mock<ISchemaEntity>(); A.CallTo(() => schemaV1.Name).Returns(schemaId.Name);
A.CallTo(() => schemaV1.AppId).Returns(appId.Id);
schemaV1Mock.Setup(x => x.Id).Returns(schemaId.Id); A.CallTo(() => schemaV2.Id).Returns(schemaId.Id);
schemaV1Mock.Setup(x => x.Name).Returns(schemaId.Name); A.CallTo(() => schemaV2.Name).Returns(schemaId.Name);
schemaV1Mock.Setup(x => x.AppId).Returns(appId.Id); A.CallTo(() => schemaV2.AppId).Returns(appId.Id);
schemaV2Mock.Setup(x => x.Id).Returns(schemaId.Id); sut = new CachingSchemaProvider(cache, repository);
schemaV2Mock.Setup(x => x.Name).Returns(schemaId.Name);
schemaV2Mock.Setup(x => x.AppId).Returns(appId.Id);
schemaV1 = schemaV1Mock.Object;
schemaV2 = schemaV2Mock.Object;
sut = new CachingSchemaProvider(cache, repository.Object);
} }
[Fact] [Fact]
@ -73,33 +67,32 @@ namespace Squidex.Domain.Apps.Read.Schemas
[Fact] [Fact]
public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before() public async Task Should_also_retrieve_schema_by_name_if_retrieved_by_id_before()
{ {
repository.Setup(x => x.FindSchemaAsync(schemaId.Id)).Returns(Task.FromResult(schemaV1)); A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).Returns(Task.FromResult(schemaV1));
await ProvideSchemaById(schemaV1); await ProvideSchemaById(schemaV1);
await ProvideSchemaByName(schemaV1); await ProvideSchemaByName(schemaV1);
repository.Verify(x => x.FindSchemaAsync(schemaId.Id), Times.Once()); A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).MustHaveHappened();
repository.Verify(x => x.FindSchemaAsync(appId.Id, schemaId.Name), Times.Never()); A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).MustNotHaveHappened();
} }
[Fact] [Fact]
public async Task Should_also_retrieve_schema_by_id_if_retrieved_by_name_before() public async Task Should_also_retrieve_schema_by_id_if_retrieved_by_name_before()
{ {
repository.Setup(x => x.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(Task.FromResult(schemaV1)); A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(Task.FromResult(schemaV1));
await ProvideSchemaByName(schemaV1); await ProvideSchemaByName(schemaV1);
await ProvideSchemaById(schemaV1); await ProvideSchemaById(schemaV1);
repository.Verify(x => x.FindSchemaAsync(appId.Id, schemaId.Name), Times.Once()); A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).MustNotHaveHappened();
repository.Verify(x => x.FindSchemaAsync(schemaId.Id), Times.Never()); A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).MustHaveHappened();
} }
[Fact] [Fact]
public async Task Should_clear_cache_for_id_after_update_event() public async Task Should_clear_cache_for_id_after_update_event()
{ {
var schemas = ProviderResults(schemaV1, schemaV2); A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).Returns(schemaV2);
A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).Returns(schemaV1).Once();
repository.Setup(x => x.FindSchemaAsync(schemaId.Id)).Returns(() => Task.FromResult(schemas()));
await ProvideSchemaById(schemaV1); await ProvideSchemaById(schemaV1);
@ -107,15 +100,14 @@ namespace Squidex.Domain.Apps.Read.Schemas
await ProvideSchemaById(schemaV2); await ProvideSchemaById(schemaV2);
repository.Verify(x => x.FindSchemaAsync(schemaId.Id), Times.Exactly(2)); A.CallTo(() => repository.FindSchemaAsync(schemaId.Id)).MustHaveHappened(Repeated.Exactly.Times(2));
} }
[Fact] [Fact]
public async Task Should_clear_cache_for_name_after_update_event() public async Task Should_clear_cache_for_name_after_update_event()
{ {
var schemas = ProviderResults(schemaV1, schemaV2); A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(schemaV2);
A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(schemaV1).Once();
repository.Setup(x => x.FindSchemaAsync(appId.Id, schemaId.Name)).Returns(() => Task.FromResult(schemas()));
await ProvideSchemaByName(schemaV1); await ProvideSchemaByName(schemaV1);
@ -123,7 +115,7 @@ namespace Squidex.Domain.Apps.Read.Schemas
await ProvideSchemaByName(schemaV2); await ProvideSchemaByName(schemaV2);
repository.Verify(x => x.FindSchemaAsync(appId.Id, schemaId.Name), Times.Exactly(2)); A.CallTo(() => repository.FindSchemaAsync(appId.Id, schemaId.Name)).MustHaveHappened(Repeated.Exactly.Times(2));
} }
private async Task ProvideSchemaById(ISchemaEntity schema) private async Task ProvideSchemaById(ISchemaEntity schema)
@ -135,12 +127,5 @@ namespace Squidex.Domain.Apps.Read.Schemas
{ {
Assert.Equal(schema, await sut.FindSchemaByNameAsync(appId.Id, schemaId.Name)); Assert.Equal(schema, await sut.FindSchemaByNameAsync(appId.Id, schemaId.Name));
} }
private static Func<T> ProviderResults<T>(params T[] items)
{
var index = 0;
return () => items[index++];
}
} }
} }

Loading…
Cancel
Save