// Copyright (c) Umbraco. // See LICENSE for more details. using System.Collections.Generic; using System.Linq; using Examine; using Moq; using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Scoping; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Examine; namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Examine; [TestFixture] public class UmbracoContentValueSetValidatorTests { [Test] public void Invalid_Category() { var validator = new ContentValueSetValidator( false, true, Mock.Of(), Mock.Of()); var result = validator.Validate(ValueSet.FromObject("555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); result = validator.Validate( ValueSet.FromObject("777", IndexTypes.Media, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); result = validator.Validate(ValueSet.FromObject( "555", "invalid-category", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); } [Test] public void Must_Have_Path() { var validator = new ContentValueSetValidator( false, true, Mock.Of(), Mock.Of()); var 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); } [Test] public void Parent_Id() { var validator = new ContentValueSetValidator( false, true, Mock.Of(), Mock.Of(), 555); var 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); } [Test] 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" }); var result = validator.Validate(valueSet); // Note - Result is still valid, excluded is not the same as filtered. Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); Assert.IsFalse(result.ValueSet.Values.ContainsKey("path")); Assert.IsTrue(result.ValueSet.Values.ContainsKey("hello")); Assert.IsTrue(result.ValueSet.Values.ContainsKey("world")); } [Test] public void Exclusion_Field_List() { var validator = new ValueSetValidator( null, null, null, new[] { "hello", "world" }); var valueSet = ValueSet.FromObject( "555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555", world = "your oyster" }); var result = validator.Validate(valueSet); // Note - Result is still valid, excluded is not the same as filtered. Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); Assert.IsTrue(result.ValueSet.Values.ContainsKey("path")); Assert.IsFalse(result.ValueSet.Values.ContainsKey("hello")); Assert.IsFalse(result.ValueSet.Values.ContainsKey("world")); } [Test] public void Inclusion_Exclusion_Field_List() { var validator = new ValueSetValidator( null, null, new[] { "hello", "world" }, new[] { "world" }); var valueSet = ValueSet.FromObject( "555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555", world = "your oyster" }); var result = validator.Validate(valueSet); // Note - Result is still valid, excluded is not the same as filtered. Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); Assert.IsFalse(result.ValueSet.Values.ContainsKey("path")); Assert.IsTrue(result.ValueSet.Values.ContainsKey("hello")); Assert.IsFalse(result.ValueSet.Values.ContainsKey("world")); } [Test] public void Inclusion_Type_List() { var validator = new ContentValueSetValidator( false, true, Mock.Of(), Mock.Of(), includeItemTypes: new List { "include-content" }); var 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, "include-content", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); } [Test] public void Exclusion_Type_List() { var validator = new ContentValueSetValidator( false, true, Mock.Of(), Mock.Of(), excludeItemTypes: new List { "exclude-content" }); var result = validator.Validate(ValueSet.FromObject( "555", IndexTypes.Content, "test-content", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); result = validator.Validate(ValueSet.FromObject( "555", IndexTypes.Content, new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); result = validator.Validate(ValueSet.FromObject( "555", IndexTypes.Content, "exclude-content", new { hello = "world", path = "-1,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); } [Test] public void Inclusion_Exclusion_Type_List() { var validator = new ContentValueSetValidator( false, true, Mock.Of(), Mock.Of(), includeItemTypes: new List { "include-content", "exclude-content" }, excludeItemTypes: new List { "exclude-content" }); var 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); } [Test] public void Recycle_Bin_Content() { var validator = new ContentValueSetValidator( true, false, Mock.Of(), Mock.Of()); var result = validator.Validate(ValueSet.FromObject( "555", IndexTypes.Content, new { hello = "world", path = "-1,-20,555" })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(ValueSet.FromObject( "555", IndexTypes.Content, new { hello = "world", path = "-1,-20,555,777" })); 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(new ValueSet( "555", IndexTypes.Content, new Dictionary { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.PublishedFieldName] = "y", })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); } [Test] public void Recycle_Bin_Media() { var validator = new ContentValueSetValidator( true, false, Mock.Of(), Mock.Of()); var 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); } [Test] public void Published_Only() { var validator = new ContentValueSetValidator( true, true, Mock.Of(), Mock.Of()); var 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 { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.PublishedFieldName] = "n", })); Assert.AreEqual(ValueSetValidationStatus.Failed, result.Status); result = validator.Validate(new ValueSet( "555", IndexTypes.Content, new Dictionary { ["hello"] = "world", ["path"] = "-1,555", [UmbracoExamineFieldNames.PublishedFieldName] = "y", })); Assert.AreEqual(ValueSetValidationStatus.Valid, result.Status); } [Test] public void Published_Only_With_Variants() { var validator = new ContentValueSetValidator( true, true, Mock.Of(), Mock.Of()); var result = validator.Validate(new ValueSet( "555", IndexTypes.Content, new Dictionary { ["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 { ["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 { ["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); // Note - Result is still valid, excluded is not the same as filtered. Assert.AreEqual(ValueSetValidationStatus.Valid, 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")); } [Test] public void Non_Protected() { var publicAccessService = new Mock(); publicAccessService.Setup(x => x.IsProtected("-1,555")) .Returns(Attempt.Succeed(new PublicAccessEntry(Guid.NewGuid(), 555, 444, 333, Enumerable.Empty()))); publicAccessService.Setup(x => x.IsProtected("-1,777")) .Returns(Attempt.Fail()); var validator = new ContentValueSetValidator( false, false, publicAccessService.Object, Mock.Of()); var 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); } }