Files
Umbraco-CMS/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.cs
Bjarke Berg 608f2e3c76 Scheduled publishing in Management API (#15680)
* Only use datetimeoffset in API

* Updated publish endpoint to take schedule information

* Fixed test builds

* OpenApi updates

* Update OpenApi schema

* Fixed issues with publishing.

* Added validation before publishing. Had to move a lot of classes to core.

* added missing files

* Added validation info to error

* Typo

* Clean up and adding missing result

* Updating to AvailableCultures instead of PublishedCultures

* Handle time needs to be in the future

* validate only cultures that needs to be published

* Fix typos

* Filter out cultures that we are not trying to publish from the validation errors

* Don't filter out only the available cultures, to accommodate non-created variants

* Only allow publish of existing cultures

* Fixed issues found in test

* fixed build

---------

Co-authored-by: Elitsa <elm@umbraco.dk>
2024-02-21 09:10:48 +01:00

136 lines
5.6 KiB
C#

using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentPublishing;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Tests.Common.Builders;
using Umbraco.Cms.Tests.Common.Builders.Extensions;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
public partial class ContentPublishingServiceTests : UmbracoIntegrationTestWithContent
{
private IContentPublishingService ContentPublishingService => GetRequiredService<IContentPublishingService>();
private static readonly ISet<string> _allCultures = new HashSet<string>(){ "*" };
private static CultureAndScheduleModel MakeModel(ISet<string> cultures) => new CultureAndScheduleModel()
{
CulturesToPublishImmediately = cultures,
Schedules = new ContentScheduleCollection()
};
private static CultureAndScheduleModel MakeModel(ContentScheduleCollection schedules) => new CultureAndScheduleModel()
{
CulturesToPublishImmediately = new HashSet<string>(),
Schedules = schedules
};
[SetUp]
public void SetupTest()
{
ContentNotificationHandler.PublishingContent = null;
ContentNotificationHandler.UnpublishingContent = null;
}
private async Task<Content> CreateInvalidContent(IContent? parent = null)
{
var template = TemplateBuilder.CreateTextPageTemplate();
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
// create a new content type and allow the default content type as child
var contentType = ContentTypeBuilder.CreateSimpleContentType("umbMandatory", "Mandatory Doc Type", mandatoryProperties: true, defaultTemplateId: template.Id);
contentType.AllowedAsRoot = true;
contentType.AllowedContentTypes = new[] { new ContentTypeSort(ContentType.Key, 0, ContentType.Alias) };
ContentTypeService.Save(contentType);
// allow the new content type as child to the default content type
ContentType.AllowedContentTypes = new[] { new ContentTypeSort(contentType.Key, 0, contentType.Alias) };
ContentTypeService.Save(ContentType);
var content = ContentBuilder.CreateSimpleContent(contentType, "Invalid Content", parent?.Id ?? Constants.System.Root);
content.SetValue("title", string.Empty);
content.SetValue("bodyText", string.Empty);
content.SetValue("author", string.Empty);
ContentService.Save(content);
return content;
}
private async Task<(ILanguage LangEn, ILanguage LangDa, IContentType contentType)> SetupVariantTest(bool englishIsMandatoryLanguage = false)
{
var langEn = (await LanguageService.GetAsync("en-US"))!;
if (englishIsMandatoryLanguage)
{
langEn.IsMandatory = true;
await LanguageService.UpdateAsync(langEn, Constants.Security.SuperUserKey);
}
var langDa = new LanguageBuilder()
.WithCultureInfo("da-DK")
.Build();
await LanguageService.CreateAsync(langDa, Constants.Security.SuperUserKey);
var template = TemplateBuilder.CreateTextPageTemplate();
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
var key = Guid.NewGuid();
var contentType = new ContentTypeBuilder()
.WithAlias("variantContent")
.WithName("Variant Content")
.WithKey(key)
.WithContentVariation(ContentVariation.Culture)
.AddAllowedContentType()
.WithKey(key)
.WithAlias("variantContent")
.Done()
.AddPropertyGroup()
.WithAlias("content")
.WithName("Content")
.WithSupportsPublishing(true)
.AddPropertyType()
.WithAlias("title")
.WithName("Title")
.WithVariations(ContentVariation.Culture)
.WithMandatory(true)
.Done()
.Done()
.Build();
contentType.AllowedAsRoot = true;
await ContentTypeService.SaveAsync(contentType, Constants.Security.SuperUserKey);
return (langEn, langDa, contentType);
}
protected override void CustomTestSetup(IUmbracoBuilder builder)
=> builder
.AddNotificationHandler<ContentPublishingNotification, ContentNotificationHandler>()
.AddNotificationHandler<ContentUnpublishingNotification, ContentNotificationHandler>();
private void VerifyIsPublished(Guid key) => Assert.IsTrue(ContentService.GetById(key)!.Published);
private void VerifyIsNotPublished(Guid key) => Assert.IsFalse(ContentService.GetById(key)!.Published);
private ILanguageService LanguageService => GetRequiredService<ILanguageService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private class ContentNotificationHandler : INotificationHandler<ContentPublishingNotification>, INotificationHandler<ContentUnpublishingNotification>
{
public static Action<ContentPublishingNotification>? PublishingContent { get; set; }
public static Action<ContentUnpublishingNotification>? UnpublishingContent { get; set; }
public void Handle(ContentPublishingNotification notification) => PublishingContent?.Invoke(notification);
public void Handle(ContentUnpublishingNotification notification) => UnpublishingContent?.Invoke(notification);
}
}