Adds test for PerformScheduledPublish, fixes issues with resetting dirty props, fixes other issues found

This commit is contained in:
Shannon
2018-11-07 21:32:12 +11:00
parent df40a3d588
commit adf52425d2
8 changed files with 125 additions and 35 deletions

View File

@@ -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);

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -423,7 +423,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Publishes and unpublishes scheduled documents.
/// </summary>
IEnumerable<PublishResult> PerformScheduledPublish();
IEnumerable<PublishResult> PerformScheduledPublish(DateTime date);
#endregion

View File

@@ -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

View File

@@ -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.

View File

@@ -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()
{