Esempio n. 1
0
        /// <summary>
        /// Construct from an Umbraco 8 ContentNodeKit.
        /// </summary>
        internal UmbracoNode(UmbracoXmlParser parser, int id, ContentNodeKit treeNode, string url, List <int> pathIds, List <string> pathNames)
        {
            _parser = parser;
            if (treeNode.PublishedData != null)
            {
                _propertyData = treeNode.PublishedData.Properties;
            }

            Id  = id;
            Uid = treeNode.Node.Uid.ToString().Replace("-", string.Empty).ToLower();

            ParentId = pathIds.Skip(pathIds.Count - 2).FirstOrDefault();
            if (ParentId == -1)
            {
                ParentId = null;
            }

            Name        = pathNames.Last();
            Url         = url;
            PathIds     = pathIds.Skip(1).ToList(); // skip -1 root
            PathNames   = pathNames;
            Doctype     = _parser.Options.DoctypeMapping != null && _parser.Options.DoctypeMapping.ContainsKey(treeNode.ContentTypeId) ? _parser.Options.DoctypeMapping[treeNode.ContentTypeId] : treeNode.ContentTypeId.ToString();
            Level       = pathIds.Count - 1;
            CreateDate  = new DateTime(treeNode.Node.CreateDate.Ticks - (treeNode.Node.CreateDate.Ticks % TimeSpan.TicksPerSecond), treeNode.Node.CreateDate.Kind);
            UpdateDate  = treeNode.PublishedData != null ? new DateTime(treeNode.PublishedData.VersionDate.Ticks - (treeNode.PublishedData.VersionDate.Ticks % TimeSpan.TicksPerSecond), treeNode.PublishedData.VersionDate.Kind) : CreateDate;
            CreatorName = _parser.Options.UserMapping != null && _parser.Options.UserMapping.ContainsKey(treeNode.Node.CreatorId) ? _parser.Options.UserMapping[treeNode.Node.CreatorId] : treeNode.Node.CreatorId.ToString();
            WriterName  = _parser.Options.UserMapping != null && treeNode.PublishedData != null && _parser.Options.UserMapping.ContainsKey(treeNode.PublishedData.WriterId) ? _parser.Options.UserMapping[treeNode.PublishedData.WriterId] : treeNode.PublishedData != null?treeNode.PublishedData.WriterId.ToString() : null;

            TemplateId = treeNode.PublishedData != null && treeNode.PublishedData.TemplateId.HasValue ? treeNode.PublishedData.TemplateId.Value : default(int);
        }
Esempio n. 2
0
        private ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            if (dto.EditData == null && dto.EditDataRaw == null)
            {
                throw new InvalidOperationException("No data for media " + dto.Id);
            }

            bool published         = true;
            var  deserializedMedia = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

            var p = new ContentData
            {
                Name         = dto.EditName,
                Published    = published,
                TemplateId   = -1,
                VersionId    = dto.VersionId,
                VersionDate  = dto.EditVersionDate,
                WriterId     = dto.CreatorId,                  // what-else?
                Properties   = deserializedMedia.PropertyData, // TODO: We don't want to allocate empty arrays
                CultureInfos = deserializedMedia.CultureData
            };

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit
            {
                Node          = n,
                ContentTypeId = dto.ContentTypeId,
                PublishedData = p
            };

            return(s);
        }
Esempio n. 3
0
        private static ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto)
        {
            if (dto.EditData == null)
            {
                throw new Exception("No data for media " + dto.Id);
            }

            var nested = DeserializeNestedData(dto.EditData);

            var p = new ContentData
            {
                Name         = dto.EditName,
                Published    = true,
                TemplateId   = -1,
                VersionId    = dto.VersionId,
                VersionDate  = dto.EditVersionDate,
                WriterId     = dto.CreatorId, // what-else?
                Properties   = nested.PropertyData,
                CultureInfos = nested.CultureData
            };

            var n = new ContentNode(dto.Id, dto.Uid,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit
            {
                Node          = n,
                ContentTypeId = dto.ContentTypeId,
                PublishedData = p
            };

            return(s);
        }
        private ContentNodeKit CreateMediaNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            if (dto.EditData == null && dto.EditDataRaw == null)
            {
                throw new InvalidOperationException("No data for media " + dto.Id);
            }

            bool published         = true;
            var  deserializedMedia = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

            var p = new ContentData(
                dto.EditName,
                null,
                dto.VersionId,
                dto.EditVersionDate,
                dto.CreatorId,
                -1,
                published,
                deserializedMedia?.PropertyData,
                deserializedMedia?.CultureData);

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit(n, dto.ContentTypeId, null, p);

            return(s);
        }
