mirror of https://github.com/Squidex/squidex.git
16 changed files with 267 additions and 23 deletions
@ -0,0 +1,57 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Domain.Apps.Core.Contents; |
|||
using Squidex.Infrastructure; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Contents |
|||
{ |
|||
public sealed class DefaultWorkflowsValidator : IWorkflowsValidator |
|||
{ |
|||
private readonly IAppProvider appProvider; |
|||
|
|||
public DefaultWorkflowsValidator(IAppProvider appProvider) |
|||
{ |
|||
Guard.NotNull(appProvider, nameof(appProvider)); |
|||
|
|||
this.appProvider = appProvider; |
|||
} |
|||
|
|||
public async Task<IReadOnlyList<string>> ValidateAsync(Guid appId, Workflows workflows) |
|||
{ |
|||
Guard.NotNull(workflows, nameof(workflows)); |
|||
|
|||
var errors = new List<string>(); |
|||
|
|||
if (workflows.Values.Count(x => x.SchemaIds.Count == 0) > 1) |
|||
{ |
|||
errors.Add("Multiple workflows cover all schemas."); |
|||
} |
|||
|
|||
var uniqueSchemaIds = workflows.Values.SelectMany(x => x.SchemaIds).Distinct().ToList(); |
|||
|
|||
foreach (var schemaId in uniqueSchemaIds) |
|||
{ |
|||
if (workflows.Values.Count(x => x.SchemaIds.Contains(schemaId)) > 1) |
|||
{ |
|||
var schema = await appProvider.GetSchemaAsync(appId, schemaId); |
|||
|
|||
if (schema != null) |
|||
{ |
|||
errors.Add($"The schema `{schema.SchemaDef.Name}` is covered by multiple workflows."); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return errors; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Squidex.Domain.Apps.Core.Contents; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Contents |
|||
{ |
|||
public interface IWorkflowsValidator |
|||
{ |
|||
Task<IReadOnlyList<string>> ValidateAsync(Guid appId, Workflows workflows); |
|||
} |
|||
} |
|||
@ -1,2 +1,8 @@ |
|||
@import '_vars'; |
|||
@import '_mixins'; |
|||
@import '_mixins'; |
|||
|
|||
.panel-alert { |
|||
ul { |
|||
margin: 0; |
|||
} |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
// ==========================================================================
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|||
// All rights reserved. Licensed under the MIT license.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Squidex.Domain.Apps.Core.Contents; |
|||
using Squidex.Domain.Apps.Core.Schemas; |
|||
using Squidex.Domain.Apps.Entities.Schemas; |
|||
using Squidex.Infrastructure; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Contents |
|||
{ |
|||
public class DefaultWorkflowsValidatorTests |
|||
{ |
|||
private readonly IAppProvider appProvider = A.Fake<IAppProvider>(); |
|||
private readonly NamedId<Guid> appId = NamedId.Of(Guid.NewGuid(), "my-app"); |
|||
private readonly NamedId<Guid> schemaId = NamedId.Of(Guid.NewGuid(), "my-schema"); |
|||
private readonly DefaultWorkflowsValidator sut; |
|||
|
|||
public DefaultWorkflowsValidatorTests() |
|||
{ |
|||
var schema = A.Fake<ISchemaEntity>(); |
|||
|
|||
A.CallTo(() => schema.Id).Returns(schemaId.Id); |
|||
A.CallTo(() => schema.SchemaDef).Returns(new Schema(schemaId.Name)); |
|||
|
|||
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, A<Guid>.Ignored, false)) |
|||
.Returns(Task.FromResult<ISchemaEntity>(null)); |
|||
|
|||
A.CallTo(() => appProvider.GetSchemaAsync(appId.Id, schemaId.Id, false)) |
|||
.Returns(schema); |
|||
|
|||
sut = new DefaultWorkflowsValidator(appProvider); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_generate_error_if_multiple_workflows_cover_all_schemas() |
|||
{ |
|||
var workflows = Workflows.Empty |
|||
.Add(Guid.NewGuid(), "workflow1") |
|||
.Add(Guid.NewGuid(), "workflow2"); |
|||
|
|||
var errors = await sut.ValidateAsync(appId.Id, workflows); |
|||
|
|||
Assert.Equal(errors, new string[] { "Multiple workflows cover all schemas." }); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_generate_error_if_multiple_workflows_cover_specific_schema() |
|||
{ |
|||
var id1 = Guid.NewGuid(); |
|||
var id2 = Guid.NewGuid(); |
|||
|
|||
var workflows = Workflows.Empty |
|||
.Add(id1, "workflow1") |
|||
.Add(id2, "workflow2") |
|||
.Update(id1, new Workflow(default, Workflow.EmptySteps, new List<Guid> { schemaId.Id })) |
|||
.Update(id2, new Workflow(default, Workflow.EmptySteps, new List<Guid> { schemaId.Id })); |
|||
|
|||
var errors = await sut.ValidateAsync(appId.Id, workflows); |
|||
|
|||
Assert.Equal(errors, new string[] { "The schema `my-schema` is covered by multiple workflows." }); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_generate_error_if_schema_deleted() |
|||
{ |
|||
var id1 = Guid.NewGuid(); |
|||
var id2 = Guid.NewGuid(); |
|||
|
|||
var oldSchemaId = Guid.NewGuid(); |
|||
|
|||
var workflows = Workflows.Empty |
|||
.Add(id1, "workflow1") |
|||
.Add(id2, "workflow2") |
|||
.Update(id1, new Workflow(default, Workflow.EmptySteps, new List<Guid> { oldSchemaId })) |
|||
.Update(id2, new Workflow(default, Workflow.EmptySteps, new List<Guid> { oldSchemaId })); |
|||
|
|||
var errors = await sut.ValidateAsync(appId.Id, workflows); |
|||
|
|||
Assert.Empty(errors); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_generate_errors_for_no_overlaps() |
|||
{ |
|||
var id1 = Guid.NewGuid(); |
|||
var id2 = Guid.NewGuid(); |
|||
|
|||
var workflows = Workflows.Empty |
|||
.Add(id1, "workflow1") |
|||
.Add(id2, "workflow2") |
|||
.Update(id1, new Workflow(default, Workflow.EmptySteps, new List<Guid> { schemaId.Id })); |
|||
|
|||
var errors = await sut.ValidateAsync(appId.Id, workflows); |
|||
|
|||
Assert.Empty(errors); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_not_generate_errors_for_empty_workflows() |
|||
{ |
|||
var errors = await sut.ValidateAsync(appId.Id, Workflows.Empty); |
|||
|
|||
Assert.Empty(errors); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue