/// <summary>
 /// Event Receiver Info (Content Type)
 /// </summary>
 /// <param name="contentType">The content type</param>
 /// <param name="type">The event receiver type</param>
 /// <param name="syncType">The synchronization type</param>
 public EventReceiverInfo(ContentTypeInfo contentType, SPEventReceiverType type, SPEventReceiverSynchronization syncType)
 {
     this.ContentType = contentType;
     this.ReceiverType = type;
     this.EventOwner = EventReceiverOwner.ContentType;
     this.SynchronizationType = syncType;
 }
 /// <summary>
 /// Event Receiver Info (Content Type)
 /// </summary>
 /// <param name="contentType">The content type</param>
 /// <param name="type">The event receiver type</param>
 /// <param name="syncType">The synchronization type</param>
 /// <param name="assemblyName">The full name of the Assembly</param>
 /// <param name="className">The fullname of the Type/Class </param>
 public EventReceiverInfo(ContentTypeInfo contentType, SPEventReceiverType type, SPEventReceiverSynchronization syncType, string assemblyName, string className)
 {
     this.ContentType = contentType;
     this.ReceiverType = type;
     this.SynchronizationType = syncType;
     this.AssemblyName = assemblyName;
     this.ClassName = className;
 }
        public SPContentType EnsureContentType(SPContentTypeCollection contentTypeCollection, ContentTypeInfo contentTypeInfo)
        {
            var contentType = this.InnerEnsureContentType(contentTypeCollection, contentTypeInfo);

            SPList list;
            if (!TryGetListFromContentTypeCollection(contentTypeCollection, out list))
            {
                // Set the content type title, description, and group information for each language.
                // Only do this when not on a web because the SPContentType Title property does not support resource values at this level.
                // The content type for a list is created at the root web level, then added to the list.
                this.SetTitleDescriptionAndGroupValues(contentTypeInfo, contentType);
            }

            return contentType;
        }
        public void EnsureContentType_WhenAlreadyExists_ShouldReturnSameContentType()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var contentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;
                    var expectedNumberOfContentTypes = contentTypeCollection.Count + 1;
                    var expectedContentTypeId = new SPContentTypeId(contentTypeId);
                    var expectedDisplayName = contentTypeInfo.DisplayNameResourceKey;
                    var expectedDescription = contentTypeInfo.DescriptionResourceKey;
                    var expectedGroup = contentTypeInfo.GroupResourceKey;

                    // Act
                    contentTypeHelper.EnsureContentType(contentTypeCollection, contentTypeInfo);
                    var actualContentType = contentTypeHelper.EnsureContentType(contentTypeCollection, contentTypeInfo);
                    var actualNumberOfContentTypes = contentTypeCollection.Count;

                    // Assert
                    Assert.AreEqual(expectedNumberOfContentTypes, actualNumberOfContentTypes);
                    Assert.IsNotNull(actualContentType);
                    Assert.AreEqual(expectedContentTypeId, actualContentType.Id);
                    Assert.AreEqual(expectedDisplayName, actualContentType.NameResource.Value);
                    Assert.AreEqual(expectedDescription, actualContentType.DescriptionResource.Value);
                    Assert.AreEqual(expectedGroup, actualContentType.Group);

                    var contentTypeRefetched = testScope.SiteCollection.RootWeb.ContentTypes["NameKey"];
                    Assert.IsNotNull(contentTypeRefetched);
                    Assert.AreEqual(expectedContentTypeId, contentTypeRefetched.Id);
                    Assert.AreEqual(expectedDisplayName, contentTypeRefetched.NameResource.Value);
                    Assert.AreEqual(expectedDescription, contentTypeRefetched.DescriptionResource.Value);
                    Assert.AreEqual(expectedGroup, contentTypeRefetched.Group);
                }
            }
        }
Exemple #5
0
        public void EnsureList_WhenEnsuringANewListInSubWebWithSpecifiedContentTypes_AndContentTypeAlreadyExistsOnRootWeb_ItShouldAddChildOfRootWebContentTypeToList()
        {
            // Arrange
            const string Url = "testUrl";

            var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

            var contentTypeInfo = new ContentTypeInfo(contentTypeId, "ContentTypeNameKey", "ContentTypeDescKey", "GroupKey");

            var listInfo = new ListInfo(Url, "NameKey", "DescriptionKey")
            {
                ContentTypes = new List<ContentTypeInfo>()
                    {
                        contentTypeInfo
                    }
            };

            using (var testScope = SiteTestScope.BlankSite())
            {
                var rootWeb = testScope.SiteCollection.RootWeb;
                var subWeb = testScope.SiteCollection.RootWeb.Webs.Add("subweb");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var listHelper = injectionScope.Resolve<IListHelper>();
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Add the content type to the root web beforehand
                    contentTypeHelper.EnsureContentType(rootWeb.ContentTypes, contentTypeInfo);

                    var numberOfListsBefore = subWeb.Lists.Count;
                    var numberOfContentTypesBefore = rootWeb.ContentTypes.Count;

                    // Act
                    var list = listHelper.EnsureList(subWeb, listInfo);

                    // Assert
                    Assert.AreEqual(numberOfListsBefore + 1, subWeb.Lists.Count);
                    Assert.AreEqual(listInfo.DisplayNameResourceKey, list.TitleResource.Value);
                    list = subWeb.GetList("subweb/" + Url);
                    Assert.IsNotNull(list);
                    var listContentType = list.ContentTypes["ContentTypeNameKey"];
                    Assert.IsNotNull(listContentType);

                    // Make sure CT was not re-provisionned on root web and that list CT is child of root web CT
                    Assert.AreEqual(numberOfContentTypesBefore, rootWeb.ContentTypes.Count);    // same number before/after because initial count was take after CT was ensured on root web
                    var rootWebContentType = rootWeb.ContentTypes["ContentTypeNameKey"];
                    Assert.IsNotNull(rootWebContentType);

                    Assert.IsTrue(listContentType.Id.IsChildOf(rootWebContentType.Id));
                }
            }
        }
 /// <summary>
 /// Event Receiver Info (Content Type)
 /// </summary>
 /// <param name="contentType">The content type</param>
 /// <param name="type">The event receiver type</param>
 public EventReceiverInfo(ContentTypeInfo contentType, SPEventReceiverType type)
     : this(contentType, type, SPEventReceiverSynchronization.Default)
 {
 }
        public void EnsureFolderHierarchy_WhenInList_ShouldApplyFolderSpecificContentTypesChoicesInRibbonNewItemDropdown()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange

                // Create some content types, children of Item CT
                var contentTypeId1 = ContentTypeIdBuilder.CreateChild(SPBuiltInContentTypeId.Item, new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));
                var contentTypeId2 = ContentTypeIdBuilder.CreateChild(SPBuiltInContentTypeId.Item, new Guid("{A7BAA5B7-C57B-4928-9778-818D267505A1}"));

                var itemContentType1 = new ContentTypeInfo(contentTypeId1, "itemCT1NameKey", "ItemCT1DescrKey", "GroupKey");
                var itemContentType2 = new ContentTypeInfo(contentTypeId2, "ItemCT2NameKey", "ItemCT2DescrKey", "GroupKey");

                var rootFolderInfo = new FolderInfo("somepath")
                {
                    Subfolders = new List<FolderInfo>()
                    {
                        new FolderInfo("somelevel2path")
                        {
                            Subfolders = new List<FolderInfo>()
                            {
                                new FolderInfo("level3")
                                {
                                    UniqueContentTypeOrder = new List<ContentTypeInfo>() { itemContentType2 }
                                }
                            },
                            UniqueContentTypeOrder = new List<ContentTypeInfo>() { itemContentType1 }
                        },
                        new FolderInfo("somelevel2path alt")
                    },
                    UniqueContentTypeOrder = new List<ContentTypeInfo>()
                    {
                        // order: 2-1
                        itemContentType2,
                        itemContentType1
                    }
                };

                var listInfo = new ListInfo("somelistpath", "ListNameKey", "ListDescrKey")
                {
                    ContentTypes = new List<ContentTypeInfo>() { itemContentType1, itemContentType2 }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var folderHelper = injectionScope.Resolve<IFolderHelper>();
                    var listHelper = injectionScope.Resolve<IListHelper>();

                    // Make sure our CTs are available on list (this will add CTs to the root web and
                    // associate some child CTs to the list).
                    var ensuredList = listHelper.EnsureList(testScope.SiteCollection.RootWeb, listInfo);

                    // Act
                    folderHelper.EnsureFolderHierarchy(ensuredList, rootFolderInfo);

                    // Assert

                    // root folder should have order 2-1
                    var rootFolder = ensuredList.RootFolder;
                    Assert.AreEqual(2, rootFolder.UniqueContentTypeOrder.Count);
                    Assert.IsTrue(itemContentType2.ContentTypeId.IsParentOf(rootFolder.UniqueContentTypeOrder[0].Id));
                    Assert.IsTrue(itemContentType1.ContentTypeId.IsParentOf(rootFolder.UniqueContentTypeOrder[1].Id));

                    // lvl2 folder should have page1CT only
                    var lvl2Folder = ensuredList.RootFolder.SubFolders.Cast<SPFolder>().Single(f => f.Name == "somelevel2path");
                    Assert.AreEqual(1, lvl2Folder.UniqueContentTypeOrder.Count);
                    Assert.IsTrue(itemContentType1.ContentTypeId.IsParentOf(lvl2Folder.UniqueContentTypeOrder[0].Id));

                    // lvl2Alt should inherit root folder
                    var lvl2Alt = ensuredList.RootFolder.SubFolders.Cast<SPFolder>().Single(f => f.Name == "somelevel2path alt");
                    Assert.IsNull(lvl2Alt.UniqueContentTypeOrder);

                    // lvl3 should have page2CT only
                    var lvl3Folder = lvl2Folder.SubFolders.Cast<SPFolder>().Single(f => f.Name == "level3");
                    Assert.AreEqual(1, lvl3Folder.UniqueContentTypeOrder.Count);
                    Assert.IsTrue(itemContentType2.ContentTypeId.IsParentOf(lvl3Folder.UniqueContentTypeOrder[0].Id));
                }
            }
        }
Exemple #8
0
        private static SPContentType GetListContentType(SPList list, ContentTypeInfo contentTypeInfo)
        {
            var contentTypeId = contentTypeInfo.ContentTypeId;

            // If content type is direct child of item, remove it
            var bestMatchItem = list.ContentTypes.BestMatch(contentTypeId);
            if (bestMatchItem.Parent == contentTypeId)
            {
                return list.ContentTypes[bestMatchItem];
            }

            return null;
        }
        private void SetTitleDescriptionAndGroupValues(ContentTypeInfo contentTypeInfo, SPContentType contentType)
        {
            //// Get a list of the available languages and end with the main language
            var web = contentType.ParentWeb;
            var availableLanguages = web.SupportedUICultures.Reverse().ToList();

            // If it's a publishing web, add the variation labels as available languages
            if (PublishingWeb.IsPublishingWeb(web) && this.variationHelper.IsVariationsEnabled(web.Site))
            {
                var labels = this.variationHelper.GetVariationLabels(web.Site);
                if (labels.Count > 0)
                {
                    // Predicate to check if the web contains the label language in it's available languages
                    Func<VariationLabel, bool> notAvailableWebLanguageFunc = (label) =>
                        !availableLanguages.Any(lang => lang.Name.Equals(label.Language, StringComparison.OrdinalIgnoreCase));

                    // Get the label languages that aren't already in the web's available languages
                    var labelLanguages = labels
                        .Where(notAvailableWebLanguageFunc)
                        .Select(label => new CultureInfo(label.Language));

                    availableLanguages.AddRange(labelLanguages);
                }
            }

            // If multiple languages are enabled, since we have a full ContentTypeInfo object, we want to populate 
            // all alternate language labels for the Content Type
            foreach (CultureInfo availableLanguage in availableLanguages)
            {
                var previousUiCulture = Thread.CurrentThread.CurrentUICulture;
                Thread.CurrentThread.CurrentUICulture = availableLanguage;

                contentType.Name = this.resourceLocator.GetResourceString(contentTypeInfo.ResourceFileName, contentTypeInfo.DisplayNameResourceKey);

                contentType.Description = this.resourceLocator.GetResourceString(contentTypeInfo.ResourceFileName, contentTypeInfo.DescriptionResourceKey);
                contentType.Description = this.resourceLocator.Find(contentTypeInfo.ResourceFileName, contentTypeInfo.DescriptionResourceKey, availableLanguage.LCID);

                contentType.Group = this.resourceLocator.GetResourceString(contentTypeInfo.ResourceFileName, contentTypeInfo.GroupResourceKey);

                Thread.CurrentThread.CurrentUICulture = previousUiCulture;
            }

            contentType.Update();
        }
