Browse Source

Cache fix.

pull/636/head
Sebastian 5 years ago
parent
commit
1b06ae6ddd
  1. 2
      backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs
  2. 12
      backend/src/Squidex.Domain.Apps.Entities/AppProvider.cs
  3. 24
      backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs
  4. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/DefaultWorkflowsValidator.cs
  5. 2
      backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs
  6. 2
      backend/src/Squidex.Domain.Apps.Entities/IAppProvider.cs
  7. 2
      backend/src/Squidex.Domain.Apps.Entities/Rules/DomainObject/Guards/RuleTriggerValidator.cs
  8. 19
      backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs
  9. 2
      backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj
  10. 2
      backend/src/Squidex.Web/Pipeline/SchemaResolver.cs
  11. 2
      backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs
  12. 2
      backend/src/Squidex/Squidex.csproj
  13. 138
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Indexes/AppsIndexTests.cs
  14. 4
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultWorkflowsValidatorTests.cs
  15. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs
  16. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ContentQueryServiceTests.cs
  17. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/Guards/GuardRuleTests.cs
  18. 6
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/Guards/Triggers/ContentChangedTriggerTests.cs
  19. 28
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Indexes/SchemasIndexTests.cs
  20. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj
  21. 6
      backend/tests/Squidex.Web.Tests/Pipeline/SchemaResolverTests.cs

2
backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/QueryByQuery.cs

@ -68,7 +68,7 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations
try
{
var schema = await appProvider.GetSchemaAsync(appId, schemaId, false);
var schema = await appProvider.GetSchemaAsync(appId, schemaId);
if (schema == null)
{

12
backend/src/Squidex.Domain.Apps.Entities/AppProvider.cs

@ -49,7 +49,7 @@ namespace Squidex.Domain.Apps.Entities
return (null, null);
}
var schema = await GetSchemaAsync(appId, id, false, canCache);
var schema = await GetSchemaAsync(appId, id, canCache);
if (schema == null)
{
@ -71,7 +71,7 @@ namespace Squidex.Domain.Apps.Entities
localCache.Add(AppCacheKey(app.Id), app);
}
return app?.IsArchived == true ? null : app;
return app;
}
public async Task<IAppEntity?> GetAppAsync(string appName, bool canCache = false)
@ -86,7 +86,7 @@ namespace Squidex.Domain.Apps.Entities
localCache.Add(AppCacheKey(app.Id), app);
}
return app?.IsArchived == true ? null : app;
return app;
}
public async Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, string name, bool canCache = false)
@ -101,10 +101,10 @@ namespace Squidex.Domain.Apps.Entities
localCache.Add(SchemaCacheKey(appId, schema.Id), schema);
}
return schema?.IsDeleted == true ? null : schema;
return schema;
}
public async Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, DomainId id, bool allowDeleted = false, bool canCache = false)
public async Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, DomainId id, bool canCache = false)
{
var schema = await localCache.GetOrCreateAsync(SchemaCacheKey(appId, id), () =>
{
@ -116,7 +116,7 @@ namespace Squidex.Domain.Apps.Entities
localCache.Add(SchemaCacheKey(appId, schema.Id), schema);
}
return schema?.IsDeleted == true && !allowDeleted ? null : schema;
return schema;
}
public async Task<List<IAppEntity>> GetUserAppsAsync(string userId, PermissionSet permissions)

24
backend/src/Squidex.Domain.Apps.Entities/Apps/Indexes/AppsIndex.cs

@ -149,7 +149,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
if (app != null)
{
await CacheItAsync(app, false);
await CacheItAsync(app);
}
return app;
@ -232,7 +232,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
if (app != null)
{
await CacheItAsync(app, true);
await InvalidateItAsync(app);
switch (context.Command)
{
@ -290,6 +290,11 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
{
await Index(contributorId).RemoveAsync(app.Id);
}
if (app.CreatedBy.IsClient || !app.Contributors.ContainsKey(app.CreatedBy.Identifier))
{
await Index(app.CreatedBy.Identifier).RemoveAsync(app.Id);
}
}
private IAppsByNameIndexGrain Index()
@ -306,7 +311,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
{
var app = (await grainFactory.GetGrain<IAppGrain>(id.ToString()).GetStateAsync()).Value;
if (app.Version <= EtagVersion.Empty)
if (app.Version <= EtagVersion.Empty || app.IsArchived)
{
return null;
}
@ -324,11 +329,18 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
return $"{typeof(AppsIndex)}_Apps_Name_{name}";
}
private Task CacheItAsync(IAppEntity app, bool publish)
private Task InvalidateItAsync(IAppEntity app)
{
return grainCache.RemoveAsync(
GetCacheKey(app.Id),
GetCacheKey(app.Name));
}
private Task CacheItAsync(IAppEntity app)
{
return Task.WhenAll(
grainCache.AddAsync(GetCacheKey(app.Id), app, CacheDuration, publish),
grainCache.AddAsync(GetCacheKey(app.Name), app, CacheDuration, publish));
grainCache.AddAsync(GetCacheKey(app.Id), app, CacheDuration),
grainCache.AddAsync(GetCacheKey(app.Name), app, CacheDuration));
}
}
}

