public void Published_Only() { var validator = new ContentValueSetValidator( true, true, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>()); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(new ValueSet( "555", IndexTypes.Content, new Dictionary <string, object> { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.PublishedFieldName] = "n" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(new ValueSet( "555", IndexTypes.Content, new Dictionary <string, object> { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.PublishedFieldName] = "y" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); }
public void Inclusion_Exclusion_Type_List() { var validator = new ContentValueSetValidator( false, true, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>(), includeItemTypes: new List <string> { "include-content", "exclude-content" }, excludeItemTypes: new List <string> { "exclude-content" }); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "exclude-content", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, "include-content", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); }
/// <summary> /// Special check for invalid paths /// </summary> /// <param name="values"></param> /// <param name="onComplete"></param> protected override void PerformIndexItems(IEnumerable <ValueSet> values, Action <IndexOperationEventArgs> onComplete) { // We don't want to re-enumerate this list, but we need to split it into 2x enumerables: invalid and valid items. // The Invalid items will be deleted, these are items that have invalid paths (i.e. moved to the recycle bin, etc...) // Then we'll index the Value group all together. var invalidOrValid = values.GroupBy(v => { if (!v.Values.TryGetValue("path", out IReadOnlyList <object>?paths) || paths.Count <= 0 || paths[0] == null) { return(ValueSetValidationStatus.Failed); } ValueSetValidationResult validationResult = ValueSetValidator.Validate(v); return(validationResult.Status); }).ToList(); var hasDeletes = false; var hasUpdates = false; // ordering by descending so that Filtered/Failed processes first foreach (IGrouping <ValueSetValidationStatus, ValueSet> group in invalidOrValid.OrderByDescending(x => x.Key)) { switch (group.Key) { case ValueSetValidationStatus.Valid: hasUpdates = true; //these are the valid ones, so just index them all at once base.PerformIndexItems(group.ToList(), onComplete); break; case ValueSetValidationStatus.Failed: // don't index anything that is invalid break; case ValueSetValidationStatus.Filtered: hasDeletes = true; // these are the invalid/filtered items so we'll delete them // since the path is not valid we need to delete this item in // case it exists in the index already and has now // been moved to an invalid parent. base.PerformDeleteFromIndex(group.Select(x => x.Id), null); break; } } if ((hasDeletes && !hasUpdates) || (!hasDeletes && !hasUpdates)) { //we need to manually call the completed method onComplete(new IndexOperationEventArgs(this, 0)); } }
public void Must_Have_Path() { var validator = new ContentValueSetValidator( false, true, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>()); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); }
public void Inclusion_Field_List() { var validator = new ValueSetValidator( null, null, new[] { "hello", "world" }, null); var valueSet = ValueSet.FromObject("555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555", world = "your oyster" }); ValueSetValidationResult result = validator.Validate(valueSet); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); Assert.IsFalse(result.ValueSet.Values.ContainsKey("path")); Assert.IsTrue(result.ValueSet.Values.ContainsKey("hello")); Assert.IsTrue(result.ValueSet.Values.ContainsKey("world")); }
public void Recycle_Bin_Media() { var validator = new ContentValueSetValidator( true, false, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>()); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,-21,555" })); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,-21,555,777" })); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Media, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); }
public void Invalid_Category() { var validator = new ContentValueSetValidator( false, true, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>()); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationResult.Valid, result); result = validator.Validate(ValueSet.FromObject("777", IndexTypes.Media, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationResult.Valid, result); result = validator.Validate(ValueSet.FromObject("555", "invalid-category", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationResult.Failed, result); }
public void Non_Protected() { var publicAccessService = new Mock <IPublicAccessService>(); publicAccessService.Setup(x => x.IsProtected("-1,555")) .Returns(Attempt.Succeed(new PublicAccessEntry(Guid.NewGuid(), 555, 444, 333, Enumerable.Empty <PublicAccessRule>()))); publicAccessService.Setup(x => x.IsProtected("-1,777")) .Returns(Attempt.Fail <PublicAccessEntry>()); var validator = new ContentValueSetValidator( false, false, publicAccessService.Object, Mock.Of <IScopeProvider>()); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); result = validator.Validate(ValueSet.FromObject("777", IndexTypes.Content, new { hello = "world", path = "-1,777" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); }
public void Parent_Id() { var validator = new ContentValueSetValidator( false, true, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>(), 555); ValueSetValidationResult result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,444" })); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555,777" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555,777,999" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); }
public void Published_Only_With_Variants() { var validator = new ContentValueSetValidator(true, true, Mock.Of <IPublicAccessService>(), Mock.Of <IScopeProvider>()); ValueSetValidationResult result = validator.Validate(new ValueSet( "555", IndexTypes.Content, new Dictionary <string, object> { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.VariesByCultureFieldName] = "y", [UmbracoExamineFieldNames.PublishedFieldName] = "n" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(new ValueSet( "555", IndexTypes.Content, new Dictionary <string, object> { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.VariesByCultureFieldName] = "y", [UmbracoExamineFieldNames.PublishedFieldName] = "y" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); var valueSet = new ValueSet( "555", IndexTypes.Content, new Dictionary <string, object> { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.VariesByCultureFieldName] = "y", [$"{UmbracoExamineFieldNames.PublishedFieldName}_en-us"] = "y", ["hello_en-us"] = "world", ["title_en-us"] = "my title", [$"{UmbracoExamineFieldNames.PublishedFieldName}_es-es"] = "n", ["hello_es-ES"] = "world", ["title_es-ES"] = "my title", [UmbracoExamineFieldNames.PublishedFieldName] = "y" }); Assert.AreEqual(10, valueSet.Values.Count()); Assert.IsTrue(valueSet.Values.ContainsKey($"{UmbracoExamineFieldNames.PublishedFieldName}_es-es")); Assert.IsTrue(valueSet.Values.ContainsKey("hello_es-ES")); Assert.IsTrue(valueSet.Values.ContainsKey("title_es-ES")); result = validator.Validate(valueSet); Assert.AreEqual(ValueSetValidationStatus.Filtered, result.Status); Assert.AreEqual(7, result.ValueSet.Values.Count()); // filtered to 7 values (removes es-es values) Assert.IsFalse(result.ValueSet.Values.ContainsKey($"{UmbracoExamineFieldNames.PublishedFieldName}_es-es")); Assert.IsFalse(result.ValueSet.Values.ContainsKey("hello_es-ES")); Assert.IsFalse(result.ValueSet.Values.ContainsKey("title_es-ES")); }
public override ValueSetValidationResult Validate(ValueSet valueSet) { ValueSetValidationResult baseValidate = base.Validate(valueSet); valueSet = baseValidate.ValueSet; if (baseValidate.Status == ValueSetValidationStatus.Failed) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } var isFiltered = baseValidate.Status == ValueSetValidationStatus.Filtered; var filteredValues = valueSet.Values.ToDictionary(x => x.Key, x => x.Value.ToList()); //check for published content if (valueSet.Category == IndexTypes.Content && PublishedValuesOnly) { if (!valueSet.Values.TryGetValue(UmbracoExamineFieldNames.PublishedFieldName, out IReadOnlyList <object>?published)) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } if (!published[0].Equals("y")) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } //deal with variants, if there are unpublished variants than we need to remove them from the value set if (valueSet.Values.TryGetValue(UmbracoExamineFieldNames.VariesByCultureFieldName, out IReadOnlyList <object>?variesByCulture) && variesByCulture.Count > 0 && variesByCulture[0].Equals("y")) { //so this valueset is for a content that varies by culture, now check for non-published cultures and remove those values foreach (KeyValuePair <string, IReadOnlyList <object> > publishField in valueSet.Values .Where(x => x.Key.StartsWith($"{UmbracoExamineFieldNames.PublishedFieldName}_")).ToList()) { if (publishField.Value.Count <= 0 || !publishField.Value[0].Equals("y")) { //this culture is not published, so remove all of these culture values var cultureSuffix = publishField.Key.Substring(publishField.Key.LastIndexOf('_')); foreach (KeyValuePair <string, IReadOnlyList <object> > cultureField in valueSet.Values .Where(x => x.Key.InvariantEndsWith(cultureSuffix)).ToList()) { filteredValues.Remove(cultureField.Key); isFiltered = true; } } } } } //must have a 'path' if (!valueSet.Values.TryGetValue(PathKey, out IReadOnlyList <object>?pathValues)) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } if (pathValues.Count == 0) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } if (pathValues[0] == null) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } if (pathValues[0].ToString().IsNullOrWhiteSpace()) { return(new ValueSetValidationResult(ValueSetValidationStatus.Failed, valueSet)); } var path = pathValues[0].ToString(); var filteredValueSet = new ValueSet(valueSet.Id, valueSet.Category, valueSet.ItemType, filteredValues.ToDictionary(x => x.Key, x => (IEnumerable <object>)x.Value)); // We need to validate the path of the content based on ParentId, protected content and recycle bin rules. // We cannot return FAILED here because we need the value set to get into the indexer and then deal with it from there // because we need to remove anything that doesn't pass by protected content in the cases that umbraco data is moved to an illegal parent. if (!ValidatePath(path !, valueSet.Category) || !ValidateRecycleBin(path !, valueSet.Category) || !ValidateProtectedContent(path !, valueSet.Category)) { return(new ValueSetValidationResult(ValueSetValidationStatus.Filtered, filteredValueSet)); } return(new ValueSetValidationResult( isFiltered ? ValueSetValidationStatus.Filtered : ValueSetValidationStatus.Valid, filteredValueSet)); }