public async Task <IEnrichedContentEntity> EnrichAsync(IContentEntity content, Context context) { Guard.NotNull(content, nameof(content)); var enriched = await EnrichAsync(Enumerable.Repeat(content, 1), context); return(enriched[0]); }
public async Task <IEnrichedContentEntity> EnrichAsync(IContentEntity content, bool cloneData, Context context) { Guard.NotNull(content); var enriched = await EnrichInternalAsync(Enumerable.Repeat(content, 1), cloneData, context); return(enriched[0]); }
private static async Task ValidateCanUpdate(IContentEntity content, IContentWorkflow contentWorkflow, ClaimsPrincipal user) { var status = content.NewStatus ?? content.Status; if (!await contentWorkflow.CanUpdateAsync(content, status, user)) { throw new DomainException(T.Get("contents.workflowErrorUpdate", new { status })); } }
public static void CanCreateDraft(CreateContentDraft command, IContentEntity content) { Guard.NotNull(command, nameof(command)); if (content.Status != Status.Published) { throw new DomainException(T.Get("contents.draftNotCreateForUnpublished")); } }
public async Task Should_not_invoke_query_service_if_nothing_to_enrich() { var source = new IContentEntity[0]; await sut.EnrichAsync(source, requestContext); A.CallTo(() => assetQuery.QueryAsync(A <Context> .Ignored, A <Q> .Ignored)) .MustNotHaveHappened(); }
public static void CanDeleteDraft(DeleteContentDraft command, IContentEntity content) { Guard.NotNull(command, nameof(command)); if (content.NewStatus == null) { throw new DomainException(T.Get("contents.draftToDeleteNotFound")); } }
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"); } } }); }
public static async Task CanPatch(IContentEntity content, IContentWorkflow contentWorkflow, PatchContent command) { Guard.NotNull(command, nameof(command)); Validate.It(() => "Cannot patch content.", e => { ValidateData(command, e); }); await ValidateCanUpdate(content, contentWorkflow); }
public async Task <bool> CanUpdateAsync(IContentEntity content) { var workflow = await GetWorkflowAsync(content.AppId.Id, content.SchemaId.Id); if (workflow.TryGetStep(content.Status, out var step)) { return(!step.NoUpdate); } return(true); }
public async Task <StatusInfo> GetInfoAsync(IContentEntity content, Status status) { var workflow = await GetWorkflowAsync(content.AppId.Id, content.SchemaId.Id); if (workflow.TryGetStep(status, out var step)) { return(new StatusInfo(status, GetColor(step))); } return(new StatusInfo(status, StatusColors.Draft)); }
private static JObject GetInputContent(IContentEntity content) { var camelContent = new NamedContentData(); foreach (var kvp in content.Data) { camelContent[kvp.Key.ToCamelCase()] = kvp.Value; } return(JObject.FromObject(camelContent)); }
public async Task <bool> CanUpdateAsync(IContentEntity content, Status status, ClaimsPrincipal user) { var workflow = await GetWorkflowAsync(content.AppId.Id, content.SchemaId.Id); if (workflow.TryGetStep(status, out var step)) { return(step.NoUpdate == null || !IsTrue(step.NoUpdate, content.Data, user)); } return(true); }
public static void CheckPermission(IContentEntity content, ContentCommand command, string permission) { if (content.CreatedBy?.Equals(command.Actor) == true) { return; } if (!command.User.Allows(permission, content.AppId.Name, content.SchemaId.Name)) { throw new DomainForbiddenException(T.Get("common.errorNoPermission")); } }
/// <summary> /// Promotes a revision to the current live content. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void PromoteVersion(object sender, EventArgs e) { var link = (LinkButton)sender; Content c = new Content(); IContentEntity entity = c.GetContentEntity(_contentID); entity.CurrentRevision = new Guid(link.ID); c.SaveEntity(entity); Response.Redirect(Request.RawUrl); }
public static void CheckPermission(IContentEntity content, ContentCommand command, params string[] permissions) { if (Equals(content.CreatedBy, command.Actor) || command.User == null) { return; } if (permissions.All(x => !command.User.Allows(x, content.AppId.Name, content.SchemaId.Name))) { throw new DomainForbiddenException(T.Get("common.errorNoPermission")); } }
public static async Task CanPatch(PatchContent command, IContentEntity content, IContentWorkflow contentWorkflow) { Guard.NotNull(command, nameof(command)); Validate.It(e => { ValidateData(command, e); }); await ValidateCanUpdate(content, contentWorkflow, command.User); }
public async Task Should_not_invoke_query_service_if_no_assets_found() { var source = new IContentEntity[] { CreateContent(new Guid[0], new Guid[0]) }; var enriched = await sut.EnrichAsync(source, requestContext); Assert.NotNull(enriched.ElementAt(0).ReferenceData); A.CallTo(() => assetQuery.QueryAsync(A <Context> .Ignored, A <Q> .Ignored)) .MustNotHaveHappened(); }
public async Task Should_not_enrich_references_if_disabled() { var source = new IContentEntity[] { CreateContent(new Guid[] { Guid.NewGuid() }, new Guid[0]) }; var enriched = await sut.EnrichAsync(source, new Context(Mocks.ApiUser(), Mocks.App(appId))); Assert.Null(enriched.ElementAt(0).ReferenceData); A.CallTo(() => assetQuery.QueryAsync(A <Context> .Ignored, A <Q> .Ignored)) .MustNotHaveHappened(); }
public static async Task CanPatch(IContentEntity content, IContentWorkflow contentWorkflow, PatchContent command, bool isProposal) { Guard.NotNull(command); Validate.It(() => "Cannot patch content.", e => { ValidateData(command, e); }); if (!isProposal) { await ValidateCanUpdate(content, contentWorkflow, command.User); } }
public async Task Should_enrich_with_reference_data() { var ref1_1 = CreateRefContent(Guid.NewGuid(), "ref1_1", 13); var ref1_2 = CreateRefContent(Guid.NewGuid(), "ref1_2", 17); var ref2_1 = CreateRefContent(Guid.NewGuid(), "ref2_1", 23); var ref2_2 = CreateRefContent(Guid.NewGuid(), "ref2_2", 29); var source = new IContentEntity[] { CreateContent(new Guid[] { ref1_1.Id }, new Guid[] { ref2_1.Id }), CreateContent(new Guid[] { ref1_2.Id }, new Guid[] { ref2_2.Id }) }; A.CallTo(() => contentQuery.QueryAsync(A <Context> .Ignored, A <IReadOnlyList <Guid> > .That.Matches(x => x.Count == 4))) .Returns(ResultList.CreateFrom(4, ref1_1, ref1_2, ref2_1, ref2_2)); var enriched = await sut.EnrichAsync(source, requestContext); Assert.Equal( new NamedContentData() .AddField("ref1", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "ref1_1, 13") .Add("de", "ref1_1, 13"))) .AddField("ref2", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "ref2_1, 23") .Add("de", "ref2_1, 23"))), enriched.ElementAt(0).ReferenceData); Assert.Equal( new NamedContentData() .AddField("ref1", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "ref1_2, 17") .Add("de", "ref1_2, 17"))) .AddField("ref2", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "ref2_2, 29") .Add("de", "ref2_2, 29"))), enriched.ElementAt(1).ReferenceData); }
public static async Task CanUpdate(IContentEntity content, IContentWorkflow contentWorkflow, UpdateContent command, bool isProposal) { Guard.NotNull(command, nameof(command)); Validate.It(() => "Cannot update content.", e => { ValidateData(command, e); }); if (!isProposal) { await ValidateCanUpdate(content, contentWorkflow); } }
public async Task Should_not_enrich_when_content_has_more_items() { var ref1_1 = CreateRefContent(Guid.NewGuid(), 1, "ref1_1", 13, refSchemaId1); var ref1_2 = CreateRefContent(Guid.NewGuid(), 2, "ref1_2", 17, refSchemaId1); var ref2_1 = CreateRefContent(Guid.NewGuid(), 3, "ref2_1", 23, refSchemaId2); var ref2_2 = CreateRefContent(Guid.NewGuid(), 4, "ref2_2", 29, refSchemaId2); var source = new IContentEntity[] { CreateContent(new[] { ref1_1.Id }, new[] { ref2_1.Id, ref2_2.Id }), CreateContent(new[] { ref1_2.Id }, new[] { ref2_1.Id, ref2_2.Id }) }; A.CallTo(() => contentQuery.QueryAsync(A <Context> .That.Matches(x => x.IsNoEnrichment()), A <IReadOnlyList <Guid> > .That.Matches(x => x.Count == 4))) .Returns(ResultList.CreateFrom(4, ref1_1, ref1_2, ref2_1, ref2_2)); var enriched = await sut.EnrichAsync(source, requestContext); Assert.Equal( new NamedContentData() .AddField("ref1", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "ref1_1, 13") .Add("de", "ref1_1, 13"))) .AddField("ref2", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "2 Reference(s)") .Add("de", "2 Reference(s)"))), enriched.ElementAt(0).ReferenceData); Assert.Equal( new NamedContentData() .AddField("ref1", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "ref1_2, 17") .Add("de", "ref1_2, 17"))) .AddField("ref2", new ContentFieldData() .AddJsonValue("iv", JsonValue.Object() .Add("en", "2 Reference(s)") .Add("de", "2 Reference(s)"))), enriched.ElementAt(1).ReferenceData); }
public static ContentDto FromContent(IContentEntity content) { var response = SimpleMapper.Map(content, new ContentDto()); response.Data = content.Data; response.DataDraft = content.DataDraft; if (content.ScheduleJob != null) { response.ScheduleJob = SimpleMapper.Map(content.ScheduleJob, new ScheduleJobDto()); } return(response); }
private static async Task UpdateReferencing(CommandContext context, IContentEntity reference, ContentData data) { await context.CommandBus.PublishAsync(new UpdateContent { AppId = reference.AppId, SchemaId = reference.SchemaId, ContentId = reference.Id, DoNotScript = true, DoNotValidate = true, Data = data, // Also set the expected version, otherwise it will be overriden with the version from the request. ExpectedVersion = reference.Version }); }
/// <summary> /// Fills in basic page information. /// </summary> /// <param name="page">The IContentEntity object that represents the page.</param> private void FillPageContent(IContentEntity page) { txtTitle.Text = page.Title; txtAuthor.Text = page.Author; txtURL.Text = page.FriendlyUrl; txtDescription.Text = page.Description; txtKeywords.Text = page.Keywords; chkExcludeSearch.Checked = page.Visible; chkFollowLinks.Checked = page.FollowLinks; if (page.ParentID.HasValue) { siteTree.FindNode(page.ParentID.ToString()).Selected = true; } }
public static async Task CanUpdate(UpdateContent command, IContentEntity content, IContentWorkflow contentWorkflow) { Guard.NotNull(command, nameof(command)); CheckPermission(content, command, Permissions.AppContentsUpdate); Validate.It(e => { ValidateData(command, e); }); await ValidateCanUpdate(content, contentWorkflow, command.User); }
public async Task <StatusInfo[]> GetNextAsync(IContentEntity content, Status status, ClaimsPrincipal user) { var result = new List <StatusInfo>(); var workflow = await GetWorkflowAsync(content.AppId.Id, content.SchemaId.Id); foreach (var(to, step, transition) in workflow.GetTransitions(status)) { if (IsTrue(transition, content.Data, user)) { result.Add(new StatusInfo(to, GetColor(step))); } } return(result.ToArray()); }
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)); } })); }
/// <summary> /// Loads content and revisions for editing. /// </summary> private void LoadExistingContent() { if (_contentID.HasValue) { _contentEntity = _content.GetContentEntity(_contentID.Value); ValidateCurrentSite(); _contentRevisions = _content.LoadRevisions(_contentID.Value, _siteID); _currentRevision = ((List <IContentRevision>)_contentRevisions).Find(i => i.VersionID == _contentEntity.CurrentRevision); } else { // this is new content, so assign some IDs for use throughout the page _contentID = Guid.NewGuid(); } }
public async Task Should_not_invoke_steps() { var source = new IContentEntity[0]; var step1 = A.Fake <IContentEnricherStep>(); var step2 = A.Fake <IContentEnricherStep>(); var sut = new ContentEnricher(new[] { step1, step2 }, new Lazy <IContentQueryService>(() => contentQuery)); await sut.EnrichAsync(source, requestContext); A.CallTo(() => step1.EnrichAsync(requestContext, A <IEnumerable <ContentEntity> > .Ignored, A <ProvideSchema> .Ignored)) .MustNotHaveHappened(); A.CallTo(() => step2.EnrichAsync(requestContext, A <IEnumerable <ContentEntity> > .Ignored, A <ProvideSchema> .Ignored)) .MustNotHaveHappened(); }