2
backend/src/Squidex.Domain.Apps.Entities/Contents/DefaultWorkflowsValidator.cs

@ -42,7 +42,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
{
if (workflows.Values.Count(x => x.SchemaIds.Contains(schemaId)) > 1)
{
var schema = await appProvider.GetSchemaAsync(appId, schemaId, false);
var schema = await appProvider.GetSchemaAsync(appId, schemaId);
if (schema != null)
{

2
backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentQueryService.cs

@ -191,7 +191,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var schemaId = DomainId.Create(guid);
schema = await appProvider.GetSchemaAsync(context.App.Id, schemaId, false, canCache);
schema = await appProvider.GetSchemaAsync(context.App.Id, schemaId, canCache);
}
if (schema == null)

2
backend/src/Squidex.Domain.Apps.Entities/IAppProvider.cs

@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Entities
Task<List<IAppEntity>> GetUserAppsAsync(string userId, PermissionSet permissions);
Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, DomainId id, bool allowDeleted, bool canCache = false);
Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, DomainId id, bool canCache = false);
Task<ISchemaEntity?> GetSchemaAsync(DomainId appId, string name, bool canCache = false);

2
backend/src/Squidex.Domain.Apps.Entities/Rules/DomainObject/Guards/RuleTriggerValidator.cs

@ -32,7 +32,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
Guard.NotNull(action, nameof(action));
Guard.NotNull(appProvider, nameof(appProvider));
var visitor = new RuleTriggerValidator(x => appProvider.GetSchemaAsync(appId, x, false));
var visitor = new RuleTriggerValidator(x => appProvider.GetSchemaAsync(appId, x));
return action.Accept(visitor);
}

19
backend/src/Squidex.Domain.Apps.Entities/Schemas/Indexes/SchemasIndex.cs

@ -99,7 +99,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
if (schema != null)
{
await CacheItAsync(schema, false);
await CacheItAsync(schema);
}
return schema;
@ -164,7 +164,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
if (schema != null)
{
await CacheItAsync(schema, true);
await InvalidateItAsync(schema);
if (context.Command is DeleteSchema)
{
@ -208,7 +208,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
{
var schema = (await grainFactory.GetGrain<ISchemaGrain>(id.ToString()).GetStateAsync()).Value;
if (schema.Version <= EtagVersion.Empty)
if (schema.Version <= EtagVersion.Empty || schema.IsDeleted)
{
return null;
}
@ -226,11 +226,18 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
return $"{typeof(SchemasIndex)}_Schemas_Id_{appId}_{id}";
}
private Task CacheItAsync(ISchemaEntity schema, bool publish)
private Task InvalidateItAsync(ISchemaEntity schema)
{
return grainCache.RemoveAsync(
GetCacheKey(schema.AppId.Id, schema.Id),
GetCacheKey(schema.AppId.Id, schema.SchemaDef.Name));
}
private Task CacheItAsync(ISchemaEntity schema)
{
return Task.WhenAll(
grainCache.AddAsync(GetCacheKey(schema.AppId.Id, schema.Id), schema, CacheDuration, publish),
grainCache.AddAsync(GetCacheKey(schema.AppId.Id, schema.SchemaDef.Name), schema, CacheDuration, publish));
grainCache.AddAsync(GetCacheKey(schema.AppId.Id, schema.Id), schema, CacheDuration),
grainCache.AddAsync(GetCacheKey(schema.AppId.Id, schema.SchemaDef.Name), schema, CacheDuration));
}
}
}

2
backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj

@ -25,7 +25,7 @@
<PackageReference Include="NJsonSchema" Version="10.3.2" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.Assets" Version="1.3.0" />
<PackageReference Include="Squidex.Caching" Version="1.6.0" />
<PackageReference Include="Squidex.Caching" Version="1.7.0" />
<PackageReference Include="Squidex.Hosting.Abstractions" Version="1.8.0" />
<PackageReference Include="Squidex.Log" Version="1.1.0" />
<PackageReference Include="Squidex.Text" Version="1.5.0" />

2
backend/src/Squidex.Web/Pipeline/SchemaResolver.cs

@ -62,7 +62,7 @@ namespace Squidex.Web.Pipeline
{
var schemaId = DomainId.Create(guid);
return appProvider.GetSchemaAsync(appId, schemaId, false, canCache);
return appProvider.GetSchemaAsync(appId, schemaId, canCache);
}
else
{

2
backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs

@ -84,7 +84,7 @@ namespace Squidex.Areas.Api.Controllers.Schemas
{
var schemaId = DomainId.Create(guid);
schema = await appProvider.GetSchemaAsync(AppId, schemaId, false);
schema = await appProvider.GetSchemaAsync(AppId, schemaId);
}
else
{

2
backend/src/Squidex/Squidex.csproj

@ -63,7 +63,7 @@
<PackageReference Include="Squidex.Assets.FTP" Version="1.3.0" />
<PackageReference Include="Squidex.Assets.Mongo" Version="1.3.0" />
<PackageReference Include="Squidex.Assets.S3" Version="1.3.0" />
<PackageReference Include="Squidex.Caching.Orleans" Version="1.5.0" />
<PackageReference Include="Squidex.Caching.Orleans" Version="1.7.0" />
<PackageReference Include="Squidex.ClientLibrary" Version="6.8.0" />
<PackageReference Include="Squidex.Hosting" Version="1.8.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />

138
backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/Indexes/AppsIndexTests.cs

@ -29,10 +29,12 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
{
private readonly IGrainFactory grainFactory = A.Fake<IGrainFactory>();
private readonly IAppsByNameIndexGrain indexByName = A.Fake<IAppsByNameIndexGrain>();
private readonly IAppsByUserIndexGrain indexByUser = A.Fake<IAppsByUserIndexGrain>();
private readonly IAppsByUserIndexGrain indexForUser = A.Fake<IAppsByUserIndexGrain>();
private readonly IAppsByUserIndexGrain indexForClient = A.Fake<IAppsByUserIndexGrain>();
private readonly ICommandBus commandBus = A.Fake<ICommandBus>();
private readonly NamedId<DomainId> appId = NamedId.Of(DomainId.NewGuid(), "my-app");
private readonly string userId = "user-1";
private readonly string userId = "user1";
private readonly string clientId = "client1";
private readonly AppsIndex sut;
public AppsIndexTests()
@ -41,7 +43,10 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
.Returns(indexByName);
A.CallTo(() => grainFactory.GetGrain<IAppsByUserIndexGrain>(userId, null))
.Returns(indexByUser);
.Returns(indexForUser);
A.CallTo(() => grainFactory.GetGrain<IAppsByUserIndexGrain>(clientId, null))
.Returns(indexForClient);
var cache =
new ReplicatedCache(new MemoryCache(Options.Create(new MemoryCacheOptions())), new SimplePubSub(A.Fake<ILogger<SimplePubSub>>()),
@ -68,7 +73,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
{
var (expected, _) = SetupApp();
A.CallTo(() => indexByUser.GetIdsAsync())
A.CallTo(() => indexForUser.GetIdsAsync())
.Returns(new List<DomainId> { appId.Id });
var actual = await sut.GetAppsForUserAsync(userId, PermissionSet.Empty);
@ -84,7 +89,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.GetIdsAsync(A<string[]>.That.IsSameSequenceAs(new[] { appId.Name })))
.Returns(new List<DomainId> { appId.Id });
A.CallTo(() => indexByUser.GetIdsAsync())
A.CallTo(() => indexForUser.GetIdsAsync())
.Returns(new List<DomainId> { appId.Id });
var actual = await sut.GetAppsForUserAsync(userId, new PermissionSet($"squidex.apps.{appId.Name}"));
@ -188,26 +193,42 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
.MustNotHaveHappened();
}
[Fact]
public async Task Should_return_null_if_app_archived()
{
SetupApp(isArchived: true);
var actual1 = await sut.GetAppAsync(appId.Id, true);
var actual2 = await sut.GetAppAsync(appId.Id, true);
Assert.Null(actual1);
Assert.Null(actual2);
}
[Fact]
public async Task Should_return_null_if_app_not_created()
{
SetupApp(EtagVersion.NotFound);
var actual = await sut.GetAppAsync(appId.Id, false);
var actual1 = await sut.GetAppAsync(appId.Id, true);
var actual2 = await sut.GetAppAsync(appId.Id, true);
Assert.Null(actual);
Assert.Null(actual1);
Assert.Null(actual2);
}
[Fact]
public async Task Should_add_app_to_indexes_on_create()
public async Task Should_add_app_to_indexes_when_creating()
{
var token = RandomHash.Simple();
A.CallTo(() => indexByName.ReserveAsync(appId.Id, appId.Name))
.Returns(token);
var command = Create(appId.Name);
var context =
new CommandContext(Create(appId.Name), commandBus)
new CommandContext(command, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -218,20 +239,22 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.RemoveReservationAsync(A<string>._))
.MustNotHaveHappened();
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustHaveHappened();
}
[Fact]
public async Task Should_also_app_to_user_index_if_app_created_by_client()
public async Task Should_also_add_to_user_index_if_app_is_created_by_client()
{
var token = RandomHash.Simple();
A.CallTo(() => indexByName.ReserveAsync(appId.Id, appId.Name))
.Returns(token);
var command = CreateFromClient(appId.Name);
var context =
new CommandContext(CreateFromClient(appId.Name), commandBus)
new CommandContext(command, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -242,8 +265,11 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.RemoveReservationAsync(A<string>._))
.MustNotHaveHappened();
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForClient.AddAsync(appId.Id))
.MustHaveHappened();
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustNotHaveHappened();
}
[Fact]
@ -254,8 +280,10 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.ReserveAsync(appId.Id, appId.Name))
.Returns(token);
var command = CreateFromClient(appId.Name);
var context =
new CommandContext(CreateFromClient(appId.Name), commandBus);
new CommandContext(command, commandBus);
await sut.HandleAsync(context);
@ -265,18 +293,20 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.RemoveReservationAsync(token))
.MustHaveHappened();
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_not_add_to_indexes_on_create_if_name_taken()
public async Task Should_not_add_to_indexes_when_name_is_taken()
{
A.CallTo(() => indexByName.ReserveAsync(appId.Id, appId.Name))
.Returns(Task.FromResult<string?>(null));
var command = Create(appId.Name);
var context =
new CommandContext(Create(appId.Name), commandBus)
new CommandContext(command, commandBus)
.Complete();
await Assert.ThrowsAsync<ValidationException>(() => sut.HandleAsync(context));
@ -287,15 +317,17 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.RemoveReservationAsync(A<string>._))
.MustNotHaveHappened();
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_not_add_to_indexes_on_create_if_name_invalid()
public async Task Should_not_add_to_indexes_when_name_is_invalid()
{
var command = Create("INVALID");
var context =
new CommandContext(Create("INVALID"), commandBus)
new CommandContext(command, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -306,12 +338,12 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.RemoveReservationAsync(A<string>._))
.MustNotHaveHappened();
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_add_app_to_index_on_contributor_assignment()
public async Task Should_add_app_to_index_when_contributor_assigned()
{
SetupApp();
@ -323,7 +355,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
await sut.HandleAsync(context);
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustHaveHappened();
}
@ -362,7 +394,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
}
[Fact]
public async Task Should_remove_from_user_index_on_remove_of_contributor()
public async Task Should_remove_from_user_index_when_contributor_removed()
{
SetupApp();
@ -374,12 +406,12 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
await sut.HandleAsync(context);
A.CallTo(() => indexByUser.RemoveAsync(appId.Id))
A.CallTo(() => indexForUser.RemoveAsync(appId.Id))
.MustHaveHappened();
}
[Fact]
public async Task Should_remove_app_from_indexes_on_archive()
public async Task Should_remove_app_from_indexes_when_app_gets_archived()
{
SetupApp();
@ -394,7 +426,30 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
A.CallTo(() => indexByName.RemoveAsync(appId.Id))
.MustHaveHappened();
A.CallTo(() => indexByUser.RemoveAsync(appId.Id))
A.CallTo(() => indexForUser.RemoveAsync(appId.Id))
.MustHaveHappenedOnceExactly();
}
[Fact]
public async Task Should_also_remove_app_from_client_index_when_created_by_client()
{
SetupApp(fromClient: true);
var command = new ArchiveApp { AppId = appId };
var context =
new CommandContext(command, commandBus)
.Complete();
await sut.HandleAsync(context);
A.CallTo(() => indexByName.RemoveAsync(appId.Id))
.MustHaveHappened();
A.CallTo(() => indexForUser.RemoveAsync(appId.Id))
.MustHaveHappened();
A.CallTo(() => indexForClient.RemoveAsync(appId.Id))
.MustHaveHappened();
}
@ -405,7 +460,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
await sut.RebuildByContributorsAsync(userId, apps);
A.CallTo(() => indexByUser.RebuildAsync(apps))
A.CallTo(() => indexForUser.RebuildAsync(apps))
.MustHaveHappened();
}
@ -416,7 +471,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
await sut.RebuildByContributorsAsync(appId.Id, users);
A.CallTo(() => indexByUser.AddAsync(appId.Id))
A.CallTo(() => indexForUser.AddAsync(appId.Id))
.MustHaveHappened();
}
@ -458,7 +513,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
.MustHaveHappened();
}
private (IAppEntity, IAppGrain) SetupApp(long version = 0)
private (IAppEntity, IAppGrain) SetupApp(long version = 0, bool fromClient = false, bool isArchived = false)
{
var appEntity = A.Fake<IAppEntity>();
@ -468,9 +523,22 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
.Returns(appId.Name);
A.CallTo(() => appEntity.Version)
.Returns(version);
A.CallTo(() => appEntity.IsArchived)
.Returns(isArchived);
A.CallTo(() => appEntity.Contributors)
.Returns(AppContributors.Empty.Assign(userId, Role.Owner));
if (fromClient)
{
A.CallTo(() => appEntity.CreatedBy)
.Returns(ClientActor());
}
else
{
A.CallTo(() => appEntity.CreatedBy)
.Returns(UserActor());
}
var appGrain = A.Fake<IAppGrain>();
A.CallTo(() => appGrain.GetStateAsync())
@ -484,22 +552,22 @@ namespace Squidex.Domain.Apps.Entities.Apps.Indexes
private CreateApp Create(string name)
{
return new CreateApp { AppId = appId.Id, Name = name, Actor = ActorSubject() };
return new CreateApp { AppId = appId.Id, Name = name, Actor = UserActor() };
}
private CreateApp CreateFromClient(string name)
{
return new CreateApp { AppId = appId.Id, Name = name, Actor = ActorClient() };
return new CreateApp { AppId = appId.Id, Name = name, Actor = ClientActor() };
}
private RefToken ActorSubject()
private RefToken UserActor()
{
return new RefToken(RefTokenType.Subject, userId);
}
private RefToken ActorClient()
private RefToken ClientActor()
{
return new RefToken(RefTokenType.Client, userId);
return new RefToken(RefTokenType.Client, clientId);
}
}
}

