Browse Source

Fix and simplify tests.

pull/656/head
Sebastian 5 years ago
parent
commit
d521775c11
  1. 8
      backend/src/Squidex.Domain.Apps.Entities/Contents/DefaultContentWorkflow.cs
  2. 6
      backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/GuardContent.cs
  3. 10
      backend/src/Squidex.Domain.Apps.Entities/Contents/DynamicContentWorkflow.cs
  4. 8
      backend/src/Squidex.Domain.Apps.Entities/Contents/IContentWorkflow.cs
  5. 2
      backend/src/Squidex.Domain.Apps.Entities/SquidexCommand.cs
  6. 5
      backend/src/Squidex.Infrastructure/RefToken.cs
  7. 15
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DomainObject/AppCommandMiddlewareTests.cs
  8. 64
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/DomainObject/AssetCommandMiddlewareTests.cs
  9. 15
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/ContentCommandMiddlewareTests.cs
  10. 161
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs
  11. 22
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/EnrichWithWorkflowsTests.cs
  12. 26
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/Guards/GuardRuleTests.cs
  13. 15
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/RuleCommandMiddlewareTests.cs
  14. 81
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/Guards/GuardSchemaTests.cs
  15. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs

8
backend/src/Squidex.Domain.Apps.Entities/Contents/DefaultContentWorkflow.cs

@ -52,19 +52,19 @@ namespace Squidex.Domain.Apps.Entities.Contents
return Task.FromResult(Status.Draft);
}
public Task<bool> CanPublishOnCreateAsync(ISchemaEntity schema, ContentData data, ClaimsPrincipal user)
public Task<bool> CanPublishOnCreateAsync(ISchemaEntity schema, ContentData data, ClaimsPrincipal? user)
{
return Task.FromResult(true);
}
public Task<bool> CanMoveToAsync(IContentEntity content, Status status, Status next, ClaimsPrincipal user)
public Task<bool> CanMoveToAsync(IContentEntity content, Status status, Status next, ClaimsPrincipal? user)
{
var result = Flow.TryGetValue(status, out var step) && step.Transitions.Any(x => x.Status == next);
return Task.FromResult(result);
}
public Task<bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal user)
public Task<bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal? user)
{
var result = status != Status.Archived;
@ -78,7 +78,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
return Task.FromResult(result);
}
public Task<StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal user)
public Task<StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal? user)
{
var result = Flow.TryGetValue(status, out var step) ? step.Transitions : Array.Empty<StatusInfo>();

6
backend/src/Squidex.Domain.Apps.Entities/Contents/DomainObject/Guards/GuardContent.cs

@ -169,7 +169,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
if (command.CheckReferrers)
{
var hasReferrer = await contentRepository.HasReferrersAsync(content.AppId.Id, command.ContentId, SearchScope.All);
var hasReferrer = await contentRepository.HasReferrersAsync(content.AppId.Id, content.Id, SearchScope.All);
if (hasReferrer)
{
@ -186,7 +186,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
}
}
private static async Task ValidateCanUpdate(IContentEntity content, IContentWorkflow contentWorkflow, ClaimsPrincipal user)
private static async Task ValidateCanUpdate(IContentEntity content, IContentWorkflow contentWorkflow, ClaimsPrincipal? user)
{
var status = content.NewStatus ?? content.Status;
@ -198,7 +198,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
public static void CheckPermission(IContentEntity content, ContentCommand command, string permission)
{
if (content.CreatedBy?.Equals(command.Actor) == true)
if (Equals(content.CreatedBy, command.Actor) || command.User == null)
{
return;
}

10
backend/src/Squidex.Domain.Apps.Entities/Contents/DynamicContentWorkflow.cs

@ -38,21 +38,21 @@ namespace Squidex.Domain.Apps.Entities.Contents
return workflow.Steps.Select(x => new StatusInfo(x.Key, GetColor(x.Value))).ToArray();
}
public async Task<bool> CanMoveToAsync(IContentEntity content, Status status, Status next, ClaimsPrincipal user)
public async Task<bool> CanMoveToAsync(IContentEntity content, Status status, Status next, ClaimsPrincipal? user)
{
var workflow = await GetWorkflowAsync(content.AppId.Id, content.SchemaId.Id);
return workflow.TryGetTransition(status, next, out var transition) && IsTrue(transition, content.Data, user);
}
public async Task<bool> CanPublishOnCreateAsync(ISchemaEntity schema, ContentData data, ClaimsPrincipal user)
public async Task<bool> CanPublishOnCreateAsync(ISchemaEntity schema, ContentData data, ClaimsPrincipal? user)
{
var workflow = await GetWorkflowAsync(schema.AppId.Id, schema.Id);
return workflow.TryGetTransition(workflow.Initial, Status.Published, out var transition) && IsTrue(transition, data, user);
}
public async Task<bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal user)
public async Task<bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal? user)
{
var workflow = await GetWorkflowAsync(content.AppId.Id, content.SchemaId.Id);
@ -85,7 +85,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
return status;
}
public async Task<StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal user)
public async Task<StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal? user)
{
var result = new List<StatusInfo>();
@ -102,7 +102,7 @@ namespace Squidex.Domain.Apps.Entities.Contents
return result.ToArray();
}
private bool IsTrue(WorkflowCondition condition, ContentData data, ClaimsPrincipal user)
private bool IsTrue(WorkflowCondition condition, ContentData data, ClaimsPrincipal? user)
{
if (condition?.Roles != null && user != null)
{

8
backend/src/Squidex.Domain.Apps.Entities/Contents/IContentWorkflow.cs

@ -16,15 +16,15 @@ namespace Squidex.Domain.Apps.Entities.Contents
{
Task<Status> GetInitialStatusAsync(ISchemaEntity schema);
Task<bool> CanPublishOnCreateAsync(ISchemaEntity schema, ContentData data, ClaimsPrincipal user);
Task<bool> CanPublishOnCreateAsync(ISchemaEntity schema, ContentData data, ClaimsPrincipal? user);
Task<bool> CanMoveToAsync(IContentEntity content, Status status, Status next, ClaimsPrincipal user);
Task<bool> CanMoveToAsync(IContentEntity content, Status status, Status next, ClaimsPrincipal? user);
Task<bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal user);
Task<bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal? user);
Task<StatusInfo> GetInfoAsync(IContentEntity content, Status status);
Task<StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal user);
Task<StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal? user);
Task<StatusInfo[]> GetAllAsync(ISchemaEntity schema);
}

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