Esempio n. 5
0
    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);
        }
    }
        private List <int> GetNodeIdPath(ContentNodeKit treeNode)
        {
            var paths = new List <int>();

            if (treeNode.Node != null && !string.IsNullOrEmpty(treeNode.Node.Path))
            {
                paths.AddRange(treeNode.Node.Path.Split(',').AsEnumerable().Select(i => Convert.ToInt32(i)));
            }

            return(paths);
        }
    private static void SetContentTypeProperties(
        IShortStringHelper shortStringHelper,
        DataType labelDataType,
        DataType rteDataType,
        ContentNodeKit kit,
        ContentType contentType)
    {
        foreach (var property in kit.DraftData.Properties)
        {
            var propertyType = new PropertyType(shortStringHelper, labelDataType, property.Key);

            if (!contentType.PropertyTypeExists(propertyType.Alias))
            {
                if (propertyType.Alias == "content")
                {
                    propertyType.DataTypeId = rteDataType.Id;
                }

                contentType.AddPropertyType(propertyType);
            }
        }
    }
Esempio n. 8
0
        private static ContentNodeKit CreateContentNodeKit(ContentSourceDto dto)
        {
            ContentData d = null;
            ContentData p = null;

            if (dto.Edited)
            {
                if (dto.EditData == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new Exception("Missing cmsContentNu edited content for node " + dto.Id + ", consider rebuilding.");
                    }
                    Current.Logger.Warn <DatabaseDataSource>("Missing cmsContentNu edited content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    var nested = DeserializeNestedData(dto.EditData);

                    d = new ContentData
                    {
                        Name         = dto.EditName,
                        Published    = false,
                        TemplateId   = dto.EditTemplateId,
                        VersionId    = dto.VersionId,
                        VersionDate  = dto.EditVersionDate,
                        WriterId     = dto.EditWriterId,
                        Properties   = nested.PropertyData,
                        CultureInfos = nested.CultureData
                    };
                }
            }

            if (dto.Published)
            {
                if (dto.PubData == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new Exception("Missing cmsContentNu published content for node " + dto.Id + ", consider rebuilding.");
                    }
                    Current.Logger.Warn <DatabaseDataSource>("Missing cmsContentNu published content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    var nested = DeserializeNestedData(dto.PubData);

                    p = new ContentData
                    {
                        Name         = dto.PubName,
                        UrlSegment   = nested.UrlSegment,
                        Published    = true,
                        TemplateId   = dto.PubTemplateId,
                        VersionId    = dto.VersionId,
                        VersionDate  = dto.PubVersionDate,
                        WriterId     = dto.PubWriterId,
                        Properties   = nested.PropertyData,
                        CultureInfos = nested.CultureData
                    };
                }
            }

            var n = new ContentNode(dto.Id, dto.Uid,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit
            {
                Node          = n,
                ContentTypeId = dto.ContentTypeId,
                DraftData     = d,
                PublishedData = p
            };

            return(s);
        }
Esempio n. 9
0
        private void Init()
        {
            Current.Reset();

            var factory = Mock.Of <IFactory>();

            Current.Factory = factory;

            var configs = new Configs();

            Mock.Get(factory).Setup(x => x.GetInstance(typeof(Configs))).Returns(configs);
            var globalSettings = new GlobalSettings();

            configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
            configs.Add <IGlobalSettings>(() => globalSettings);

            var publishedModelFactory = new NoopPublishedModelFactory();

            Mock.Get(factory).Setup(x => x.GetInstance(typeof(IPublishedModelFactory))).Returns(publishedModelFactory);

            // create a content node kit
            var kit = new ContentNodeKit
            {
                ContentTypeId = 2,
                Node          = new ContentNode(1, Guid.NewGuid(), 0, "-1,1", 0, -1, DateTime.Now, 0),
                DraftData     = new ContentData
                {
                    Name        = "It Works2!",
                    Published   = false,
                    TemplateId  = 0,
                    VersionId   = 2,
                    VersionDate = DateTime.Now,
                    WriterId    = 0,
                    Properties  = 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"
                              }
                          } }
                    },
                    CultureInfos = 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)
                          } }
                    }
                },
                PublishedData = new ContentData
                {
                    Name        = "It Works1!",
                    Published   = true,
                    TemplateId  = 0,
                    VersionId   = 1,
                    VersionDate = DateTime.Now,
                    WriterId    = 0,
                    Properties  = 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"
                              }
                          } }
                    },
                    CultureInfos = 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)
                          } }
                    }
                }
            };

            // create a data source for NuCache
            var dataSource = new TestDataSource(kit);

            var runtime = Mock.Of <IRuntimeState>();

            Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run);

            // create data types, property types and content types
            var dataType = new DataType(new VoidEditor("Editor", Mock.Of <ILogger>()))
            {
                Id = 3
            };

            var dataTypes = new[]
            {
                dataType
            };

            _propertyType = new PropertyType("Umbraco.Void.Editor", ValueStorageType.Nvarchar)
            {
                Alias = "prop", DataTypeId = 3, Variations = ContentVariation.Culture
            };
            _contentType = new ContentType(-1)
            {
                Id = 2, Alias = "alias-ct", Variations = ContentVariation.Culture
            };
            _contentType.AddPropertyType(_propertyType);

            var contentTypes = new[]
            {
                _contentType
            };

            var contentTypeService = new Mock <IContentTypeService>();

            contentTypeService.Setup(x => x.GetAll()).Returns(contentTypes);
            contentTypeService.Setup(x => x.GetAll(It.IsAny <int[]>())).Returns(contentTypes);

            var mediaTypeService = new Mock <IMediaTypeService>();

            mediaTypeService.Setup(x => x.GetAll()).Returns(Enumerable.Empty <IMediaType>());
            mediaTypeService.Setup(x => x.GetAll(It.IsAny <int[]>())).Returns(Enumerable.Empty <IMediaType>());

            var contentTypeServiceBaseFactory = new Mock <IContentTypeBaseServiceProvider>();

            contentTypeServiceBaseFactory.Setup(x => x.For(It.IsAny <IContentBase>())).Returns(contentTypeService.Object);

            var dataTypeService = Mock.Of <IDataTypeService>();

            Mock.Get(dataTypeService).Setup(x => x.GetAll()).Returns(dataTypes);

            // create a service context
            var serviceContext = ServiceContext.CreatePartial(
                dataTypeService: dataTypeService,
                memberTypeService: Mock.Of <IMemberTypeService>(),
                memberService: Mock.Of <IMemberService>(),
                contentTypeService: contentTypeService.Object,
                mediaTypeService: mediaTypeService.Object,
                localizationService: Mock.Of <ILocalizationService>(),
                domainService: Mock.Of <IDomainService>()
                );

            // create a scope provider
            var scopeProvider = Mock.Of <IScopeProvider>();

            Mock.Get(scopeProvider)
            .Setup(x => x.CreateScope(
                       It.IsAny <IsolationLevel>(),
                       It.IsAny <RepositoryCacheMode>(),
                       It.IsAny <IEventDispatcher>(),
                       It.IsAny <bool?>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>()))
            .Returns(Mock.Of <IScope>);

            // create a published content type factory
            var contentTypeFactory = new PublishedContentTypeFactory(
                Mock.Of <IPublishedModelFactory>(),
                new PropertyValueConverterCollection(Array.Empty <IPropertyValueConverter>()),
                dataTypeService);

            // create a variation accessor
            _variationAccesor = new TestVariationContextAccessor();

            // at last, create the complete NuCache snapshot service!
            var options = new PublishedSnapshotServiceOptions {
                IgnoreLocalDb = true
            };

            _snapshotService = new PublishedSnapshotService(options,
                                                            null,
                                                            runtime,
                                                            serviceContext,
                                                            contentTypeFactory,
                                                            null,
                                                            new TestPublishedSnapshotAccessor(),
                                                            _variationAccesor,
                                                            Mock.Of <IProfilingLogger>(),
                                                            scopeProvider,
                                                            Mock.Of <IDocumentRepository>(),
                                                            Mock.Of <IMediaRepository>(),
                                                            Mock.Of <IMemberRepository>(),
                                                            new TestDefaultCultureAccessor(),
                                                            dataSource,
                                                            globalSettings,
                                                            Mock.Of <IEntityXmlSerializer>(),
                                                            Mock.Of <IPublishedModelFactory>(),
                                                            new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }));

            // invariant is the current default
            _variationAccesor.VariationContext = new VariationContext();

            Mock.Get(factory).Setup(x => x.GetInstance(typeof(IVariationContextAccessor))).Returns(_variationAccesor);
        }
