Browse Source

Fix app context for commands that run after app creation.

pull/405/head
Sebastian 6 years ago
parent
commit
025661d4f1
  1. 41
      src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs
  2. 34
      src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs
  3. 11
      src/Squidex.Infrastructure/Commands/GrainCommandMiddleware.cs
  4. 2
      src/Squidex/Config/Domain/EntitiesServices.cs
  5. 58
      tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppCommandMiddlewareTests.cs

41
src/Squidex.Domain.Apps.Entities/Apps/AppCommandMiddleware.cs

@ -0,0 +1,41 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading.Tasks;
using Orleans;
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands;
namespace Squidex.Domain.Apps.Entities.Apps
{
public sealed class AppCommandMiddleware : GrainCommandMiddleware<AppCommand, IAppGrain>
{
private readonly IContextProvider contextProvider;
public AppCommandMiddleware(IGrainFactory grainFactory, IContextProvider contextProvider)
: base(grainFactory)
{
Guard.NotNull(contextProvider, nameof(contextProvider));
this.contextProvider = contextProvider;
}
public override async Task HandleAsync(CommandContext context, Func<Task> next)
{
await ExecuteCommandAsync(context);
if (context.PlainResult is IAppEntity app)
{
contextProvider.Context.App = app;
}
await next();
}
}
}

34
src/Squidex.Domain.Apps.Entities/Contents/Queries/ContentEnricher.cs

@ -61,7 +61,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
if (contents.Any())
{
var appVersion = context.App.Version.ToString();
var appVersion = context.App?.Version.ToString();
var cache = new Dictionary<(Guid, Status), StatusInfo>();
@ -77,27 +77,33 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
await ResolveCanUpdateAsync(content, result);
}
result.CacheDependencies.Add(appVersion);
if (appVersion != null)
{
result.CacheDependencies.Add(appVersion);
}
results.Add(result);
}
foreach (var group in results.GroupBy(x => x.SchemaId.Id))
if (context.App != null)
{
var schema = await ContentQuery.GetSchemaOrThrowAsync(context, group.Key.ToString());
foreach (var group in results.GroupBy(x => x.SchemaId.Id))
{
var schema = await ContentQuery.GetSchemaOrThrowAsync(context, group.Key.ToString());
var schemaIdentity = schema.Id.ToString();
var schemaVersion = schema.Version.ToString();
var schemaIdentity = schema.Id.ToString();
var schemaVersion = schema.Version.ToString();
foreach (var content in group)
{
content.CacheDependencies.Add(schemaIdentity);
content.CacheDependencies.Add(schemaVersion);
}
foreach (var content in group)
{
content.CacheDependencies.Add(schemaIdentity);
content.CacheDependencies.Add(schemaVersion);
}
if (ShouldEnrichWithReferences(context))
{
await ResolveReferencesAsync(schema, group, context);
if (ShouldEnrichWithReferences(context))
{
await ResolveReferencesAsync(schema, group, context);
}
}
}
}

11
src/Squidex.Infrastructure/Commands/GrainCommandMiddleware.cs

@ -23,6 +23,13 @@ namespace Squidex.Infrastructure.Commands
}
public virtual async Task HandleAsync(CommandContext context, Func<Task> next)
{
await ExecuteCommandAsync(context);
await next();
}
protected async Task ExecuteCommandAsync(CommandContext context)
{
if (context.Command is TCommand typedCommand)
{
@ -30,11 +37,9 @@ namespace Squidex.Infrastructure.Commands
context.Complete(result);
}
await next();
}
protected async Task<object> ExecuteCommandAsync(TCommand typedCommand)
private async Task<object> ExecuteCommandAsync(TCommand typedCommand)
{
var grain = grainFactory.GetGrain<TGrain>(typedCommand.AggregateId);

2
src/Squidex/Config/Domain/EntitiesServices.cs

@ -246,7 +246,7 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<AppsByNameIndexCommandMiddleware>()
.As<ICommandMiddleware>();
services.AddSingletonAs<GrainCommandMiddleware<AppCommand, IAppGrain>>()
services.AddSingletonAs<AppCommandMiddleware>()
.As<ICommandMiddleware>();
services.AddSingletonAs<GrainCommandMiddleware<CommentsCommand, ICommentGrain>>()

58
tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppCommandMiddlewareTests.cs

@ -0,0 +1,58 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Threading.Tasks;
using FakeItEasy;
using Orleans;
using Squidex.Domain.Apps.Entities.Apps.State;
using Squidex.Domain.Apps.Entities.TestHelpers;
using Squidex.Infrastructure.Commands;
using Xunit;
namespace Squidex.Domain.Apps.Entities.Apps
{
public class AppCommandMiddlewareTests : HandlerTestBase<AppState>
{
private readonly IContextProvider contextProvider = A.Fake<IContextProvider>();
private readonly Guid appId = Guid.NewGuid();
private readonly Context requestContext = new Context();
private readonly AppCommandMiddleware sut;
public sealed class MyCommand : SquidexCommand
{
}
protected override Guid Id
{
get { return appId; }
}
public AppCommandMiddlewareTests()
{
A.CallTo(() => contextProvider.Context)
.Returns(requestContext);
sut = new AppCommandMiddleware(A.Fake<IGrainFactory>(), contextProvider);
}
[Fact]
public async Task Should_replace_context_app_with_grain_result()
{
var result = A.Fake<IAppEntity>();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
context.Complete(result);
await sut.HandleAsync(context);
Assert.Same(result, requestContext.App);
}
}
}
Loading…
Cancel
Save