4
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultWorkflowsValidatorTests.cs

@ -30,10 +30,10 @@ namespace Squidex.Domain.Apps.Entities.Contents
{
var schema = Mocks.Schema(appId, schemaId, new Schema(schemaId.Name));
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false))
.Returns(Task.FromResult<ISchemaEntity?>(null));
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false))
.Returns(schema);
sut = new DefaultWorkflowsValidator(appProvider);

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/MongoDb/ContentsQueryFixture.cs

@ -140,7 +140,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.MongoDb
{
var appProvider = A.Fake<IAppProvider>();
A.CallTo(() => appProvider.GetSchemaAsync(A<DomainId>._, A<DomainId>._, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(A<DomainId>._, A<DomainId>._, false))
.ReturnsLazily(x => Task.FromResult<ISchemaEntity?>(CreateSchema(x.GetArgument<DomainId>(0)!, x.GetArgument<DomainId>(1)!)));
return appProvider;

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/ContentQueryServiceTests.cs

@ -73,7 +73,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
var ctx = CreateContext(isFrontend: false, allowSchema: true);
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, true))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, true))
.Returns(schema);
var result = await sut.GetSchemaOrThrowAsync(ctx, input);

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/Guards/GuardRuleTests.cs

@ -34,7 +34,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
public GuardRuleTests()
{
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false))
.Returns(Mocks.Schema(appId, schemaId));
}