Esempio n. 10
0
        /// <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);
        }
Esempio n. 11
0
        private ContentNodeKit CreateContentNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            ContentData d = null;
            ContentData p = null;

            if (dto.Edited)
            {
                if (dto.EditData == null && dto.EditDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu edited content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu edited content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = false;
                    var  deserializedContent = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

                    d = new ContentData
                    {
                        Name         = dto.EditName,
                        Published    = published,
                        TemplateId   = dto.EditTemplateId,
                        VersionId    = dto.VersionId,
                        VersionDate  = dto.EditVersionDate,
                        WriterId     = dto.EditWriterId,
                        Properties   = deserializedContent.PropertyData, // TODO: We don't want to allocate empty arrays
                        CultureInfos = deserializedContent.CultureData,
                        UrlSegment   = deserializedContent.UrlSegment
                    };
                }
            }

            if (dto.Published)
            {
                if (dto.PubData == null && dto.PubDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu published content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu published content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = true;
                    var  deserializedContent = serializer.Deserialize(dto, dto.PubData, dto.PubDataRaw, published);

                    p = new ContentData
                    {
                        Name         = dto.PubName,
                        UrlSegment   = deserializedContent.UrlSegment,
                        Published    = published,
                        TemplateId   = dto.PubTemplateId,
                        VersionId    = dto.VersionId,
                        VersionDate  = dto.PubVersionDate,
                        WriterId     = dto.PubWriterId,
                        Properties   = deserializedContent.PropertyData, // TODO: We don't want to allocate empty arrays
                        CultureInfos = deserializedContent.CultureData
                    };
                }
            }

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit
            {
                Node          = n,
                ContentTypeId = dto.ContentTypeId,
                DraftData     = d,
                PublishedData = p
            };

            return(s);
        }
