Esempio n. 1
0
        public async Task ChangeStatus_should_refresh_properties_and_unset_schedule_when_completed()
        {
            var dueTime = Instant.MaxValue;

            await ExecuteCreateAsync();
            await ExecuteChangeStatusAsync(Status.Archived, dueTime);

            var command = new ChangeContentStatus {
                Status = Status.Archived, StatusJobId = sut.Snapshot.ScheduleJob !.Id
            };

            A.CallTo(() => contentWorkflow.CanMoveToAsync(A <IContentEntity> ._, Status.Draft, Status.Archived, User))
            .Returns(true);

            var result = await PublishAsync(command);

            result.ShouldBeEquivalent(sut.Snapshot);

            Assert.Null(sut.Snapshot.ScheduleJob);

            LastEvents
            .ShouldHaveSameEvents(
                CreateContentEvent(new ContentStatusChanged {
                Status = Status.Archived
            })
                );

            A.CallTo(() => scriptEngine.TransformAsync(A <ScriptVars> ._, "<change-script>", ScriptOptions()))
            .MustHaveHappened();
        }
Esempio n. 2
0
        public async Task Should_throw_exception_when_workflow_transition_not_valid()
        {
            var context = CreateContext(CreateContent(Status.Draft), normalSchema);

            A.CallTo(() => contentWorkflow.CanMoveToAsync(((ContentEntity)context.Content), Status.Draft, Status.Archived, context.User))
            .Returns(false);

            await Assert.ThrowsAsync <ValidationException>(() => context.CheckTransitionAsync(Status.Archived));
        }
Esempio n. 3
0
        public async Task Should_throw_exception_if_workflow_transition_not_valid()
        {
            var operation = Operation(CreateContent(Status.Draft), normalSchema);

            A.CallTo(() => contentWorkflow.CanMoveToAsync((ContentEntity)operation.Snapshot, Status.Draft, Status.Archived, operation.User))
            .Returns(false);

            await Assert.ThrowsAsync <ValidationException>(() => operation.CheckTransitionAsync(Status.Archived));
        }
Esempio n. 4
0
        public async Task CanChangeStatus_should_throw_exception_if_due_date_in_past()
        {
            var content = CreateContent(Status.Draft, false);
            var command = new ChangeContentStatus {
                Status = Status.Published, DueTime = dueTimeInPast, User = user
            };

            A.CallTo(() => contentWorkflow.CanMoveToAsync(content, command.Status, user))
            .Returns(true);

            await ValidationAssert.ThrowsAsync(() => GuardContent.CanChangeStatus(schema, content, contentWorkflow, command, false),
                                               new ValidationError("Due time must be in the future.", "DueTime"));
        }
Esempio n. 5
0
        public async Task CanChangeStatus_should_throw_exception_if_status_flow_not_valid()
        {
            var content = CreateContent(Status.Draft);

            var command = CreateCommand(new ChangeContentStatus {
                Status = Status.Published
            });

            A.CallTo(() => workflow.CanMoveToAsync(content, content.Status, command.Status, user))
            .Returns(false);

            await ValidationAssert.ThrowsAsync(() => GuardContent.CanChangeStatus(command, content, workflow, contentRepository, schema),
                                               new ValidationError("Cannot change status from Draft to Published.", "Status"));
        }
Esempio n. 6
0
        public async Task ChangeStatus_should_refresh_properties_and_revert_scheduling_when_invoked_by_scheduler()
        {
            await ExecuteCreateAsync();
            await ExecuteChangeStatusAsync(Status.Published, Instant.MaxValue);

            var command = new ChangeContentStatus {
                Status = Status.Published, JobId = sut.Snapshot.ScheduleJob.Id
            };

            A.CallTo(() => contentWorkflow.CanMoveToAsync(A <IContentEntity> .Ignored, Status.Published, User))
            .Returns(false);

            var result = await sut.ExecuteAsync(CreateContentCommand(command));

            result.ShouldBeEquivalent(sut.Snapshot);

            Assert.Null(sut.Snapshot.ScheduleJob);

            LastEvents
            .ShouldHaveSameEvents(
                CreateContentEvent(new ContentSchedulingCancelled())
                );

            A.CallTo(() => scriptEngine.Execute(A <ScriptContext> .Ignored, "<change-script>"))
            .MustNotHaveHappened();
        }
Esempio n. 7
0
        public static Task CanChangeStatus(ISchemaEntity schema, ContentState content, IContentWorkflow contentWorkflow, ChangeContentStatus command)
        {
            Guard.NotNull(command, nameof(command));

            if (schema.SchemaDef.IsSingleton)
            {
                if (content.NewVersion == null || command.Status != Status.Published)
                {
                    throw new DomainException("Singleton content cannot be updated.");
                }

                return(Task.CompletedTask);
            }

            return(Validate.It(() => "Cannot change status.", async e =>
            {
                if (!await contentWorkflow.CanMoveToAsync(content, content.EditingStatus, command.Status, command.User))
                {
                    e($"Cannot change status from {content.Status} to {command.Status}.", nameof(command.Status));
                }

                if (command.DueTime.HasValue && command.DueTime.Value < SystemClock.Instance.GetCurrentInstant())
                {
                    e("Due time must be in the future.", nameof(command.DueTime));
                }
            }));
        }