Exemple #10
0
        private SPContentType InnerEnsureContentType(SPContentTypeCollection contentTypeCollection, ContentTypeInfo contentTypeInfo)
        {
            if (contentTypeCollection == null)
            {
                throw new ArgumentNullException("contentTypeCollection");
            }

            SPContentTypeId contentTypeId = contentTypeInfo.ContentTypeId;
            SPList          list          = null;

            var contentTypeResourceTitle = this.resourceLocator.GetResourceString(contentTypeInfo.ResourceFileName, contentTypeInfo.DisplayNameResourceKey);

            if (TryGetListFromContentTypeCollection(contentTypeCollection, out list))
            {
                // Make sure its not already in the list.
                var contentTypeInList = list.ContentTypes.Cast <SPContentType>().FirstOrDefault(ct => ct.Id == contentTypeId || ct.Parent.Id == contentTypeId);
                if (contentTypeInList == null)
                {
                    // Can we add the content type to the list?
                    if (list.IsContentTypeAllowed(contentTypeId))
                    {
                        // Enable content types if not yet done.
                        if (!list.ContentTypesEnabled)
                        {
                            list.ContentTypesEnabled = true;
                            list.Update(true);
                        }

                        // Try to use the list's web's content type if it already exists
                        var contentTypeInWeb = list.ParentWeb.Site.RootWeb.AvailableContentTypes[contentTypeId];

                        if (contentTypeInWeb == null)
                        {
                            // By convention, content types should always exist on root web as site-collection-wide
                            // content types before they get linked on a specific list.
                            var rootWebContentTypeCollection = list.ParentWeb.Site.RootWeb.ContentTypes;
                            contentTypeInWeb = this.EnsureContentType(rootWebContentTypeCollection, contentTypeInfo);

                            this.log.Warn(
                                "EnsureContentType - Forced the creation of Content Type (name={0} ctid={1}) on the root web (url=) instead of adding the CT directly on the list (id={2} title={3}). By convention, all CTs should be provisonned on RootWeb before being re-used in lists.",
                                contentTypeInWeb.Name,
                                contentTypeInWeb.Id.ToString(),
                                list.ID,
                                list.Title);
                        }

                        // Add the web content type to the collection.
                        return(list.ContentTypes.Add(contentTypeInWeb));
                    }
                }
                else
                {
                    this.InnerEnsureFieldInContentType(contentTypeInList, contentTypeInfo.Fields);

                    return(contentTypeInList);
                }
            }
            else
            {
                SPWeb web = null;
                if (TryGetWebFromContentTypeCollection(contentTypeCollection, out web))
                {
                    // Make sure its not already in ther web.
                    var contentTypeInWeb = web.ContentTypes[contentTypeId];
                    if (contentTypeInWeb == null)
                    {
                        SPContentTypeCollection rootWebContentTypeCollection = null;

                        if (web.ID == web.Site.RootWeb.ID)
                        {
                            rootWebContentTypeCollection = contentTypeCollection;
                        }
                        else
                        {
                            rootWebContentTypeCollection = web.Site.RootWeb.ContentTypes;

                            this.log.Warn(
                                "EnsureContentType - Will force creation of content type (id={0} name={1}) on root web instead of on specified sub-web. This is to enforce the following convention: all CTs should be provisioned at root of site collection, to ease maintenance. Ensure your content types on the root web's SPContentTypeCollection to avoid this warning.",
                                contentTypeId.ToString(),
                                contentTypeInfo.DisplayNameResourceKey);
                        }

                        var contentTypeInRootWeb = rootWebContentTypeCollection[contentTypeId];

                        if (contentTypeInRootWeb == null)
                        {
                            // Add the content type to the Root Web collection. By convention, we avoid provisioning
                            // CTs directly on sub-webs to make CT management easier (i.e. all of your site collection's
                            // content types should be configured at the root of the site collection).
                            var newWebContentType = new SPContentType(contentTypeId, rootWebContentTypeCollection, contentTypeResourceTitle);
                            contentTypeInRootWeb = rootWebContentTypeCollection.Add(newWebContentType);
                        }

                        this.InnerEnsureFieldInContentType(contentTypeInRootWeb, contentTypeInfo.Fields);

                        return(contentTypeInRootWeb);
                    }
                    else
                    {
                        this.InnerEnsureFieldInContentType(contentTypeInWeb, contentTypeInfo.Fields);
                        return(contentTypeInWeb);
                    }
                }

                // Case if there is no Content Types in the Web (e.g single SPWeb)
                var returnedContentType = this.EnsureContentType(contentTypeCollection, contentTypeInfo);
                return(returnedContentType);
            }

            return(null);
        }
Exemple #11
0
        public void EnsureField_WhenContentTypeFieldCollection_ShouldThrowArgumentException()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                var fieldId = new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}");
                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    fieldId,
                    "NameKey",
                    "DescriptionKey",
                    "GroupKey")
                {
                    MaxLength = 50,
                    Required = RequiredType.Required
                };

                var contentTypeInfo = new ContentTypeInfo(SPBuiltInContentTypeId.BasicPage.ToString() + "01", "CTNameKey", "CTDescrKey", "GroupKey");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    IContentTypeHelper contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    SPContentType ensuredContentType = contentTypeHelper.EnsureContentType(testScope.SiteCollection.RootWeb.ContentTypes, contentTypeInfo);

                    IFieldHelper fieldHelper = injectionScope.Resolve<IFieldHelper>();
                    var fieldsCollection = ensuredContentType.Fields;

                    SPField field = fieldHelper.EnsureField(fieldsCollection, textFieldInfo);
                }
            }
        }
        public void EnsureContentType_WhenUpdatingRootWebCT_AndFieldsNotAlreadyExists_ShouldProvisionFieldsAsSiteColumn()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var fieldId = new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}");
                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    fieldId,
                    "Test_FieldTitle",
                    "Test_FieldDescription",
                    "Test_ContentGroup")
                {
                    MaxLength = 50,
                    Required = RequiredType.Required
                };

                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Provision the CT a first time, without the field
                    var actualContentType = contentTypeHelper.EnsureContentType(testScope.SiteCollection.RootWeb.ContentTypes, contentTypeInfo);

                    // Change the CTInfo to add field
                    contentTypeInfo.Fields = new List<BaseFieldInfo>() { textFieldInfo };

                    // Act
                    var ensuredContentType = contentTypeHelper.EnsureContentType(testScope.SiteCollection.RootWeb.ContentTypes, contentTypeInfo);

                    // Assert
                    var contentTypeRefetched = testScope.SiteCollection.RootWeb.ContentTypes["NameKey"];

                    // Field should be on ensured CT
                    Assert.IsNotNull(ensuredContentType.Fields[fieldId]);
                    Assert.IsNotNull(contentTypeRefetched.Fields[fieldId]);

                    // Field should be a site column now also
                    Assert.IsNotNull(testScope.SiteCollection.RootWeb.Fields[fieldId]);
                }
            }
        }
        public void EnsureContentType_WhenCreatingSubWebListCT_ShouldProvisionContentTypeOnRootWebAndFieldsAsSiteColumn()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var fieldId = new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}");
                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    fieldId,
                    "Test_FieldTitle",
                    "Test_FieldDescription",
                    "Test_ContentGroup")
                {
                    MaxLength = 50,
                    Required = RequiredType.Required
                };

                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey")
                {
                    Fields = new List<BaseFieldInfo>()
                    {
                        textFieldInfo
                    }
                };

                ListInfo listInfo = new ListInfo("sometestlistpath", "DynamiteTestListNameKey", "DynamiteTestListDescriptionKey");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var subWeb = testScope.SiteCollection.RootWeb.Webs.Add("subweb");

                    var listHelper = injectionScope.Resolve<IListHelper>();
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Start by provisioning a list without CT
                    var ensuredList = listHelper.EnsureList(subWeb, listInfo);

                    // Act
                    var ensuredListContentType = contentTypeHelper.EnsureContentType(ensuredList.ContentTypes, contentTypeInfo);

                    // Assert
                    var contentTypeWebRefetched = testScope.SiteCollection.RootWeb.ContentTypes["NameKey"];
                    var contentTypeListRefetched = testScope.SiteCollection.RootWeb.Webs["subweb"].Lists[ensuredList.ID].ContentTypes["NameKey"];

                    // CT should be on RootWeb
                    Assert.IsNotNull(contentTypeWebRefetched);

                    // CT should be on List
                    Assert.IsNotNull(ensuredList.ContentTypes["NameKey"]);
                    Assert.IsNotNull(contentTypeWebRefetched);

                    // Field should be on ensured CTs (web + list)
                    Assert.IsNotNull(ensuredListContentType.Fields[fieldId]);
                    Assert.IsNotNull(contentTypeListRefetched.Fields[fieldId]);
                    Assert.IsNotNull(contentTypeWebRefetched.Fields[fieldId]);

                    // Field should be a site column now also
                    Assert.IsNotNull(testScope.SiteCollection.RootWeb.Fields[fieldId]);
                }
            }
        }
        public void EnsureContentType_WhenNotRedefiningParentFields_ShouldRespectParentFieldOrdering()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var reorderedFieldId = new Guid("{5FDCC376-228A-4F2F-B66D-A4CABE7DF538}");

                var contentTypeId = ContentTypeIdBuilder.CreateChild(
                    SPBuiltInContentTypeId.Announcement,
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(
                    contentTypeId,
                    "ChildAnnouncement",
                    "ChildAnnouncementDescription",
                    "ChildAnnouncementGroup")
                {
                    Fields = new[]
                        {
                            new TextFieldInfo(
                                "ShouldBeLast", 
                                reorderedFieldId, 
                                "ShouldBeLastName", 
                                "ShouldBeLastDesc", 
                                "ShouldBeLastGroup"), 
                        }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var contentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;

                    // Act
                    var actualContentType = contentTypeHelper.EnsureContentType(contentTypeCollection, contentTypeInfo);
                    var actualRefetchedContentType = testScope.SiteCollection.RootWeb.ContentTypes[contentTypeId];

                    // Assert
                    // Note: Hidden content type field is always the first field
                    Assert.AreEqual(BuiltInFields.Title.Id, actualContentType.Fields[1].Id);
                    Assert.AreEqual(BuiltInFields.Body.Id, actualContentType.Fields[2].Id);
                    Assert.AreEqual(BuiltInFields.Expires.Id, actualContentType.Fields[3].Id);
                    Assert.AreEqual(reorderedFieldId, actualContentType.Fields[4].Id);

                    Assert.AreEqual(BuiltInFields.Title.Id, actualRefetchedContentType.Fields[1].Id);
                    Assert.AreEqual(BuiltInFields.Body.Id, actualRefetchedContentType.Fields[2].Id);
                    Assert.AreEqual(BuiltInFields.Expires.Id, actualRefetchedContentType.Fields[3].Id);
                    Assert.AreEqual(reorderedFieldId, actualRefetchedContentType.Fields[4].Id);
                }
            }
        }
        public void EnsureContentType_WhenNotModifyingFieldRequiredProperty_ShouldNotUpdateContentTypeFieldLink()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                // Note: the body field is already "not required"
                var notRequiredBodyField = BuiltInFields.Body;
                notRequiredBodyField.Required = RequiredType.NotRequired;

                var contentTypeId = ContentTypeIdBuilder.CreateChild(
                    SPBuiltInContentTypeId.Announcement,
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(
                    contentTypeId,
                    "ChildAnnouncement",
                    "ChildAnnouncementDescription",
                    "ChildAnnouncementGroup")
                {
                    Fields = new[]
                        {
                            BuiltInFields.Title,
                            BuiltInFields.Expires,
                            notRequiredBodyField
                        }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var contentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;

                    // Act
                    var actualContentType = contentTypeHelper.EnsureContentType(contentTypeCollection, contentTypeInfo);
                    var actualRefetchedContentType = testScope.SiteCollection.RootWeb.ContentTypes[contentTypeId];

                    // Assert
                    Assert.IsFalse(actualContentType.FieldLinks[BuiltInFields.Body.Id].Required);
                    Assert.IsFalse(actualRefetchedContentType.FieldLinks[BuiltInFields.Body.Id].Required);
                }
            }
        }
        public void EnsureContentType_WhenEnsuringAMinimalFieldInfoOOTBColumnAsFieldOnContentType_AndOOTBSiteColumnIsNOTAvailable_ShouldFailBecauseSuchOOTBSiteColumnShouldBeAddedByOOTBFeatures()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                ContentTypeInfo contentTypeInfo = new ContentTypeInfo(
                    ContentTypeIdBuilder.CreateChild(new SPContentTypeId("0x01"), Guid.NewGuid()),
                    "CTNameKey",
                    "CTDescrKey",
                    "GroupKey")
                {
                    Fields = new List<BaseFieldInfo>()
                        {
                            PublishingFields.PublishingPageContent  // Should be missing from site columns (only available in Publishing sites)
                        }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    IContentTypeHelper contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var contentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;

                    // Act + Assert
                    SPContentType contentType = contentTypeHelper.EnsureContentType(contentTypeCollection, contentTypeInfo);
                }
            }
        }
        public void EnsureContentType_WhenEnsuringAMinimalFieldInfoOOTBColumnAsFieldOnContentType_AndOOTBSiteColumnIsAvailable_ShouldMakeFieldAvailableOnCT()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                ContentTypeInfo contentTypeInfo = new ContentTypeInfo(
                    ContentTypeIdBuilder.CreateChild(new SPContentTypeId("0x01"), Guid.NewGuid()),
                    "CTNameKey",
                    "CTDescrKey",
                    "GroupKey")
                    {
                        Fields = new List<BaseFieldInfo>()
                        {
                            BuiltInFields.AssignedTo,   // OOTB User field
                            BuiltInFields.Cellphone,    // OOTB Text field
                            BuiltInFields.EnterpriseKeywords    // OOTB Taxonomy Multi field
                        }
                    };

                ListInfo listInfo = new ListInfo("somelistpath", "ListNameKey", "ListDescrKey")
                    {
                        ContentTypes = new List<ContentTypeInfo>()
                        {
                            contentTypeInfo
                        }
                    };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    IContentTypeHelper contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var contentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;

                    // Act
                    SPContentType contentType = contentTypeHelper.EnsureContentType(contentTypeCollection, contentTypeInfo);

                    // Assert
                    Assert.IsNotNull(contentType.Fields[BuiltInFields.AssignedTo.Id]);
                    Assert.IsNotNull(contentType.Fields[BuiltInFields.Cellphone.Id]);
                    Assert.IsNotNull(contentType.Fields[BuiltInFields.EnterpriseKeywords.Id]);

                    // Use the CT's OOTB fields in a list and create an item just for kicks
                    IListHelper listHelper = injectionScope.Resolve<IListHelper>();
                    SPList list = listHelper.EnsureList(testScope.SiteCollection.RootWeb, listInfo);
                    SPListItem item = list.AddItem();
                    item.Update();

                    var ensuredUser1 = testScope.SiteCollection.RootWeb.EnsureUser(Environment.UserName);

                    IFieldValueWriter writer = injectionScope.Resolve<IFieldValueWriter>();
                    writer.WriteValuesToListItem(
                        item,
                        new List<FieldValueInfo>()
                        {
                            new FieldValueInfo(BuiltInFields.AssignedTo, new UserValue(ensuredUser1)),
                            new FieldValueInfo(BuiltInFields.Cellphone, "Test Cellphone Value"),
                            new FieldValueInfo(BuiltInFields.EnterpriseKeywords, new TaxonomyValueCollection())
                        });

                    item.Update();

                    Assert.IsNotNull(item[BuiltInFields.AssignedTo.Id]);
                    Assert.IsNotNull(item[BuiltInFields.Cellphone.Id]);
                    Assert.IsNotNull(item[BuiltInFields.EnterpriseKeywords.Id]);
                }
            }
        }