Esempio n. 12
0
        /// <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));
        }
Esempio n. 13
0
        public void StandaloneVariations()
        {
            // this test implements a full standalone NuCache (based upon a test IDataSource, does not
            // use any local db files, does not rely on any database) - and tests variations

            Current.Reset();
            Current.UnlockConfigs();
            Current.Configs.Add(SettingsForTests.GenerateMockUmbracoSettings);
            Current.Configs.Add <IGlobalSettings>(() => new GlobalSettings());
            var globalSettings = Current.Configs.Global();

            // create a content node kit
            var kit = new ContentNodeKit
            {
                ContentTypeId = 2,
                Node          = new ContentNode(1, Guid.NewGuid(), 0, "-1,1", 0, -1, DateTime.Now, 0),
                DraftData     = new ContentData {
                    Name       = "It Works2!", Published = false, TemplateId = 0, VersionId = 2, VersionDate = DateTime.Now, WriterId = 0,
                    Properties = 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"
                              }
                          } }
                    },
                    CultureInfos = new Dictionary <string, CultureVariation>
                    {
                        { "fr-FR", new CultureVariation {
                              Name = "name-fr2", Date = new DateTime(2018, 01, 03, 01, 00, 00)
                          } },
                        { "en-UK", new CultureVariation {
                              Name = "name-uk2", Date = new DateTime(2018, 01, 04, 01, 00, 00)
                          } }
                    }
                },
                PublishedData = new ContentData {
                    Name       = "It Works1!", Published = true, TemplateId = 0, VersionId = 1, VersionDate = DateTime.Now, WriterId = 0,
                    Properties = 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"
                              }
                          } }
                    },
                    CultureInfos = new Dictionary <string, CultureVariation>
                    {
                        { "fr-FR", new CultureVariation {
                              Name = "name-fr1", Date = new DateTime(2018, 01, 01, 01, 00, 00)
                          } },
                        { "en-UK", new CultureVariation {
                              Name = "name-uk1", Date = new DateTime(2018, 01, 02, 01, 00, 00)
                          } }
                    }
                }
            };

            // create a data source for NuCache
            var dataSource = new TestDataSource(kit);

            var runtime = Mock.Of <IRuntimeState>();

            Mock.Get(runtime).Setup(x => x.Level).Returns(RuntimeLevel.Run);

            // create data types, property types and content types
            var dataType = new DataType(new VoidEditor("Editor", Mock.Of <ILogger>()))
            {
                Id = 3
            };

            var dataTypes = new[]
            {
                dataType
            };

            var propertyType = new PropertyType("Umbraco.Void.Editor", ValueStorageType.Nvarchar)
            {
                Alias = "prop", DataTypeId = 3, Variations = ContentVariation.Culture
            };
            var contentType = new ContentType(-1)
            {
                Id = 2, Alias = "alias-ct", Variations = ContentVariation.Culture
            };

            contentType.AddPropertyType(propertyType);

            var contentTypes = new[]
            {
                contentType
            };

            var contentTypeService = Mock.Of <IContentTypeService>();

            Mock.Get(contentTypeService).Setup(x => x.GetAll()).Returns(contentTypes);
            Mock.Get(contentTypeService).Setup(x => x.GetAll(It.IsAny <int[]>())).Returns(contentTypes);

            var dataTypeService = Mock.Of <IDataTypeService>();

            Mock.Get(dataTypeService).Setup(x => x.GetAll()).Returns(dataTypes);

            // create a service context
            var serviceContext = ServiceContext.CreatePartial(
                dataTypeService: dataTypeService,
                memberTypeService: Mock.Of <IMemberTypeService>(),
                memberService: Mock.Of <IMemberService>(),
                contentTypeService: contentTypeService,
                localizationService: Mock.Of <ILocalizationService>()
                );

            // create a scope provider
            var scopeProvider = Mock.Of <IScopeProvider>();

            Mock.Get(scopeProvider)
            .Setup(x => x.CreateScope(
                       It.IsAny <IsolationLevel>(),
                       It.IsAny <RepositoryCacheMode>(),
                       It.IsAny <IEventDispatcher>(),
                       It.IsAny <bool?>(),
                       It.IsAny <bool>(),
                       It.IsAny <bool>()))
            .Returns(Mock.Of <IScope>);

            // create a published content type factory
            var contentTypeFactory = new PublishedContentTypeFactory(
                Mock.Of <IPublishedModelFactory>(),
                new PropertyValueConverterCollection(Array.Empty <IPropertyValueConverter>()),
                dataTypeService);

            // create a variation accessor
            var variationAccessor = new TestVariationContextAccessor();

            // at last, create the complete NuCache snapshot service!
            var options = new PublishedSnapshotService.Options {
                IgnoreLocalDb = true
            };
            var snapshotService = new PublishedSnapshotService(options,
                                                               null,
                                                               runtime,
                                                               serviceContext,
                                                               contentTypeFactory,
                                                               null,
                                                               new TestPublishedSnapshotAccessor(),
                                                               variationAccessor,
                                                               Mock.Of <ILogger>(),
                                                               scopeProvider,
                                                               Mock.Of <IDocumentRepository>(),
                                                               Mock.Of <IMediaRepository>(),
                                                               Mock.Of <IMemberRepository>(),
                                                               new TestDefaultCultureAccessor(),
                                                               dataSource,
                                                               globalSettings,
                                                               new SiteDomainHelper());

            // get a snapshot, get a published content
            var snapshot         = snapshotService.CreatePublishedSnapshot(previewToken: null);
            var publishedContent = snapshot.Content.GetById(1);

            // invariant is the current default
            variationAccessor.VariationContext = new VariationContext();

            Assert.IsNotNull(publishedContent);
            Assert.AreEqual("It Works1!", publishedContent.Name);
            Assert.AreEqual("val1", publishedContent.Value <string>("prop"));
            Assert.AreEqual("val-fr1", publishedContent.Value <string>("prop", "fr-FR"));
            Assert.AreEqual("val-uk1", publishedContent.Value <string>("prop", "en-UK"));

            Assert.AreEqual("name-fr1", publishedContent.GetCulture("fr-FR").Name);
            Assert.AreEqual("name-uk1", publishedContent.GetCulture("en-UK").Name);

            var draftContent = snapshot.Content.GetById(true, 1);

            Assert.AreEqual("It Works2!", draftContent.Name);
            Assert.AreEqual("val2", draftContent.Value <string>("prop"));
            Assert.AreEqual("val-fr2", draftContent.Value <string>("prop", "fr-FR"));
            Assert.AreEqual("val-uk2", draftContent.Value <string>("prop", "en-UK"));

            Assert.AreEqual("name-fr2", draftContent.GetCulture("fr-FR").Name);
            Assert.AreEqual("name-uk2", draftContent.GetCulture("en-UK").Name);

            // now french is default
            variationAccessor.VariationContext = new VariationContext("fr-FR");
            Assert.AreEqual("val-fr1", publishedContent.Value <string>("prop"));
            Assert.AreEqual("name-fr1", publishedContent.GetCulture().Name);
            Assert.AreEqual("name-fr1", publishedContent.Name);
            Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.GetCulture().Date);

            // now uk is default
            variationAccessor.VariationContext = new VariationContext("en-UK");
            Assert.AreEqual("val-uk1", publishedContent.Value <string>("prop"));
            Assert.AreEqual("name-uk1", publishedContent.GetCulture().Name);
            Assert.AreEqual("name-uk1", publishedContent.Name);
            Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.GetCulture().Date);

            // invariant needs to be retrieved explicitely, when it's not default
            Assert.AreEqual("val1", publishedContent.Value <string>("prop", culture: ""));

            // but,
            // if the content type / property type does not vary, then it's all invariant again
            // modify the content type and property type, notify the snapshot service
            contentType.Variations  = ContentVariation.Nothing;
            propertyType.Variations = ContentVariation.Nothing;
            snapshotService.Notify(new[] { new ContentTypeCacheRefresher.JsonPayload("IContentType", publishedContent.ContentType.Id, ContentTypeChangeTypes.RefreshMain) });

            // get a new snapshot (nothing changed in the old one), get the published content again
            var anotherSnapshot = snapshotService.CreatePublishedSnapshot(previewToken: null);
            var againContent    = anotherSnapshot.Content.GetById(1);

            Assert.AreEqual(ContentVariation.Nothing, againContent.ContentType.Variations);
            Assert.AreEqual(ContentVariation.Nothing, againContent.ContentType.GetPropertyType("prop").Variations);

            // now, "no culture" means "invariant"
            Assert.AreEqual("It Works1!", againContent.Name);
            Assert.AreEqual("val1", againContent.Value <string>("prop"));
        }
        private ContentNodeKit CreateContentNodeKit(ContentSourceDto dto, IContentCacheDataSerializer serializer)
        {
            ContentData?d = null;
            ContentData?p = null;

            if (dto.Edited)
            {
                if (dto.EditData == null && dto.EditDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu edited content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu edited content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = false;
                    var  deserializedContent = serializer.Deserialize(dto, dto.EditData, dto.EditDataRaw, published);

                    d = new ContentData(
                        dto.EditName,
                        deserializedContent?.UrlSegment,
                        dto.VersionId,
                        dto.EditVersionDate,
                        dto.EditWriterId,
                        dto.EditTemplateId,
                        published,
                        deserializedContent?.PropertyData,
                        deserializedContent?.CultureData);
                }
            }

            if (dto.Published)
            {
                if (dto.PubData == null && dto.PubDataRaw == null)
                {
                    if (Debugger.IsAttached)
                    {
                        throw new InvalidOperationException("Missing cmsContentNu published content for node " + dto.Id + ", consider rebuilding.");
                    }

                    _logger.LogWarning("Missing cmsContentNu published content for node {NodeId}, consider rebuilding.", dto.Id);
                }
                else
                {
                    bool published           = true;
                    var  deserializedContent = serializer.Deserialize(dto, dto.PubData, dto.PubDataRaw, published);

                    p = new ContentData(
                        dto.PubName,
                        deserializedContent?.UrlSegment,
                        dto.VersionId,
                        dto.PubVersionDate,
                        dto.PubWriterId,
                        dto.PubTemplateId,
                        published,
                        deserializedContent?.PropertyData,
                        deserializedContent?.CultureData);
                }
            }

            var n = new ContentNode(dto.Id, dto.Key,
                                    dto.Level, dto.Path, dto.SortOrder, dto.ParentId, dto.CreateDate, dto.CreatorId);

            var s = new ContentNodeKit(n, dto.ContentTypeId, d, p);

            return(s);
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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);
        }