6
backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/Guards/Triggers/ContentChangedTriggerTests.cs

@ -42,14 +42,14 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards.Triggers
new ValidationError("Schema ID is required.", "Schemas")
});
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false))
.MustNotHaveHappened();
}
[Fact]
public async Task Should_add_error_if_schemas_ids_are_not_valid()
{
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false))
.Returns(Task.FromResult<ISchemaEntity?>(null));
var trigger = new ContentChangedTriggerV2
@ -92,7 +92,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards.Triggers
[Fact]
public async Task Should_not_add_error_if_schemas_ids_are_valid()
{
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false))
.Returns(Mocks.Schema(appId, schemaId));
var trigger = new ContentChangedTriggerV2

28
backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Indexes/SchemasIndexTests.cs

@ -154,7 +154,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
}
[Fact]
public async Task Should_return_schema_if_deleted()
public async Task Should_return_empty_schemas_if_schema_deleted()
{
var (schema, _) = SetupSchema(0, true);
@ -163,19 +163,21 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
var actual = await sut.GetSchemasAsync(appId.Id);
Assert.Same(actual[0], schema);
Assert.Empty(actual);
}
[Fact]
public async Task Should_add_schema_to_index_on_create()
public async Task Should_add_schema_to_index_when_creating()
{
var token = RandomHash.Simple();
A.CallTo(() => index.ReserveAsync(schemaId.Id, schemaId.Name))
.Returns(token);
var command = Create(schemaId.Name);
var context =
new CommandContext(Create(schemaId.Name), commandBus)
new CommandContext(command, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -195,8 +197,10 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
A.CallTo(() => index.ReserveAsync(schemaId.Id, schemaId.Name))
.Returns(token);
var command = Create(schemaId.Name);
var context =
new CommandContext(Create(schemaId.Name), commandBus);
new CommandContext(command, commandBus);
await sut.HandleAsync(context);
@ -208,13 +212,15 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
}
[Fact]
public async Task Should_not_add_to_index_on_create_if_name_taken()
public async Task Should_not_add_to_indexes_when_name_is_taken()
{
A.CallTo(() => index.ReserveAsync(schemaId.Id, schemaId.Name))
.Returns(Task.FromResult<string?>(null));
var command = Create(schemaId.Name);
var context =
new CommandContext(Create(schemaId.Name), commandBus)
new CommandContext(command, commandBus)
.Complete();
await Assert.ThrowsAsync<ValidationException>(() => sut.HandleAsync(context));
@ -227,10 +233,12 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
}
[Fact]
public async Task Should_not_add_to_index_on_create_if_name_invalid()
public async Task Should_not_add_to_indexes_when_name_is_invalid()
{
var command = Create("INVALID");
var context =
new CommandContext(Create("INVALID"), commandBus)
new CommandContext(command, commandBus)
.Complete();
await sut.HandleAsync(context);
@ -277,7 +285,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Indexes
}
[Fact]
public async Task Should_remove_schema_from_index_on_delete_when_existed_before()
public async Task Should_remove_schema_from_index_when_deleted_and_exists()
{
var (schema, _) = SetupSchema();

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj

@ -27,7 +27,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="Microsoft.Orleans.TestingHost" Version="3.4.0" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" PrivateAssets="all" />
<PackageReference Include="Squidex.Caching.Orleans" Version="1.5.0" />
<PackageReference Include="Squidex.Caching.Orleans" Version="1.7.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="all" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
<PackageReference Include="xunit" Version="2.4.1" />

6
backend/tests/Squidex.Web.Tests/Pipeline/SchemaResolverTests.cs

@ -66,7 +66,7 @@ namespace Squidex.Web.Pipeline
{
actionContext.RouteData.Values["name"] = schemaId.Id.ToString();
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, false, true))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<DomainId>._, true))
.Returns(Task.FromResult<ISchemaEntity?>(null));
await sut.OnActionExecutionAsync(actionExecutingContext, next);
@ -82,7 +82,7 @@ namespace Squidex.Web.Pipeline
var schema = CreateSchema();
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, true))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, true))
.Returns(schema);
await sut.OnActionExecutionAsync(actionExecutingContext, next);
@ -100,7 +100,7 @@ namespace Squidex.Web.Pipeline
var schema = CreateSchema();
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false, false))
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false))
.Returns(schema);
await sut.OnActionExecutionAsync(actionExecutingContext, next);

Loading…
Cancel
Save