Exemple #18
0
        public void EnsureField_WhenFieldIsUpdatedOnRootSiteAndIsUsedInAListAndFieldInfoAreChangesPushedToListIsTrue_ShouldUpdateFieldOnList()
        {
            // Arrange
            // Configure a field
            var textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}"),
                    "NameKey",
                    "DescriptionKey",
                    "GroupKey")
            {
                Required = RequiredType.NotRequired,
                MaxLength = 50,
                AreChangesPushedToList = true
            };           

            // Configure a content type
            var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

            var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey")
            {
                Fields = new List<BaseFieldInfo>()
                {
                    textFieldInfo
                }
            };

            // Configure a list
            var listInfo = new ListInfo("Lists/SomeList", "nameKey", "descriptionKey")
            {
                ContentTypes = new List<ContentTypeInfo>()
                {
                    contentTypeInfo
                }
            };

            using (var testScope = SiteTestScope.BlankSite())
            using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
            {
                // Act
                var rootWeb = testScope.SiteCollection.RootWeb;
                
                var fieldHelper = injectionScope.Resolve<IFieldHelper>();
                var listHelper = injectionScope.Resolve<IListHelper>();
                var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                // Create content type if initial field
                var contentType = contentTypeHelper.EnsureContentType(rootWeb.ContentTypes, contentTypeInfo);

                // Create list with the above content type
                var list = listHelper.EnsureList(rootWeb, listInfo);

                // Update the field definition
                var updatedTextFieldInfo = textFieldInfo;
                updatedTextFieldInfo.MaxLength = 200;

                // Update the field in the root site
                var updatedField = fieldHelper.EnsureField(rootWeb.Fields, updatedTextFieldInfo) as SPFieldText;

                // Get Field from list
                var updatedListField = list.Fields.Cast<SPField>().Single(f => f.InternalName.Equals(textFieldInfo.InternalName, StringComparison.InvariantCultureIgnoreCase)) as SPFieldText;
                
                // Assert
                Assert.AreEqual(updatedTextFieldInfo.MaxLength, updatedField.MaxLength);
                Assert.AreEqual(updatedTextFieldInfo.MaxLength, updatedListField.MaxLength);
            }            
        }
Exemple #19
0
        public void EnsureList_WhenSpecifyingBothContentTypesAndFieldDefinitions_AndSiteColumnAndContenTypeAlreadyThere_ShouldProvisionListContentType_ThenOverrideFieldDefinitionOnTheList()
        {
            // Arrange
            const string Url = "testUrl";

            var testFieldInfoRequired = new TextFieldInfo("TestFieldInfoText", new Guid("{3AB6C2FB-DA24-4C67-A4CC-7FA4CE07A03F}"), "NameKey", "DescriptionKey", "GroupKey")
            {
                Required = RequiredType.Required
            };

            var sameTestFieldInfoButNotRequired = new TextFieldInfo("TestFieldInfoText", new Guid("{3AB6C2FB-DA24-4C67-A4CC-7FA4CE07A03F}"), "NameKeyAlt", "DescriptionKey", "GroupKey")
            {
                Required = RequiredType.NotRequired
            };

            var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

            var contentTypeInfo = new ContentTypeInfo(contentTypeId, "ContentTypeNameKey", "ContentTypeDescKey", "GroupKey")
            {
                Fields = new List<BaseFieldInfo>()
                    {
                        testFieldInfoRequired
                    }
            };

            var listInfo = new ListInfo(Url, "NameKey", "DescriptionKey")
            {
                ContentTypes = new List<ContentTypeInfo>()
                    {
                        contentTypeInfo     // this includes testFieldInfoRequired 
                    },
                FieldDefinitions = new List<BaseFieldInfo>()
                    {
                        sameTestFieldInfoButNotRequired     // this is the list-specific field definition override
                    }
            };

            using (var testScope = SiteTestScope.BlankSite())
            {
                var rootWeb = testScope.SiteCollection.RootWeb;

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var listHelper = injectionScope.Resolve<IListHelper>();
                    var fieldHelper = injectionScope.Resolve<IFieldHelper>();
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Provision the site column and site content type first
                    var siteColumn = fieldHelper.EnsureField(rootWeb.Fields, testFieldInfoRequired);
                    var siteContentType = contentTypeHelper.EnsureContentType(rootWeb.ContentTypes, contentTypeInfo);

                    // Act: Provision the list with an alternate field definition (NotRequired)
                    var list = listHelper.EnsureList(rootWeb, listInfo);
                    var listRefetched = rootWeb.Lists[list.ID];

                    // Assert

                    // Site column should've been added to root web
                    var siteColumnRefetched = rootWeb.Fields[testFieldInfoRequired.Id];
                    Assert.IsNotNull(siteColumnRefetched);
                    Assert.IsTrue(siteColumnRefetched.Required);
                    Assert.AreEqual("NameKey", siteColumnRefetched.Title);

                    // Content type should've been added to root web
                    var siteContentTypeRefetched = rootWeb.ContentTypes[new SPContentTypeId(contentTypeId)];
                    Assert.IsNotNull(siteContentTypeRefetched);
                    Assert.IsNotNull(siteContentTypeRefetched.Fields[testFieldInfoRequired.Id]);

                    // Content type should've been added to new list
                    var listContentType = list.ContentTypes["ContentTypeNameKey"];
                    Assert.IsNotNull(listContentType);
                    Assert.IsNotNull(listContentType.Fields[testFieldInfoRequired.Id]);

                    var listContentTypeRefetched = rootWeb.Lists[list.ID].ContentTypes["ContentTypeNameKey"];
                    Assert.IsNotNull(listContentTypeRefetched);
                    Assert.IsNotNull(listContentTypeRefetched.Fields[testFieldInfoRequired.Id]);

                    // New list should hold a NotRequired variant of the site column
                    var listColumn = list.Fields[sameTestFieldInfoButNotRequired.Id];
                    Assert.IsFalse(listColumn.Required);
                    Assert.AreEqual("NameKeyAlt", listColumn.Title);

                    var listColumnRefetched = rootWeb.Lists[list.ID].Fields[sameTestFieldInfoButNotRequired.Id];
                    Assert.IsFalse(listColumnRefetched.Required);    // definition should've been overriden for the list only
                    Assert.AreEqual("NameKeyAlt", listColumnRefetched.Title);
                }
            }
        }
        public void EnsureContentType_WhenOnSubWebList_AndRootWebCTAlreadyExists_ShouldProvisionChildContentTypeOnList()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var fieldId = new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}");
                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    fieldId,
                    "Test_FieldTitle",
                    "Test_FieldDescription",
                    "Test_ContentGroup")
                {
                    MaxLength = 50,
                    Required = RequiredType.Required
                };

                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey")
                {
                    Fields = new List<BaseFieldInfo>()
                    {
                        textFieldInfo
                    }
                };

                ListInfo listInfo = new ListInfo("sometestlistpath", "DynamiteTestListNameKey", "DynamiteTestListDescriptionKey");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var rootWeb = testScope.SiteCollection.RootWeb;
                    var subWeb = rootWeb.Webs.Add("subweb");

                    var listHelper = injectionScope.Resolve<IListHelper>();
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Start by provisioning a list without CT
                    var ensuredSubWebList = listHelper.EnsureList(subWeb, listInfo);

                    // Also provision the existing CT on the root web
                    var ensuredRootWebCT = contentTypeHelper.EnsureContentType(rootWeb.ContentTypes, contentTypeInfo);

                    // Act
                    var ensuredListContentType = contentTypeHelper.EnsureContentType(ensuredSubWebList.ContentTypes, contentTypeInfo);

                    // Assert
                    Assert.IsTrue(ensuredListContentType.Id.IsChildOf(ensuredRootWebCT.Id));
                }
            }
        }
Exemple #21
0
        public void EnsureList_WhenUpdateingContentTypesOnList_ShouldUpdateUniqueContentTypeOrderToFollowInputOrder()
        {
            // Arrange
            const string Url = "testUrl";

            var testFieldInfo = new TextFieldInfo("TestFieldInfoText", new Guid("{3AB6C2FB-DA24-4C67-A4CC-7FA4CE07A03F}"), "NameKey", "DescriptionKey", "GroupKey")
            {
                Required = RequiredType.Required
            };

            var contentTypeId1 = ContentTypeIdBuilder.CreateChild(SPBuiltInContentTypeId.Item, new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));
            var contentTypeId2 = ContentTypeIdBuilder.CreateChild(SPBuiltInContentTypeId.Item, new Guid("{A7BAA5B7-C57B-4928-9778-818D267505A1}"));

            var contentTypeInfo1 = new ContentTypeInfo(contentTypeId1, "ContentTypeNameKey1", "ContentTypeDescKey1", "GroupKey")
            {
                Fields = new List<BaseFieldInfo>()
                    {
                        testFieldInfo
                    }
            };

            var contentTypeInfo2 = new ContentTypeInfo(contentTypeId2, "ContentTypeNameKey2", "ContentTypeDescKey2", "GroupKey")
            {
                Fields = new List<BaseFieldInfo>()
                    {
                        testFieldInfo
                    }
            };

            var listInfo = new ListInfo(Url, "NameKey", "DescriptionKey")
            {
                ContentTypes = new List<ContentTypeInfo>()
                    {
                        contentTypeInfo1,
                        contentTypeInfo2
                    }
            };

            using (var testScope = SiteTestScope.BlankSite())
            {
                var rootWeb = testScope.SiteCollection.RootWeb;

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var listHelper = injectionScope.Resolve<IListHelper>();
                    
                    // Ensure a first time with ordering #1 > #2
                    var list = listHelper.EnsureList(rootWeb, listInfo);

                    // Change the ordering
                    listInfo.ContentTypes = new List<ContentTypeInfo>()
                        {
                            contentTypeInfo2,
                            contentTypeInfo1
                        };

                    // Act: Re-provision to update the ordering
                    list = listHelper.EnsureList(rootWeb, listInfo);
                    var listRefetched = rootWeb.Lists[list.ID];

                    // Assert
                    var listUniqueContentTypeOrder = list.RootFolder.UniqueContentTypeOrder;
                    Assert.IsTrue(listUniqueContentTypeOrder[0].Id.IsChildOf(contentTypeInfo2.ContentTypeId));
                    Assert.IsTrue(listUniqueContentTypeOrder[1].Id.IsChildOf(contentTypeInfo1.ContentTypeId));

                    var listUniqueContentTypeOrderRefetched = listRefetched.RootFolder.UniqueContentTypeOrder;
                    Assert.IsTrue(listUniqueContentTypeOrderRefetched[0].Id.IsChildOf(contentTypeInfo2.ContentTypeId));
                    Assert.IsTrue(listUniqueContentTypeOrderRefetched[1].Id.IsChildOf(contentTypeInfo1.ContentTypeId));
                }
            }
        }
        public void EnsureContentType_WhenOnSubWeb_AndRootWebCTAlreadyExists_ShouldUpdateAndReturnExistingRootWebCT()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var fieldId = new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}");
                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    fieldId,
                    "Test_FieldTitle",
                    "Test_FieldDescription",
                    "Test_ContentGroup")
                {
                    MaxLength = 50,
                    Required = RequiredType.Required
                };

                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var rootWeb = testScope.SiteCollection.RootWeb;
                    var subWeb = rootWeb.Webs.Add("subweb");

                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Also provision the existing CT on the root web
                    var ensuredRootWebCT = contentTypeHelper.EnsureContentType(rootWeb.ContentTypes, contentTypeInfo);

                    // Change CT definition a little bit
                    contentTypeInfo.DescriptionResourceKey = "DescriptionKeyAlt";
                    contentTypeInfo.Fields = new List<BaseFieldInfo>()
                    {
                        textFieldInfo
                    };

                    // Act
                    var ensuredSubWebContentType = contentTypeHelper.EnsureContentType(subWeb.ContentTypes, contentTypeInfo);

                    // Assert
                    Assert.AreEqual(ensuredRootWebCT.Id, ensuredSubWebContentType.Id);

                    var refetchedRootWebCT = rootWeb.ContentTypes["NameKey"];
                    Assert.IsNotNull(refetchedRootWebCT.Fields[textFieldInfo.Id]);
                    Assert.AreEqual("DescriptionKeyAlt", refetchedRootWebCT.Description);
                }
            }
        }
