private ContentNodeKit CreateInvariantKit(int id, int parentId, int sortOrder, Dictionary <int, string> paths) { if (!paths.TryGetValue(parentId, out var parentPath)) { throw new Exception("Unknown parent."); } var path = paths[id] = parentPath + "," + id; var level = path.Count(x => x == ','); var now = DateTime.Now; var contentData = ContentDataBuilder.CreateBasic("N" + id, now); return(ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, id, path, sortOrder, level, parentId, 0, Guid.NewGuid(), DateTime.Now, null, contentData)); }
public void MoveFromRootTest() { InitializedCache(GetInvariantKits(), _contentTypes); // get snapshot var snapshot = GetPublishedSnapshot(); // do some changes var kit = NuCacheContentService.ContentKits[1]; NuCacheContentService.ContentKits[1] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, "-1,3,10,1", 1, 1, 10, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); // notify SnapshotService.Notify( new[] { new ContentCacheRefresher.JsonPayload(1, Guid.Empty, TreeChangeTypes.RefreshBranch) }, out _, out _); // changes that *I* make are immediately visible on the current snapshot var documents = snapshot.Content.GetAtRoot().ToArray(); AssertDocuments(documents, "N2", "N3"); documents = snapshot.Content.GetById(10).Children(VariationContextAccessor).ToArray(); AssertDocuments(documents, "N1"); Assert.AreEqual(10, snapshot.Content.GetById(1).Parent?.Id); }
private ContentNodeKit CreateVariantKit(int id, int parentId, int sortOrder, Dictionary <int, string> paths) { if (!paths.TryGetValue(parentId, out var parentPath)) { throw new Exception("Unknown parent."); } var path = paths[id] = parentPath + "," + id; var level = path.Count(x => x == ','); var now = DateTime.Now; var contentData = ContentDataBuilder.CreateVariant( "N" + id, GetCultureInfos(id, now), now); return(ContentNodeKitBuilder.CreateWithContent( _contentTypeVariant.Id, id, path, sortOrder, level, parentId, draftData: null, publishedData: contentData)); }
private IEnumerable <ContentNodeKit> CreateChildren( int startId, ContentNodeKit parent, IMediaType mediaType, int count) { for (var i = 0; i < count; i++) { var id = startId + i + 1; var item1Data = new ContentDataBuilder() .WithName("Child " + id) .WithProperties(new PropertyDataBuilder() .WithPropertyData("content", "<div>This is some content</div>") .Build()) .Build(); var parentPath = parent.Node.Path; var item1 = ContentNodeKitBuilder.CreateWithContent( mediaType.Id, id, $"{parentPath},{id}", draftData: item1Data, publishedData: item1Data); yield return(item1); } }
public void ReOrderTest() { InitializedCache(GetInvariantKits(), _contentTypes); // get snapshot var snapshot = GetPublishedSnapshot(); // do some changes var kit = NuCacheContentService.ContentKits[7]; NuCacheContentService.ContentKits[7] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, kit.Node.Path, 1, kit.Node.Level, kit.Node.ParentContentId, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); kit = NuCacheContentService.ContentKits[8]; NuCacheContentService.ContentKits[8] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, kit.Node.Path, 3, kit.Node.Level, kit.Node.ParentContentId, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); kit = NuCacheContentService.ContentKits[9]; NuCacheContentService.ContentKits[9] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, kit.Node.Path, 2, kit.Node.Level, kit.Node.ParentContentId, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); // notify SnapshotService.Notify( new[] { new ContentCacheRefresher.JsonPayload(kit.Node.ParentContentId, Guid.Empty, TreeChangeTypes.RefreshBranch), }, out _, out _); // changes that *I* make are immediately visible on the current snapshot var documents = snapshot.Content.GetById(kit.Node.ParentContentId).Children(VariationContextAccessor).ToArray(); AssertDocuments(documents, "N7", "N9", "N8"); }
private ContentNodeKit CreateRoot(out MediaType mediaType) { mediaType = new MediaType(ShortStringHelper, -1); var item1Data = new ContentDataBuilder() .WithName("Content 1") .WithProperties(new PropertyDataBuilder() .WithPropertyData("content", "<div>This is some content</div>") .Build()) // build with a dynamically created media type .Build(ShortStringHelper, _propertyDataTypes, mediaType, "image2"); var item1 = ContentNodeKitBuilder.CreateWithContent( mediaType.Id, 1, "-1,1", draftData: item1Data, publishedData: item1Data); return(item1); }
public void MoveTest() { InitializedCache(GetInvariantKits(), _contentTypes); // get snapshot var snapshot = GetPublishedSnapshot(); // do some changes var kit = NuCacheContentService.ContentKits[4]; NuCacheContentService.ContentKits[4] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, kit.Node.Path, 2, kit.Node.Level, kit.Node.ParentContentId, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); kit = NuCacheContentService.ContentKits[5]; NuCacheContentService.ContentKits[5] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, kit.Node.Path, 3, kit.Node.Level, kit.Node.ParentContentId, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); kit = NuCacheContentService.ContentKits[6]; NuCacheContentService.ContentKits[6] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, kit.Node.Path, 4, kit.Node.Level, kit.Node.ParentContentId, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); kit = NuCacheContentService.ContentKits[7]; NuCacheContentService.ContentKits[7] = ContentNodeKitBuilder.CreateWithContent( _contentTypeInvariant.Id, kit.Node.Id, "-1,1,7", 1, kit.Node.Level, 1, draftData: null, publishedData: ContentDataBuilder.CreateBasic(kit.PublishedData.Name)); // notify SnapshotService.Notify( new[] { // removal must come first new ContentCacheRefresher.JsonPayload(2, Guid.Empty, TreeChangeTypes.RefreshBranch), new ContentCacheRefresher.JsonPayload(1, Guid.Empty, TreeChangeTypes.RefreshBranch), }, out _, out _); // changes that *I* make are immediately visible on the current snapshot var documents = snapshot.Content.GetById(1).Children(VariationContextAccessor).ToArray(); AssertDocuments(documents, "N7", "N4", "N5", "N6"); documents = snapshot.Content.GetById(2).Children(VariationContextAccessor).ToArray(); AssertDocuments(documents, "N9", "N8"); Assert.AreEqual(1, snapshot.Content.GetById(7).Parent?.Id); }
private IEnumerable <ContentNodeKit> GetVariantWithDraftKits() { var paths = new Dictionary <int, string> { { -1, "-1" } }; Dictionary <string, CultureVariation> GetCultureInfos(int id, DateTime now) { var en = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; var fr = new[] { 1, 3, 4, 6, 7, 9, 10, 12 }; var infos = new Dictionary <string, CultureVariation>(); if (en.Contains(id)) { infos["en-US"] = new CultureVariation { Name = "N" + id + "-" + "en-US", Date = now, IsDraft = false }; } if (fr.Contains(id)) { infos["fr-FR"] = new CultureVariation { Name = "N" + id + "-" + "fr-FR", Date = now, IsDraft = false }; } return(infos); } ContentNodeKit CreateKit(int id, int parentId, int sortOrder) { if (!paths.TryGetValue(parentId, out var parentPath)) { throw new Exception("Unknown parent."); } var path = paths[id] = parentPath + "," + id; var level = path.Count(x => x == ','); var now = DateTime.Now; ContentData CreateContentData(bool published) { return(ContentDataBuilder.CreateVariant( "N" + id, GetCultureInfos(id, now), now, published)); } var withDraft = id % 2 == 0; var withPublished = !withDraft; return(ContentNodeKitBuilder.CreateWithContent( _contentTypeVariant.Id, id, path, sortOrder, level, parentId, draftData: withDraft ? CreateContentData(false) : null, publishedData: withPublished ? CreateContentData(true) : null)); } yield return(CreateKit(1, -1, 1)); yield return(CreateKit(2, -1, 2)); yield return(CreateKit(3, -1, 3)); yield return(CreateKit(4, 1, 1)); yield return(CreateKit(5, 1, 2)); yield return(CreateKit(6, 1, 3)); yield return(CreateKit(7, 2, 3)); yield return(CreateKit(8, 2, 2)); yield return(CreateKit(9, 2, 1)); yield return(CreateKit(10, 3, 1)); yield return(CreateKit(11, 4, 1)); yield return(CreateKit(12, 4, 2)); }
/// <summary> /// Creates a content cache /// </summary> /// <param name="dataTypes"></param> /// <param name="contentTypes"></param> /// <returns></returns> /// <remarks> /// Builds a content hierarchy of 3 nodes, each has a different set of cultural properties. /// The first 2 share the same content type, the last one is a different content type. /// NOTE: The content items themselves are 'Invariant' but their properties are 'Variant' by culture. /// Normally in Umbraco this is prohibited but our APIs and database do actually support that behavior. /// It is simpler to have these tests run this way, else we would need to use WithCultureInfos /// for each item and pass in name values for all cultures we are supporting and then specify the /// default VariationContextAccessor.VariationContext value to be a default culture instead of "". /// </remarks> private IEnumerable <ContentNodeKit> CreateCache(IDataType[] dataTypes, out ContentType[] contentTypes) { var result = new List <ContentNodeKit>(); var propertyDataTypes = new Dictionary <string, IDataType> { // we only have one data type for this test which will be resolved with string empty. [string.Empty] = dataTypes[0] }; var contentType1 = new ContentType(ShortStringHelper, -1); ContentData item1Data = new ContentDataBuilder() .WithName("Content 1") .WithProperties(new PropertyDataBuilder() .WithPropertyData("welcomeText", "Welcome") .WithPropertyData("welcomeText", "Welcome", "en-US") .WithPropertyData("welcomeText", "Willkommen", "de") .WithPropertyData("welcomeText", "Welkom", "nl") .WithPropertyData("welcomeText2", "Welcome") .WithPropertyData("welcomeText2", "Welcome", "en-US") .WithPropertyData("noprop", "xxx") .Build()) // build with a dynamically created content type .Build(ShortStringHelper, propertyDataTypes, contentType1, "ContentType1"); ContentNodeKit item1 = ContentNodeKitBuilder.CreateWithContent( contentType1.Id, 1, "-1,1", draftData: item1Data, publishedData: item1Data); result.Add(item1); ContentData item2Data = new ContentDataBuilder() .WithName("Content 2") .WithProperties(new PropertyDataBuilder() .WithPropertyData("welcomeText", "Welcome") .WithPropertyData("welcomeText", "Welcome", "en-US") .WithPropertyData("noprop", "xxx") .Build()) // build while dynamically updating the same content type .Build(ShortStringHelper, propertyDataTypes, contentType1); ContentNodeKit item2 = ContentNodeKitBuilder.CreateWithContent( contentType1.Id, 2, "-1,1,2", parentContentId: 1, draftData: item2Data, publishedData: item2Data); result.Add(item2); var contentType2 = new ContentType(ShortStringHelper, -1); ContentData item3Data = new ContentDataBuilder() .WithName("Content 3") .WithProperties(new PropertyDataBuilder() .WithPropertyData("prop3", "Oxxo") .WithPropertyData("prop3", "Oxxo", "en-US") .Build()) // build with a dynamically created content type .Build(ShortStringHelper, propertyDataTypes, contentType2, "ContentType2"); ContentNodeKit item3 = ContentNodeKitBuilder.CreateWithContent( contentType2.Id, 3, "-1,1,2,3", parentContentId: 2, draftData: item3Data, publishedData: item3Data); result.Add(item3); contentTypes = new[] { contentType1, contentType2 }; return(result); }
private ContentNodeKit CreateKit() { var draftData = new ContentDataBuilder() .WithName("It Works2!") .WithPublished(false) .WithProperties(new Dictionary <string, PropertyData[]> { ["prop"] = new[] { new PropertyData { Culture = "", Segment = "", Value = "val2" }, new PropertyData { Culture = "fr-FR", Segment = "", Value = "val-fr2" }, new PropertyData { Culture = "en-UK", Segment = "", Value = "val-uk2" }, new PropertyData { Culture = "dk-DA", Segment = "", Value = "val-da2" }, new PropertyData { Culture = "de-DE", Segment = "", Value = "val-de2" } } }) .WithCultureInfos(new Dictionary <string, CultureVariation> { // draft data = everything, and IsDraft indicates what's edited ["fr-FR"] = new CultureVariation { Name = "name-fr2", IsDraft = true, Date = new DateTime(2018, 01, 03, 01, 00, 00) }, ["en-UK"] = new CultureVariation { Name = "name-uk2", IsDraft = true, Date = new DateTime(2018, 01, 04, 01, 00, 00) }, ["dk-DA"] = new CultureVariation { Name = "name-da2", IsDraft = true, Date = new DateTime(2018, 01, 05, 01, 00, 00) }, ["de-DE"] = new CultureVariation { Name = "name-de1", IsDraft = false, Date = new DateTime(2018, 01, 02, 01, 00, 00) } }) .Build(); var publishedData = new ContentDataBuilder() .WithName("It Works1!") .WithPublished(true) .WithProperties(new Dictionary <string, PropertyData[]> { ["prop"] = new[] { new PropertyData { Culture = "", Segment = "", Value = "val1" }, new PropertyData { Culture = "fr-FR", Segment = "", Value = "val-fr1" }, new PropertyData { Culture = "en-UK", Segment = "", Value = "val-uk1" } } }) .WithCultureInfos(new Dictionary <string, CultureVariation> { // published data = only what's actually published, and IsDraft has to be false ["fr-FR"] = new CultureVariation { Name = "name-fr1", IsDraft = false, Date = new DateTime(2018, 01, 01, 01, 00, 00) }, ["en-UK"] = new CultureVariation { Name = "name-uk1", IsDraft = false, Date = new DateTime(2018, 01, 02, 01, 00, 00) }, ["de-DE"] = new CultureVariation { Name = "name-de1", IsDraft = false, Date = new DateTime(2018, 01, 02, 01, 00, 00) } }) .Build(); var kit = ContentNodeKitBuilder.CreateWithContent( 2, 1, "-1,1", 0, draftData: draftData, publishedData: publishedData); return(kit); }
/// <summary> /// Generate a collection of <see cref="ContentNodeKit"/> based on legacy umbraco XML /// </summary> /// <param name="xml">The legacy umbraco XML</param> /// <param name="shortStringHelper"></param> /// <param name="contentTypes">Dynamically generates a list of <see cref="ContentType"/>s based on the XML data</param> /// <param name="dataTypes">Dynamically generates a list of <see cref="DataType"/> for tests</param> /// <returns></returns> public static IEnumerable <ContentNodeKit> GetContentNodeKits( string xml, IShortStringHelper shortStringHelper, out ContentType[] contentTypes, out DataType[] dataTypes) { // use the label data type for all data for these tests except in the case // where a property is named 'content', in which case use the RTE. var serializer = new ConfigurationEditorJsonSerializer(); var labelDataType = new DataType(new VoidEditor("Label", Mock.Of <IDataValueEditorFactory>()), serializer) { Id = 3 }; var rteDataType = new DataType(new VoidEditor("RTE", Mock.Of <IDataValueEditorFactory>()), serializer) { Id = 4 }; dataTypes = new[] { labelDataType, rteDataType }; var kitsAndXml = new List <(ContentNodeKit kit, XElement node)>(); var xDoc = XDocument.Parse(xml); IEnumerable <XElement> nodes = xDoc.XPathSelectElements("//*[@isDoc]"); foreach (XElement node in nodes) { var id = node.AttributeValue <int>("id"); Guid key = node.AttributeValue <Guid?>("key") ?? id.ToGuid(); var propertyElements = node.Elements().Where(x => x.Attribute("id") == null); var properties = new Dictionary <string, PropertyData[]>(); foreach (XElement propertyElement in propertyElements) { properties[propertyElement.Name.LocalName] = new[] { // TODO: builder? new PropertyData { Culture = string.Empty, Segment = string.Empty, Value = propertyElement.Value } }; } var contentData = new ContentDataBuilder() .WithName(node.AttributeValue <string>("nodeName")) .WithProperties(properties) .WithPublished(true) .WithTemplateId(node.AttributeValue <int>("template")) .WithUrlSegment(node.AttributeValue <string>("urlName")) .WithVersionDate(node.AttributeValue <DateTime>("updateDate")) .WithWriterId(node.AttributeValue <int>("writerID")) .Build(); ContentNodeKit kit = ContentNodeKitBuilder.CreateWithContent( node.AttributeValue <int>("nodeType"), id, node.AttributeValue <string>("path"), node.AttributeValue <int>("sortOrder"), node.AttributeValue <int>("level"), node.AttributeValue <int>("parentID"), node.AttributeValue <int>("creatorID"), key, node.AttributeValue <DateTime>("createDate"), contentData, contentData); kitsAndXml.Add((kit, node)); } // put together the unique content types var contentTypesIdToType = new Dictionary <int, ContentType>(); foreach ((ContentNodeKit kit, XElement node) in kitsAndXml) { if (!contentTypesIdToType.TryGetValue(kit.ContentTypeId, out ContentType contentType)) { contentType = new ContentType(shortStringHelper, -1) { Id = kit.ContentTypeId, Alias = node.Name.LocalName }; SetContentTypeProperties(shortStringHelper, labelDataType, rteDataType, kit, contentType); contentTypesIdToType[kit.ContentTypeId] = contentType; } else { // we've already created it but might need to add properties SetContentTypeProperties(shortStringHelper, labelDataType, rteDataType, kit, contentType); } } contentTypes = contentTypesIdToType.Values.ToArray(); return(kitsAndXml.Select(x => x.kit)); }
private IEnumerable <ContentNodeKit> CreateCache( bool createChildren, IDataType dataType, out ContentType[] contentTypes) { var result = new List <ContentNodeKit>(); var valueCounter = 1; var parentId = 3; var properties = new Dictionary <string, string> { ["property1"] = "Property 1", ["property2"] = "Property 2", }; ContentType parentContentType = CreateContentType("Parent", dataType, new Dictionary <string, string>(properties) { ["property3"] = "Property 3" }); ContentType childContentType = CreateContentType("Child", dataType, new Dictionary <string, string>(properties) { ["property4"] = "Property 4" }); ContentType child2ContentType = CreateContentType("Child2", dataType, new Dictionary <string, string>(properties) { ["property4"] = "Property 4" }); contentTypes = new[] { parentContentType, childContentType, child2ContentType }; ContentData parentData = new ContentDataBuilder() .WithName("Page" + Guid.NewGuid()) .WithProperties(new PropertyDataBuilder() .WithPropertyData("property1", "value" + valueCounter) .WithPropertyData("property2", "value" + (valueCounter + 1)) .WithPropertyData("property3", "value" + (valueCounter + 2)) .Build()) .Build(); ContentNodeKit parent = ContentNodeKitBuilder.CreateWithContent( parentContentType.Id, parentId, $"-1,{parentId}", draftData: parentData, publishedData: parentData); result.Add(parent); if (createChildren) { for (int i = 0; i < 3; i++) { valueCounter += 3; var childId = parentId + i + 1; ContentData childData = new ContentDataBuilder() .WithName("Page" + Guid.NewGuid()) .WithProperties(new PropertyDataBuilder() .WithPropertyData("property1", "value" + valueCounter) .WithPropertyData("property2", "value" + (valueCounter + 1)) .WithPropertyData("property4", "value" + (valueCounter + 2)) .Build()) .Build(); ContentNodeKit child = ContentNodeKitBuilder.CreateWithContent( i > 0 ? childContentType.Id : child2ContentType.Id, childId, $"-1,{parentId},{childId}", i, draftData: childData, publishedData: childData); result.Add(child); } } return(result); }
private void PopulateCache(string culture = "fr-FR") { var dataTypes = GetDefaultDataTypes(); var propertyDataTypes = new Dictionary <string, IDataType> { // we only have one data type for this test which will be resolved with string empty. [string.Empty] = dataTypes[0] }; var contentType1 = new ContentType(ShortStringHelper, -1); ContentData rootData = new ContentDataBuilder() .WithName("Page" + Guid.NewGuid()) .WithCultureInfos(new Dictionary <string, CultureVariation> { [culture] = new CultureVariation { Name = "root", IsDraft = true, Date = DateTime.Now, UrlSegment = "root" }, }) .Build(ShortStringHelper, propertyDataTypes, contentType1, "alias"); ContentNodeKit root = ContentNodeKitBuilder.CreateWithContent( contentType1.Id, 9876, $"-1,9876", draftData: rootData, publishedData: rootData); ContentData parentData = new ContentDataBuilder() .WithName("Page" + Guid.NewGuid()) .WithCultureInfos(new Dictionary <string, CultureVariation> { [culture] = new CultureVariation { Name = "home", IsDraft = true, Date = DateTime.Now, UrlSegment = "home" }, }) .Build(); ContentNodeKit parent = ContentNodeKitBuilder.CreateWithContent( contentType1.Id, 5432, $"-1,9876,5432", parentContentId: 9876, draftData: parentData, publishedData: parentData); ContentData contentData = new ContentDataBuilder() .WithName("Page" + Guid.NewGuid()) .WithCultureInfos(new Dictionary <string, CultureVariation> { [culture] = new CultureVariation { Name = "name-fr2", IsDraft = true, Date = DateTime.Now, UrlSegment = "test-fr" }, }) .Build(); ContentNodeKit content = ContentNodeKitBuilder.CreateWithContent( contentType1.Id, 1234, $"-1,9876,5432,1234", parentContentId: 5432, draftData: contentData, publishedData: contentData); InitializedCache(new[] { root, parent, content }, new[] { contentType1 }, dataTypes: dataTypes); }