Esempio n. 8
0
        public static Task CanChangeStatus(ISchemaEntity schema, ContentState content, IContentWorkflow contentWorkflow, ChangeContentStatus command)
        {
            Guard.NotNull(command, nameof(command));

            if (schema.SchemaDef.IsSingleton)
            {
                if (content.NewVersion == null || command.Status != Status.Published)
                {
                    throw new DomainException(T.Get("contents.singletonNotChangeable"));
                }

                return(Task.CompletedTask);
            }

            return(Validate.It(async e =>
            {
                if (!await contentWorkflow.CanMoveToAsync(content, content.EditingStatus, command.Status, command.User))
                {
                    e(T.Get("contents.statusTransitionNotAllowed", new { oldStatus = content.EditingStatus, newStatus = command.Status }), nameof(command.Status));
                }

                if (command.DueTime.HasValue && command.DueTime.Value < SystemClock.Instance.GetCurrentInstant())
                {
                    e(T.Get("contents.statusSchedulingNotInFuture"), nameof(command.DueTime));
                }
            }));
        }
Esempio n. 9
0
        public static Task CanChangeStatus(ISchemaEntity schema, IContentEntity content, IContentWorkflow contentWorkflow, ChangeContentStatus command, bool isChangeConfirm)
        {
            Guard.NotNull(command, nameof(command));

            if (schema.SchemaDef.IsSingleton && command.Status != Status.Published)
            {
                throw new DomainException("Singleton content cannot be changed.");
            }

            return(Validate.It(() => "Cannot change status.", async e =>
            {
                if (isChangeConfirm)
                {
                    if (!content.IsPending)
                    {
                        e("Content has no changes to publish.", nameof(command.Status));
                    }
                }
                else if (!await contentWorkflow.CanMoveToAsync(content, command.Status, command.User))
                {
                    e($"Cannot change status from {content.Status} to {command.Status}.", nameof(command.Status));
                }

                if (command.DueTime.HasValue && command.DueTime.Value < SystemClock.Instance.GetCurrentInstant())
                {
                    e("Due time must be in the future.", nameof(command.DueTime));
                }
            }));
        }
Esempio n. 10
0
        public static async Task CanChangeStatus(ChangeContentStatus command,
                                                 IContentEntity content,
                                                 IContentWorkflow contentWorkflow,
                                                 IContentRepository contentRepository,
                                                 ISchemaEntity schema)
        {
            Guard.NotNull(command, nameof(command));

            CheckPermission(content, command, Permissions.AppContentsChangeStatus, Permissions.AppContentsUpsert);

            var newStatus = command.Status;

            if (schema.SchemaDef.IsSingleton)
            {
                if (content.NewStatus == null || newStatus != Status.Published)
                {
                    throw new DomainException(T.Get("contents.singletonNotChangeable"));
                }

                return;
            }

            var oldStatus = content.NewStatus ?? content.Status;

            if (oldStatus == Status.Published && command.CheckReferrers)
            {
                var hasReferrer = await contentRepository.HasReferrersAsync(content.AppId.Id, command.ContentId, SearchScope.Published);

                if (hasReferrer)
                {
                    throw new DomainException(T.Get("contents.referenced"));
                }
            }

            await Validate.It(async e =>
            {
                if (!command.DoNotValidateWorkflow)
                {
                    if (!await contentWorkflow.CanMoveToAsync(content, oldStatus, newStatus, command.User))
                    {
                        var values = new { oldStatus, newStatus };

                        e(T.Get("contents.statusTransitionNotAllowed", values), "Status");
                    }
                }
                else
                {
                    var info = await contentWorkflow.GetInfoAsync(content, newStatus);

                    if (info == null)
                    {
                        e(T.Get("contents.statusNotValid"), "Status");
                    }
                }
            });
        }
Esempio n. 11
0
        public static Task CanChangeStatus(ChangeContentStatus command,
                                           IContentEntity content,
                                           IContentWorkflow contentWorkflow,
                                           IContentRepository contentRepository,
                                           ISchemaEntity schema)
        {
            Guard.NotNull(command, nameof(command));

            CheckPermission(content, command, Permissions.AppContentsChangeStatus);

            if (schema.SchemaDef.IsSingleton)
            {
                if (content.NewStatus == null || command.Status != Status.Published)
                {
                    throw new DomainException(T.Get("contents.singletonNotChangeable"));
                }

                return(Task.CompletedTask);
            }

            return(Validate.It(async e =>
            {
                var status = content.NewStatus ?? content.Status;

                if (!await contentWorkflow.CanMoveToAsync(content, status, command.Status, command.User))
                {
                    var values = new { oldStatus = status, newStatus = command.Status };

                    e(T.Get("contents.statusTransitionNotAllowed", values), nameof(command.Status));
                }

                if (content.Status == Status.Published && command.CheckReferrers)
                {
                    var hasReferrer = await contentRepository.HasReferrersAsync(content.AppId.Id, command.ContentId, SearchScope.Published);

                    if (hasReferrer)
                    {
                        throw new DomainException(T.Get("contents.referenced"));
                    }
                }

                if (command.DueTime.HasValue && command.DueTime.Value < SystemClock.Instance.GetCurrentInstant())
                {
                    e(T.Get("contents.statusSchedulingNotInFuture"), nameof(command.DueTime));
                }
            }));
        }