Exemple #23
0
        public SPContentType EnsureContentType(SPContentTypeCollection contentTypeCollection, ContentTypeInfo contentTypeInfo)
        {
            var contentType = this.InnerEnsureContentType(contentTypeCollection, contentTypeInfo);

            SPList list;

            if (!TryGetListFromContentTypeCollection(contentTypeCollection, out list))
            {
                // Set the content type title, description, and group information for each language.
                // Only do this when not on a web because the SPContentType Title property does not support resource values at this level.
                // The content type for a list is created at the root web level, then added to the list.
                this.SetTitleDescriptionAndGroupValues(contentTypeInfo, contentType);
            }

            return(contentType);
        }
        public void EnsureContentType_WhenOnSubWeb_AndRootWebCTDoesntAlreadyExists_ShouldProvisionRootWebCT()
        {
            using (var testScope = SiteTestScope.BlankSite())
            {
                // Arrange
                var fieldId = new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}");
                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalName",
                    fieldId,
                    "Test_FieldTitle",
                    "Test_FieldDescription",
                    "Test_ContentGroup")
                {
                    MaxLength = 50,
                    Required = RequiredType.Required
                };

                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "NameKey", "DescriptionKey", "GroupKey")
                {
                    Fields = new List<BaseFieldInfo>()
                    {
                        textFieldInfo
                    }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var rootWeb = testScope.SiteCollection.RootWeb;
                    var subWeb = rootWeb.Webs.Add("subweb");

                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Act
                    var ensuredSubWebContentType = contentTypeHelper.EnsureContentType(subWeb.ContentTypes, contentTypeInfo);

                    // Assert
                    var refetchedRootWebCT = rootWeb.ContentTypes["NameKey"];
                    Assert.IsNotNull(refetchedRootWebCT);

                    // CT shouldn't ever end up on sub-web exclusively (we wanna force the creation of RootWeb CT instead)
                    Assert.IsNull(subWeb.ContentTypes.Cast<SPContentType>().SingleOrDefault(ct => ct.Id == ensuredSubWebContentType.Id));
                }
            }
        }
        public void ToEntity_WhenMappingFromPagesLibraryItem_AndItemPropertiesAreFilledWithValues_ShouldMapEntityWithAllPageValues()
        {
            using (var testScope = SiteTestScope.PublishingSite())
            {
                // Arrange
                IntegerFieldInfo integerFieldInfo = new IntegerFieldInfo(
                    "TestInternalNameInteger",
                    new Guid("{12E262D0-C7C4-4671-A266-064CDBD3905A}"),
                    "NameKeyInt",
                    "DescriptionKeyInt",
                    "GroupKey");

                NumberFieldInfo numberFieldInfo = new NumberFieldInfo(
                    "TestInternalNameNumber",
                    new Guid("{5DD4EE0F-8498-4033-97D0-317A24988786}"),
                    "NameKeyNumber",
                    "DescriptionKeyNumber",
                    "GroupKey");

                CurrencyFieldInfo currencyFieldInfo = new CurrencyFieldInfo(
                    "TestInternalNameCurrency",
                    new Guid("{9E9963F6-1EE6-46FB-9599-783BBF4D6249}"),
                    "NameKeyCurrency",
                    "DescriptionKeyCurrency",
                    "GroupKey");

                BooleanFieldInfo boolFieldInfoBasic = new BooleanFieldInfo(
                    "TestInternalNameBool",
                    new Guid("{F556AB6B-9E51-43E2-99C9-4A4E551A4BEF}"),
                    "NameKeyBool",
                    "DescriptionKeyBool",
                    "GroupKey");

                BooleanFieldInfo boolFieldInfoDefaultTrue = new BooleanFieldInfo(
                    "TestInternalNameBoolTrue",
                    new Guid("{0D0289AD-C5FB-495B-96C6-48CC46737D08}"),
                    "NameKeyBoolTrue",
                    "DescriptionKeyBoolTrue",
                    "GroupKey")
                {
                    DefaultValue = true
                };

                BooleanFieldInfo boolFieldInfoDefaultFalse = new BooleanFieldInfo(
                    "TestInternalNameBoolFalse",
                    new Guid("{628181BD-9B0B-4B7E-934F-1CF1796EA4E4}"),
                    "NameKeyBoolFalse",
                    "DescriptionKeyBoolFalse",
                    "GroupKey")
                {
                    DefaultValue = false
                };

                DateTimeFieldInfo dateTimeFieldInfoFormula = new DateTimeFieldInfo(
                    "TestInternalNameDateFormula",
                    new Guid("{D23EAD73-9E18-46DB-A426-41B2D47F696C}"),
                    "NameKeyDateTimeFormula",
                    "DescriptionKeyDateTimeFormula",
                    "GroupKey")
                {
                    DefaultFormula = "=[Today]"
                };

                DateTimeFieldInfo dateTimeFieldInfoDefault = new DateTimeFieldInfo(
                    "TestInternalNameDateDefault",
                    new Guid("{016BF8D9-CEDC-4BF4-BA21-AC6A8F174AD5}"),
                    "NameKeyDateTimeDefault",
                    "DescriptionKeyDateTimeDefault",
                    "GroupKey");

                TextFieldInfo textFieldInfo = new TextFieldInfo(
                    "TestInternalNameText",
                    new Guid("{0C58B4A1-B360-47FE-84F7-4D8F58AE80F6}"),
                    "NameKey",
                    "DescriptionKey",
                    "GroupKey");

                NoteFieldInfo noteFieldInfo = new NoteFieldInfo(
                    "TestInternalNameNote",
                    new Guid("{E315BB24-19C3-4F2E-AABC-9DE5EFC3D5C2}"),
                    "NameKeyAlt",
                    "DescriptionKeyAlt",
                    "GroupKey");

                HtmlFieldInfo htmlFieldInfo = new HtmlFieldInfo(
                    "TestInternalNameHtml",
                    new Guid("{D16958E7-CF9A-4C38-A8BB-99FC03BFD913}"),
                    "NameKeyAlt",
                    "DescriptionKeyAlt",
                    "GroupKey");

                ImageFieldInfo imageFieldInfo = new ImageFieldInfo(
                    "TestInternalNameImage",
                    new Guid("{6C5B9E77-B621-43AA-BFBF-B333093EFCAE}"),
                    "NameKeyImage",
                    "DescriptionKeyImage",
                    "GroupKey");

                UrlFieldInfo urlFieldInfo = new UrlFieldInfo(
                    "TestInternalNameUrl",
                    new Guid("{208F904C-5A1C-4E22-9A79-70B294FABFDA}"),
                    "NameKeyUrl",
                    "DescriptionKeyUrl",
                    "GroupKey");

                UrlFieldInfo urlFieldInfoImage = new UrlFieldInfo(
                    "TestInternalNameUrlImg",
                    new Guid("{96D22CFF-5B40-4675-B632-28567792E11B}"),
                    "NameKeyUrlImg",
                    "DescriptionKeyUrlImg",
                    "GroupKey")
                {
                    Format = UrlFieldFormat.Image
                };

                LookupFieldInfo lookupFieldInfo = new LookupFieldInfo(
                    "TestInternalNameLookup",
                    new Guid("{62F8127C-4A8C-4217-8BD8-C6712753AFCE}"),
                    "NameKey",
                    "DescriptionKey",
                    "GroupKey");

                LookupFieldInfo lookupFieldInfoAlt = new LookupFieldInfo(
                    "TestInternalNameLookupAlt",
                    new Guid("{1F05DFFA-6396-4AEF-AD23-72217206D35E}"),
                    "NameKey",
                    "DescriptionKey",
                    "GroupKey")
                {
                    ShowField = "ID"
                };

                LookupMultiFieldInfo lookupMultiFieldInfo = new LookupMultiFieldInfo(
                    "TestInternalNameLookupM",
                    new Guid("{2C9D4C0E-21EB-4742-8C6C-4C30DCD08A05}"),
                    "NameKeyMulti",
                    "DescriptionKeyMulti",
                    "GroupKey");

                var ensuredUser1 = testScope.SiteCollection.RootWeb.EnsureUser(Environment.UserDomainName + "\\" + Environment.UserName);
                var ensuredUser2 = testScope.SiteCollection.RootWeb.EnsureUser("OFFICE\\maxime.boissonneault");

                UserFieldInfo userFieldInfo = new UserFieldInfo(
                    "TestInternalNameUser",
                    new Guid("{5B74DD50-0D2D-4D24-95AF-0C4B8AA3F68A}"),
                    "NameKeyUser",
                    "DescriptionKeyUser",
                    "GroupKey");

                UserMultiFieldInfo userMultiFieldInfo = new UserMultiFieldInfo(
                    "TestInternalNameUserMulti",
                    new Guid("{8C662588-D54E-4905-B232-856C2239B036}"),
                    "NameKeyUserMulti",
                    "DescriptionKeyUserMulti",
                    "GroupKey");

                MediaFieldInfo mediaFieldInfo = new MediaFieldInfo(
                    "TestInternalNameMedia",
                    new Guid("{A2F070FE-FE33-44FC-9FDF-D18E74ED4D67}"),
                    "NameKeyMedia",
                    "DescriptionKeyMEdia",
                    "GroupKey");

                var testTermSet = new TermSetInfo(Guid.NewGuid(), "Test Term Set"); // keep Ids random because, if this test fails midway, the term
                // set will not be cleaned up and upon next test run we will
                // run into a term set and term ID conflicts.
                var levelOneTermA = new TermInfo(Guid.NewGuid(), "Term A", testTermSet);
                var levelOneTermB = new TermInfo(Guid.NewGuid(), "Term B", testTermSet);
                var levelTwoTermAA = new TermInfo(Guid.NewGuid(), "Term A-A", testTermSet);
                var levelTwoTermAB = new TermInfo(Guid.NewGuid(), "Term A-B", testTermSet);

                TaxonomySession session = new TaxonomySession(testScope.SiteCollection);
                TermStore defaultSiteCollectionTermStore = session.DefaultSiteCollectionTermStore;
                Group defaultSiteCollectionGroup = defaultSiteCollectionTermStore.GetSiteCollectionGroup(testScope.SiteCollection);
                TermSet newTermSet = defaultSiteCollectionGroup.CreateTermSet(testTermSet.Label, testTermSet.Id);
                Term createdTermA = newTermSet.CreateTerm(levelOneTermA.Label, Language.English.Culture.LCID, levelOneTermA.Id);
                Term createdTermB = newTermSet.CreateTerm(levelOneTermB.Label, Language.English.Culture.LCID, levelOneTermB.Id);
                Term createdTermAA = createdTermA.CreateTerm(levelTwoTermAA.Label, Language.English.Culture.LCID, levelTwoTermAA.Id);
                Term createdTermAB = createdTermA.CreateTerm(levelTwoTermAB.Label, Language.English.Culture.LCID, levelTwoTermAB.Id);
                defaultSiteCollectionTermStore.CommitAll();

                TaxonomyFieldInfo taxoFieldInfo = new TaxonomyFieldInfo(
                    "TestInternalNameTaxo",
                    new Guid("{18CC105F-16C9-43E2-9933-37F98452C038}"),
                    "NameKey",
                    "DescriptionKey",
                    "GroupKey")
                {
                    TermStoreMapping = new TaxonomyContext(testTermSet)     // choices limited to all terms in test term set
                };

                TaxonomyMultiFieldInfo taxoMultiFieldInfo = new TaxonomyMultiFieldInfo(
                    "TestInternalNameTaxoMulti",
                    new Guid("{2F49D362-B014-41BB-9959-1000C9A7FFA0}"),
                    "NameKeyMulti",
                    "DescriptionKey",
                    "GroupKey")
                {
                    TermStoreMapping = new TaxonomyContext(levelOneTermA)   // choices limited to children of a specific term, instead of having full term set choices
                };

                var fieldsToEnsure = new List<BaseFieldInfo>()
                    {
                        integerFieldInfo,
                        numberFieldInfo,
                        currencyFieldInfo,
                        boolFieldInfoBasic,
                        boolFieldInfoDefaultTrue,
                        boolFieldInfoDefaultFalse,
                        dateTimeFieldInfoFormula,
                        dateTimeFieldInfoDefault,
                        textFieldInfo,
                        noteFieldInfo,
                        htmlFieldInfo,
                        imageFieldInfo,
                        urlFieldInfo,
                        urlFieldInfoImage,
                        lookupFieldInfo,
                        lookupFieldInfoAlt,
                        lookupMultiFieldInfo,
                        userFieldInfo,
                        userMultiFieldInfo,
                        mediaFieldInfo,
                        taxoFieldInfo,
                        taxoMultiFieldInfo
                    };

                ListInfo lookupListInfo = new ListInfo("sometestlistpathlookup", "DynamiteTestListNameKeyLookup", "DynamiteTestListDescriptionKeyLookup");

                ContentTypeInfo pageContentType = new ContentTypeInfo(
                    ContentTypeIdBuilder.CreateChild(ContentTypeId.ArticlePage, Guid.NewGuid()),
                    "PageCTNameKey",
                    "PageCTDescrKey",
                    "ContentGroupKey")
                    {
                        Fields = fieldsToEnsure
                    };

                // Note how we need to specify SPSite for injection context - ISharePointEntityBinder's implementation
                // is lifetime-scoped to InstancePerSite.
                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope(testScope.SiteCollection))
                {
                    var listHelper = injectionScope.Resolve<IListHelper>();
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var folderHelper = injectionScope.Resolve<IFolderHelper>();

                    // Lookup field ListId setup
                    SPList lookupList = listHelper.EnsureList(testScope.SiteCollection.RootWeb, lookupListInfo);
                    lookupFieldInfo.ListId = lookupList.ID;
                    lookupFieldInfoAlt.ListId = lookupList.ID;
                    lookupMultiFieldInfo.ListId = lookupList.ID;

                    // Create the looked-up items
                    var lookupItem1 = lookupList.Items.Add();
                    lookupItem1["Title"] = "Test Item 1";
                    lookupItem1.Update();

                    var lookupItem2 = lookupList.Items.Add();
                    lookupItem2["Title"] = "Test Item 2";
                    lookupItem2.Update();

                    // Get the Pages library and add our CT to it
                    SPList list = testScope.SiteCollection.RootWeb.GetPagesLibrary();
                    list.EnableVersioning = true;
                    list.Update();

                    SPContentType myEnsuredContentType = contentTypeHelper.EnsureContentType(list.ContentTypes, pageContentType);

                    // Create page at root of pages lib
                    var masterPageGallery = testScope.SiteCollection.RootWeb.GetCatalog(SPListTemplateType.MasterPageCatalog);
                    var item = masterPageGallery.Items.Cast<SPListItem>().First(i => i.Name == "ArticleLeft.aspx");
                    var serverRelativePageUrl = SPUtility.ConcatUrls(masterPageGallery.RootFolder.ServerRelativeUrl, "MyArticleLeftTest.aspx");
                    item.CopyTo(SPUtility.ConcatUrls(testScope.SiteCollection.Url, serverRelativePageUrl)); // assumes site collection doesn't have managed path (i.e. we're dealing with a host-name site coll.)

                    PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(testScope.SiteCollection.RootWeb);  
                    PageLayout pageLayout = publishingWeb.GetAvailablePageLayouts().First(pl => pl.Name == "MyArticleLeftTest.aspx");  
                    pageLayout.AssociatedContentType = myEnsuredContentType;

                    var myArticleLeftPageLayout = new PageLayoutInfo("MyArticleLeftTest.aspx", myEnsuredContentType.Id);
                    folderHelper.EnsureFolderHierarchy(
                        list,
                            new FolderInfo("Root")
                            {
                                Pages = new[]
                                {
                                new PageInfo("MyTestPage", myArticleLeftPageLayout)
                                {
                                    FieldValues = new[]
                                    {
                                        new FieldValueInfo(integerFieldInfo, 555),
                                        new FieldValueInfo(numberFieldInfo, 5.5),
                                        new FieldValueInfo(currencyFieldInfo, 500.95),
                                        new FieldValueInfo(boolFieldInfoBasic, true),
                                        new FieldValueInfo(boolFieldInfoDefaultTrue, false),
                                        new FieldValueInfo(boolFieldInfoDefaultFalse, true),
                                        new FieldValueInfo(dateTimeFieldInfoFormula, new DateTime(1977, 7, 7)),
                                        new FieldValueInfo(dateTimeFieldInfoDefault, new DateTime(1977, 7, 7)),
                                        new FieldValueInfo(textFieldInfo, "Text value"),
                                        new FieldValueInfo(noteFieldInfo, "Note value"),
                                        new FieldValueInfo(htmlFieldInfo, "<p class=\"some-css-class\">HTML value</p>"),
                                        new FieldValueInfo(
                                            imageFieldInfo, 
                                            new ImageValue()
                                            {
                                                Hyperlink = "http://github.com/GSoft-SharePoint/",
                                                ImageUrl = "/_layouts/15/MyFolder/MyImage.png"
                                            }),
                                        new FieldValueInfo(
                                            urlFieldInfo, 
                                            new UrlValue()
                                            {
                                                Url = "http://github.com/GSoft-SharePoint/",
                                                Description = "patate!"
                                            }),
                                        new FieldValueInfo(
                                            urlFieldInfoImage, 
                                            new UrlValue()
                                            {
                                                Url = "http://github.com/GSoft-SharePoint/",
                                                Description = "patate!"
                                            }),
                                        new FieldValueInfo(lookupFieldInfo, new LookupValue(1, "Test Item 1")),
                                        new FieldValueInfo(lookupFieldInfoAlt, new LookupValue(2, "2")),
                                        new FieldValueInfo(lookupMultiFieldInfo, new LookupValueCollection() { new LookupValue(1, "Test Item 1"), new LookupValue(2, "Test Item 2") }),
                                        new FieldValueInfo(userFieldInfo, new UserValue(ensuredUser1)),
                                        new FieldValueInfo(userMultiFieldInfo, new UserValueCollection(new[] { new UserValue(ensuredUser1), new UserValue(ensuredUser2) })),
                                        new FieldValueInfo(
                                            mediaFieldInfo, 
                                            new MediaValue()
                                            {
                                                Title = "Some media file title",
                                                Url = "/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf",
                                                IsAutoPlay = true,
                                                IsLoop = true,
                                                PreviewImageUrl = "/_layouts/15/Images/logo.png"
                                            }),
                                        new FieldValueInfo(taxoFieldInfo, new TaxonomyValue(createdTermB)),
                                        new FieldValueInfo(taxoMultiFieldInfo, new TaxonomyValueCollection(new[] { createdTermAA, createdTermAB }))
                                    }
                                }
                            }
                        });

                    var pages = publishingWeb.GetPublishingPages();
                    var testPage = pages.Single(p => p.Title == "MyTestPage");

                    var entityBinder = injectionScope.Resolve<ISharePointEntityBinder>();
                    var entityMappedFromSingleItem = new TestItemEntityWithLookups();
                    var entityMappedFromItemVersion = new TestItemEntityWithLookups();

                    // Act

                    // Map from SPListItem
                    entityBinder.ToEntity<TestItemEntityWithLookups>(entityMappedFromSingleItem, testPage.ListItem);

                    // Map from SPListItemVersion
                    entityBinder.ToEntity<TestItemEntityWithLookups>(entityMappedFromItemVersion, testPage.ListItem.Versions[0]);

                    // Map from DataRow/SPListItemCollection
                    var pagesLibrary = testScope.SiteCollection.RootWeb.GetPagesLibrary();
                    var caml = injectionScope.Resolve<ICamlBuilder>();
                    var items = pagesLibrary.GetItems(new SPQuery() { Query = caml.Where(caml.Equal(caml.FieldRef("Title"), caml.Value("MyTestPage"))) });
                    var entitiesMappedFromItemCollection = entityBinder.Get<TestItemEntity>(items);

                    // Assert
                    // #1 Validate straight single list item to entity mappings
                    Assert.AreEqual(555, entityMappedFromSingleItem.IntegerProperty);
                    Assert.AreEqual(5.5, entityMappedFromSingleItem.DoubleProperty);
                    Assert.AreEqual(500.95, entityMappedFromSingleItem.CurrencyProperty);
                    Assert.IsTrue(entityMappedFromSingleItem.BoolProperty.Value);
                    Assert.IsFalse(entityMappedFromSingleItem.BoolDefaultTrueProperty);
                    Assert.IsTrue(entityMappedFromSingleItem.BoolDefaultFalseProperty);
                    Assert.AreEqual(new DateTime(1977, 7, 7), entityMappedFromSingleItem.DateTimeFormulaProperty);
                    Assert.AreEqual(new DateTime(1977, 7, 7), entityMappedFromSingleItem.DateTimeProperty);
                    Assert.AreEqual("Text value", entityMappedFromSingleItem.TextProperty);
                    Assert.AreEqual("Note value", entityMappedFromSingleItem.NoteProperty);
                    Assert.AreEqual("<p class=\"some-css-class\">HTML value</p>", entityMappedFromSingleItem.HtmlProperty);

                    Assert.IsNotNull(entityMappedFromSingleItem.ImageProperty);
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entityMappedFromSingleItem.ImageProperty.Hyperlink);
                    Assert.AreEqual("/_layouts/15/MyFolder/MyImage.png", entityMappedFromSingleItem.ImageProperty.ImageUrl);

                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entityMappedFromSingleItem.UrlProperty.Url);
                    Assert.AreEqual("patate!", entityMappedFromSingleItem.UrlProperty.Description);

                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entityMappedFromSingleItem.UrlImageProperty.Url);
                    Assert.AreEqual("patate!", entityMappedFromSingleItem.UrlProperty.Description);

                    Assert.AreEqual(1, entityMappedFromSingleItem.LookupProperty.Id);
                    Assert.AreEqual("Test Item 1", entityMappedFromSingleItem.LookupProperty.Value);

                    Assert.AreEqual(2, entityMappedFromSingleItem.LookupAltProperty.Id);
                    Assert.AreEqual("2", entityMappedFromSingleItem.LookupAltProperty.Value); // ShowField/LookupField is ID

                    Assert.AreEqual(1, entityMappedFromSingleItem.LookupMultiProperty[0].Id);
                    Assert.AreEqual("Test Item 1", entityMappedFromSingleItem.LookupMultiProperty[0].Value);
                    Assert.AreEqual(2, entityMappedFromSingleItem.LookupMultiProperty[1].Id);
                    Assert.AreEqual("Test Item 2", entityMappedFromSingleItem.LookupMultiProperty[1].Value);

                    Assert.AreEqual(ensuredUser1.Name, entityMappedFromSingleItem.UserProperty.DisplayName);

                    Assert.AreEqual(ensuredUser1.Name, entityMappedFromSingleItem.UserMultiProperty[0].DisplayName);
                    Assert.AreEqual("Maxime Boissonneault", entityMappedFromSingleItem.UserMultiProperty[1].DisplayName);

                    Assert.AreEqual("Some media file title", entityMappedFromSingleItem.MediaProperty.Title);
                    Assert.AreEqual(HttpUtility.UrlDecode("/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf"), entityMappedFromSingleItem.MediaProperty.Url);
                    Assert.IsTrue(entityMappedFromSingleItem.MediaProperty.IsAutoPlay);
                    Assert.IsTrue(entityMappedFromSingleItem.MediaProperty.IsLoop);
                    Assert.AreEqual("/_layouts/15/Images/logo.png", entityMappedFromSingleItem.MediaProperty.PreviewImageUrl);

                    Assert.AreEqual(levelOneTermB.Id, entityMappedFromSingleItem.TaxonomyProperty.Id);
                    Assert.AreEqual(levelOneTermB.Label, entityMappedFromSingleItem.TaxonomyProperty.Label);

                    Assert.AreEqual(levelTwoTermAA.Id, entityMappedFromSingleItem.TaxonomyMultiProperty[0].Id);
                    Assert.AreEqual(levelTwoTermAA.Label, entityMappedFromSingleItem.TaxonomyMultiProperty[0].Label);
                    Assert.AreEqual(levelTwoTermAB.Id, entityMappedFromSingleItem.TaxonomyMultiProperty[1].Id);
                    Assert.AreEqual(levelTwoTermAB.Label, entityMappedFromSingleItem.TaxonomyMultiProperty[1].Label);

                    // #2 Validate list item version mappings
                    Assert.AreEqual(555, entityMappedFromItemVersion.IntegerProperty);
                    Assert.AreEqual(5.5, entityMappedFromItemVersion.DoubleProperty);
                    Assert.AreEqual(500.95, entityMappedFromItemVersion.CurrencyProperty);
                    Assert.IsTrue(entityMappedFromItemVersion.BoolProperty.Value);
                    Assert.IsFalse(entityMappedFromItemVersion.BoolDefaultTrueProperty);
                    Assert.IsTrue(entityMappedFromItemVersion.BoolDefaultFalseProperty);
                    Assert.AreEqual(new DateTime(1977, 7, 7), entityMappedFromItemVersion.DateTimeFormulaProperty);
                    Assert.AreEqual(new DateTime(1977, 7, 7), entityMappedFromItemVersion.DateTimeProperty);
                    Assert.AreEqual("Text value", entityMappedFromItemVersion.TextProperty);
                    Assert.AreEqual("Note value", entityMappedFromItemVersion.NoteProperty);
                    Assert.AreEqual("<p class=\"some-css-class\">HTML value</p>", entityMappedFromItemVersion.HtmlProperty);

                    Assert.IsNotNull(entityMappedFromItemVersion.ImageProperty);
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entityMappedFromItemVersion.ImageProperty.Hyperlink);
                    Assert.AreEqual("/_layouts/15/MyFolder/MyImage.png", entityMappedFromItemVersion.ImageProperty.ImageUrl);

                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entityMappedFromItemVersion.UrlProperty.Url);
                    Assert.AreEqual("patate!", entityMappedFromItemVersion.UrlProperty.Description);

                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entityMappedFromItemVersion.UrlImageProperty.Url);
                    Assert.AreEqual("patate!", entityMappedFromItemVersion.UrlProperty.Description);

                    Assert.AreEqual(1, entityMappedFromItemVersion.LookupProperty.Id);
                    Assert.AreEqual("Test Item 1", entityMappedFromItemVersion.LookupProperty.Value);

                    Assert.AreEqual(2, entityMappedFromItemVersion.LookupAltProperty.Id);
                    Assert.AreEqual("2", entityMappedFromItemVersion.LookupAltProperty.Value); // ShowField/LookupField is ID

                    Assert.AreEqual(1, entityMappedFromItemVersion.LookupMultiProperty[0].Id);
                    Assert.AreEqual("Test Item 1", entityMappedFromItemVersion.LookupMultiProperty[0].Value);
                    Assert.AreEqual(2, entityMappedFromItemVersion.LookupMultiProperty[1].Id);
                    Assert.AreEqual("Test Item 2", entityMappedFromItemVersion.LookupMultiProperty[1].Value);

                    Assert.AreEqual(ensuredUser1.Name, entityMappedFromItemVersion.UserProperty.DisplayName);

                    Assert.AreEqual(ensuredUser1.Name, entityMappedFromItemVersion.UserMultiProperty[0].DisplayName);
                    Assert.AreEqual("Maxime Boissonneault", entityMappedFromItemVersion.UserMultiProperty[1].DisplayName);

                    Assert.AreEqual("Some media file title", entityMappedFromItemVersion.MediaProperty.Title);
                    Assert.AreEqual(HttpUtility.UrlDecode("/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf"), entityMappedFromItemVersion.MediaProperty.Url);
                    Assert.IsTrue(entityMappedFromItemVersion.MediaProperty.IsAutoPlay);
                    Assert.IsTrue(entityMappedFromItemVersion.MediaProperty.IsLoop);
                    Assert.AreEqual("/_layouts/15/Images/logo.png", entityMappedFromItemVersion.MediaProperty.PreviewImageUrl);

                    Assert.AreEqual(levelOneTermB.Id, entityMappedFromItemVersion.TaxonomyProperty.Id);
                    Assert.AreEqual(levelOneTermB.Label, entityMappedFromItemVersion.TaxonomyProperty.Label);

                    Assert.AreEqual(levelTwoTermAA.Id, entityMappedFromItemVersion.TaxonomyMultiProperty[0].Id);
                    Assert.AreEqual(levelTwoTermAA.Label, entityMappedFromItemVersion.TaxonomyMultiProperty[0].Label);
                    Assert.AreEqual(levelTwoTermAB.Id, entityMappedFromItemVersion.TaxonomyMultiProperty[1].Id);
                    Assert.AreEqual(levelTwoTermAB.Label, entityMappedFromItemVersion.TaxonomyMultiProperty[1].Label);

                    // #3 Validate straight list item collection to entity mappings
                    Assert.AreEqual(555, entitiesMappedFromItemCollection[0].IntegerProperty);
                    Assert.AreEqual(5.5, entitiesMappedFromItemCollection[0].DoubleProperty);
                    Assert.AreEqual(500.95, entitiesMappedFromItemCollection[0].CurrencyProperty);
                    Assert.IsTrue(entitiesMappedFromItemCollection[0].BoolProperty.Value);
                    Assert.IsFalse(entitiesMappedFromItemCollection[0].BoolDefaultTrueProperty);
                    Assert.IsTrue(entitiesMappedFromItemCollection[0].BoolDefaultFalseProperty);
                    Assert.AreEqual(new DateTime(1977, 7, 7), entitiesMappedFromItemCollection[0].DateTimeFormulaProperty);
                    Assert.AreEqual(new DateTime(1977, 7, 7), entitiesMappedFromItemCollection[0].DateTimeProperty);
                    Assert.AreEqual("Text value", entitiesMappedFromItemCollection[0].TextProperty);
                    Assert.AreEqual("Note value", entitiesMappedFromItemCollection[0].NoteProperty);
                    Assert.AreEqual("<p class=\"some-css-class\">HTML value</p>", entitiesMappedFromItemCollection[0].HtmlProperty);

                    Assert.IsNotNull(entitiesMappedFromItemCollection[0].ImageProperty);
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entitiesMappedFromItemCollection[0].ImageProperty.Hyperlink);
                    Assert.AreEqual("/_layouts/15/MyFolder/MyImage.png", entitiesMappedFromItemCollection[0].ImageProperty.ImageUrl);

                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entitiesMappedFromItemCollection[0].UrlProperty.Url);
                    Assert.AreEqual("patate!", entitiesMappedFromItemCollection[0].UrlProperty.Description);

                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", entitiesMappedFromItemCollection[0].UrlImageProperty.Url);
                    Assert.AreEqual("patate!", entitiesMappedFromItemCollection[0].UrlImageProperty.Description);

                    // No lookups or User fields because DataRow formatting screws up lookup values (we lose the lookup IDs)
                    Assert.AreEqual("Some media file title", entitiesMappedFromItemCollection[0].MediaProperty.Title);
                    Assert.AreEqual(HttpUtility.UrlDecode("/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf"), entitiesMappedFromItemCollection[0].MediaProperty.Url);
                    Assert.IsTrue(entitiesMappedFromItemCollection[0].MediaProperty.IsAutoPlay);
                    Assert.IsTrue(entitiesMappedFromItemCollection[0].MediaProperty.IsLoop);
                    Assert.AreEqual("/_layouts/15/Images/logo.png", entitiesMappedFromItemCollection[0].MediaProperty.PreviewImageUrl);

                    Assert.AreEqual(levelOneTermB.Id, entitiesMappedFromItemCollection[0].TaxonomyProperty.Id);
                    Assert.AreEqual(levelOneTermB.Label, entitiesMappedFromItemCollection[0].TaxonomyProperty.Label);

                    Assert.AreEqual(levelTwoTermAA.Id, entitiesMappedFromItemCollection[0].TaxonomyMultiProperty[0].Id);
                    Assert.AreEqual(levelTwoTermAA.Label, entitiesMappedFromItemCollection[0].TaxonomyMultiProperty[0].Label);
                    Assert.AreEqual(levelTwoTermAB.Id, entitiesMappedFromItemCollection[0].TaxonomyMultiProperty[1].Id);
                    Assert.AreEqual(levelTwoTermAB.Label, entitiesMappedFromItemCollection[0].TaxonomyMultiProperty[1].Label);
                }

                // Cleanup term set so that we don't pollute the metadata store
                newTermSet.Delete();
                defaultSiteCollectionTermStore.CommitAll();
            }
        }
        public void EnsureFolderHierarchy_WhenFolderDefaultValuesAreSpecifiedInPagesLibraryFolder_AndYouCreateAPage_ThenPageShouldHaveDefaultValue()
        {
            using (var testScope = SiteTestScope.PublishingSite())
            {
                // Arrange
                IntegerFieldInfo integerFieldInfo = new IntegerFieldInfo(
                    "TestInternalNameInteger",
                    new Guid("{12E262D0-C7C4-4671-A266-064CDBD3905A}"),
                    "NameKeyInt",
                    "DescriptionKeyInt",
                    "GroupKey");

                NumberFieldInfo numberFieldInfo = new NumberFieldInfo(
                    "TestInternalNameNumber",
                    new Guid("{5DD4EE0F-8498-4033-97D0-317A24988786}"),
                    "NameKeyNumber",
                    "DescriptionKeyNumber",
                    "GroupKey");

                CurrencyFieldInfo currencyFieldInfo = new CurrencyFieldInfo(
                    "TestInternalNameCurrency",
                    new Guid("{9E9963F6-1EE6-46FB-9599-783BBF4D6249}"),
                    "NameKeyCurrency",
                    "DescriptionKeyCurrency",
                    "GroupKey")
                {
                    LocaleId = 3084 // fr-CA
                };

                DateTimeFieldInfo dateOnlyFieldInfo = new DateTimeFieldInfo(
                    "TestInternalNameDate",
                    new Guid("{D23EAD73-9E18-46DB-A426-41B2D47F696C}"),
                    "NameKeyDate",
                    "DescriptionKeyDate",
                    "GroupKey")
                {
                    // Important that there be no DefaultFormula and no DefaultValue, otherwise the
                    // folder default column value would be ignored.
                    // See related test above: EnsureFolderHierarchy_WhenDateTimeFieldDefaultAlreadyDefined_AndAttemptingToSetFolderDefaultDate_ShouldThrownNotSupportedException
                };

                DateTimeFieldInfo dateTimeFieldInfo = new DateTimeFieldInfo(
                  "TestInternalNameDateTime",
                  new Guid("{526F9055-7472-4CFA-A31D-E2B7BFB1FD7D}"),
                  "NameKeyDateTime",
                  "DescriptionKeyDateTime",
                  "GroupKey")
                {
                    // Important that there be no DefaultFormula and no DefaultValue, otherwise the
                    // folder default column value would be ignored.
                    // See related test above: EnsureFolderHierarchy_WhenDateTimeFieldDefaultAlreadyDefined_AndAttemptingToSetFolderDefaultDate_ShouldThrownNotSupportedException
                    Format = DateTimeFieldFormat.DateTime
                };

                UrlFieldInfo urlFieldInfo = new UrlFieldInfo(
                    "TestInternalNameUrl",
                    new Guid("{208F904C-5A1C-4E22-9A79-70B294FABFDA}"),
                    "NameKeyUrl",
                    "DescriptionKeyUrl",
                    "GroupKey")
                {
                };

                UrlFieldInfo urlFieldInfoImage = new UrlFieldInfo(
                    "TestInternalNameUrlImg",
                    new Guid("{96D22CFF-5B40-4675-B632-28567792E11B}"),
                    "NameKeyUrlImg",
                    "DescriptionKeyUrlImg",
                    "GroupKey")
                {
                    Format = UrlFieldFormat.Image
                };

                MediaFieldInfo mediaFieldInfo = new MediaFieldInfo(
                    "TestInternalNameMedia",
                    new Guid("{A2F070FE-FE33-44FC-9FDF-D18E74ED4D67}"),
                    "NameKeyMedia",
                    "DescriptionKeyMEdia",
                    "GroupKey");

                var testTermSet = new TermSetInfo(Guid.NewGuid(), "Test Term Set"); // keep Ids random because, if this test fails midway, the term
                // set will not be cleaned up and upon next test run we will
                // run into a term set and term ID conflicts.
                var levelOneTermA = new TermInfo(Guid.NewGuid(), "Term A", testTermSet);
                var levelOneTermB = new TermInfo(Guid.NewGuid(), "Term B", testTermSet);
                var levelTwoTermAA = new TermInfo(Guid.NewGuid(), "Term A-A", testTermSet);
                var levelTwoTermAB = new TermInfo(Guid.NewGuid(), "Term A-B", testTermSet);

                TaxonomySession session = new TaxonomySession(testScope.SiteCollection);
                TermStore defaultSiteCollectionTermStore = session.DefaultSiteCollectionTermStore;
                Group defaultSiteCollectionGroup = defaultSiteCollectionTermStore.GetSiteCollectionGroup(testScope.SiteCollection);
                TermSet newTermSet = defaultSiteCollectionGroup.CreateTermSet(testTermSet.Label, testTermSet.Id);
                Term createdTermA = newTermSet.CreateTerm(levelOneTermA.Label, Language.English.Culture.LCID, levelOneTermA.Id);
                Term createdTermB = newTermSet.CreateTerm(levelOneTermB.Label, Language.English.Culture.LCID, levelOneTermB.Id);
                Term createdTermAA = createdTermA.CreateTerm(levelTwoTermAA.Label, Language.English.Culture.LCID, levelTwoTermAA.Id);
                Term createdTermAB = createdTermA.CreateTerm(levelTwoTermAB.Label, Language.English.Culture.LCID, levelTwoTermAB.Id);
                defaultSiteCollectionTermStore.CommitAll();

                TaxonomyFieldInfo taxoFieldInfo = new TaxonomyFieldInfo(
                    "TestInternalNameTaxo",
                    new Guid("{18CC105F-16C9-43E2-9933-37F98452C038}"),
                    "NameKeyTaxo",
                    "DescriptionKey",
                    "GroupKey")
                {
                    TermStoreMapping = new TaxonomyContext(testTermSet)     // choices limited to all terms in test term set
                };

                TaxonomyMultiFieldInfo taxoMultiFieldInfo = new TaxonomyMultiFieldInfo(
                    "TestInternalNameTaxoMulti",
                    new Guid("{2F49D362-B014-41BB-9959-1000C9A7FFA0}"),
                    "NameKeyTaxoMulti",
                    "DescriptionKey",
                    "GroupKey")
                {
                    TermStoreMapping = new TaxonomyContext(levelOneTermA)   // choices limited to children of a specific term, instead of having full term set choices
                };

                // Create a list that contains all the fields we've prepared
                var fieldsToEnsure = new List<BaseFieldInfo>()
                    {
                        integerFieldInfo,
                        numberFieldInfo,
                        currencyFieldInfo,
                        dateOnlyFieldInfo,
                        dateTimeFieldInfo,
                        urlFieldInfo,
                        urlFieldInfoImage,
                        mediaFieldInfo,
                        taxoFieldInfo,
                        taxoMultiFieldInfo
                    };
                
                // Prepare some MetadataDefaults that we'll apply on the second-level folder
                var fieldDefaultValues = new List<FieldValueInfo>()
                {
                    new FieldValueInfo(integerFieldInfo, 555),
                    new FieldValueInfo(numberFieldInfo, 5.0),
                    new FieldValueInfo(currencyFieldInfo, 535.95),
                    new FieldValueInfo(dateOnlyFieldInfo, new DateTime(1976, 1, 1)),
                    new FieldValueInfo(dateTimeFieldInfo, new DateTime(1977, 1, 1)),
                    new FieldValueInfo(
                        urlFieldInfo, 
                        new UrlValue()
                        {
                            Url = "http://github.com/GSoft-SharePoint/",
                            Description = "patate!"
                        }),
                    new FieldValueInfo(
                        urlFieldInfoImage, 
                        new UrlValue()
                        {
                            Url = "http://github.com/GSoft-SharePoint/",
                            Description = "patate!"
                        }),
                    new FieldValueInfo(
                        mediaFieldInfo, 
                        new MediaValue()
                        {
                            Title = "Some media file title",
                            Url = "/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf",
                            IsAutoPlay = true,
                            IsLoop = true,
                            PreviewImageUrl = "/_layouts/15/Images/logo.png"
                        }),
                    new FieldValueInfo(taxoFieldInfo, new TaxonomyValue(levelOneTermB)),
                    new FieldValueInfo(
                        taxoMultiFieldInfo, 
                        new TaxonomyValueCollection(
                            new List<TaxonomyValue>() 
                                { 
                                    new TaxonomyValue(levelTwoTermAA), 
                                    new TaxonomyValue(levelTwoTermAB)
                                }))
                };

                // We gotta update the ArticlePage Content type with our fields
                var articlePageCT = new ContentTypeInfo(
                    "0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D",
                    "UpdatedArticlePageCT",
                    "UpdatedArticlePageCTDescription",
                    "GroupKey")
                    {
                        Fields = fieldsToEnsure
                    };

                // Default values are configured on the level 2 folder (not on the root folder)
                var articleLeftPageLayoutInfo = new PageLayoutInfo("ArticleLeft.aspx", "0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D");
                var folderInfoLvl2 = new FolderInfo("somelevel2path")
                {
                    FieldDefaultValues = fieldDefaultValues,
                    Pages = new List<PageInfo>() 
                    { 
                        new PageInfo("DynamiteTestPage", articleLeftPageLayoutInfo),
                        new PageInfo("DynamiteTestPageWithValues", articleLeftPageLayoutInfo)
                        {
                            FieldValues = new List<FieldValueInfo>()
                            {
                                new FieldValueInfo(dateOnlyFieldInfo, new DateTime(1998, 1, 1)),
                                new FieldValueInfo(dateTimeFieldInfo, new DateTime(1999, 1, 1)),
                                new FieldValueInfo(taxoFieldInfo, new TaxonomyValue(levelOneTermA))
                            }
                        }
                    }
                };

                var rootFolderInfo = new FolderInfo("somepath")
                {
                    Subfolders = new List<FolderInfo>()
                    {
                        folderInfoLvl2
                    }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Init the test Pages library (we're in a Pub Site, the Pages lib already exists and we want to add fields to it)
                    SPList list = testScope.SiteCollection.RootWeb.GetPagesLibrary();
                    contentTypeHelper.EnsureContentType(list.ContentTypes, articlePageCT);      // this should add the field to the Pages lib

                    var folderHelper = injectionScope.Resolve<IFolderHelper>();

                    // Act: ensure the folder hierarchy with a page inside 2nd level subfolder which has MetadataDefaults for all possible types
                    var ensuredRootFolder = folderHelper.EnsureFolderHierarchy(list, rootFolderInfo);

                    // Assert
                    var pubWeb = PublishingWeb.GetPublishingWeb(testScope.SiteCollection.RootWeb);
                    var recursivePagesQuery = new SPQuery() { ViewAttributes = "Scope=\"Recursive\"" };

                    // Fetch all pages. WARNING: all dates will be returned in UTC time, because our SPQuery is modified
                    // by GetPublishingPages to force DatesInUtc=true.
                    var allPages = pubWeb.GetPublishingPages(recursivePagesQuery);
                    var ourPageWithDefaults = allPages["/Pages/somelevel2path/DynamiteTestPage.aspx"];
                    var ourPageWithDefaultsAndValues = allPages["/Pages/somelevel2path/DynamiteTestPageWithValues.aspx"];

                    // In 1st publishing page's list item, all metadata defaults should've been applied
                    Assert.AreEqual(555, ourPageWithDefaults.ListItem["TestInternalNameInteger"]);
                    Assert.AreEqual(5.0, ourPageWithDefaults.ListItem["TestInternalNameNumber"]);
                    Assert.AreEqual(535.95, ourPageWithDefaults.ListItem["TestInternalNameCurrency"]);
                    Assert.AreEqual(new DateTime(1976, 1, 1), ((DateTime)ourPageWithDefaults.ListItem["TestInternalNameDate"]).ToLocalTime());    // SPListItem should normally return DateTime as local time (not UTC), but since we used GetPublishingPage, dates are in UTC
                    Assert.AreEqual(new DateTime(1977, 1, 1), ((DateTime)ourPageWithDefaults.ListItem["TestInternalNameDateTime"]).ToLocalTime());
                    
                    var urlFieldVal = new SPFieldUrlValue(ourPageWithDefaults.ListItem["TestInternalNameUrl"].ToString());
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", urlFieldVal.Url);
                    Assert.AreEqual("patate!", urlFieldVal.Description);

                    var urlImageFieldVal = new SPFieldUrlValue(ourPageWithDefaults.ListItem["TestInternalNameUrlImg"].ToString());
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", urlImageFieldVal.Url);
                    Assert.AreEqual("patate!", urlImageFieldVal.Description);

                    var mediaFieldVal = MediaFieldValue.FromString(ourPageWithDefaults.ListItem["TestInternalNameMedia"].ToString());
                    Assert.AreEqual("Some media file title", mediaFieldVal.Title);
                    Assert.AreEqual(HttpUtility.UrlDecode("/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf"), mediaFieldVal.MediaSource);
                    Assert.IsTrue(mediaFieldVal.AutoPlay);
                    Assert.IsTrue(mediaFieldVal.Loop);
                    Assert.AreEqual("/_layouts/15/Images/logo.png", mediaFieldVal.PreviewImageSource);

                    var taxoFieldValue = (TaxonomyFieldValue)ourPageWithDefaults.ListItem["TestInternalNameTaxo"];
                    Assert.AreNotEqual(-1, taxoFieldValue.WssId);
                    Assert.AreEqual(levelOneTermB.Id, new Guid(taxoFieldValue.TermGuid));
                    Assert.AreEqual(levelOneTermB.Label, taxoFieldValue.Label);

                    var taxoFieldValueMulti = (TaxonomyFieldValueCollection)ourPageWithDefaults.ListItem["TestInternalNameTaxoMulti"];
                    Assert.AreNotEqual(-1, taxoFieldValueMulti[0].WssId);
                    Assert.AreEqual(levelTwoTermAA.Id, new Guid(taxoFieldValueMulti[0].TermGuid));
                    Assert.AreEqual(levelTwoTermAA.Label, taxoFieldValueMulti[0].Label);
                    Assert.AreNotEqual(-1, taxoFieldValueMulti[1].WssId);
                    Assert.AreEqual(levelTwoTermAB.Id, new Guid(taxoFieldValueMulti[1].TermGuid));
                    Assert.AreEqual(levelTwoTermAB.Label, taxoFieldValueMulti[1].Label);

                    // In 2nd publishing page's list item, metadata defaults should've been applied everywhere except where we specified item values
                    Assert.AreEqual(5.0, ourPageWithDefaultsAndValues.ListItem["TestInternalNameNumber"]);
                    Assert.AreEqual(535.95, ourPageWithDefaultsAndValues.ListItem["TestInternalNameCurrency"]);
                    Assert.AreEqual(new DateTime(1998, 1, 1), ((DateTime)ourPageWithDefaultsAndValues.ListItem["TestInternalNameDate"]).ToLocalTime());     // PageInfo Value should be applied, not folder MetadataDefaul
                    Assert.AreEqual(new DateTime(1999, 1, 1), ((DateTime)ourPageWithDefaultsAndValues.ListItem["TestInternalNameDateTime"]).ToLocalTime());     // PageInfo Value should be applied, not folder MetadataDefault
                    
                    urlFieldVal = new SPFieldUrlValue(ourPageWithDefaultsAndValues.ListItem["TestInternalNameUrl"].ToString());
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", urlFieldVal.Url);
                    Assert.AreEqual("patate!", urlFieldVal.Description);     // proper Url description will never be set for Format=Hyperlink

                    urlImageFieldVal = new SPFieldUrlValue(ourPageWithDefaultsAndValues.ListItem["TestInternalNameUrlImg"].ToString());
                    Assert.AreEqual("http://github.com/GSoft-SharePoint/", urlImageFieldVal.Url);
                    Assert.AreEqual("patate!", urlImageFieldVal.Description);     // proper Url description will never be set for Format=Image either

                    mediaFieldVal = MediaFieldValue.FromString(ourPageWithDefaultsAndValues.ListItem["TestInternalNameMedia"].ToString());
                    Assert.AreEqual("Some media file title", mediaFieldVal.Title);
                    Assert.AreEqual(HttpUtility.UrlDecode("/sites/test/SiteAssets/01_01_ASP.NET%20MVC%203%20Fundamentals%20Intro%20-%20Overview.asf"), mediaFieldVal.MediaSource);
                    Assert.IsTrue(mediaFieldVal.AutoPlay);
                    Assert.IsTrue(mediaFieldVal.Loop);
                    Assert.AreEqual("/_layouts/15/Images/logo.png", mediaFieldVal.PreviewImageSource);

                    taxoFieldValue = (TaxonomyFieldValue)ourPageWithDefaultsAndValues.ListItem["TestInternalNameTaxo"];  // PageInfo Value should be applied, not folder MetadataDefault
                    Assert.AreNotEqual(-1, taxoFieldValue.WssId);
                    Assert.AreEqual(levelOneTermA.Id, new Guid(taxoFieldValue.TermGuid));
                    Assert.AreEqual(levelOneTermA.Label, taxoFieldValue.Label);

                    taxoFieldValueMulti = (TaxonomyFieldValueCollection)ourPageWithDefaultsAndValues.ListItem["TestInternalNameTaxoMulti"];
                    Assert.AreNotEqual(-1, taxoFieldValueMulti[0].WssId);
                    Assert.AreEqual(levelTwoTermAA.Id, new Guid(taxoFieldValueMulti[0].TermGuid));
                    Assert.AreEqual(levelTwoTermAA.Label, taxoFieldValueMulti[0].Label);
                    Assert.AreNotEqual(-1, taxoFieldValueMulti[1].WssId);
                    Assert.AreEqual(levelTwoTermAB.Id, new Guid(taxoFieldValueMulti[1].TermGuid));
                    Assert.AreEqual(levelTwoTermAB.Label, taxoFieldValueMulti[1].Label);
                }
            }
        }
        private SPContentType InnerEnsureContentType(SPContentTypeCollection contentTypeCollection, ContentTypeInfo contentTypeInfo)
        {
            if (contentTypeCollection == null)
            {
                throw new ArgumentNullException("contentTypeCollection");
            }

            SPContentTypeId contentTypeId = contentTypeInfo.ContentTypeId;
            SPList list = null;

            var contentTypeResourceTitle = this.resourceLocator.GetResourceString(contentTypeInfo.ResourceFileName, contentTypeInfo.DisplayNameResourceKey);

            if (TryGetListFromContentTypeCollection(contentTypeCollection, out list))
            {
                // Make sure its not already in the list.
                var contentTypeInList = list.ContentTypes.Cast<SPContentType>().FirstOrDefault(ct => ct.Id == contentTypeId || ct.Parent.Id == contentTypeId);
                if (contentTypeInList == null)
                {
                    // Can we add the content type to the list?
                    if (list.IsContentTypeAllowed(contentTypeId))
                    {
                        // Enable content types if not yet done.
                        if (!list.ContentTypesEnabled)
                        {
                            list.ContentTypesEnabled = true;
                            list.Update(true);
                        }

                        // Try to use the list's web's content type if it already exists
                        var contentTypeInWeb = list.ParentWeb.Site.RootWeb.AvailableContentTypes[contentTypeId];

                        if (contentTypeInWeb == null)
                        {
                            // By convention, content types should always exist on root web as site-collection-wide
                            // content types before they get linked on a specific list.
                            var rootWebContentTypeCollection = list.ParentWeb.Site.RootWeb.ContentTypes;
                            contentTypeInWeb = this.EnsureContentType(rootWebContentTypeCollection, contentTypeInfo);

                            this.log.Warn(
                                "EnsureContentType - Forced the creation of Content Type (name={0} ctid={1}) on the root web (url=) instead of adding the CT directly on the list (id={2} title={3}). By convention, all CTs should be provisonned on RootWeb before being re-used in lists.",
                                contentTypeInWeb.Name,
                                contentTypeInWeb.Id.ToString(),
                                list.ID,
                                list.Title);
                        }

                        // Add the web content type to the collection.
                        return list.ContentTypes.Add(contentTypeInWeb);
                    }
                }
                else
                {
                    this.InnerEnsureFieldInContentType(contentTypeInList, contentTypeInfo.Fields);

                    return contentTypeInList;
                }
            }
            else
            {
                SPWeb web = null;
                if (TryGetWebFromContentTypeCollection(contentTypeCollection, out web))
                {
                    // Make sure its not already in ther web.
                    var contentTypeInWeb = web.ContentTypes[contentTypeId];
                    if (contentTypeInWeb == null)
                    {
                        SPContentTypeCollection rootWebContentTypeCollection = null;

                        if (web.ID == web.Site.RootWeb.ID)
                        {
                            rootWebContentTypeCollection = contentTypeCollection;
                        }
                        else
                        {
                            rootWebContentTypeCollection = web.Site.RootWeb.ContentTypes;

                            this.log.Warn(
                                "EnsureContentType - Will force creation of content type (id={0} name={1}) on root web instead of on specified sub-web. This is to enforce the following convention: all CTs should be provisioned at root of site collection, to ease maintenance. Ensure your content types on the root web's SPContentTypeCollection to avoid this warning.",
                                contentTypeId.ToString(),
                                contentTypeInfo.DisplayNameResourceKey);
                        }

                        var contentTypeInRootWeb = rootWebContentTypeCollection[contentTypeId];

                        if (contentTypeInRootWeb == null)
                        {
                            // Add the content type to the Root Web collection. By convention, we avoid provisioning
                            // CTs directly on sub-webs to make CT management easier (i.e. all of your site collection's
                            // content types should be configured at the root of the site collection).
                            var newWebContentType = new SPContentType(contentTypeId, rootWebContentTypeCollection, contentTypeResourceTitle);
                            contentTypeInRootWeb = rootWebContentTypeCollection.Add(newWebContentType);
                        }

                        this.InnerEnsureFieldInContentType(contentTypeInRootWeb, contentTypeInfo.Fields);

                        return contentTypeInRootWeb;
                    }
                    else
                    {
                        this.InnerEnsureFieldInContentType(contentTypeInWeb, contentTypeInfo.Fields);
                        return contentTypeInWeb;
                    }
                }

                // Case if there is no Content Types in the Web (e.g single SPWeb)
                var returnedContentType = this.EnsureContentType(contentTypeCollection, contentTypeInfo);
                return returnedContentType;
            }

            return null;
        }
        public void EnsureContentType_WhenEnglishAndFrenchSiteCollection_ShouldCreateCTWithBothDisplayNames()
        {
            using (var testScope = SiteTestScope.BlankSite(Language.English.Culture.LCID))
            {
                // Add French so that both languages are supported
                var rootWeb = testScope.SiteCollection.RootWeb;
                rootWeb.AddSupportedUICulture(Language.French.Culture);
                rootWeb.Update();

                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "Test_ContentTypeTitle", "Test_ContentTypeDescription", "Test_ContentGroup");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    IContentTypeHelper contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var rootWebContentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;

                    SPContentType contentType = contentTypeHelper.EnsureContentType(rootWebContentTypeCollection, contentTypeInfo);
                    SPContentType contentTypeFromOldCollection = rootWebContentTypeCollection[contentType.Id];
                    SPContentType contentTypeRefetched = testScope.SiteCollection.RootWeb.ContentTypes[contentType.Id];
                    
                    // Set MUI to english
                    var ambientThreadCulture = Thread.CurrentThread.CurrentUICulture;
                    Thread.CurrentThread.CurrentUICulture = Language.English.Culture;

                    Assert.AreEqual("EN Content Type Title", contentType.Name);
                    Assert.AreEqual("EN Content Type Description", contentType.Description);
                    Assert.AreEqual("EN Content Group", contentType.Group);

                    Assert.AreEqual("EN Content Type Title", contentTypeFromOldCollection.Name);
                    Assert.AreEqual("EN Content Type Description", contentTypeFromOldCollection.Description);
                    Assert.AreEqual("EN Content Group", contentTypeFromOldCollection.Group);

                    Assert.AreEqual("EN Content Type Title", contentTypeRefetched.Name);
                    Assert.AreEqual("EN Content Type Description", contentTypeRefetched.Description);
                    Assert.AreEqual("EN Content Group", contentTypeRefetched.Group);

                    // Set MUI to french
                    Thread.CurrentThread.CurrentUICulture = Language.French.Culture;

                    Assert.AreEqual("FR Nom de type de contenu", contentType.Name);
                    Assert.AreEqual("FR Description de type de contenu", contentType.Description);
                    Assert.AreEqual("FR Groupe de contenu", contentType.Group);

                    Assert.AreEqual("FR Nom de type de contenu", contentTypeFromOldCollection.Name);
                    Assert.AreEqual("FR Description de type de contenu", contentTypeFromOldCollection.Description);
                    Assert.AreEqual("FR Groupe de contenu", contentTypeFromOldCollection.Group);

                    Assert.AreEqual("FR Nom de type de contenu", contentTypeRefetched.Name);
                    Assert.AreEqual("FR Description de type de contenu", contentTypeRefetched.Description);
                    Assert.AreEqual("FR Groupe de contenu", contentTypeRefetched.Group);

                    // Reset MUI to its old abient value
                    Thread.CurrentThread.CurrentUICulture = ambientThreadCulture;
                }
            }
        }
        public void EnsureFolderHierarchy_WhenInPagesLibrary_AndAttemptingToSetDefaultPublishingImageValue_ShouldThrownNotSupportedException()
        {
            using (var testScope = SiteTestScope.PublishingSite())
            {
                // Arrange
                ImageFieldInfo imageFieldInfo = new ImageFieldInfo(
                    "TestInternalNameImage",
                    new Guid("{6C5B9E77-B621-43AA-BFBF-B333093EFCAE}"),
                    "NameKeyImage",
                    "DescriptionKeyImage",
                    "GroupKey")
                {
                };

                var fieldsToEnsure = new List<BaseFieldInfo>()
                {
                    imageFieldInfo
                };

                // We gotta update the ArticlePage Content type with our fields
                var articlePageCT = new ContentTypeInfo(
                    "0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D",
                    "UpdatedArticlePageCT",
                    "UpdatedArticlePageCTDescription",
                    "GroupKey")
                {
                    Fields = fieldsToEnsure
                };

                // Default values configured on the level 2 folder (not on the root folder)
                var folderInfoLvl2 = new FolderInfo("somelevel2path")
                {
                    FieldDefaultValues = new List<FieldValueInfo>() 
                    { 
                        new FieldValueInfo(
                            imageFieldInfo, 
                            new ImageValue()
                            {
                                Hyperlink = "http://github.com/GSoft-SharePoint/",
                                ImageUrl = "/_layouts/15/MyFolder/MyImage.png"
                            })
                    }
                };

                var rootFolderInfo = new FolderInfo("somepath")
                {
                    Subfolders = new List<FolderInfo>()
                    {
                        folderInfoLvl2
                    }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    // Init the test Pages library (we're in a Pub Site, the Pages lib already exists and we want to add fields to it)
                    SPList list = testScope.SiteCollection.RootWeb.GetPagesLibrary();
                    contentTypeHelper.EnsureContentType(list.ContentTypes, articlePageCT);      // this should add the field to the Pages lib

                    var folderHelper = injectionScope.Resolve<IFolderHelper>();

                    // Act: try to set a folder default on a Publishing Image field
                    try
                    {
                        var ensuredRootFolder = folderHelper.EnsureFolderHierarchy(list, rootFolderInfo);
                        Assert.Fail("Should've thrown NotSupportedException");
                    }
                    catch (NotSupportedException)
                    {
                    }
                }
            }
        }
