Adds test for PerformScheduledPublish, fixes issues with resetting dirty props, fixes other issues found
This commit is contained in:
@@ -57,7 +57,7 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
internal static IReadOnlyList<string> GetCulturesUnpublishing(this IContent content)
|
||||
{
|
||||
if (!content.ContentType.VariesByCulture() && !content.IsPropertyDirty("PublishCultureInfos"))
|
||||
if (!content.ContentType.VariesByCulture() && !content.IsPropertyDirty("PublishCultureInfos") && !content.Published)
|
||||
return Array.Empty<string>();
|
||||
|
||||
var culturesChanging = content.CultureInfos.Where(x => x.Value.IsDirty()).Select(x => x.Key);
|
||||
|
||||
@@ -147,11 +147,9 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="changeType"></param>
|
||||
/// <param name="date"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<ContentSchedule> GetPending(ContentScheduleChange changeType, DateTime date)
|
||||
public IReadOnlyList<ContentSchedule> GetPending(ContentScheduleChange changeType, DateTime date)
|
||||
{
|
||||
if (_schedule.TryGetValue(string.Empty, out var changes))
|
||||
return changes.Values.Where(x => x.Date <= date);
|
||||
return Enumerable.Empty<ContentSchedule>();
|
||||
return _schedule.Values.SelectMany(x => x.Values).Where(x => x.Date <= date).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1083,9 +1083,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
//load in the schedule
|
||||
if (schedule.TryGetValue(temp.Content.Id, out var s))
|
||||
temp.Content.ContentSchedule = s;
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
temp.Content.ResetDirtyProperties(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,6 +1097,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
|
||||
SetVariations(temp.Content, contentVariations, documentVariations);
|
||||
}
|
||||
|
||||
foreach(var c in content)
|
||||
c.ResetDirtyProperties(false); // reset dirty initial properties (U4-1946)
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Core.Publishing
|
||||
/// </returns>
|
||||
public int CheckPendingAndProcess()
|
||||
{
|
||||
var results = _contentService.PerformScheduledPublish();
|
||||
var results = _contentService.PerformScheduledPublish(DateTime.Now);
|
||||
return results.Count(x => x.Success);
|
||||
|
||||
}
|
||||
|
||||
@@ -423,7 +423,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Publishes and unpublishes scheduled documents.
|
||||
/// </summary>
|
||||
IEnumerable<PublishResult> PerformScheduledPublish();
|
||||
IEnumerable<PublishResult> PerformScheduledPublish(DateTime date);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -1174,7 +1174,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PublishResult> PerformScheduledPublish()
|
||||
public IEnumerable<PublishResult> PerformScheduledPublish(DateTime date)
|
||||
{
|
||||
var evtMsgs = EventMessagesFactory.Get();
|
||||
|
||||
@@ -1182,7 +1182,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
{
|
||||
scope.WriteLock(Constants.Locks.ContentTree);
|
||||
|
||||
var now = DateTime.Now;
|
||||
var now = date;
|
||||
|
||||
foreach (var d in GetContentForRelease(now))
|
||||
{
|
||||
@@ -1192,7 +1192,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
//find which cultures have pending schedules
|
||||
var pendingCultures = d.ContentSchedule.GetPending(ContentScheduleChange.Start, now)
|
||||
.Select(x => x.Culture)
|
||||
.Distinct();
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (var c in pendingCultures)
|
||||
{
|
||||
@@ -1202,10 +1203,13 @@ namespace Umbraco.Core.Services.Implement
|
||||
d.PublishCulture(c);
|
||||
}
|
||||
|
||||
result = SavePublishing(d, d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
|
||||
if (pendingCultures.Count > 0)
|
||||
{
|
||||
result = SavePublishing(d, d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1214,9 +1218,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
result = SaveAndPublish(d, userId: d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
yield return result;
|
||||
}
|
||||
|
||||
yield return result;
|
||||
}
|
||||
|
||||
foreach (var d in GetContentForExpiration(now))
|
||||
@@ -1227,7 +1230,8 @@ namespace Umbraco.Core.Services.Implement
|
||||
//find which cultures have pending schedules
|
||||
var pendingCultures = d.ContentSchedule.GetPending(ContentScheduleChange.End, now)
|
||||
.Select(x => x.Culture)
|
||||
.Distinct();
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
foreach (var c in pendingCultures)
|
||||
{
|
||||
@@ -1237,10 +1241,13 @@ namespace Umbraco.Core.Services.Implement
|
||||
d.UnpublishCulture(c);
|
||||
}
|
||||
|
||||
result = SavePublishing(d, d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
|
||||
if (pendingCultures.Count > 0)
|
||||
{
|
||||
result = SavePublishing(d, d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to publish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1249,9 +1256,10 @@ namespace Umbraco.Core.Services.Implement
|
||||
result = Unpublish(d, userId: d.WriterId);
|
||||
if (result.Success == false)
|
||||
Logger.Error<ContentService>(null, "Failed to unpublish document id={DocumentId}, reason={Reason}.", d.Id, result.Result);
|
||||
yield return result;
|
||||
}
|
||||
|
||||
yield return result;
|
||||
|
||||
}
|
||||
|
||||
scope.Complete();
|
||||
@@ -2292,14 +2300,14 @@ namespace Umbraco.Core.Services.Implement
|
||||
if (variesByCulture)
|
||||
{
|
||||
var publishedCultures = content.PublishedCultures.ToList();
|
||||
var cannotBePublished = publishedCultures.Count == 0; // no published cultures = cannot be published
|
||||
if (!cannotBePublished)
|
||||
{
|
||||
var mandatoryCultures = _languageRepository.GetMany().Where(x => x.IsMandatory).Select(x => x.IsoCode);
|
||||
cannotBePublished = mandatoryCultures.Any(x => !publishedCultures.Contains(x, StringComparer.OrdinalIgnoreCase)); // missing mandatory culture = cannot be published
|
||||
}
|
||||
|
||||
if (cannotBePublished)
|
||||
if (publishedCultures.Count == 0) // no published cultures = cannot be published
|
||||
return new PublishResult(PublishResultType.FailedPublishNothingToPublish, evtMsgs, content);
|
||||
|
||||
var mandatoryCultures = _languageRepository.GetMany().Where(x => x.IsMandatory).Select(x => x.IsoCode);
|
||||
var mandatoryMissing = mandatoryCultures.Any(x => !publishedCultures.Contains(x, StringComparer.OrdinalIgnoreCase)); // missing mandatory culture = cannot be published
|
||||
|
||||
if (mandatoryMissing)
|
||||
return new PublishResult(PublishResultType.FailedPublishMandatoryCultureMissing, evtMsgs, content);
|
||||
|
||||
//track which cultures are being published
|
||||
@@ -2312,7 +2320,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
if (((Content) content).PublishedState != PublishedState.Publishing && content.PublishedVersionId == 0)
|
||||
{
|
||||
Logger.Info<ContentService>("Document {ContentName} (id={ContentId}) cannot be published: {Reason}", content.Name, content.Id, "document does not have published values");
|
||||
return new PublishResult(PublishResultType.FailedPublishNoPublishedValues, evtMsgs, content);
|
||||
return new PublishResult(PublishResultType.FailedPublishNothingToPublish, evtMsgs, content);
|
||||
}
|
||||
|
||||
//loop over each culture publishing - or string.Empty for invariant
|
||||
|
||||
@@ -97,9 +97,9 @@
|
||||
FailedPublishContentInvalid = FailedPublish | 8,
|
||||
|
||||
/// <summary>
|
||||
/// Cannot republish a document that hasn't been published.
|
||||
/// Cannot publish a document that has no publishing flags or values
|
||||
/// </summary>
|
||||
FailedPublishNoPublishedValues = FailedPublish | 9, // in ContentService.StrategyCanPublish - fixme weird
|
||||
FailedPublishNothingToPublish = FailedPublish | 9, // in ContentService.StrategyCanPublish - fixme weird
|
||||
|
||||
/// <summary>
|
||||
/// Some mandatory cultures are missing.
|
||||
|
||||
@@ -250,6 +250,90 @@ namespace Umbraco.Tests.Services
|
||||
Assert.That(hierarchy.All(c => c.Path.StartsWith("-1,-20") == false), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Perform_Scheduled_Publishing()
|
||||
{
|
||||
var langUk = new Language("en-GB") { IsDefault = true };
|
||||
var langFr = new Language("fr-FR");
|
||||
|
||||
ServiceContext.LocalizationService.Save(langFr);
|
||||
ServiceContext.LocalizationService.Save(langUk);
|
||||
|
||||
var ctInvariant = MockedContentTypes.CreateBasicContentType("invariantPage");
|
||||
ServiceContext.ContentTypeService.Save(ctInvariant);
|
||||
|
||||
var ctVariant = MockedContentTypes.CreateBasicContentType("variantPage");
|
||||
ctVariant.Variations = ContentVariation.Culture;
|
||||
ServiceContext.ContentTypeService.Save(ctVariant);
|
||||
|
||||
var now = DateTime.Now;
|
||||
|
||||
//10x invariant content, half is scheduled to be published in 5 seconds, the other half is scheduled to be unpublished in 5 seconds
|
||||
var invariant = new List<IContent>();
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var c = MockedContent.CreateBasicContent(ctInvariant);
|
||||
c.Name = "name" + i;
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
c.ContentSchedule.Add(now.AddSeconds(5), null); //release in 5 seconds
|
||||
var r = ServiceContext.ContentService.Save(c);
|
||||
Assert.IsTrue(r.Success, r.Result.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
c.ContentSchedule.Add(null, now.AddSeconds(5)); //expire in 5 seconds
|
||||
var r = ServiceContext.ContentService.SaveAndPublish(c);
|
||||
Assert.IsTrue(r.Success, r.Result.ToString());
|
||||
}
|
||||
invariant.Add(c);
|
||||
}
|
||||
|
||||
//10x variant content, half is scheduled to be published in 5 seconds, the other half is scheduled to be unpublished in 5 seconds
|
||||
var variant = new List<IContent>();
|
||||
var alternatingCulture = langFr.IsoCode;
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var c = MockedContent.CreateBasicContent(ctVariant);
|
||||
c.SetCultureName("name-uk" + i, langUk.IsoCode);
|
||||
c.SetCultureName("name-fr" + i, langFr.IsoCode);
|
||||
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
c.ContentSchedule.Add(alternatingCulture, now.AddSeconds(5), null); //release in 5 seconds
|
||||
var r = ServiceContext.ContentService.Save(c);
|
||||
Assert.IsTrue(r.Success, r.Result.ToString());
|
||||
|
||||
alternatingCulture = alternatingCulture == langFr.IsoCode ? langUk.IsoCode : langFr.IsoCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
c.ContentSchedule.Add(alternatingCulture, null, now.AddSeconds(5)); //expire in 5 seconds
|
||||
var r = ServiceContext.ContentService.SaveAndPublish(c);
|
||||
Assert.IsTrue(r.Success, r.Result.ToString());
|
||||
}
|
||||
variant.Add(c);
|
||||
}
|
||||
|
||||
|
||||
var runSched = ServiceContext.ContentService.PerformScheduledPublish(
|
||||
now.AddMinutes(1)).ToList(); //lets go way later just to be safe, NOTE: This is NOT based on actual timer so it's safe
|
||||
|
||||
//this is 21 because the test data installed before this test runs has a scheduled item!
|
||||
Assert.AreEqual(21, runSched.Count);
|
||||
Assert.AreEqual(20, runSched.Count(x => x.Success),
|
||||
string.Join(Environment.NewLine, runSched.Select(x => $"{x.Entity.Name} - {x.Result}")));
|
||||
|
||||
Assert.AreEqual(5, runSched.Count(x => x.Result == PublishResultType.SuccessPublish),
|
||||
string.Join(Environment.NewLine, runSched.Select(x => $"{x.Entity.Name} - {x.Result}")));
|
||||
Assert.AreEqual(5, runSched.Count(x => x.Result == PublishResultType.SuccessUnpublish),
|
||||
string.Join(Environment.NewLine, runSched.Select(x => $"{x.Entity.Name} - {x.Result}")));
|
||||
Assert.AreEqual(5, runSched.Count(x => x.Result == PublishResultType.SuccessPublishCulture),
|
||||
string.Join(Environment.NewLine, runSched.Select(x => $"{x.Entity.Name} - {x.Result}")));
|
||||
Assert.AreEqual(5, runSched.Count(x => x.Result == PublishResultType.SuccessUnpublishCulture),
|
||||
string.Join(Environment.NewLine, runSched.Select(x => $"{x.Entity.Name} - {x.Result}")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Remove_Scheduled_Publishing_Date()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user