@ -15,7 +15,7 @@ namespace Squidex.Domain.Apps.Entities
{
public RefToken Actor { get; set; }
public ClaimsPrincipal User { get; set; }
public ClaimsPrincipal? User { get; set; }
public bool FromRule { get; set; }

5
backend/src/Squidex.Infrastructure/RefToken.cs

@ -54,11 +54,6 @@ namespace Squidex.Infrastructure
return $"{Type.ToString().ToLowerInvariant()}:{Identifier}";
}
public override int GetHashCode()
{
return (Type.GetHashCode() * 397) ^ Identifier.GetHashCode();
}
public static bool TryParse(string? value, [MaybeNullWhen(false)] out RefToken result)
{
value = value?.Trim(TrimChars);

15
backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/DomainObject/AppCommandMiddlewareTests.cs

@ -53,8 +53,9 @@ namespace Squidex.Domain.Apps.Entities.Apps.DomainObject
{
var result = A.Fake<IAppEntity>();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);
@ -68,8 +69,9 @@ namespace Squidex.Domain.Apps.Entities.Apps.DomainObject
{
var file = new NoopAssetFile();
var command = CreateCommand(new UploadAppImage { AppId = appId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new UploadAppImage { AppId = appId, File = file });
A.CallTo(() => assetThumbnailGenerator.GetImageInfoAsync(A<Stream>._))
.Returns(new ImageInfo(100, 100, false));
@ -87,8 +89,9 @@ namespace Squidex.Domain.Apps.Entities.Apps.DomainObject
var file = new NoopAssetFile();
var command = CreateCommand(new UploadAppImage { AppId = appId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new UploadAppImage { AppId = appId, File = file });
A.CallTo(() => assetThumbnailGenerator.GetImageInfoAsync(stream))
.Returns(Task.FromResult<ImageInfo?>(null));

64
backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/DomainObject/AssetCommandMiddlewareTests.cs

@ -87,8 +87,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Should_not_invoke_enricher_for_other_result()
{
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(12);
@ -103,8 +104,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
{
var result = new AssetEntity();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);
@ -121,8 +123,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
{
var result = A.Fake<IAssetEntity>();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);
@ -139,8 +142,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Create_should_create_domain_object()
{
var command = CreateCommand(new CreateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new CreateAsset { AssetId = assetId, File = file });
await sut.HandleAsync(context);
@ -155,8 +159,11 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Create_should_calculate_hash()
{
var command = CreateCommand(new CreateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var command = new CreateAsset { AssetId = assetId, File = file };
var context =
CreateCommandContext(
command);
await sut.HandleAsync(context);
@ -166,8 +173,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Create_should_return_duplicate_result_if_file_with_same_hash_found()
{
var command = CreateCommand(new CreateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new CreateAsset { AssetId = assetId, File = file });
SetupSameHashAsset(file.FileName, file.FileSize, out _);
@ -181,8 +189,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Create_should_not_return_duplicate_result_if_file_with_same_hash_found_but_duplicate_allowed()
{
var command = CreateCommand(new CreateAsset { AssetId = assetId, File = file, Duplicate = true });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new CreateAsset { AssetId = assetId, File = file, Duplicate = true });
SetupSameHashAsset(file.FileName, file.FileSize, out _);
@ -196,8 +205,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Create_should_pass_through_duplicate()
{
var command = CreateCommand(new CreateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new CreateAsset { AssetId = assetId, File = file });
SetupSameHashAsset(file.FileName, file.FileSize, out var duplicate);
@ -213,8 +223,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Update_should_update_domain_object()
{
var command = CreateCommand(new UpdateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new UpdateAsset { AssetId = assetId, File = file });
await ExecuteCreateAsync();
@ -227,8 +238,11 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Update_should_calculate_hash()
{
var command = CreateCommand(new UpdateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var command = new UpdateAsset { AssetId = assetId, File = file };
var context =
CreateCommandContext(
command);
await ExecuteCreateAsync();
@ -240,8 +254,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task Update_should_enrich_asset()
{
var command = CreateCommand(new UpdateAsset { AssetId = assetId, File = file });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new UpdateAsset { AssetId = assetId, File = file });
await ExecuteCreateAsync();
@ -255,8 +270,9 @@ namespace Squidex.Domain.Apps.Entities.Assets.DomainObject
[Fact]
public async Task AnnotateAsset_should_enrich_asset()
{
var command = CreateCommand(new AnnotateAsset { AssetId = assetId, FileName = "newName" });
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new AnnotateAsset { AssetId = assetId, FileName = "newName" });
await ExecuteCreateAsync();

15
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/ContentCommandMiddlewareTests.cs

@ -46,8 +46,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
[Fact]
public async Task Should_not_invoke_enricher_for_other_result()
{
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(12);
@ -62,8 +63,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var result = new ContentEntity();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);
@ -80,8 +82,9 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject
{
var result = A.Fake<IContentEntity>();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);

161
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DomainObject/Guards/GuardContentTests.cs

@ -25,88 +25,86 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
{
public class GuardContentTests : IClassFixture<TranslationsFixture>
{
private readonly IContentWorkflow contentWorkflow = A.Fake<IContentWorkflow>();
private readonly IContentWorkflow workflow = A.Fake<IContentWorkflow>();
private readonly IContentRepository contentRepository = A.Fake<IContentRepository>();
private readonly NamedId<DomainId> appId = NamedId.Of(DomainId.NewGuid(), "my-app");
private readonly NamedId<DomainId> schemaId = NamedId.Of(DomainId.NewGuid(), "my-schema");
private readonly ISchemaEntity schema;
private readonly ISchemaEntity singleton;
private readonly ClaimsPrincipal user = Mocks.FrontendUser();
private readonly Instant dueTimeInPast = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromHours(1));
private readonly RefToken actor = RefToken.User("123");
public GuardContentTests()
{
schema =
Mocks.Schema(appId, schemaId, new Schema(schemaId.Name));
singleton =
Mocks.Schema(appId, schemaId, new Schema(schemaId.Name, isSingleton: true));
}
[Fact]
public async Task CanCreate_should_throw_exception_if_data_is_null()
{
var schema = CreateSchema(false);
var command = new CreateContent();
await ValidationAssert.ThrowsAsync(() => GuardContent.CanCreate(command, contentWorkflow, schema),
await ValidationAssert.ThrowsAsync(() => GuardContent.CanCreate(command, workflow, schema),
new ValidationError("Data is required.", "Data"));
}
[Fact]
public async Task CanCreate_should_throw_exception_if_singleton()
{
var schema = CreateSchema(true);
var command = new CreateContent { Data = new ContentData() };
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanCreate(command, contentWorkflow, schema));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanCreate(command, workflow, singleton));
}
[Fact]
public async Task CanCreate_should_not_throw_exception_if_singleton_and_id_is_schema_id()
{
var schema = CreateSchema(true);
var command = new CreateContent { Data = new ContentData(), ContentId = schema.Id };
await GuardContent.CanCreate(command, contentWorkflow, schema);
await GuardContent.CanCreate(command, workflow, schema);
}
[Fact]
public async Task CanCreate_should_throw_exception_publish_not_allowed()
public async Task CanCreate_should_throw_exception_if_publishing_not_allowed()
{
var schema = CreateSchema(false);
SetupCanCreatePublish(schema, false);
SetupCanCreatePublish(false);
var command = new CreateContent { Data = new ContentData(), Publish = true };
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanCreate(command, contentWorkflow, schema));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanCreate(command, workflow, schema));
}
[Fact]
public async Task CanCreate_should_not_throw_exception_publishing_allowed()
public async Task CanCreate_should_not_throw_exception_if_publishing_allowed()
{
var schema = CreateSchema(false);
SetupCanCreatePublish(schema, true);
SetupCanCreatePublish(true);
var command = new CreateContent { Data = new ContentData(), Publish = true };
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanCreate(command, contentWorkflow, schema));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanCreate(command, workflow, schema));
}
[Fact]
public async Task CanCreate_should_not_throw_exception_if_data_is_not_null()
{
var schema = CreateSchema(false);
var command = new CreateContent { Data = new ContentData() };
await GuardContent.CanCreate(command, contentWorkflow, schema);
await GuardContent.CanCreate(command, workflow, schema);
}
[Fact]
public async Task CanUpdate_should_throw_exception_if_data_is_null()
{
SetupCanUpdate(true);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new UpdateContent());
await ValidationAssert.ThrowsAsync(() => GuardContent.CanUpdate(command, content, contentWorkflow),
await ValidationAssert.ThrowsAsync(() => GuardContent.CanUpdate(command, content, workflow),
new ValidationError("Data is required.", "Data"));
}
@ -116,9 +114,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
SetupCanUpdate(false);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new UpdateContent { Data = new ContentData() });
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanUpdate(command, content, contentWorkflow));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanUpdate(command, content, workflow));
}
[Fact]
@ -127,9 +126,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
SetupCanUpdate(true);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new UpdateContent { Data = new ContentData() });
await GuardContent.CanUpdate(command, content, contentWorkflow);
await GuardContent.CanUpdate(command, content, workflow);
}
[Fact]
@ -138,9 +138,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
SetupCanUpdate(true);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new PatchContent());
await ValidationAssert.ThrowsAsync(() => GuardContent.CanPatch(command, content, contentWorkflow),
await ValidationAssert.ThrowsAsync(() => GuardContent.CanPatch(command, content, workflow),
new ValidationError("Data is required.", "Data"));
}
@ -150,9 +151,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
SetupCanUpdate(false);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new PatchContent { Data = new ContentData() });
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanPatch(command, content, contentWorkflow));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanPatch(command, content, workflow));
}
[Fact]
@ -161,95 +163,91 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
SetupCanUpdate(true);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new PatchContent { Data = new ContentData() });
await GuardContent.CanPatch(command, content, contentWorkflow);
await GuardContent.CanPatch(command, content, workflow);
}
[Fact]
public async Task CanChangeStatus_should_throw_exception_if_singleton()
{
var schema = CreateSchema(true);
var content = CreateContent(Status.Published);
var command = CreateCommand(new ChangeContentStatus { Status = Status.Draft });
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanChangeStatus(command, content, contentWorkflow, contentRepository, schema));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanChangeStatus(command, content, workflow, contentRepository, singleton));
}
[Fact]
public async Task CanChangeStatus_should_throw_exception_if_due_date_in_past()
{
var schema = CreateSchema(false);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new ChangeContentStatus { Status = Status.Published, DueTime = dueTimeInPast });
A.CallTo(() => contentWorkflow.CanMoveToAsync(content, content.Status, command.Status, user))
A.CallTo(() => workflow.CanMoveToAsync(content, content.Status, command.Status, user))
.Returns(true);
await ValidationAssert.ThrowsAsync(() => GuardContent.CanChangeStatus(command, content, contentWorkflow, contentRepository, schema),
await ValidationAssert.ThrowsAsync(() => GuardContent.CanChangeStatus(command, content, workflow, contentRepository, schema),
new ValidationError("Due time must be in the future.", "DueTime"));
}
[Fact]
public async Task CanChangeStatus_should_throw_exception_if_status_flow_not_valid()
{
var schema = CreateSchema(false);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new ChangeContentStatus { Status = Status.Published });
A.CallTo(() => contentWorkflow.CanMoveToAsync(content, content.Status, command.Status, user))
A.CallTo(() => workflow.CanMoveToAsync(content, content.Status, command.Status, user))
.Returns(false);
await ValidationAssert.ThrowsAsync(() => GuardContent.CanChangeStatus(command, content, contentWorkflow, contentRepository, schema),
await ValidationAssert.ThrowsAsync(() => GuardContent.CanChangeStatus(command, content, workflow, contentRepository, schema),
new ValidationError("Cannot change status from Draft to Published.", "Status"));
}
[Fact]
public async Task CanChangeStatus_should_throw_exception_if_referenced()
{
var schema = CreateSchema(true);
var content = CreateContent(Status.Published);
var command = CreateCommand(new ChangeContentStatus { Status = Status.Draft });
A.CallTo(() => contentRepository.HasReferrersAsync(appId.Id, content.Id, SearchScope.Published))
.Returns(true);
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanChangeStatus(command, content, contentWorkflow, contentRepository, schema));
await Assert.ThrowsAsync<ValidationException>(() => GuardContent.CanChangeStatus(command, content, workflow, contentRepository, schema));
}
[Fact]
public async Task CanChangeStatus_should_not_throw_exception_if_singleton_is_published()
{
var schema = CreateSchema(true);
var content = CreateDraftContent(Status.Draft);
var command = CreateCommand(new ChangeContentStatus { Status = Status.Published });
await GuardContent.CanChangeStatus(command, content, contentWorkflow, contentRepository, schema);
await GuardContent.CanChangeStatus(command, content, workflow, contentRepository, singleton);
}
[Fact]
public async Task CanChangeStatus_should_not_throw_exception_if_status_flow_valid()
{
var schema = CreateSchema(false);
var content = CreateContent(Status.Draft);
var command = CreateCommand(new ChangeContentStatus { Status = Status.Published });
A.CallTo(() => contentWorkflow.CanMoveToAsync(content, content.Status, command.Status, user))
A.CallTo(() => workflow.CanMoveToAsync(content, content.Status, command.Status, user))
.Returns(true);
await GuardContent.CanChangeStatus(command, content, contentWorkflow, contentRepository, schema);
await GuardContent.CanChangeStatus(command, content, workflow, contentRepository, schema);
}
[Fact]
public void CreateDraft_should_throw_exception_if_not_published()
{
var content = CreateContent(Status.Draft);
var command = CreateCommand(new CreateContentDraft());
Assert.Throws<DomainException>(() => GuardContent.CanCreateDraft(command, content));
@ -259,6 +257,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
public void CreateDraft_should_not_throw_exception()
{
var content = CreateContent(Status.Published);
var command = CreateCommand(new CreateContentDraft());
GuardContent.CanCreateDraft(command, content);
@ -267,9 +266,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
[Fact]
public void CanDeleteDraft_should_throw_exception_if_no_draft_found()
{
CreateSchema(false);
var content = CreateContent(Status.Published);
var command = CreateCommand(new DeleteContentDraft());
Assert.Throws<DomainException>(() => GuardContent.CanDeleteDraft(command, content));
@ -279,6 +277,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
public void CanDeleteDraft_should_not_throw_exception()
{
var content = CreateDraftContent(Status.Draft);
var command = CreateCommand(new DeleteContentDraft());
GuardContent.CanDeleteDraft(command, content);
@ -287,21 +286,19 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
[Fact]
public async Task CanDelete_should_throw_exception_if_singleton()
{
var schema = CreateSchema(true);
var content = CreateContent(Status.Published);
var command = CreateCommand(new DeleteContent());
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanDelete(command, content, contentRepository, schema));
await Assert.ThrowsAsync<DomainException>(() => GuardContent.CanDelete(command, content, contentRepository, singleton));
}
[Fact]
public async Task CanDelete_should_throw_exception_if_referenced()
{
var schema = CreateSchema(true);
var content = CreateContent(Status.Published);
var command = CreateCommand(new DeleteContent());
var command = CreateCommand(new DeleteContent { CheckReferrers = true });
A.CallTo(() => contentRepository.HasReferrersAsync(appId.Id, content.Id, SearchScope.All))
.Returns(true);
@ -312,9 +309,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
[Fact]
public async Task CanDelete_should_not_throw_exception()
{
var schema = CreateSchema(false);
var content = CreateContent(Status.Published);
var command = CreateCommand(new DeleteContent());
await GuardContent.CanDelete(command, content, contentRepository, schema);
@ -324,21 +320,35 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
public void CheckPermission_should_not_throw_exception_if_content_is_from_current_user()
{
var content = CreateContent(status: Status.Published);
var command = CreateCommand(new DeleteContent());
GuardContent.CheckPermission(content, command, Permissions.AppContentsDelete);
}
[Fact]
public void CheckPermission_should_not_throw_exception_if_content_is_from_another_user_but_user_has_permission()
public void CheckPermission_should_not_throw_exception_if_user_is_null()
{
var permission = Permissions.ForApp(Permissions.AppContentsDelete, appId.Name, schemaId.Name).Id;
var content = CreateContent(Status.Published);
var otherUser = Mocks.FrontendUser(permission: permission);
var otherActor = RefToken.User("456");
var commandActor = RefToken.User("456");
var command = CreateCommand(new DeleteContent { Actor = commandActor });
command.User = null;
GuardContent.CheckPermission(content, command, Permissions.AppContentsDelete);
}
[Fact]
public void CheckPermission_should_not_throw_exception_if_content_is_from_another_user_but_user_has_permission()
{
var content = CreateContent(Status.Published);
var command = CreateCommand(new DeleteContent { Actor = otherActor, User = otherUser });
var permission = Permissions.ForApp(Permissions.AppContentsDelete, appId.Name, schemaId.Name).Id;
var commandUser = Mocks.FrontendUser(permission: permission);
var commandActor = RefToken.User("456");
var command = CreateCommand(new DeleteContent { Actor = commandActor, User = commandUser });
GuardContent.CheckPermission(content, command, Permissions.AppContentsDelete);
}
@ -346,31 +356,26 @@ namespace Squidex.Domain.Apps.Entities.Contents.DomainObject.Guards
[Fact]
public void CheckPermission_should_exception_if_content_is_from_another_user_and_user_has_no_permission()
{
var otherActor = RefToken.User("456");
var content = CreateContent(Status.Published);
var command = CreateCommand(new DeleteContent { Actor = otherActor });
var commandActor = RefToken.User("456");
var command = CreateCommand(new DeleteContent { Actor = commandActor });
Assert.Throws<DomainForbiddenException>(() => GuardContent.CheckPermission(content, command, Permissions.AppContentsDelete));
}
private void SetupCanUpdate(bool canUpdate)
{
A.CallTo(() => contentWorkflow.CanUpdateAsync(A<IContentEntity>._, A<Status>._, user))
A.CallTo(() => workflow.CanUpdateAsync(A<IContentEntity>._, A<Status>._, user))
.Returns(canUpdate);
}
private void SetupCanCreatePublish(ISchemaEntity schema, bool canCreate)
private void SetupCanCreatePublish(bool canCreate)
{
A.CallTo(() => contentWorkflow.CanPublishOnCreateAsync(schema, A<ContentData>._, user))
A.CallTo(() => workflow.CanPublishOnCreateAsync(schema, A<ContentData>._, user))
.Returns(canCreate);
}
private ISchemaEntity CreateSchema(bool isSingleton)
{
return Mocks.Schema(appId, schemaId, new Schema(schemaId.Name, isSingleton: isSingleton));
}
private T CreateCommand<T>(T command) where T : ContentCommand
{
if (command.Actor == null)

22
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Queries/EnrichWithWorkflowsTests.cs

@ -18,7 +18,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
public class EnrichWithWorkflowsTests
{
private readonly IContentWorkflow contentWorkflow = A.Fake<IContentWorkflow>();
private readonly IContentWorkflow workflow = A.Fake<IContentWorkflow>();
private readonly Context requestContext;
private readonly NamedId<DomainId> appId = NamedId.Of(DomainId.NewGuid(), "my-app");
private readonly NamedId<DomainId> schemaId = NamedId.Of(DomainId.NewGuid(), "my-schema");
@ -29,7 +29,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
requestContext = new Context(Mocks.FrontendUser(), Mocks.App(appId));
sut = new EnrichWithWorkflows(contentWorkflow);
sut = new EnrichWithWorkflows(workflow);
}
[Fact]
@ -42,7 +42,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
new StatusInfo(Status.Published, StatusColors.Published)
};
A.CallTo(() => contentWorkflow.GetNextAsync(content, content.Status, requestContext.User))
A.CallTo(() => workflow.GetNextAsync(content, content.Status, requestContext.User))
.Returns(nexts);
await sut.EnrichAsync(requestContext, new[] { content }, null!);
@ -59,7 +59,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
Assert.Equal(Status.Published, content.NextStatuses?.Single().Status);
A.CallTo(() => contentWorkflow.GetNextAsync(content, A<Status>._, requestContext.User))
A.CallTo(() => workflow.GetNextAsync(content, A<Status>._, requestContext.User))
.MustNotHaveHappened();
}
@ -72,7 +72,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
Assert.Empty(content.NextStatuses);
A.CallTo(() => contentWorkflow.GetNextAsync(content, A<Status>._, requestContext.User))
A.CallTo(() => workflow.GetNextAsync(content, A<Status>._, requestContext.User))
.MustNotHaveHappened();
}
@ -81,7 +81,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var content = new ContentEntity { SchemaId = schemaId };
A.CallTo(() => contentWorkflow.GetInfoAsync(content, content.Status))
A.CallTo(() => workflow.GetInfoAsync(content, content.Status))
.Returns(new StatusInfo(Status.Published, StatusColors.Published));
await sut.EnrichAsync(requestContext, new[] { content }, null!);
@ -94,7 +94,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var content = new ContentEntity { SchemaId = schemaId, NewStatus = Status.Archived };
A.CallTo(() => contentWorkflow.GetInfoAsync(content, content.NewStatus.Value))
A.CallTo(() => workflow.GetInfoAsync(content, content.NewStatus.Value))
.Returns(new StatusInfo(Status.Published, StatusColors.Archived));
await sut.EnrichAsync(requestContext, new[] { content }, null!);
@ -107,7 +107,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var content = new ContentEntity { SchemaId = schemaId, ScheduleJob = ScheduleJob.Build(Status.Archived, user, default) };
A.CallTo(() => contentWorkflow.GetInfoAsync(content, content.ScheduleJob.Status))
A.CallTo(() => workflow.GetInfoAsync(content, content.ScheduleJob.Status))
.Returns(new StatusInfo(Status.Published, StatusColors.Archived));
await sut.EnrichAsync(requestContext, new[] { content }, null!);
@ -120,7 +120,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var content = new ContentEntity { SchemaId = schemaId };
A.CallTo(() => contentWorkflow.GetInfoAsync(content, content.Status))
A.CallTo(() => workflow.GetInfoAsync(content, content.Status))
.Returns(Task.FromResult<StatusInfo>(null!));
var ctx = requestContext.Clone(b => b.WithResolveFlow(false));
@ -135,7 +135,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
{
var content = new ContentEntity { SchemaId = schemaId };
A.CallTo(() => contentWorkflow.CanUpdateAsync(content, content.Status, requestContext.User))
A.CallTo(() => workflow.CanUpdateAsync(content, content.Status, requestContext.User))
.Returns(true);
var ctx = requestContext.Clone(b => b.WithResolveFlow(false));
@ -156,7 +156,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Queries
Assert.False(content.CanUpdate);
A.CallTo(() => contentWorkflow.CanUpdateAsync(content, A<Status>._, requestContext.User))
A.CallTo(() => workflow.CanUpdateAsync(content, A<Status>._, requestContext.User))
.MustNotHaveHappened();
}
}

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

@ -41,15 +41,14 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
[Fact]
public async Task CanCreate_should_throw_exception_if_trigger_null()
{
var command = new CreateRule
var command = CreateCommand(new CreateRule
{
Trigger = null!,
Action = new TestAction
{
Url = validUrl
},
AppId = appId
};
Trigger = null!,
});
await ValidationAssert.ThrowsAsync(() => GuardRule.CanCreate(command, appProvider),
new ValidationError("Trigger is required.", "Trigger"));
@ -58,15 +57,14 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
[Fact]
public async Task CanCreate_should_throw_exception_if_action_null()
{
var command = new CreateRule
var command = CreateCommand(new CreateRule
{
Trigger = new ContentChangedTriggerV2
{
Schemas = ReadOnlyCollection.Empty<ContentChangedTriggerSchemaV2>()
},
Action = null!,
AppId = appId
};
});
await ValidationAssert.ThrowsAsync(() => GuardRule.CanCreate(command, appProvider),
new ValidationError("Action is required.", "Action"));
@ -75,7 +73,7 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
[Fact]
public async Task CanCreate_should_not_throw_exception_if_trigger_and_action_valid()
{
var command = new CreateRule
var command = CreateCommand(new CreateRule
{
Trigger = new ContentChangedTriggerV2
{
@ -84,9 +82,8 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
Action = new TestAction
{
Url = validUrl
},
AppId = appId
};
}
});
await GuardRule.CanCreate(command, appProvider);
}
@ -150,6 +147,13 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject.Guards
GuardRule.CanDelete(command);
}
private CreateRule CreateCommand(CreateRule command)
{
command.AppId = appId;
return command;
}
private IRuleEntity Rule()
{
var rule = A.Fake<IRuleEntity>();

15
backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/DomainObject/RuleCommandMiddlewareTests.cs

@ -45,8 +45,9 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject
[Fact]
public async Task Should_not_invoke_enricher_for_other_result()
{
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(12);
@ -61,8 +62,9 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject
{
var result = new RuleEntity();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);
@ -79,8 +81,9 @@ namespace Squidex.Domain.Apps.Entities.Rules.DomainObject
{
var result = A.Fake<IRuleEntity>();
var command = CreateCommand(new MyCommand());
var context = CreateContextForCommand(command);
var context =
CreateCommandContext(
new MyCommand());
context.Complete(result);

81
backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/Guards/GuardSchemaTests.cs

@ -36,7 +36,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_name_not_valid()
{
var command = new CreateSchema { AppId = appId, Name = "INVALID NAME" };
var command = CreateCommand(new CreateSchema { Name = "INVALID NAME" });
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Name is not a valid slug.", "Name"));
@ -45,9 +45,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_field_name_invalid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -58,7 +57,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Name is not a Javascript property name.",
@ -68,9 +67,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_field_properties_null()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -81,7 +79,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Properties is required.",
@ -91,9 +89,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_field_properties_not_valid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -104,7 +101,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Max length must be greater or equal to min length.",
@ -115,9 +112,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_field_partitioning_not_valid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -128,7 +124,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Partitioning is not a valid value.",
@ -138,9 +134,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_fields_contains_duplicate_name()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -157,7 +152,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Field 'field1' has been added twice.",
@ -167,9 +162,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_nested_field_name_invalid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -188,7 +182,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Name is not a Javascript property name.",
@ -198,9 +192,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_nested_field_properties_null()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -219,7 +212,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Properties is required.",
@ -229,9 +222,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_nested_field_is_array()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -250,7 +242,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Nested field cannot be array fields.",
@ -260,9 +252,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_nested_field_properties_not_valid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -281,7 +272,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Max length must be greater or equal to min length.",
@ -292,9 +283,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_nested_field_have_duplicate_names()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -318,7 +308,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
}
},
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Field 'nested1' has been added twice.",
@ -328,9 +318,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_ui_field_is_invalid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -345,7 +334,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
FieldsInLists = new FieldNames("field1"),
FieldsInReferences = new FieldNames("field1"),
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("UI field cannot be hidden.",
@ -361,7 +350,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_invalid_lists_field_are_used()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
Fields = new[]
{
@ -381,7 +370,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
FieldsInLists = new FieldNames(null!, null!, "field3", "field1", "field1", "field4"),
FieldsInReferences = null,
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Field is required.",
@ -399,7 +388,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_invalid_references_field_are_used()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
Fields = new[]
{
@ -419,7 +408,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
FieldsInLists = null,
FieldsInReferences = new FieldNames(null!, null!, "field3", "field1", "field1", "field4"),
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Field is required.",
@ -437,12 +426,12 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_throw_exception_if_references_contains_meta_field()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
FieldsInLists = null,
FieldsInReferences = new FieldNames("meta.id"),
Name = "new-schema"
};
});
ValidationAssert.Throws(() => GuardSchema.CanCreate(command),
new ValidationError("Field is not part of the schema.",
@ -452,9 +441,8 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
[Fact]
public void CanCreate_should_not_throw_exception_if_command_is_valid()
{
var command = new CreateSchema
var command = CreateCommand(new CreateSchema
{
AppId = appId,
Fields = new[]
{
new UpsertSchemaField
@ -494,7 +482,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
FieldsInLists = new FieldNames("field1", "meta.id"),
FieldsInReferences = new FieldNames("field1"),
Name = "new-schema"
};
});
GuardSchema.CanCreate(command);
}
@ -706,6 +694,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.DomainObject.Guards
GuardSchema.CanDelete(command);
}
private CreateSchema CreateCommand(CreateSchema command)
{
command.AppId = appId;
return command;
}
private static StringFieldProperties ValidProperties()
{
return new StringFieldProperties { MinLength = 10, MaxLength = 20 };

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/TestHelpers/HandlerTestBase.cs

@ -73,7 +73,7 @@ namespace Squidex.Domain.Apps.Entities.TestHelpers
.Invokes((IEnumerable<Envelope<IEvent>> events) => LastEvents = events);
}
protected CommandContext CreateContextForCommand<TCommand>(TCommand command) where TCommand : SquidexCommand
protected CommandContext CreateCommandContext<TCommand>(TCommand command) where TCommand : SquidexCommand
{
return new CommandContext(CreateCommand(command), A.Dummy<ICommandBus>());
}

Loading…
Cancel
Save