Exemple #30
0
        public void EnsureList_WhenEnsuringANewListInRootWebWithSpecifiedContentTypes_AndContentTypeDoesntExistOnRootWebYet_ItShouldAddThemToBothRootWebAndList()
        {
            // Arrange
            const string Url = "testUrl";
            
            var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

            var contentTypeInfo = new ContentTypeInfo(contentTypeId, "ContentTypeNameKey", "ContentTypeDescKey", "GroupKey");

            var listInfo = new ListInfo(Url, "NameKey", "DescriptionKey")
                {
                    ContentTypes = new List<ContentTypeInfo>()
                    {
                        contentTypeInfo
                    }
                };

            using (var testScope = SiteTestScope.BlankSite())
            {
                var rootWeb = testScope.SiteCollection.RootWeb;

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var listHelper = injectionScope.Resolve<IListHelper>();
                    var numberOfListsBefore = rootWeb.Lists.Count;
                    var numberOfContentTypesBefore = rootWeb.ContentTypes.Count;
                    
                    // Act
                    var list = listHelper.EnsureList(rootWeb, listInfo);

                    // Assert
                    Assert.AreEqual(numberOfListsBefore + 1, rootWeb.Lists.Count);
                    Assert.AreEqual(listInfo.DisplayNameResourceKey, list.TitleResource.Value);
                    list = rootWeb.GetList(Url);
                    Assert.IsNotNull(list);
                    var listContentType = list.ContentTypes["ContentTypeNameKey"];
                    Assert.IsNotNull(listContentType);
                    Assert.IsTrue(list.ContentTypesEnabled);

                    // Make sure CT was provisionned on root web and that list CT is child of root web CT
                    Assert.AreEqual(numberOfContentTypesBefore + 1, rootWeb.ContentTypes.Count);
                    var rootWebContentType = rootWeb.ContentTypes["ContentTypeNameKey"];
                    Assert.IsNotNull(rootWebContentType);
                    Assert.AreEqual(contentTypeInfo.DisplayNameResourceKey, rootWebContentType.NameResource.Value);

                    Assert.IsTrue(listContentType.Id.IsChildOf(rootWebContentType.Id));
                }
            }
        }
        public void EnsureContentType_WhenEnglishOnlySiteCollection_ShouldCreateCTWithEnglishDisplayName()
        {
            using (var testScope = SiteTestScope.BlankSite(Language.English.Culture.LCID))
            {
                var contentTypeId = string.Format(
                    CultureInfo.InvariantCulture,
                    "0x0100{0:N}",
                    new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));

                var contentTypeInfo = new ContentTypeInfo(contentTypeId, "Test_ContentTypeTitle", "Test_ContentTypeDescription", "Test_ContentGroup");

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    IContentTypeHelper contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();
                    var rootWebContentTypeCollection = testScope.SiteCollection.RootWeb.ContentTypes;

                    SPContentType contentType = contentTypeHelper.EnsureContentType(rootWebContentTypeCollection, contentTypeInfo);

                    Assert.AreEqual("EN Content Type Title", contentType.Name);
                    Assert.AreEqual("EN Content Type Description", contentType.Description);
                    Assert.AreEqual("EN Content Group", contentType.Group);

                    SPContentType contentTypeFromOldCollection = rootWebContentTypeCollection[contentType.Id];

                    Assert.AreEqual("EN Content Type Title", contentTypeFromOldCollection.Name);
                    Assert.AreEqual("EN Content Type Description", contentTypeFromOldCollection.Description);
                    Assert.AreEqual("EN Content Group", contentTypeFromOldCollection.Group);

                    SPContentType contentTypeRefetched = testScope.SiteCollection.RootWeb.ContentTypes[contentType.Id];

                    Assert.AreEqual("EN Content Type Title", contentTypeRefetched.Name);
                    Assert.AreEqual("EN Content Type Description", contentTypeRefetched.Description);
                    Assert.AreEqual("EN Content Group", contentTypeRefetched.Group);
                }
            }
        }
        public void EnsureFolderHierarchy_WhenInPagesLibrary_ShouldApplyFolderSpecificContentTypesChoicesInRibbonNewPageDropdown()
        {
            using (var testScope = SiteTestScope.PublishingSite())
            {
                // Arrange

                // Create some content types, children of Article Page, the base Page Layout-based page CT
                var contentTypeId1 = ContentTypeIdBuilder.CreateChild(ContentTypeId.ArticlePage, new Guid("{F8B6FF55-2C9E-4FA2-A705-F55FE3D18777}"));
                var contentTypeId2 = ContentTypeIdBuilder.CreateChild(ContentTypeId.ArticlePage, new Guid("{A7BAA5B7-C57B-4928-9778-818D267505A1}"));

                var pageContentType1 = new ContentTypeInfo(contentTypeId1, "PageCT1NameKey", "PageCT1DescrKey", "GroupKey");
                var pageContentType2 = new ContentTypeInfo(contentTypeId2, "PageCT2NameKey", "PageCT2DescrKey", "GroupKey");

                var rootFolderInfo = new FolderInfo("somepath")
                {
                    Subfolders = new List<FolderInfo>()
                    {
                        new FolderInfo("somelevel2path")
                        {
                            Subfolders = new List<FolderInfo>()
                            {
                                new FolderInfo("level3")
                                {
                                    UniqueContentTypeOrder = new List<ContentTypeInfo>() { pageContentType2 }
                                }
                            },
                            UniqueContentTypeOrder = new List<ContentTypeInfo>() { pageContentType1 }
                        },
                        new FolderInfo("somelevel2path alt")
                    },
                    UniqueContentTypeOrder = new List<ContentTypeInfo>()
                    {
                        // order: 2-1
                        pageContentType2,
                        pageContentType1
                    }
                };

                using (var injectionScope = IntegrationTestServiceLocator.BeginLifetimeScope())
                {
                    var folderHelper = injectionScope.Resolve<IFolderHelper>();
                    var contentTypeHelper = injectionScope.Resolve<IContentTypeHelper>();

                    var pagesLibrary = testScope.SiteCollection.RootWeb.GetPagesLibrary();

                    // Make sure our CTs are available on lib (this will add CTs to the root web and
                    // associate some child CTs to the list).
                    contentTypeHelper.EnsureContentType(
                        pagesLibrary.ContentTypes, 
                        new List<ContentTypeInfo>() { pageContentType1, pageContentType2 });
                    pagesLibrary.Update();

                    // Act
                    folderHelper.EnsureFolderHierarchy(pagesLibrary, rootFolderInfo);

                    // Assert

                    // root folder should have order 2-1
                    var rootFolder = pagesLibrary.RootFolder;
                    Assert.AreEqual(2, rootFolder.UniqueContentTypeOrder.Count);
                    Assert.IsTrue(pageContentType2.ContentTypeId.IsParentOf(rootFolder.UniqueContentTypeOrder[0].Id));
                    Assert.IsTrue(pageContentType1.ContentTypeId.IsParentOf(rootFolder.UniqueContentTypeOrder[1].Id));

                    // lvl2 folder should have page1CT only
                    var lvl2Folder = pagesLibrary.RootFolder.SubFolders.Cast<SPFolder>().Single(f => f.Name == "somelevel2path");
                    Assert.AreEqual(1, lvl2Folder.UniqueContentTypeOrder.Count);
                    Assert.IsTrue(pageContentType1.ContentTypeId.IsParentOf(lvl2Folder.UniqueContentTypeOrder[0].Id));

                    // lvl2Alt should inherit root folder
                    var lvl2Alt = pagesLibrary.RootFolder.SubFolders.Cast<SPFolder>().Single(f => f.Name == "somelevel2path alt");
                    Assert.IsNull(lvl2Alt.UniqueContentTypeOrder);

                    // lvl3 should have page2CT only
                    var lvl3Folder = lvl2Folder.SubFolders.Cast<SPFolder>().Single(f => f.Name == "level3");
                    Assert.AreEqual(1, lvl3Folder.UniqueContentTypeOrder.Count);
                    Assert.IsTrue(pageContentType2.ContentTypeId.IsParentOf(lvl3Folder.UniqueContentTypeOrder[0].Id));
                }
            }
        }