diff --git a/src/Squidex.Domain.Apps.Entities/Contents/DefaultContentWorkflow.cs b/src/Squidex.Domain.Apps.Entities/Contents/DefaultContentWorkflow.cs new file mode 100644 index 000000000..a75dd30a2 --- /dev/null +++ b/src/Squidex.Domain.Apps.Entities/Contents/DefaultContentWorkflow.cs @@ -0,0 +1,75 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Squidex.Domain.Apps.Core.Contents; +using Squidex.Domain.Apps.Entities.Schemas; +using Squidex.Infrastructure.Tasks; + +namespace Squidex.Domain.Apps.Entities.Contents +{ + public sealed class DefaultContentWorkflow : IContentWorkflow + { + private static readonly Status2 Draft = new Status2("Draft"); + private static readonly Status2 Archived = new Status2("Archived"); + private static readonly Status2 Published = new Status2("Published"); + + private static readonly Dictionary Flow = new Dictionary + { + [Draft] = new[] { Published, Archived }, + [Archived] = new[] { Draft }, + [Published] = new[] { Draft, Archived } + }; + + public Task GetInitialStatusAsync(ISchemaEntity schema) + { + return Task.FromResult(Draft); + } + + public Task IsValidNextStatus(IContentEntity content, Status2 next) + { + return TaskHelper.True; + } + + public Task CanUpdateAsync(IContentEntity content) + { + return TaskHelper.True; + } + + public Task GetNextsAsync(IContentEntity content) + { + Status2 statusToCheck; + + switch (content.Status) + { + case Status.Draft: + statusToCheck = Draft; + break; + case Status.Archived: + statusToCheck = Archived; + break; + case Status.Published: + statusToCheck = Published; + break; + default: + { + statusToCheck = Draft; + break; + } + } + + return Task.FromResult(Flow.TryGetValue(statusToCheck, out var result) ? result : Array.Empty()); + } + + public Task GetAllAsync(ISchemaEntity schema) + { + return Task.FromResult(new[] { Draft, Archived, Published } ); + } + } +} diff --git a/src/Squidex/Config/Domain/EntitiesServices.cs b/src/Squidex/Config/Domain/EntitiesServices.cs index 1b378c173..d44e12150 100644 --- a/src/Squidex/Config/Domain/EntitiesServices.cs +++ b/src/Squidex/Config/Domain/EntitiesServices.cs @@ -101,6 +101,9 @@ namespace Squidex.Config.Domain services.AddSingletonAs() .As(); + services.AddSingletonAs() + .AsOptional(); + services.AddSingletonAs() .AsSelf(); diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj b/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj index 7c5aefb48..0b4ac139b 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj +++ b/tests/Squidex.Domain.Apps.Core.Tests/Squidex.Domain.Apps.Core.Tests.csproj @@ -9,6 +9,7 @@ + diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultContentWorkflowTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultContentWorkflowTests.cs new file mode 100644 index 000000000..f9f368f6f --- /dev/null +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/DefaultContentWorkflowTests.cs @@ -0,0 +1,101 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschränkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using System.Threading.Tasks; +using FakeItEasy; +using Squidex.Domain.Apps.Core.Contents; +using Xunit; + +namespace Squidex.Domain.Apps.Entities.Contents +{ + public class DefaultContentWorkflowTests + { + private static readonly DefaultContentWorkflow Sut = new DefaultContentWorkflow(); + + [Fact] + public async Task Should_draft_as_initial_status_async_tests() + { + var result = await Sut.GetInitialStatusAsync(null); + + Assert.IsType(result); + Assert.Equal("Draft", result.Name); + } + + [Fact] + public async Task Should_check_is_valid_next_status_tests() + { + var entity = CreateMockContentEntity(Status.Draft); + + var status = new Status2("Draft"); + + var result = await Sut.IsValidNextStatus(entity, status); + + Assert.IsType(result); + Assert.True(result); + } + + [Fact] + public async Task Should_update_async_tests() + { + var entity = CreateMockContentEntity(Status.Draft); + + var result = await Sut.CanUpdateAsync(entity); + + Assert.IsType(result); + Assert.True(result); + } + + [Fact] + public async Task Should_get_nexts_async_tests() + { + var draftContent = CreateMockContentEntity(Status.Draft); + var archivedContent = CreateMockContentEntity(Status.Archived); + var publishedContent = CreateMockContentEntity(Status.Published); + + var draftExpected = new[] { new Status2("Published"), new Status2("Archived") }; + var archivedExpected = new[] { new Status2("Draft") }; + var publishedExpected = new[] { new Status2("Draft"), new Status2("Archived") }; + + var draftResult = await Sut.GetNextsAsync(draftContent); + var archivedResult = await Sut.GetNextsAsync(archivedContent); + var publishedResult = await Sut.GetNextsAsync(publishedContent); + + Assert.IsType(draftResult); + Assert.IsType(archivedResult); + Assert.IsType(publishedResult); + + Assert.Equal(draftExpected, draftResult); + Assert.Equal(archivedExpected, archivedResult); + Assert.Equal(publishedExpected, publishedResult); + } + + [Fact] + public async Task Should_get_all_async_tests() + { + var expected = new[] { new Status2("Draft"), new Status2("Archived"), new Status2("Published") }; + + var result = await Sut.GetAllAsync(null); + + Assert.IsType(result); + Assert.Equal(expected, result); + } + + private IContentEntity CreateMockContentEntity(Status status) + { + var content = A.Fake(); + + A.CallTo(() => content.Id).Returns(default(Guid)); + A.CallTo(() => content.Data).Returns(null); + A.CallTo(() => content.DataDraft).Returns(null); + A.CallTo(() => content.SchemaId).Returns(null); + A.CallTo(() => content.Status).Returns(status); + + return content; + } + } +}