From 6a14c320fffa50a9ca1195d83ecfab71e88e605f Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Tue, 25 Oct 2016 17:57:51 -0700 Subject: [PATCH 01/20] + Cover FieldDefinition.DefaultValue with regression tests #595 + added SelfDiagnostic_AllFields_Should_Have_DefaultValue_Tests + bootstrapped tests under "Regression.Scenarios.Fields.DefaultValues" category --- .../Impl/Scenarios/FieldScenariosTest.cs | 272 ++++++++++++++++++ 1 file changed, 272 insertions(+) diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs index 09c21f1ec..307e8f4f0 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs @@ -7,6 +7,7 @@ using SPMeta2.Regression.Tests.Impl.Scenarios.Base; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using SPMeta2.Containers.Services; @@ -760,6 +761,277 @@ public void CanDeploy_Field_To_O365_RootSiteCollection() #endregion + #region default values + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + [TestCategory("CI.Core")] + public void SelfDiagnostic_AllFields_Should_Have_DefaultValue_Tests() + { + var isValid = true; + + var methods = GetType().GetMethods(); + var targetTypes = new List(); + + var assemblies = new[] + { + typeof(FieldDefinition).Assembly, + typeof(TaxonomyFieldDefinition).Assembly, + }; + + targetTypes.AddRange(ReflectionUtils.GetTypesFromAssemblies(assemblies)); + + Trace.WriteLine(string.Format("Found [{0}] fied types.", targetTypes.Count)); + + foreach (var fieldType in targetTypes.OrderBy(m => m.Name)) + { + var fullDefName = fieldType.Name; + var shortDefName = fieldType.Name.Replace("Definition", string.Empty); + + var testName = string.Format("CanDeploy_{0}_DefaultValue", shortDefName); + + var testExists = methods.Any(m => m.Name == testName); + + if (!testExists) + isValid = false; + + Trace.WriteLine(string.Format("[{0}] def: {1} test method: {2}", + testExists, fullDefName, testName)); + } + + Assert.IsTrue(isValid); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_BooleanField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_BusinessDataField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_CalculatedField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_ChoiceField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_ComputedField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_CurrencyField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_DateTimeField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_DependentLookupField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_Field_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_GeolocationField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_GuidField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_HTMLField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_ImageField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_LinkField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_LookupField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_MediaField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_MultiChoiceField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_NoteField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_NumberField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_OutcomeChoiceField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_SummaryLinkField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_TaxonomyField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_TextField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_URLField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + public void CanDeploy_UserField_DefaultValue() + { + // Cover FieldDefinition.DefaultValue with regression tests #595 + // https://github.com/SubPointSolutions/spmeta2/issues/595 + throw new NotImplementedException(); + } + + #endregion + #region utils protected FieldDefinition GetLocalizedFieldDefinition() From 4e18caf25f723026c095e1110169165b849196c6 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 02:59:20 -0700 Subject: [PATCH 02/20] + Add CSOM 'MetadataNavigationSettingsDefinition' provision support #738 --- .../MetadataNavigationHierarchyConfig.cs | 43 ++-- .../MetadataNavigationKeyFilterConfig.cs | 19 +- .../MetadataNavigationSettingsConfig.cs | 173 ++++++++++++- .../MetadataNavigationSettingsModelHandler.cs | 239 ++++++++++-------- .../MetadataNavigationSettingsScenarios.cs | 133 +++++----- 5 files changed, 397 insertions(+), 210 deletions(-) diff --git a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationHierarchyConfig.cs b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationHierarchyConfig.cs index f6b0369eb..973ff5930 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationHierarchyConfig.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationHierarchyConfig.cs @@ -1,18 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - - -namespace SPMeta2.CSOM.Standard.Config -{ - public class MetadataNavigationHierarchyConfig - { - public MetadataNavigationHierarchyConfig(Guid fieldId) - { - this.FieldId = fieldId; - } - - public Guid FieldId { get; set; } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + + +namespace SPMeta2.CSOM.Standard.Config +{ + public class MetadataNavigationHierarchyConfig + { + #region constructors + public MetadataNavigationHierarchyConfig() + { + + } + #endregion + + #region properties + public Guid FieldId { get; set; } + public string FieldType { get; set; } + public string CachedName { get; set; } + public string CachedDisplayName { get; set; } + #endregion + } +} diff --git a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationKeyFilterConfig.cs b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationKeyFilterConfig.cs index 83ec88df1..37d34444a 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationKeyFilterConfig.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationKeyFilterConfig.cs @@ -8,11 +8,18 @@ namespace SPMeta2.CSOM.Standard.Config { public class MetadataNavigationKeyFilterConfig { - public MetadataNavigationKeyFilterConfig(Guid fieldId) - { - this.FieldId = fieldId; - } - - public Guid FieldId { get; set; } + #region constructors + public MetadataNavigationKeyFilterConfig() + { + + } + #endregion + + #region properties + public Guid FieldId { get; set; } + public string FieldType { get; set; } + public string CachedName { get; set; } + public string CachedDisplayName { get; set; } + #endregion } } diff --git a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs index e37ce8354..22bd2c552 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs @@ -2,43 +2,198 @@ using System.Collections.Generic; using System.Linq; using System.Text; - +using System.Xml.Linq; using Microsoft.SharePoint.Client; +using SPMeta2.CSOM.Extensions; using SPMeta2.Enumerations; using SPMeta2.Exceptions; +using SPMeta2.Utils; namespace SPMeta2.CSOM.Standard.Config { public class MetadataNavigationSettingsConfig { + #region constructors + + public MetadataNavigationSettingsConfig() + { + SettingDocument = new XDocument(new XElement("MetadataNavigationSettings")); + + SettingDocument.Root.SetAttribute("SchemaVersion", "1"); + SettingDocument.Root.SetAttribute("IsEnabled", "True"); + SettingDocument.Root.SetAttribute("AutoIndex", "True"); + } + + #endregion + + #region properties + + protected XDocument SettingDocument { get; set; } + + + #endregion + + #region static + public static MetadataNavigationSettingsConfig GetMetadataNavigationSettings(List list) { - throw new SPMeta2NotImplementedException("MetadataNavigationSettings provision for CSOM isnot yet implemented by M2 - https://github.com/SubPointSolutions/spmeta2/issues/738"); + var result = new MetadataNavigationSettingsConfig(); + + var context = list.Context; + + context.Load(list, l => l.RootFolder); + context.ExecuteQueryWithTrace(); + + var props = list.RootFolder.Properties; + + if (props.FieldValues.ContainsKey("client_MOSS_MetadataNavigationSettings")) + { + var value = ConvertUtils.ToString(props["client_MOSS_MetadataNavigationSettings"]); + + if (!string.IsNullOrEmpty(value)) + { + result.SettingDocument = XDocument.Parse(value); + } + } + + return result; } - public void AddConfiguredHierarchy(MetadataNavigationHierarchyConfig metadataNavigationHierarchy) + #endregion + + #region methods + + public void AddConfiguredHierarchy(MetadataNavigationHierarchyConfig item) { - throw new SPMeta2NotImplementedException("MetadataNavigationSettings provision for CSOM isnot yet implemented by M2 - https://github.com/SubPointSolutions/spmeta2/issues/738"); + var currentKey = FindConfiguredKeyFilter(item.FieldId); + + if (currentKey == null) + { + var root = SettingDocument.Root; + + var parentNode = root.Descendants("NavigationHierarchies").FirstOrDefault(); + + if (parentNode == null) + { + parentNode = new XElement("NavigationHierarchies"); + root.Add(parentNode); + + var folderHierarchyNode = new XElement("FolderHierarchy"); + + folderHierarchyNode.SetAttribute("HideFoldersNode", "False"); + parentNode.Add(folderHierarchyNode); + } + + var newNode = new XElement("MetadataField"); + + newNode.SetAttributeValue("FieldID", item.FieldId.ToString("D")); + newNode.SetAttributeValue("FieldType", item.FieldType); + + newNode.SetAttributeValue("CachedName", item.CachedName); + newNode.SetAttributeValue("CachedDisplayName", item.CachedDisplayName); + + parentNode.Add(newNode); + } } - public void AddConfiguredKeyFilter(MetadataNavigationKeyFilterConfig metadataNavigationKeyFilterConfig) + public void AddConfiguredKeyFilter(MetadataNavigationKeyFilterConfig item) { - throw new SPMeta2NotImplementedException("MetadataNavigationSettings provision for CSOM isnot yet implemented by M2 - https://github.com/SubPointSolutions/spmeta2/issues/738"); + var currentKey = FindConfiguredKeyFilter(item.FieldId); + + if (currentKey == null) + { + var root = SettingDocument.Root; + + var parentNode = root.Descendants("KeyFilters").FirstOrDefault(); + + if (parentNode == null) + { + parentNode = new XElement("KeyFilters"); + root.Add(parentNode); + } + + var newNode = new XElement("MetadataField"); + + newNode.SetAttributeValue("FieldID", item.FieldId.ToString("D")); + newNode.SetAttributeValue("FieldType", item.FieldType); + + newNode.SetAttributeValue("CachedName", item.CachedName); + newNode.SetAttributeValue("CachedDisplayName", item.CachedDisplayName); + + parentNode.Add(newNode); + } } public static void SetMetadataNavigationSettings(List list, MetadataNavigationSettingsConfig settings) { - throw new SPMeta2NotImplementedException("MetadataNavigationSettings provision for CSOM isnot yet implemented by M2 - https://github.com/SubPointSolutions/spmeta2/issues/738"); + var xmlValue = settings.SettingDocument.Root.ToString(); + + var context = list.Context; + + context.Load(list, l => l.RootFolder); + context.ExecuteQueryWithTrace(); + + list.RootFolder.Properties["client_MOSS_MetadataNavigationSettings"] = xmlValue; + list.RootFolder.Update(); + list.Update(); + + context.ExecuteQueryWithTrace(); } public MetadataNavigationHierarchyConfig FindConfiguredHierarchy(Guid guid) { - throw new SPMeta2NotImplementedException("MetadataNavigationSettings provision for CSOM isnot yet implemented by M2 - https://github.com/SubPointSolutions/spmeta2/issues/738"); + var root = SettingDocument.Root; + var parentNode = root.Descendants("NavigationHierarchies").FirstOrDefault(); + + if (parentNode == null) + return null; + + var nodes = parentNode.Descendants("MetadataField"); + var targetNode = nodes.FirstOrDefault(n => n.GetAttributeValue("FieldID") == guid.ToString("D")); + + if (targetNode != null) + { + var result = new MetadataNavigationHierarchyConfig(); + + result.FieldId = ConvertUtils.ToGuid(targetNode.GetAttributeValue("FieldID")).Value; + + result.FieldType = ConvertUtils.ToString(targetNode.GetAttributeValue("FieldType")); + result.CachedDisplayName = ConvertUtils.ToString(targetNode.GetAttributeValue("CachedDisplayName")); + result.CachedName = ConvertUtils.ToString(targetNode.GetAttributeValue("CachedName")); + + return result; + } + + return null; } public MetadataNavigationKeyFilterConfig FindConfiguredKeyFilter(Guid guid) { - throw new SPMeta2NotImplementedException("MetadataNavigationSettings provision for CSOM isnot yet implemented by M2 - https://github.com/SubPointSolutions/spmeta2/issues/738"); + var root = SettingDocument.Root; + var parentNode = root.Descendants("KeyFilters").FirstOrDefault(); + + if (parentNode == null) + return null; + + var nodes = parentNode.Descendants("MetadataField"); + var targetNode = nodes.FirstOrDefault(n => n.GetAttributeValue("FieldID") == guid.ToString("D")); + + if (targetNode != null) + { + var result = new MetadataNavigationKeyFilterConfig(); + + result.FieldId = ConvertUtils.ToGuid(targetNode.GetAttributeValue("FieldID")).Value; + + result.FieldType = ConvertUtils.ToString(targetNode.GetAttributeValue("FieldType")); + result.CachedDisplayName = ConvertUtils.ToString(targetNode.GetAttributeValue("CachedDisplayName")); + result.CachedName = ConvertUtils.ToString(targetNode.GetAttributeValue("CachedName")); + + return result; + } + + return null; } + + #endregion } } diff --git a/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/MetadataNavigationSettingsModelHandler.cs b/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/MetadataNavigationSettingsModelHandler.cs index a7582065a..dec81f893 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/MetadataNavigationSettingsModelHandler.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/MetadataNavigationSettingsModelHandler.cs @@ -1,110 +1,129 @@ -using System; -using System.Linq; -using Microsoft.SharePoint.Client; -using SPMeta2.Common; -using SPMeta2.CSOM.ModelHandlers; -using SPMeta2.CSOM.ModelHosts; -using SPMeta2.CSOM.Standard.Config; -using SPMeta2.Definitions; -using SPMeta2.Standard.Definitions; -using SPMeta2.Utils; - -namespace SPMeta2.CSOM.Standard.ModelHandlers -{ - public class MetadataNavigationSettingsModelHandler : CSOMModelHandlerBase - { - #region properties - - public override Type TargetType - { - get { return typeof(MetadataNavigationSettingsDefinition); } - } - - #endregion - - #region methods - - public override void DeployModel(object modelHost, DefinitionBase model) - { - var listHost = modelHost.WithAssertAndCast("model", value => value.RequireNotNull()); - var typedDefinition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - - DeploySettings(modelHost, listHost, typedDefinition); - } - - protected MetadataNavigationSettingsConfig GetCurrentSettings(List list) - { - return MetadataNavigationSettingsConfig.GetMetadataNavigationSettings(list); - } - - private void DeploySettings(object modelHost, ListModelHost listHost, MetadataNavigationSettingsDefinition definition) - { - var list = listHost.HostList; - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioning, - Object = list, - ObjectType = typeof(List), - ObjectDefinition = definition, - ModelHost = modelHost - }); - - var needUpdate = false; - - // deploy - var settings = GetCurrentSettings(list); - - if (definition.Hierarchies.Count() > 0) - { - foreach (var h in definition.Hierarchies) - { - if (h.FieldId.HasGuidValue()) - { - var targetField = list.Fields.GetById(h.FieldId.Value); - - settings.AddConfiguredHierarchy(new MetadataNavigationHierarchyConfig(targetField.Id)); - } - } - - needUpdate = true; - } - - if (definition.KeyFilters.Count() > 0) - { - foreach (var h in definition.KeyFilters) - { - if (h.FieldId.HasGuidValue()) - { - var targetField = list.Fields.GetById(h.FieldId.Value); - - settings.AddConfiguredKeyFilter(new MetadataNavigationKeyFilterConfig(targetField.Id)); - } - } - - needUpdate = true; - } - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = list, - ObjectType = typeof(List), - ObjectDefinition = definition, - ModelHost = modelHost - }); - - - if (needUpdate) - { - MetadataNavigationSettingsConfig.SetMetadataNavigationSettings(list, settings); - } - } - - #endregion - } -} +using System; +using System.Linq; +using Microsoft.SharePoint.Client; +using SPMeta2.Common; +using SPMeta2.CSOM.Extensions; +using SPMeta2.CSOM.ModelHandlers; +using SPMeta2.CSOM.ModelHosts; +using SPMeta2.CSOM.Standard.Config; +using SPMeta2.Definitions; +using SPMeta2.Standard.Definitions; +using SPMeta2.Utils; + +namespace SPMeta2.CSOM.Standard.ModelHandlers +{ + public class MetadataNavigationSettingsModelHandler : CSOMModelHandlerBase + { + #region properties + + public override Type TargetType + { + get { return typeof(MetadataNavigationSettingsDefinition); } + } + + #endregion + + #region methods + + public override void DeployModel(object modelHost, DefinitionBase model) + { + var listHost = modelHost.WithAssertAndCast("model", value => value.RequireNotNull()); + var typedDefinition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + + DeploySettings(modelHost, listHost, typedDefinition); + } + + protected MetadataNavigationSettingsConfig GetCurrentSettings(List list) + { + return MetadataNavigationSettingsConfig.GetMetadataNavigationSettings(list); + } + + private void DeploySettings(object modelHost, ListModelHost listHost, MetadataNavigationSettingsDefinition definition) + { + var list = listHost.HostList; + var context = list.Context; + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioning, + Object = list, + ObjectType = typeof(List), + ObjectDefinition = definition, + ModelHost = modelHost + }); + + var needUpdate = false; + + // deploy + var settings = GetCurrentSettings(list); + + if (definition.Hierarchies.Count() > 0) + { + foreach (var h in definition.Hierarchies) + { + if (h.FieldId.HasGuidValue()) + { + var targetField = list.Fields.GetById(h.FieldId.Value); + + context.Load(targetField); + context.ExecuteQueryWithTrace(); + + settings.AddConfiguredHierarchy(new MetadataNavigationHierarchyConfig + { + FieldId = targetField.Id, + FieldType = targetField.TypeAsString, + CachedDisplayName = targetField.Title, + CachedName = targetField.InternalName + }); + } + } + + needUpdate = true; + } + + if (definition.KeyFilters.Count() > 0) + { + foreach (var h in definition.KeyFilters) + { + if (h.FieldId.HasGuidValue()) + { + var targetField = list.Fields.GetById(h.FieldId.Value); + + context.Load(targetField); + context.ExecuteQueryWithTrace(); + + settings.AddConfiguredKeyFilter(new MetadataNavigationKeyFilterConfig + { + FieldId = targetField.Id, + FieldType = targetField.TypeAsString, + CachedDisplayName = targetField.Title, + CachedName = targetField.InternalName + }); + } + } + + needUpdate = true; + } + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = list, + ObjectType = typeof(List), + ObjectDefinition = definition, + ModelHost = modelHost + }); + + if (needUpdate) + { + MetadataNavigationSettingsConfig.SetMetadataNavigationSettings(list, settings); + } + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/MetadataNavigationSettingsScenarios.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/MetadataNavigationSettingsScenarios.cs index 0b59398ec..6b81457fe 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/MetadataNavigationSettingsScenarios.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/MetadataNavigationSettingsScenarios.cs @@ -39,21 +39,21 @@ public static void Cleanup() [TestCategory("Regression.Scenarios.MetadataNavigationSettings")] public void CanDeploy_MetadataNavigationSettings_With_Hierary() { - WithExcpectedException(typeof(SPMeta2NotImplementedException), () => - { - var managedNavSettings = ModelGeneratorService.GetRandomDefinition( - def => - { - def.Hierarchies.Clear(); - def.KeyFilters.Clear(); + var managedNavSettings = ModelGeneratorService.GetRandomDefinition( + def => + { + def.Hierarchies.Clear(); + def.KeyFilters.Clear(); - def.Hierarchies.Add(new MetadataNavigationHierarchy - { - FieldId = BuiltInFieldId.ContentTypeId - }); + def.Hierarchies.Add(new MetadataNavigationHierarchy + { + FieldId = BuiltInFieldId.ContentTypeId }); + }); - var model = SPMeta2Model.NewWebModel(web => + var model = SPMeta2Model.NewWebModel(rootWeb => + { + rootWeb.AddRandomWeb(web => { web.AddWebFeature(BuiltInWebFeatures.MetadataNavigationAndFiltering.Inherit(f => { @@ -64,37 +64,37 @@ public void CanDeploy_MetadataNavigationSettings_With_Hierary() { list.AddMetadataNavigationSettings(managedNavSettings); }); - }); - TestModel(model); }); + + TestModel(model); } [TestMethod] [TestCategory("Regression.Scenarios.MetadataNavigationSettings")] public void CanDeploy_MetadataNavigationSettings_With_KeyFilters() { - WithExcpectedException(typeof(SPMeta2NotImplementedException), () => - { - var managedNavSettings = ModelGeneratorService.GetRandomDefinition( - def => + var managedNavSettings = ModelGeneratorService.GetRandomDefinition( + def => + { + def.Hierarchies.Clear(); + def.KeyFilters.Clear(); + + def.KeyFilters.Add(new MetadataNavigationKeyFilter { - def.Hierarchies.Clear(); - def.KeyFilters.Clear(); - - def.KeyFilters.Add(new MetadataNavigationKeyFilter - { - FieldId = BuiltInFieldId.Created - }); - - def.KeyFilters.Add(new MetadataNavigationKeyFilter - { - FieldId = BuiltInFieldId.Modified - }); + FieldId = BuiltInFieldId.Created }); - var model = SPMeta2Model.NewWebModel(web => + def.KeyFilters.Add(new MetadataNavigationKeyFilter + { + FieldId = BuiltInFieldId.Modified + }); + }); + + var model = SPMeta2Model.NewWebModel(rootWeb => + { + rootWeb.AddRandomWeb(web => { web.AddWebFeature(BuiltInWebFeatures.MetadataNavigationAndFiltering.Inherit(f => { @@ -105,59 +105,58 @@ public void CanDeploy_MetadataNavigationSettings_With_KeyFilters() { list.AddMetadataNavigationSettings(managedNavSettings); }); - }); - TestModel(model); }); + + TestModel(model); } [TestMethod] [TestCategory("Regression.Scenarios.MetadataNavigationSettings")] public void CanDeploy_MetadataNavigationSettings_With_Hierarchies_And_KeyFilters() { - WithExcpectedException(typeof(SPMeta2NotImplementedException), - () => + + var managedNavSettings = ModelGeneratorService.GetRandomDefinition( + def => { + def.Hierarchies.Clear(); + def.KeyFilters.Clear(); - var managedNavSettings = ModelGeneratorService.GetRandomDefinition( - def => - { - def.Hierarchies.Clear(); - def.KeyFilters.Clear(); - - def.Hierarchies.Add(new MetadataNavigationHierarchy - { - FieldId = BuiltInFieldId.ContentTypeId - }); - - def.KeyFilters.Add(new MetadataNavigationKeyFilter - { - FieldId = BuiltInFieldId.Created - }); - - def.KeyFilters.Add(new MetadataNavigationKeyFilter - { - FieldId = BuiltInFieldId.Modified - }); - }); - - var model = SPMeta2Model.NewWebModel(web => + def.Hierarchies.Add(new MetadataNavigationHierarchy { - web.AddWebFeature(BuiltInWebFeatures.MetadataNavigationAndFiltering.Inherit(f => - { - f.Enable = true; - })); + FieldId = BuiltInFieldId.ContentTypeId + }); - web.AddRandomDocumentLibrary(list => - { - list.AddMetadataNavigationSettings(managedNavSettings); - }); + def.KeyFilters.Add(new MetadataNavigationKeyFilter + { + FieldId = BuiltInFieldId.Created + }); + def.KeyFilters.Add(new MetadataNavigationKeyFilter + { + FieldId = BuiltInFieldId.Modified }); + }); - TestModel(model); + var model = SPMeta2Model.NewWebModel(rootWeb => + { + rootWeb.AddRandomWeb(web => + { + web.AddWebFeature(BuiltInWebFeatures.MetadataNavigationAndFiltering.Inherit(f => + { + f.Enable = true; + })); + + web.AddRandomDocumentLibrary(list => + { + list.AddMetadataNavigationSettings(managedNavSettings); + }); }); + + }); + + TestModel(model); } #endregion From 5127cf8c594e0d6b2726af120f22eb93f3c51012 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 03:02:31 -0700 Subject: [PATCH 03/20] + SelfDiagnostic_AllFields_Should_Have_DefaultValue_Tests test fix --- .../Impl/Scenarios/FieldScenariosTest.cs | 87 +++++++++++-------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs index 307e8f4f0..d001b7f13 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs @@ -23,6 +23,56 @@ namespace SPMeta2.Regression.Tests.Impl.Scenarios { + [TestClass] + public class FieldScenariosSelfTest + { + #region default values + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.DefaultValues")] + [TestCategory("CI.Core")] + public void SelfDiagnostic_AllFields_Should_Have_DefaultValue_Tests() + { + // check if FieldScenariosTest class has all testsfor field default values + // should not inherit SPMeta2RegresionScenarioTestBase as it will force to use (init) provisioners under CI + // that's why it is separated + + var isValid = true; + + var methods = typeof(FieldScenariosTest).GetMethods(); + var targetTypes = new List(); + + var assemblies = new[] + { + typeof(FieldDefinition).Assembly, + typeof(TaxonomyFieldDefinition).Assembly + }; + + targetTypes.AddRange(ReflectionUtils.GetTypesFromAssemblies(assemblies)); + + Trace.WriteLine(string.Format("Found [{0}] fied types.", targetTypes.Count)); + + foreach (var fieldType in targetTypes.OrderBy(m => m.Name)) + { + var fullDefName = fieldType.Name; + var shortDefName = fieldType.Name.Replace("Definition", string.Empty); + + var testName = string.Format("CanDeploy_{0}_DefaultValue", shortDefName); + + var testExists = methods.Any(m => m.Name == testName); + + if (!testExists) + isValid = false; + + Trace.WriteLine(string.Format("[{0}] def: {1} test method: {2}", + testExists, fullDefName, testName)); + } + + Assert.IsTrue(isValid); + } + #endregion + } + [TestClass] public class FieldScenariosTest : SPMeta2RegresionScenarioTestBase { @@ -763,44 +813,7 @@ public void CanDeploy_Field_To_O365_RootSiteCollection() #region default values - [TestMethod] - [TestCategory("Regression.Scenarios.Fields.DefaultValues")] - [TestCategory("CI.Core")] - public void SelfDiagnostic_AllFields_Should_Have_DefaultValue_Tests() - { - var isValid = true; - - var methods = GetType().GetMethods(); - var targetTypes = new List(); - - var assemblies = new[] - { - typeof(FieldDefinition).Assembly, - typeof(TaxonomyFieldDefinition).Assembly, - }; - - targetTypes.AddRange(ReflectionUtils.GetTypesFromAssemblies(assemblies)); - Trace.WriteLine(string.Format("Found [{0}] fied types.", targetTypes.Count)); - - foreach (var fieldType in targetTypes.OrderBy(m => m.Name)) - { - var fullDefName = fieldType.Name; - var shortDefName = fieldType.Name.Replace("Definition", string.Empty); - - var testName = string.Format("CanDeploy_{0}_DefaultValue", shortDefName); - - var testExists = methods.Any(m => m.Name == testName); - - if (!testExists) - isValid = false; - - Trace.WriteLine(string.Format("[{0}] def: {1} test method: {2}", - testExists, fullDefName, testName)); - } - - Assert.IsTrue(isValid); - } [TestMethod] [TestCategory("Regression.Scenarios.Fields.DefaultValues")] From 6e0cd469c7a65dc00c1dd7a64a1105f7c4840d69 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 03:09:46 -0700 Subject: [PATCH 04/20] + NET35 fix --- .../Config/MetadataNavigationSettingsConfig.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs index 22bd2c552..1b8353f8d 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/Config/MetadataNavigationSettingsConfig.cs @@ -44,6 +44,11 @@ public static MetadataNavigationSettingsConfig GetMetadataNavigationSettings(Lis context.Load(list, l => l.RootFolder); context.ExecuteQueryWithTrace(); +#if NET35 + throw new SPMeta2NotImplementedException("Not implemented for SP2010 and NET35"); +#endif + +#if !NET35 var props = list.RootFolder.Properties; if (props.FieldValues.ContainsKey("client_MOSS_MetadataNavigationSettings")) @@ -56,6 +61,8 @@ public static MetadataNavigationSettingsConfig GetMetadataNavigationSettings(Lis } } +#endif + return result; } @@ -133,11 +140,18 @@ public static void SetMetadataNavigationSettings(List list, MetadataNavigationSe context.Load(list, l => l.RootFolder); context.ExecuteQueryWithTrace(); +#if NET35 + throw new SPMeta2NotImplementedException("Not implemented for SP2010 and NET35"); +#endif + +#if !NET35 + list.RootFolder.Properties["client_MOSS_MetadataNavigationSettings"] = xmlValue; list.RootFolder.Update(); list.Update(); context.ExecuteQueryWithTrace(); +#endif } public MetadataNavigationHierarchyConfig FindConfiguredHierarchy(Guid guid) From 2d394150999b8ed48ee82c339edf9e4ed88d679e Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 03:52:17 -0700 Subject: [PATCH 05/20] + [ExpectUpdate] coverage for RegionalSettingsDefinition #356 + SSOM impl --- .../RegionalSettingsDefinitionValidator.cs | 74 +++++++++++++++---- .../Impl/Random/RandomDefinitionTest.cs | 6 +- .../ExpectUpdateAsIntRangeService.cs | 10 +++ .../Definitions/RegionalSettingsDefinition.cs | 30 +++++++- 4 files changed, 103 insertions(+), 17 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Validation/RegionalSettingsDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM/Validation/RegionalSettingsDefinitionValidator.cs index 23cf7b957..1c4d0cf7a 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Validation/RegionalSettingsDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Validation/RegionalSettingsDefinitionValidator.cs @@ -25,19 +25,67 @@ public override void DeployModel(object modelHost, DefinitionBase model) var assert = ServiceFactory.AssertService .NewAssert(definition, spObject) - .ShouldNotBeNull(spObject) - .ShouldBeEqual(m => m.AdjustHijriDays, o => o.AdjustHijriDays) - .ShouldBeEqual(m => m.AlternateCalendarType, o => o.AlternateCalendarType) - .ShouldBeEqual(m => m.CalendarType, o => o.CalendarType) - .ShouldBeEqual(m => m.Collation, o => o.Collation) - .ShouldBeEqual(m => m.FirstDayOfWeek, o => o.FirstDayOfWeek) - .ShouldBeEqual(m => m.FirstWeekOfYear, o => o.FirstWeekOfYear) - //.ShouldBeEqual(m => m.LocaleId, o => o.LocaleId) - .ShouldBeEqual(m => m.WorkDayEndHour, o => o.WorkDayEndHour) - .ShouldBeEqual(m => m.WorkDayStartHour, o => o.WorkDayStartHour) - .ShouldBeEqual(m => m.WorkDays, o => o.WorkDays) - .ShouldBeEqual(m => m.ShowWeeks, o => o.ShowWeeks) - .ShouldBeEqual(m => m.Time24, o => o.Time24); + .ShouldNotBeNull(spObject); + + if (definition.CalendarType.HasValue) + assert.ShouldBeEqual(m => m.CalendarType, o => o.CalendarType); + else + assert.SkipProperty(m => m.CalendarType, "CalendarType is null or empty"); + + if (definition.AlternateCalendarType.HasValue) + assert.ShouldBeEqual(m => m.AlternateCalendarType, o => o.AlternateCalendarType); + else + assert.SkipProperty(m => m.AlternateCalendarType, "AlternateCalendarType is null or empty"); + + if (definition.AdjustHijriDays.HasValue) + assert.ShouldBeEqual(m => m.AdjustHijriDays, o => o.AdjustHijriDays); + else + assert.SkipProperty(m => m.AdjustHijriDays, "AdjustHijriDays is null or empty"); + + if (definition.Collation.HasValue) + assert.ShouldBeEqual(m => m.Collation, o => o.Collation); + else + assert.SkipProperty(m => m.Collation, "Collation is null or empty"); + + if (definition.WorkDayStartHour.HasValue) + assert.ShouldBeEqual(m => m.WorkDayStartHour, o => o.WorkDayStartHour); + else + assert.SkipProperty(m => m.WorkDayStartHour, "WorkDayStartHour is null or empty"); + + if (definition.WorkDayEndHour.HasValue) + assert.ShouldBeEqual(m => m.WorkDayEndHour, o => o.WorkDayEndHour); + else + assert.SkipProperty(m => m.WorkDayEndHour, "WorkDayEndHour is null or empty"); + + if (definition.WorkDays.HasValue) + assert.ShouldBeEqual(m => m.WorkDays, o => o.WorkDays); + else + assert.SkipProperty(m => m.WorkDays, "WorkDays is null or empty"); + + if (definition.Time24.HasValue) + assert.ShouldBeEqual(m => m.Time24, o => o.Time24); + else + assert.SkipProperty(m => m.Time24, "Time24 is null or empty"); + + if (definition.ShowWeeks.HasValue) + assert.ShouldBeEqual(m => m.ShowWeeks, o => o.ShowWeeks); + else + assert.SkipProperty(m => m.ShowWeeks, "ShowWeeks is null or empty"); + + if (definition.FirstDayOfWeek.HasValue) + assert.ShouldBeEqual(m => m.FirstWeekOfYear, o => o.FirstWeekOfYear); + else + assert.SkipProperty(m => m.FirstWeekOfYear, "FirstWeekOfYear is null or empty"); + + if (definition.FirstDayOfWeek.HasValue) + assert.ShouldBeEqual(m => m.FirstDayOfWeek, o => o.FirstDayOfWeek); + else + assert.SkipProperty(m => m.FirstDayOfWeek, "FirstDayOfWeek is null or empty"); + + if (definition.LocaleId.HasValue) + assert.ShouldBeEqual(m => m.LocaleId, o => o.LocaleId); + else + assert.SkipProperty(m => m.LocaleId, "LocaleId is null or empty"); if (definition.TimeZoneId.HasValue) { diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Random/RandomDefinitionTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Random/RandomDefinitionTest.cs index 6c00fe94d..a02867410 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Random/RandomDefinitionTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Random/RandomDefinitionTest.cs @@ -693,7 +693,11 @@ public void CanDeployRandom_TreeViewSettingsDefinition() [TestCategory("Regression.Rnd.Web")] public void CanDeployRandom_RegionalSettingsDefinition() { - TestRandomDefinition(); + // disable validation on the web as regional setting would toggle LCID + WithDisabledValidationOnTypes(typeof(WebDefinition), () => + { + TestRandomDefinition(); + }); } [TestMethod] diff --git a/SPMeta2/SPMeta2.Regression.Tests/Services/ExpectUpdateServices/ExpectUpdateAsIntRangeService.cs b/SPMeta2/SPMeta2.Regression.Tests/Services/ExpectUpdateServices/ExpectUpdateAsIntRangeService.cs index ebaf8c9c2..565912fba 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Services/ExpectUpdateServices/ExpectUpdateAsIntRangeService.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Services/ExpectUpdateServices/ExpectUpdateAsIntRangeService.cs @@ -30,6 +30,16 @@ public override object GetNewPropValue(ExpectUpdate attr, object obj, PropertyIn { newValue = Convert.ToUInt16(tmpValue); } + else if (prop.PropertyType == typeof(Int16?) || + prop.PropertyType == typeof(Int16)) + { + newValue = Convert.ToInt16(tmpValue); + } + else if (prop.PropertyType == typeof(UInt32?) || + prop.PropertyType == typeof(UInt32)) + { + newValue = Convert.ToUInt32(tmpValue); + } else { // TODO, as per case diff --git a/SPMeta2/SPMeta2/Definitions/RegionalSettingsDefinition.cs b/SPMeta2/SPMeta2/Definitions/RegionalSettingsDefinition.cs index 4afdd4870..4d484ec5d 100644 --- a/SPMeta2/SPMeta2/Definitions/RegionalSettingsDefinition.cs +++ b/SPMeta2/SPMeta2/Definitions/RegionalSettingsDefinition.cs @@ -28,50 +28,74 @@ public class RegionalSettingsDefinition : DefinitionBase [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 1, MaxValue = 5)] + [ExpectNullable] public short? AdjustHijriDays { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 0, MaxValue = 16)] + [ExpectNullable] public short? AlternateCalendarType { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 0, MaxValue = 16)] + [ExpectNullable] public short? CalendarType { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 0, MaxValue = 38)] + [ExpectNullable] public short? Collation { get; set; } [ExpectValidation] [DataMember] + [ExpectNullable] + [ExpectUpdateAsIntRange(MinValue = 1, MaxValue = 4)] public uint? FirstDayOfWeek { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 0, MaxValue = 2)] + [ExpectNullable] public short? FirstWeekOfYear { get; set; } - //[ExpectValidation] + [ExpectValidation] [DataMember] + [ExpectUpdateAsLCID] + [ExpectNullable] public uint? LocaleId { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdate] + [ExpectNullable] public bool? ShowWeeks { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdate] + [ExpectNullable] public bool? Time24 { get; set; } - //[ExpectValidation] + [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 5, MaxValue = 8)] + [ExpectNullable] public short? WorkDayEndHour { get; set; } [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 1, MaxValue = 5)] + [ExpectNullable] public short? WorkDays { get; set; } - //[ExpectValidation] + [ExpectValidation] [DataMember] + [ExpectUpdateAsIntRange(MinValue = 1, MaxValue = 4)] + [ExpectNullable] public short? WorkDayStartHour { get; set; } [ExpectValidation] From 9a18bef7930c3920654a16872d4dc002d1cc9b10 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 04:07:07 -0700 Subject: [PATCH 06/20] + [ExpectUpdate] coverage for RegionalSettingsDefinition #356 + CSOM impl --- ...ientRegionalSettingsDefinitionValidator.cs | 102 +++++++++++++++--- 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientRegionalSettingsDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientRegionalSettingsDefinitionValidator.cs index 1ac0fd59e..d32891f40 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientRegionalSettingsDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientRegionalSettingsDefinitionValidator.cs @@ -50,21 +50,95 @@ public override void DeployModel(object modelHost, DefinitionBase model) } else { + if (definition.CalendarType.HasValue) + assert.ShouldBeEqual(m => m.CalendarType, o => o.CalendarType); + else + assert.SkipProperty(m => m.CalendarType, "CalendarType is null or empty"); - assert - .ShouldBeEqual(m => m.AdjustHijriDays, o => o.AdjustHijriDays) - .ShouldBeEqual(m => m.AlternateCalendarType, o => o.AlternateCalendarType) - .ShouldBeEqual(m => m.CalendarType, o => o.CalendarType) - .ShouldBeEqual(m => m.Collation, o => o.Collation) - .ShouldBeEqual(m => m.FirstDayOfWeek, o => o.FirstDayOfWeek) - .ShouldBeEqual(m => m.FirstWeekOfYear, o => o.FirstWeekOfYear) - .ShouldBeEqual(m => m.LocaleId, o => o.LocaleId) - // weird stuff with these props - //.ShouldBeEqual(m => m.WorkDayEndHour, o => o.WorkDayEndHour) - //.ShouldBeEqual(m => m.WorkDayStartHour, o => o.WorkDayStartHour) - .ShouldBeEqual(m => m.WorkDays, o => o.WorkDays) - .ShouldBeEqual(m => m.ShowWeeks, o => o.ShowWeeks) - .ShouldBeEqual(m => m.Time24, o => o.Time24); + if (definition.AlternateCalendarType.HasValue) + assert.ShouldBeEqual(m => m.AlternateCalendarType, o => o.AlternateCalendarType); + else + assert.SkipProperty(m => m.AlternateCalendarType, "AlternateCalendarType is null or empty"); + + if (definition.AdjustHijriDays.HasValue) + assert.ShouldBeEqual(m => m.AdjustHijriDays, o => o.AdjustHijriDays); + else + assert.SkipProperty(m => m.AdjustHijriDays, "AdjustHijriDays is null or empty"); + + if (definition.Collation.HasValue) + assert.ShouldBeEqual(m => m.Collation, o => o.Collation); + else + assert.SkipProperty(m => m.Collation, "Collation is null or empty"); + + if (definition.WorkDayStartHour.HasValue) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.WorkDayStartHour); + // WHAT?? why minutes?? + var isValid = s.WorkDayStartHour == d.WorkDayStartHour / 60; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.WorkDayStartHour, "WorkDayStartHour is null or empty"); + + if (definition.WorkDayEndHour.HasValue) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.WorkDayEndHour); + // WHAT?? why minutes?? + var isValid = s.WorkDayEndHour == d.WorkDayEndHour / 60; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.WorkDayEndHour, "WorkDayEndHour is null or empty"); + + if (definition.WorkDays.HasValue) + assert.ShouldBeEqual(m => m.WorkDays, o => o.WorkDays); + else + assert.SkipProperty(m => m.WorkDays, "WorkDays is null or empty"); + + if (definition.Time24.HasValue) + assert.ShouldBeEqual(m => m.Time24, o => o.Time24); + else + assert.SkipProperty(m => m.Time24, "Time24 is null or empty"); + + if (definition.ShowWeeks.HasValue) + assert.ShouldBeEqual(m => m.ShowWeeks, o => o.ShowWeeks); + else + assert.SkipProperty(m => m.ShowWeeks, "ShowWeeks is null or empty"); + + if (definition.FirstDayOfWeek.HasValue) + assert.ShouldBeEqual(m => m.FirstWeekOfYear, o => o.FirstWeekOfYear); + else + assert.SkipProperty(m => m.FirstWeekOfYear, "FirstWeekOfYear is null or empty"); + + if (definition.FirstDayOfWeek.HasValue) + assert.ShouldBeEqual(m => m.FirstDayOfWeek, o => o.FirstDayOfWeek); + else + assert.SkipProperty(m => m.FirstDayOfWeek, "FirstDayOfWeek is null or empty"); + + if (definition.LocaleId.HasValue) + assert.ShouldBeEqual(m => m.LocaleId, o => o.LocaleId); + else + assert.SkipProperty(m => m.LocaleId, "LocaleId is null or empty"); if (definition.TimeZoneId.HasValue) { From 08583c25dee32a215e0e1d876080b74b51088b8c Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 05:30:36 -0700 Subject: [PATCH 07/20] + Enhance FieldDefinition with 'pushChangesToLists' option #922 + Added tests under "Regression.Scenarios.Fields.PushChangesToLists" category: * CanDeploy_Field_With_PushChangesToLists_OnSite * CanDeploy_Field_Without_PushChangesToLists_OnSite --- .../ClientListFieldLinkDefinitionValidator.cs | 37 ++- .../ListFieldLinkDefinitionValidator.cs | 305 ++++++++++-------- .../Impl/Scenarios/FieldScenariosTest.cs | 132 +++++++- 3 files changed, 333 insertions(+), 141 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientListFieldLinkDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientListFieldLinkDefinitionValidator.cs index d0e902b24..bf671391e 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientListFieldLinkDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientListFieldLinkDefinitionValidator.cs @@ -31,11 +31,44 @@ public override void DeployModel(object modelHost, DefinitionBase model) .ShouldNotBeNull(spObject) .ShouldBeEqualIfNotNullOrEmpty(m => m.FieldInternalName, o => o.InternalName) - .ShouldBeEqualIfNotNullOrEmpty(m => m.DisplayName, o => o.Title) .ShouldBeEqualIfHasValue(m => m.FieldId, o => o.Id) .ShouldBeEqualIfHasValue(m => m.Required, o => o.Required) - .ShouldBeEqualIfHasValue(m => m.Hidden, o => o.Hidden); + .ShouldBeEqualIfHasValue(m => m.Hidden, o => o.Hidden); + + if (!string.IsNullOrEmpty(definition.DisplayName)) + assert.ShouldBeEqual(m => m.DisplayName, o => o.Title); + else + { + + var regDisplayTitleProp = definition.PropertyBag.FirstOrDefault(p => p.Name == "_Reg_DisplayName"); + + if (regDisplayTitleProp != null) + { + // Enhance FieldDefinition with 'pushChangesToLists' option #922 + // https://github.com/SubPointSolutions/spmeta2/issues/922 + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.DisplayName); + var dstProp = d.GetExpressionValue(m => m.Title); + + var isValid = regDisplayTitleProp.Value == d.Title; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.DisplayName, "DisplayName is null or empty. Skipping"); + } + } if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.DefaultValue)) { diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Validation/ListFieldLinkDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM/Validation/ListFieldLinkDefinitionValidator.cs index ddac097ef..d096ba246 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Validation/ListFieldLinkDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Validation/ListFieldLinkDefinitionValidator.cs @@ -1,138 +1,167 @@ -using Microsoft.SharePoint; -using Microsoft.SharePoint.Utilities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using SPMeta2.Containers.Assertion; -using SPMeta2.Definitions; -using SPMeta2.SSOM.DefaultSyntax; -using SPMeta2.SSOM.ModelHandlers; -using SPMeta2.SSOM.ModelHosts; -using SPMeta2.Utils; -using System.Linq; -using SPMeta2.Enumerations; - -namespace SPMeta2.Regression.SSOM.Validation -{ - public class ListFieldLinkDefinitionValidator : ListFieldLinkModelHandler - { - public override void DeployModel(object modelHost, DefinitionBase model) - { - var listModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); - var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - - var list = listModelHost.HostList; - var spObject = FindExistingListField(list, definition); - - var assert = ServiceFactory.AssertService - .NewAssert(definition, spObject) - .ShouldNotBeNull(spObject); - - if (!string.IsNullOrEmpty(definition.FieldInternalName)) - assert.ShouldBeEqual(m => m.FieldInternalName, o => o.InternalName); - else - assert.SkipProperty(m => m.FieldInternalName, "FieldInternalName is null or empty. Skipping"); - - if (definition.FieldId.HasGuidValue()) - assert.ShouldBeEqual(m => m.FieldId, o => o.Id); - else - assert.SkipProperty(m => m.FieldId, "FieldId is null or empty. Skipping"); - - if (!string.IsNullOrEmpty(definition.DisplayName)) - assert.ShouldBeEqual(m => m.DisplayName, o => o.Title); - else - assert.SkipProperty(m => m.DisplayName, "DisplayName is null or empty. Skipping"); - - if (definition.Required.HasValue) - assert.ShouldBeEqual(m => m.Required, o => o.Required); - else - assert.SkipProperty(m => m.Required, "Required is null or empty. Skipping"); - - if (definition.Hidden.HasValue) - assert.ShouldBeEqual(m => m.Hidden, o => o.Hidden); - else - assert.SkipProperty(m => m.Hidden, "Hidden is null or empty. Skipping"); - - if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.DefaultValue)) - { - assert.SkipProperty(m => m.AddFieldOptions, "BuiltInAddFieldOptions.DefaultValue. Skipping."); - } - - if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.AddToAllContentTypes)) - { - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.AddFieldOptions); - var isValid = true; - - var listContentTypes = list.ContentTypes; - - foreach (SPContentType ct in listContentTypes) - { - // TODO! - if (ct.Name == "Folder") - { - // skip folder content type - continue; - } - - isValid = ct.FieldLinks.OfType().Count(l => l.Name == spObject.InternalName) > 0; - - if (!isValid) - break; - } - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - - if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.AddFieldToDefaultView)) - { - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.AddFieldOptions); - var isValid = false; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - - if (definition.AddToDefaultView) - { - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.AddToDefaultView); - var field = FindExistingListField(list, definition); - - var isValid = list.DefaultView - .ViewFields - .ToStringCollection() - .Contains(field.InternalName); - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - { - assert.SkipProperty(m => m.AddToDefaultView, "AddToDefaultView is false. Skipping."); - } - - } - } -} +using Microsoft.SharePoint; +using Microsoft.SharePoint.Utilities; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SPMeta2.Containers.Assertion; +using SPMeta2.Definitions; +using SPMeta2.SSOM.DefaultSyntax; +using SPMeta2.SSOM.ModelHandlers; +using SPMeta2.SSOM.ModelHosts; +using SPMeta2.Utils; +using System.Linq; +using SPMeta2.Enumerations; + +namespace SPMeta2.Regression.SSOM.Validation +{ + public class ListFieldLinkDefinitionValidator : ListFieldLinkModelHandler + { + public override void DeployModel(object modelHost, DefinitionBase model) + { + var listModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + + var list = listModelHost.HostList; + var spObject = FindExistingListField(list, definition); + + var assert = ServiceFactory.AssertService + .NewAssert(definition, spObject) + .ShouldNotBeNull(spObject); + + if (!string.IsNullOrEmpty(definition.FieldInternalName)) + assert.ShouldBeEqual(m => m.FieldInternalName, o => o.InternalName); + else + assert.SkipProperty(m => m.FieldInternalName, "FieldInternalName is null or empty. Skipping"); + + if (definition.FieldId.HasGuidValue()) + assert.ShouldBeEqual(m => m.FieldId, o => o.Id); + else + assert.SkipProperty(m => m.FieldId, "FieldId is null or empty. Skipping"); + + if (!string.IsNullOrEmpty(definition.DisplayName)) + assert.ShouldBeEqual(m => m.DisplayName, o => o.Title); + else + { + + var regDisplayTitleProp = definition.PropertyBag.FirstOrDefault(p => p.Name == "_Reg_DisplayName"); + + if (regDisplayTitleProp != null) + { + // Enhance FieldDefinition with 'pushChangesToLists' option #922 + // https://github.com/SubPointSolutions/spmeta2/issues/922 + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.DisplayName); + var dstProp = d.GetExpressionValue(m => m.Title); + + var isValid = regDisplayTitleProp.Value == d.Title; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.DisplayName, "DisplayName is null or empty. Skipping"); + } + } + + if (definition.Required.HasValue) + assert.ShouldBeEqual(m => m.Required, o => o.Required); + else + assert.SkipProperty(m => m.Required, "Required is null or empty. Skipping"); + + if (definition.Hidden.HasValue) + assert.ShouldBeEqual(m => m.Hidden, o => o.Hidden); + else + assert.SkipProperty(m => m.Hidden, "Hidden is null or empty. Skipping"); + + if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.DefaultValue)) + { + assert.SkipProperty(m => m.AddFieldOptions, "BuiltInAddFieldOptions.DefaultValue. Skipping."); + } + + if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.AddToAllContentTypes)) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.AddFieldOptions); + var isValid = true; + + var listContentTypes = list.ContentTypes; + + foreach (SPContentType ct in listContentTypes) + { + // TODO! + if (ct.Name == "Folder") + { + // skip folder content type + continue; + } + + isValid = ct.FieldLinks.OfType().Count(l => l.Name == spObject.InternalName) > 0; + + if (!isValid) + break; + } + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + + if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.AddFieldToDefaultView)) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.AddFieldOptions); + var isValid = false; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + + if (definition.AddToDefaultView) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.AddToDefaultView); + var field = FindExistingListField(list, definition); + + var isValid = list.DefaultView + .ViewFields + .ToStringCollection() + .Contains(field.InternalName); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.AddToDefaultView, "AddToDefaultView is false. Skipping."); + } + + } + } +} diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs index d001b7f13..49b2e62eb 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs @@ -20,6 +20,11 @@ using SPMeta2.Attributes.Regression; using SPMeta2.Containers.Extensions; +using SPMeta2.Exceptions; +using SPMeta2.Models; + +using SPMeta2.Regression.Tests.Utils; +using ReflectionUtils = SPMeta2.Utils.ReflectionUtils; namespace SPMeta2.Regression.Tests.Impl.Scenarios { @@ -456,7 +461,7 @@ protected List GetAllRandomFields() var spMetaAssembly = typeof(FieldDefinition).Assembly; var spMetaStandardAssembly = typeof(TaxonomyFieldDefinition).Assembly; - var types = ReflectionUtils.GetTypesFromAssemblies(new[] + var types = SPMeta2.Utils.ReflectionUtils.GetTypesFromAssemblies(new[] { spMetaAssembly, spMetaStandardAssembly @@ -1045,6 +1050,131 @@ public void CanDeploy_UserField_DefaultValue() #endregion + #region PushChangesToLists tests + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.PushChangesToLists")] + public void CanDeploy_Field_Without_PushChangesToLists_OnSite() + { + InternalDeploySiteFieldWithPushChangesToLists(false); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.Fields.PushChangesToLists")] + public void CanDeploy_Field_With_PushChangesToLists_OnSite() + { + InternalDeploySiteFieldWithPushChangesToLists(true); + } + + private void InternalDeploySiteFieldWithPushChangesToLists(bool pushChangesToLists) + { + var oldFieldTitle = Rnd.String(); + var newFieldTitle = Rnd.String(); + + var oldSharePointFieldTitle = string.Empty; + var newSharePointFieldTitle = string.Empty; + + // defs + var oldFieldDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.DefaultFormula = string.Empty; + def.ValidationFormula = string.Empty; + + def.Title = oldFieldTitle; + }); + + var newFieldDef = oldFieldDef.Inherit(def => + { + def.DefaultFormula = string.Empty; + def.ValidationFormula = string.Empty; + + def.Title = newFieldTitle; + }); + + var oldListDef = ModelGeneratorService.GetRandomDefinition(def => + { + + }); + + var newListDef = oldListDef.Inherit(def => + { + + }); + + var oldListFielLink = new ListFieldLinkDefinition + { + FieldId = oldFieldDef.Id + }; + + var newListFielLink = new ListFieldLinkDefinition + { + FieldId = oldFieldDef.Id + }; + + var oldSiteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddField(oldFieldDef); + }); + + var oldWebModel = SPMeta2Model.NewWebModel(web => + { + web.AddList(oldListDef, list => + { + list.AddListFieldLink(oldListFielLink); + }); + }); + + var newWebModel = SPMeta2Model.NewWebModel(web => + { + web.AddList(newListDef, list => + { + list.AddListFieldLink(newListFielLink); + }); + }); + + var newSiteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddField(newFieldDef); + }); + + // passing Reg_Title as definition PropertyBag + // later, validation handlers foe ListFieldLink will use Reg_Title instead of title + // bit if a hack + if (pushChangesToLists) + { + newListFielLink.PropertyBag.Add(new PropertyBagValue + { + Name = "_Reg_DisplayName", + Value = newFieldTitle + }); + } + else + { + newListFielLink.PropertyBag.Add(new PropertyBagValue + { + Name = "_Reg_DisplayName", + Value = oldFieldTitle + }); + } + + // deploy initial field and list + TestModel(oldSiteModel); + TestModel(oldWebModel); + + // deploy 'new' field model + TestModel(newSiteModel); + TestModel(newWebModel); + } + + private string ExtractFieldTitleFromObject(OnCreatingContext context) + { + var obj = context.Object; + + return obj.GetPropertyValue("Title") as string; + } + + #endregion + #region utils protected FieldDefinition GetLocalizedFieldDefinition() From 2a33fcd0d45262c334b05f5449f0be5a7b4c3fd0 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 15:55:34 -0700 Subject: [PATCH 08/20] + Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + boostrapped tests + passed SelfDiagnostic_AllFields_Should_Have_Value_Tests --- .../Impl/Scenarios/ListItemScenariousTest.cs | 1036 +++++++++++++---- 1 file changed, 802 insertions(+), 234 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ListItemScenariousTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ListItemScenariousTest.cs index 677b9ea6d..6217ddf47 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ListItemScenariousTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ListItemScenariousTest.cs @@ -1,234 +1,802 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using SPMeta2.Containers; -using SPMeta2.Definitions; -using SPMeta2.Enumerations; -using SPMeta2.Regression.Tests.Base; -using SPMeta2.Regression.Tests.Impl.Scenarios.Base; -using SPMeta2.Syntax.Default; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using SPMeta2.Definitions.Fields; -using SPMeta2.Regression.Tests.Prototypes; - - -namespace SPMeta2.Regression.Tests.Impl.Scenarios -{ - [TestClass] - public class ListItemScenariousTest : SPMeta2RegresionScenarioTestBase - { - #region internal - - [ClassInitializeAttribute] - public static void Init(TestContext context) - { - InternalInit(); - } - - [ClassCleanupAttribute] - public static void Cleanup() - { - InternalCleanup(); - } - - #endregion - - #region field values - - - [TestMethod] - [TestCategory("Regression.Scenarios.ListItems.Values")] - public void CanDeploy_ListItem_With_RequiredFieldValues() - { - var requiredText = RItemValues.GetRequiredTextField(ModelGeneratorService); - - var text1 = RItemValues.GetRandomTextField(ModelGeneratorService); - var text2 = RItemValues.GetRandomTextField(ModelGeneratorService); - - var contentTypeDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ParentContentTypeId = BuiltInContentTypeId.Item; - }); - - var itemDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ContentTypeName = contentTypeDef.Name; - - def.DefaultValues.Add(new FieldValue() - { - FieldName = requiredText.InternalName, - Value = Rnd.String() - }); - - def.Values.Add(new FieldValue() - { - FieldName = text1.InternalName, - Value = Rnd.String() - }); - - def.Values.Add(new FieldValue() - { - FieldName = text2.InternalName, - Value = Rnd.String() - }); - - }); - - var listDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ContentTypesEnabled = true; - def.TemplateType = BuiltInListTemplateTypeId.GenericList; - }); - - var siteModel = SPMeta2Model.NewSiteModel(site => - { - site.AddField(requiredText); - site.AddField(text1); - site.AddField(text2); - - site.AddContentType(contentTypeDef, contentType => - { - contentType.AddContentTypeFieldLink(requiredText); - contentType.AddContentTypeFieldLink(text1); - contentType.AddContentTypeFieldLink(text2); - }); - - }); - - var webModel = SPMeta2Model.NewWebModel(web => - { - web.AddList(listDef, list => - { - list.AddContentTypeLink(contentTypeDef); - list.AddListItem(itemDef); - }); - }); - - TestModel(siteModel, webModel); - } - - - [TestMethod] - [TestCategory("Regression.Scenarios.ListItems.Values")] - public void CanDeploy_ListItem_With_ContentType_ByName() - { - var contentTypeDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ParentContentTypeId = BuiltInContentTypeId.Item; - }); - - var itemDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ContentTypeName = contentTypeDef.Name; - }); - - var listDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ContentTypesEnabled = true; - def.TemplateType = BuiltInListTemplateTypeId.GenericList; - }); - - var siteModel = SPMeta2Model.NewSiteModel(site => - { - site.AddContentType(contentTypeDef); - }); - - var webModel = SPMeta2Model.NewWebModel(web => - { - web.AddList(listDef, list => - { - list.AddContentTypeLink(contentTypeDef); - list.AddListItem(itemDef); - }); - }); - - TestModel(siteModel, webModel); - } - - #endregion - - #region default list - - [TestMethod] - [TestCategory("Regression.Scenarios.ListItems")] - public void CanDeploy_ListItem_ToList() - { - var list = ModelGeneratorService.GetRandomDefinition(def => - { - def.EnableMinorVersions = false; - def.TemplateType = BuiltInListTemplateTypeId.GenericList; - }); - - var model = SPMeta2Model - .NewWebModel(web => - { - web.AddList(list, rndList => - { - rndList.AddRandomListItem(); - }); - - }); - - TestModel(model); - } - - - [TestMethod] - [TestCategory("Regression.Scenarios.ListItems")] - public void CanDeploy_ListItem_ToListFolder() - { - var list = ModelGeneratorService.GetRandomDefinition(def => - { - def.TemplateType = BuiltInListTemplateTypeId.GenericList; - }); - - var model = SPMeta2Model - .NewWebModel(web => - { - web.AddList(list, rndList => - { - rndList.AddRandomFolder(rndFolder => - { - rndFolder.AddRandomListItem(); - }); - }); - - }); - - TestModel(model); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ListItems")] - public void CanDeploy_ListItem_ToListSubFolder() - { - var list = ModelGeneratorService.GetRandomDefinition(def => - { - def.EnableMinorVersions = false; - def.TemplateType = BuiltInListTemplateTypeId.GenericList; - }); - - var model = SPMeta2Model - .NewWebModel(web => - { - web.AddList(list, rndList => - { - rndList.AddRandomFolder(rndFolder => - { - rndFolder.AddRandomFolder(rndSubFolder => - { - rndSubFolder.AddRandomListItem(); - }); - - }); - }); - - }); - - TestModel(model); - } - - #endregion - } -} +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SPMeta2.Containers; +using SPMeta2.Definitions; +using SPMeta2.Enumerations; +using SPMeta2.Regression.Tests.Base; +using SPMeta2.Regression.Tests.Impl.Scenarios.Base; +using SPMeta2.Syntax.Default; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using SPMeta2.Definitions.Fields; +using SPMeta2.Regression.Tests.Prototypes; +using SPMeta2.Standard.Definitions.Fields; +using SPMeta2.Utils; + + +namespace SPMeta2.Regression.Tests.Impl.Scenarios +{ + [TestClass] + public class ListItemScenariousSelfTest + { + #region default values + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + [TestCategory("CI.Core")] + public void SelfDiagnostic_AllFields_Should_Have_Value_Tests() + { + var isValid = true; + + var methods = typeof(ListItemScenariousTest).GetMethods(); + var targetTypes = new List(); + + var assemblies = new[] + { + typeof(FieldDefinition).Assembly, + typeof(TaxonomyFieldDefinition).Assembly + }; + + targetTypes.AddRange(ReflectionUtils.GetTypesFromAssemblies(assemblies)); + + Trace.WriteLine(string.Format("Found [{0}] fied types.", targetTypes.Count)); + + foreach (var fieldType in targetTypes.OrderBy(m => m.Name)) + { + var fullDefName = fieldType.Name; + var shortDefName = fieldType.Name.Replace("Definition", string.Empty); + + var testName1 = string.Format("CanDeploy_{0}_Value", shortDefName); + var testName2 = string.Format("CanDeploy_{0}_Values", shortDefName); + + var testExists1 = methods.Any(m => m.Name == testName1); + var testExists2 = methods.Any(m => m.Name == testName2); + + + if (!testExists1) + isValid = false; + + if (!testExists2) + isValid = false; + + Trace.WriteLine(string.Format("[{0}] def: {1} one value test method: {2}", + testExists1, fullDefName, testName1)); + + Trace.WriteLine(string.Format("[{0}] def: {1} multiple values test method: {2}", + testExists2, fullDefName, testName2)); + + Trace.WriteLine(string.Empty); + } + + Assert.IsTrue(isValid); + } + #endregion + } + + [TestClass] + public class ListItemScenariousTest : SPMeta2RegresionScenarioTestBase + { + #region internal + + [ClassInitializeAttribute] + public static void Init(TestContext context) + { + InternalInit(); + } + + [ClassCleanupAttribute] + public static void Cleanup() + { + InternalCleanup(); + } + + #endregion + + #region field values + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ListItem_With_RequiredFieldValues() + { + var requiredText = RItemValues.GetRequiredTextField(ModelGeneratorService); + + var text1 = RItemValues.GetRandomTextField(ModelGeneratorService); + var text2 = RItemValues.GetRandomTextField(ModelGeneratorService); + + var contentTypeDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ParentContentTypeId = BuiltInContentTypeId.Item; + }); + + var itemDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ContentTypeName = contentTypeDef.Name; + + def.DefaultValues.Add(new FieldValue() + { + FieldName = requiredText.InternalName, + Value = Rnd.String() + }); + + def.Values.Add(new FieldValue() + { + FieldName = text1.InternalName, + Value = Rnd.String() + }); + + def.Values.Add(new FieldValue() + { + FieldName = text2.InternalName, + Value = Rnd.String() + }); + + }); + + var listDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ContentTypesEnabled = true; + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var siteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddField(requiredText); + site.AddField(text1); + site.AddField(text2); + + site.AddContentType(contentTypeDef, contentType => + { + contentType.AddContentTypeFieldLink(requiredText); + contentType.AddContentTypeFieldLink(text1); + contentType.AddContentTypeFieldLink(text2); + }); + + }); + + var webModel = SPMeta2Model.NewWebModel(web => + { + web.AddList(listDef, list => + { + list.AddContentTypeLink(contentTypeDef); + list.AddListItem(itemDef); + }); + }); + + TestModel(siteModel, webModel); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ListItem_With_ContentType_ByName() + { + var contentTypeDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ParentContentTypeId = BuiltInContentTypeId.Item; + }); + + var itemDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ContentTypeName = contentTypeDef.Name; + }); + + var listDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ContentTypesEnabled = true; + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var siteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddContentType(contentTypeDef); + }); + + var webModel = SPMeta2Model.NewWebModel(web => + { + web.AddList(listDef, list => + { + list.AddContentTypeLink(contentTypeDef); + list.AddListItem(itemDef); + }); + }); + + TestModel(siteModel, webModel); + } + + #endregion + + #region default list + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems")] + public void CanDeploy_ListItem_ToList() + { + var list = ModelGeneratorService.GetRandomDefinition(def => + { + def.EnableMinorVersions = false; + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var model = SPMeta2Model + .NewWebModel(web => + { + web.AddList(list, rndList => + { + rndList.AddRandomListItem(); + }); + + }); + + TestModel(model); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems")] + public void CanDeploy_ListItem_ToListFolder() + { + var list = ModelGeneratorService.GetRandomDefinition(def => + { + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var model = SPMeta2Model + .NewWebModel(web => + { + web.AddList(list, rndList => + { + rndList.AddRandomFolder(rndFolder => + { + rndFolder.AddRandomListItem(); + }); + }); + + }); + + TestModel(model); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems")] + public void CanDeploy_ListItem_ToListSubFolder() + { + var list = ModelGeneratorService.GetRandomDefinition(def => + { + def.EnableMinorVersions = false; + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var model = SPMeta2Model + .NewWebModel(web => + { + web.AddList(list, rndList => + { + rndList.AddRandomFolder(rndFolder => + { + rndFolder.AddRandomFolder(rndSubFolder => + { + rndSubFolder.AddRandomListItem(); + }); + + }); + }); + + }); + + TestModel(model); + } + + #endregion + + #region field values + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_BooleanField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_BooleanField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_BusinessDataField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_BusinessDataField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_CalculatedField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_CalculatedField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ChoiceField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ChoiceField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ComputedField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ComputedField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_CurrencyField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_CurrencyField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_DateTimeField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_DateTimeField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_DependentLookupField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_DependentLookupField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_Field_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_Field_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_GeolocationField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_GeolocationField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_GuidField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_GuidField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_HTMLField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_HTMLField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ImageField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_ImageField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_LinkField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_LinkField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_LookupField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_LookupField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_MediaField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_MediaField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_MultiChoiceField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_MultiChoiceField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_NoteField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_NoteField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_NumberField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_NumberField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_OutcomeChoiceField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_OutcomeChoiceField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_SummaryLinkField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_SummaryLinkField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_TaxonomyField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_TaxonomyField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_TextField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_TextField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_URLField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_URLField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_UserField_Value() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ListItems.Values")] + public void CanDeploy_UserField_Values() + { + // Cover ListItemFieldValueDefinition/ListItemFieldValuesDefinition with regression test #533 + // https://github.com/SubPointSolutions/spmeta2/issues/533 + + throw new NotImplementedException(); + } + + #endregion + } +} From e568724d91bddde05b0f2c6dbf8a392f9f42be59 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Wed, 26 Oct 2016 20:12:57 -0700 Subject: [PATCH 09/20] + Add regression test on XsltListViewWebPart / ParameterBindings / related items #732 --- .../Validation/WebPartDefinitionValidator.cs | 767 +++++++++--------- .../Validation/WebPartDefinitionValidator.cs | 35 +- .../XsltListViewWebPartScenariosTest.cs | 72 ++ 3 files changed, 504 insertions(+), 370 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.CSOM/Validation/WebPartDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.CSOM/Validation/WebPartDefinitionValidator.cs index 02ed01ba6..9183764de 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM/Validation/WebPartDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM/Validation/WebPartDefinitionValidator.cs @@ -1,369 +1,398 @@ -using System.Net; -using Microsoft.SharePoint.Client; -using SPMeta2.Containers.Assertion; -using SPMeta2.CSOM.ModelHandlers; -using SPMeta2.CSOM.ModelHosts; -using SPMeta2.Definitions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Xml.Linq; -using SPMeta2.Attributes.Regression; -using SPMeta2.CSOM.Extensions; -using SPMeta2.Definitions.Base; -using SPMeta2.Enumerations; -using SPMeta2.Utils; -using SPMeta2.Services; - -namespace SPMeta2.Regression.CSOM.Validation -{ - public class WebPartDefinitionValidator : WebPartModelHandler - { - protected XDocument CurrentWebPartXml { get; set; } - - public override void DeployModel(object modelHost, DefinitionBase model) - { - var listItemModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); - var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - - var pageFile = listItemModelHost.HostFile; - var context = pageFile.Context; - - context.Load(pageFile); - context.ExecuteQueryWithTrace(); - - var siteServerUrl = listItemModelHost.HostSite.ServerRelativeUrl; - var webUrl = listItemModelHost.HostWeb.Url; - - var serverUrl = context.Url; - - if (siteServerUrl != "/") - serverUrl = context.Url.Split(new string[] { siteServerUrl }, StringSplitOptions.RemoveEmptyEntries)[0]; - - var absItemUrl = UrlUtility.CombineUrl(serverUrl, pageFile.ServerRelativeUrl); - - WithExistingWebPart(pageFile, definition, (spObject, spObjectDefintion) => - { +using System.Net; +using Microsoft.SharePoint.Client; +using SPMeta2.Containers.Assertion; +using SPMeta2.CSOM.ModelHandlers; +using SPMeta2.CSOM.ModelHosts; +using SPMeta2.Definitions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Xml.Linq; +using SPMeta2.Attributes.Regression; +using SPMeta2.CSOM.Extensions; +using SPMeta2.Definitions.Base; +using SPMeta2.Enumerations; +using SPMeta2.Utils; +using SPMeta2.Services; + +namespace SPMeta2.Regression.CSOM.Validation +{ + public class WebPartDefinitionValidator : WebPartModelHandler + { + protected XDocument CurrentWebPartXml { get; set; } + + public override void DeployModel(object modelHost, DefinitionBase model) + { + var listItemModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + + var pageFile = listItemModelHost.HostFile; + var context = pageFile.Context; + + context.Load(pageFile); + context.ExecuteQueryWithTrace(); + + var siteServerUrl = listItemModelHost.HostSite.ServerRelativeUrl; + var webUrl = listItemModelHost.HostWeb.Url; + + var serverUrl = context.Url; + + if (siteServerUrl != "/") + serverUrl = context.Url.Split(new string[] { siteServerUrl }, StringSplitOptions.RemoveEmptyEntries)[0]; + + var absItemUrl = UrlUtility.CombineUrl(serverUrl, pageFile.ServerRelativeUrl); + + WithExistingWebPart(pageFile, definition, (spObject, spObjectDefintion) => + { var webpartExportUrl = UrlUtility.CombineUrl(new[]{ webUrl, "_vti_bin/exportwp.aspx?pageurl=" + absItemUrl + "&" + "guidstring=" + spObjectDefintion.Id.ToString() - }); - - var assert = ServiceFactory.AssertService - .NewAssert(model, definition, spObject) - .ShouldNotBeNull(spObject); - - var webClient = new WebClient(); - - if (context.Credentials != null) - { - webClient.Credentials = context.Credentials; - webClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); - } - else - webClient.UseDefaultCredentials = true; - - var webPartXmlString = webClient.DownloadString(webpartExportUrl); - CurrentWebPartXml = WebpartXmlExtensions.LoadWebpartXmlDocument(webPartXmlString); - - - assert.ShouldBeEqual(m => m.Title, o => o.Title); - - // checking the web part type, shoul be as expected - // Add regression on 'expected' web part type #690 - - var currentType = CurrentWebPartXml.GetWebPartAssemblyQualifiedName(); - var currentClassName = currentType.Split(',').First().Trim(); - - var expectedTypeAttr = (definition.GetType().GetCustomAttributes(typeof(ExpectWebpartType)) - .FirstOrDefault() as ExpectWebpartType); - - // NULL can be on generic web part - // test should not care about that case, there other tests to enfore that attr usage - if (expectedTypeAttr != null) - { - var expectedType = expectedTypeAttr.WebPartType; - - var expectedClassName = expectedType.Split(',').First().Trim(); - - assert.ShouldBeEqual((p, s, d) => - { - var isValid = true; - - isValid = currentClassName.ToUpper() == expectedClassName.ToUpper(); - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = null, - Dst = null, - IsValid = isValid - }; - }); - } - - // props - - if (definition.Properties.Count > 0) - { - assert.ShouldBeEqual((p, s, d) => - { - var isValid = true; - - foreach (var prop in definition.Properties) - { - // returns correct one depending on the V2/V3 - var value = CurrentWebPartXml.GetProperty(prop.Name); - - // that True / true issue give a pain - // toLower for the time being - isValid = value.ToLower() == prop.Value.ToLower(); - - if (!isValid) - break; - } - - var srcProp = s.GetExpressionValue(m => m.Properties); - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.Properties, "Properties are empty. Skipping."); - - - if (!string.IsNullOrEmpty(definition.ExportMode)) - { - var value = CurrentWebPartXml.GetExportMode(); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.ExportMode); - var isValid = definition.ExportMode == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.ExportMode, "ExportMode is null or empty. Skipping."); - - if (!string.IsNullOrEmpty(definition.ChromeState)) - { - var value = CurrentWebPartXml.GetChromeState(); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.ChromeState); - var isValid = definition.ChromeState == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.ChromeState, "ChromeState is null or empty. Skipping."); - - if (!string.IsNullOrEmpty(definition.ChromeType)) - { - // returns correct one depending on the V2/V3 - var value = CurrentWebPartXml.GetChromeType(); - - var chromeType = string.Empty; - - if (CurrentWebPartXml.IsV3version()) - chromeType = WebPartChromeTypesConvertService.NormilizeValueToPartChromeTypes(definition.ChromeType); - else if (CurrentWebPartXml.IsV2version()) - chromeType = WebPartChromeTypesConvertService.NormilizeValueToFrameTypes(definition.ChromeType); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.ChromeType); - var isValid = chromeType == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.ChromeType, "ChromeType is null or empty. Skipping."); - - if (!string.IsNullOrEmpty(definition.Description)) - { - var value = CurrentWebPartXml.GetProperty("Description"); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.Description); - var isValid = (srcProp.Value as string) == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - { - assert.SkipProperty(m => m.Description, "Description is null or empty. Skipping."); - } - - if (definition.Height.HasValue) - { - var value = ConvertUtils.ToInt(CurrentWebPartXml.GetProperty("Height").Replace("px", string.Empty)); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.Height); - var isValid = definition.Height == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.Height, "Height is null or empty. Skipping."); - - if (definition.Width.HasValue) - { - var value = ConvertUtils.ToInt(CurrentWebPartXml.GetProperty("Width").Replace("px", string.Empty)); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.Width); - var isValid = definition.Width == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - { - assert.SkipProperty(m => m.Width, "Width is NULL, skipping"); - } - - if (!string.IsNullOrEmpty(definition.ImportErrorMessage)) - { - var value = CurrentWebPartXml.GetImportErrorMessage(); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.ImportErrorMessage); - var isValid = definition.ImportErrorMessage == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.ImportErrorMessage, "ImportErrorMessage is null or empty. Skipping."); - - if (!string.IsNullOrEmpty(definition.TitleIconImageUrl)) - { - var value = CurrentWebPartXml.GetTitleIconImageUrl(); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.TitleIconImageUrl); - var isValid = definition.TitleIconImageUrl == value; - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.TitleIconImageUrl, "TitleIconImageUrl is null or empty. Skipping."); - - if (!string.IsNullOrEmpty(definition.TitleUrl)) - { - var value = CurrentWebPartXml.GetTitleUrl(); - var defValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext - { - Context = listItemModelHost, - Value = value - }).Value; - - var isValid = defValue.ToUpper() == value.ToUpper(); - - assert.ShouldBeEqual((p, s, d) => - { - var srcProp = s.GetExpressionValue(m => m.TitleUrl); - - return new PropertyValidationResult - { - Tag = p.Tag, - Src = srcProp, - Dst = null, - IsValid = isValid - }; - }); - } - else - assert.SkipProperty(m => m.TitleUrl, "TitleUrl is null or empty. Skipping."); - - - assert.SkipProperty(m => m.WebpartFileName, "WebpartFileName is null or empty. Skipping."); - assert.SkipProperty(m => m.WebpartType, "WebpartType is null or empty. Skipping."); - assert.SkipProperty(m => m.WebpartXmlTemplate, "WebpartXmlTemplate is null or empty. Skipping."); - - assert.SkipProperty(m => m.ZoneId, "ZoneId is null or empty. Skipping."); - assert.SkipProperty(m => m.ZoneIndex, "ZoneIndex is null or empty. Skipping."); - - assert.SkipProperty(m => m.Id, "Id is null or empty. Skipping."); - - if (definition.ParameterBindings.Count == 0) - { - assert.SkipProperty(m => m.ParameterBindings, "ParameterBindings is null or empty. Skipping."); - } - else - { - // TODO + }); + + var assert = ServiceFactory.AssertService + .NewAssert(model, definition, spObject) + .ShouldNotBeNull(spObject); + + var webClient = new WebClient(); + + if (context.Credentials != null) + { + webClient.Credentials = context.Credentials; + webClient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f"); + } + else + webClient.UseDefaultCredentials = true; + + var webPartXmlString = webClient.DownloadString(webpartExportUrl); + CurrentWebPartXml = WebpartXmlExtensions.LoadWebpartXmlDocument(webPartXmlString); + + + assert.ShouldBeEqual(m => m.Title, o => o.Title); + + // checking the web part type, shoul be as expected + // Add regression on 'expected' web part type #690 + + var currentType = CurrentWebPartXml.GetWebPartAssemblyQualifiedName(); + var currentClassName = currentType.Split(',').First().Trim(); + + var expectedTypeAttr = (definition.GetType().GetCustomAttributes(typeof(ExpectWebpartType)) + .FirstOrDefault() as ExpectWebpartType); + + // NULL can be on generic web part + // test should not care about that case, there other tests to enfore that attr usage + if (expectedTypeAttr != null) + { + var expectedType = expectedTypeAttr.WebPartType; + + var expectedClassName = expectedType.Split(',').First().Trim(); + + assert.ShouldBeEqual((p, s, d) => + { + var isValid = true; + + isValid = currentClassName.ToUpper() == expectedClassName.ToUpper(); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = null, + Dst = null, + IsValid = isValid + }; + }); + } + + // props + + if (definition.Properties.Count > 0) + { + assert.ShouldBeEqual((p, s, d) => + { + var isValid = true; + + foreach (var prop in definition.Properties) + { + // returns correct one depending on the V2/V3 + var value = CurrentWebPartXml.GetProperty(prop.Name); + + // that True / true issue give a pain + // toLower for the time being + isValid = value.ToLower() == prop.Value.ToLower(); + + if (!isValid) + break; + } + + var srcProp = s.GetExpressionValue(m => m.Properties); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.Properties, "Properties are empty. Skipping."); + + + if (!string.IsNullOrEmpty(definition.ExportMode)) + { + var value = CurrentWebPartXml.GetExportMode(); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.ExportMode); + var isValid = definition.ExportMode == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.ExportMode, "ExportMode is null or empty. Skipping."); + + if (!string.IsNullOrEmpty(definition.ChromeState)) + { + var value = CurrentWebPartXml.GetChromeState(); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.ChromeState); + var isValid = definition.ChromeState == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.ChromeState, "ChromeState is null or empty. Skipping."); + + if (!string.IsNullOrEmpty(definition.ChromeType)) + { + // returns correct one depending on the V2/V3 + var value = CurrentWebPartXml.GetChromeType(); + + var chromeType = string.Empty; + + if (CurrentWebPartXml.IsV3version()) + chromeType = WebPartChromeTypesConvertService.NormilizeValueToPartChromeTypes(definition.ChromeType); + else if (CurrentWebPartXml.IsV2version()) + chromeType = WebPartChromeTypesConvertService.NormilizeValueToFrameTypes(definition.ChromeType); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.ChromeType); + var isValid = chromeType == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.ChromeType, "ChromeType is null or empty. Skipping."); + + if (!string.IsNullOrEmpty(definition.Description)) + { + var value = CurrentWebPartXml.GetProperty("Description"); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.Description); + var isValid = (srcProp.Value as string) == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.Description, "Description is null or empty. Skipping."); + } + + if (definition.Height.HasValue) + { + var value = ConvertUtils.ToInt(CurrentWebPartXml.GetProperty("Height").Replace("px", string.Empty)); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.Height); + var isValid = definition.Height == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.Height, "Height is null or empty. Skipping."); + + if (definition.Width.HasValue) + { + var value = ConvertUtils.ToInt(CurrentWebPartXml.GetProperty("Width").Replace("px", string.Empty)); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.Width); + var isValid = definition.Width == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.Width, "Width is NULL, skipping"); + } + + if (!string.IsNullOrEmpty(definition.ImportErrorMessage)) + { + var value = CurrentWebPartXml.GetImportErrorMessage(); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.ImportErrorMessage); + var isValid = definition.ImportErrorMessage == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.ImportErrorMessage, "ImportErrorMessage is null or empty. Skipping."); + + if (!string.IsNullOrEmpty(definition.TitleIconImageUrl)) + { + var value = CurrentWebPartXml.GetTitleIconImageUrl(); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.TitleIconImageUrl); + var isValid = definition.TitleIconImageUrl == value; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.TitleIconImageUrl, "TitleIconImageUrl is null or empty. Skipping."); + + if (!string.IsNullOrEmpty(definition.TitleUrl)) + { + var value = CurrentWebPartXml.GetTitleUrl(); + var defValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext + { + Context = listItemModelHost, + Value = value + }).Value; + + var isValid = defValue.ToUpper() == value.ToUpper(); + + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.TitleUrl); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + assert.SkipProperty(m => m.TitleUrl, "TitleUrl is null or empty. Skipping."); + + + assert.SkipProperty(m => m.WebpartFileName, "WebpartFileName is null or empty. Skipping."); + assert.SkipProperty(m => m.WebpartType, "WebpartType is null or empty. Skipping."); + assert.SkipProperty(m => m.WebpartXmlTemplate, "WebpartXmlTemplate is null or empty. Skipping."); + + assert.SkipProperty(m => m.ZoneId, "ZoneId is null or empty. Skipping."); + assert.SkipProperty(m => m.ZoneIndex, "ZoneIndex is null or empty. Skipping."); + + assert.SkipProperty(m => m.Id, "Id is null or empty. Skipping."); + + if (definition.ParameterBindings.Count == 0) + { + assert.SkipProperty(m => m.ParameterBindings, "ParameterBindings is null or empty. Skipping."); + } + else + { + assert.ShouldBeEqual((p, s, d) => + { + // that's a fast hack + // hope we eoudn't have other web part with ParameterBindings :) + var webPartBindings = CurrentWebPartXml.GetProperty("ParameterBindings"); + var isValid = true; + + var srcProp = s.GetExpressionValue(m => m.ParameterBindings); + + // one more hack, fix up later + // just checking presense of the strings + foreach (var srcBinding in s.ParameterBindings) + { + var hasName = webPartBindings.Contains(srcBinding.Name); + var hasValue = webPartBindings.Contains(srcBinding.Location); + + if (!hasName || !hasValue) + { + isValid = false; + } + } + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); } if (!string.IsNullOrEmpty(definition.AuthorizationFilter)) @@ -387,9 +416,9 @@ public override void DeployModel(object modelHost, DefinitionBase model) else { assert.SkipProperty(m => m.AuthorizationFilter, "AuthorizationFilter is null or empty. Skipping."); - } - - }); - } - } -} + } + + }); + } + } +} diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Validation/WebPartDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM/Validation/WebPartDefinitionValidator.cs index 6902cbf2d..92524a852 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Validation/WebPartDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Validation/WebPartDefinitionValidator.cs @@ -19,7 +19,9 @@ using System.IO; using System.Reflection; using System.Xml; +using Microsoft.SharePoint.WebPartPages; using SPMeta2.Attributes.Regression; +using WebPart = System.Web.UI.WebControls.WebParts.WebPart; namespace SPMeta2.Regression.SSOM.Validation { @@ -376,7 +378,38 @@ public override void DeployModel(object modelHost, DefinitionBase model) } else { - // TODO + + + assert.ShouldBeEqual((p, s, d) => + { + // that's a fast hack + // hope we eoudn't have other web part with ParameterBindings :) + var webPart = d as DataFormWebPart; + var isValid = true; + + var srcProp = s.GetExpressionValue(m => m.ParameterBindings); + + // one more hack, fix up later + // just checking presense of the strings + foreach (var srcBinding in s.ParameterBindings) + { + var hasName = webPart.ParameterBindings.Contains(srcBinding.Name); + var hasValue = webPart.ParameterBindings.Contains(srcBinding.Location); + + if (!hasName || !hasValue) + { + isValid = false; + } + } + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); } if (!string.IsNullOrEmpty(definition.AuthorizationFilter)) diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/Webparts/XsltListViewWebPartScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/Webparts/XsltListViewWebPartScenariosTest.cs index 4b1341576..14e3f61a5 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/Webparts/XsltListViewWebPartScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/Webparts/XsltListViewWebPartScenariosTest.cs @@ -1063,5 +1063,77 @@ public void CanDeploy_XsltListViewWebPart_At_SubWeb_FromRootWeb() } #endregion + + #region parameter bindings + + [TestMethod] + [TestCategory("Regression.Scenarios.Webparts.XsltListViewWebPart.ParameterBindings")] + public void CanDeploy_XsltListViewWebPart_With_ParameterBindings_ID_Filtering() + { + var dstList = ModelGeneratorService.GetRandomDefinition(def => + { + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var sourceList = ModelGeneratorService.GetRandomDefinition(def => + { + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var sourceListView = ModelGeneratorService.GetRandomDefinition(def => + { + def.Query = "{ID}"; + def.Hidden = true; + }); + + // this web part would be binded to list view + // it will also be performing 'filtering' via query string - ID + var xsltListViewWebpart = ModelGeneratorService.GetRandomDefinition(def => + { + def.ListId = Guid.Empty; + def.ListTitle = sourceList.Title; + def.ListUrl = string.Empty; + + def.ViewName = sourceListView.Title; + def.ViewId = null; + + def.JSLink = string.Empty; + + def.ParameterBindings.Add(new ParameterBindingValue + { + Name = "ID", + Location = "QueryString(ID)" + }); + }); + + var model = SPMeta2Model.NewWebModel(web => + { + web + .AddList(sourceList, list => + { + list.AddListView(sourceListView); + + list + .AddRandomListItem() + .AddRandomListItem() + .AddRandomListItem(); + }) + .AddList(dstList, list => + { + list + .AddRandomListItem() + .AddRandomListItem(); + + list.AddHostListView(BuiltInListViewDefinitions.Lists.EditForm, view => + { + view.AddXsltListViewWebPart(xsltListViewWebpart); + }); + }); + }); + + TestModel(model); + } + + #endregion } } From 3d9f96a3a2e7e8c9ca14e42afb5cd5be6c35ee2a Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Thu, 27 Oct 2016 15:02:43 -0700 Subject: [PATCH 10/20] + Enhance ContentTypeDefinition - support Name renaming #924 + CanDeploy_ContentType_And_Rename test for both CSOM/SSOM --- .../Scenarios/ContentTypeScenariosTest.cs | 1399 +++++++++-------- .../ModelHandlers/ContentTypeModelHandler.cs | 1 + 2 files changed, 742 insertions(+), 658 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ContentTypeScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ContentTypeScenariosTest.cs index b0272b4e8..d224c4580 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ContentTypeScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/ContentTypeScenariosTest.cs @@ -1,597 +1,597 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using SPMeta2.Containers; -using SPMeta2.Definitions; -using SPMeta2.Definitions.ContentTypes; -using SPMeta2.Enumerations; -using SPMeta2.Models; -using SPMeta2.Regression.Tests.Base; -using SPMeta2.Regression.Tests.Impl.Scenarios.Base; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using SPMeta2.Containers.Extensions; -using SPMeta2.Containers.Services; -using SPMeta2.Syntax.Default; -using SPMeta2.Syntax.Default.Modern; -using SPMeta2.Utils; -using SPMeta2.Containers.Templates.Documents; -using SPMeta2.Standard.Enumerations; - -namespace SPMeta2.Regression.Tests.Impl.Scenarios -{ - [TestClass] - public class ContentTypeScenariosTest : SPMeta2RegresionScenarioTestBase - { - #region internal - - [ClassInitializeAttribute] - public static void Init(TestContext context) - { - InternalInit(); - } - - [ClassCleanupAttribute] - public static void Cleanup() - { - InternalCleanup(); - } - - #endregion - - #region scopes - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.Scopes")] - public void CanDeploy_SiteScoped_ContentType() - { - var contentType = ModelGeneratorService.GetRandomDefinition(); - - var model = SPMeta2Model - .NewSiteModel(site => - { - site.AddContentType(contentType); - }); - - TestModel(model); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.Scopes")] - public void CanDeploy_WebScoped_ContentType() - { - var contentType = ModelGeneratorService.GetRandomDefinition(); - - var model = SPMeta2Model - .NewWebModel(web => - { - web.AddRandomWeb(subWeb => - { - subWeb.AddContentType(contentType); - }); - }); - - TestModel(model); - } - - - #endregion - - #region default - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes")] - public void CanDeploy_CustomListItemContentType() - { - TestRandomDefinition(def => - { - def.ParentContentTypeId = BuiltInContentTypeId.Item; - }); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes")] - public void CanDeploy_CustomListItemContentType_ByParentName() - { - TestRandomDefinition(def => - { - def.ParentContentTypeId = string.Empty; - def.ParentContentTypeName = BuiltInContentTypeNames.Item; - }); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes")] - public void CanDeploy_CustomDocumentContentType() - { - TestRandomDefinition(def => - { - def.ParentContentTypeId = BuiltInContentTypeId.Document; - }); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes")] - public void CanDeploy_CustomDocumentContentType_ByParentName() - { - TestRandomDefinition(def => - { - def.ParentContentTypeId = string.Empty; - def.ParentContentTypeName = BuiltInContentTypeNames.Document; - }); - } - - protected List GetHierarchicalContentTypes() - { - var root = ModelGeneratorService.GetRandomDefinition(def => - { - def.ParentContentTypeId = BuiltInContentTypeId.Item; - }); - - var levelOne = ModelGeneratorService.GetRandomDefinition(def => - { - def.ParentContentTypeId = root.GetContentTypeId(); - }); - - var levelTwo = ModelGeneratorService.GetRandomDefinition(def => - { - def.ParentContentTypeId = levelOne.GetContentTypeId(); - }); - +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SPMeta2.Containers; +using SPMeta2.Definitions; +using SPMeta2.Definitions.ContentTypes; +using SPMeta2.Enumerations; +using SPMeta2.Models; +using SPMeta2.Regression.Tests.Base; +using SPMeta2.Regression.Tests.Impl.Scenarios.Base; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SPMeta2.Containers.Extensions; +using SPMeta2.Containers.Services; +using SPMeta2.Syntax.Default; +using SPMeta2.Syntax.Default.Modern; +using SPMeta2.Utils; +using SPMeta2.Containers.Templates.Documents; +using SPMeta2.Standard.Enumerations; + +namespace SPMeta2.Regression.Tests.Impl.Scenarios +{ + [TestClass] + public class ContentTypeScenariosTest : SPMeta2RegresionScenarioTestBase + { + #region internal + + [ClassInitializeAttribute] + public static void Init(TestContext context) + { + InternalInit(); + } + + [ClassCleanupAttribute] + public static void Cleanup() + { + InternalCleanup(); + } + + #endregion + + #region scopes + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.Scopes")] + public void CanDeploy_SiteScoped_ContentType() + { + var contentType = ModelGeneratorService.GetRandomDefinition(); + + var model = SPMeta2Model + .NewSiteModel(site => + { + site.AddContentType(contentType); + }); + + TestModel(model); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.Scopes")] + public void CanDeploy_WebScoped_ContentType() + { + var contentType = ModelGeneratorService.GetRandomDefinition(); + + var model = SPMeta2Model + .NewWebModel(web => + { + web.AddRandomWeb(subWeb => + { + subWeb.AddContentType(contentType); + }); + }); + + TestModel(model); + } + + + #endregion + + #region default + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes")] + public void CanDeploy_CustomListItemContentType() + { + TestRandomDefinition(def => + { + def.ParentContentTypeId = BuiltInContentTypeId.Item; + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes")] + public void CanDeploy_CustomListItemContentType_ByParentName() + { + TestRandomDefinition(def => + { + def.ParentContentTypeId = string.Empty; + def.ParentContentTypeName = BuiltInContentTypeNames.Item; + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes")] + public void CanDeploy_CustomDocumentContentType() + { + TestRandomDefinition(def => + { + def.ParentContentTypeId = BuiltInContentTypeId.Document; + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes")] + public void CanDeploy_CustomDocumentContentType_ByParentName() + { + TestRandomDefinition(def => + { + def.ParentContentTypeId = string.Empty; + def.ParentContentTypeName = BuiltInContentTypeNames.Document; + }); + } + + protected List GetHierarchicalContentTypes() + { + var root = ModelGeneratorService.GetRandomDefinition(def => + { + def.ParentContentTypeId = BuiltInContentTypeId.Item; + }); + + var levelOne = ModelGeneratorService.GetRandomDefinition(def => + { + def.ParentContentTypeId = root.GetContentTypeId(); + }); + + var levelTwo = ModelGeneratorService.GetRandomDefinition(def => + { + def.ParentContentTypeId = levelOne.GetContentTypeId(); + }); + return new List(new ContentTypeDefinition[] { root, levelOne, levelTwo - }); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.ParentChild")] - public void CanDeploy_HierarchicalContentTypesOrderByIdAcs() - { - var contentTypes = GetHierarchicalContentTypes(); - - contentTypes.Sort(delegate(ContentTypeDefinition c1, ContentTypeDefinition c2) - { - return c1.IsChildOf(c2) ? -1 : 1; - }); - - var siteModel = SPMeta2Model - .NewSiteModel(site => - { - site.AddContentTypes(contentTypes); - }); - - TestModel(siteModel); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.ParentChild")] - public void CanDeploy_HierarchicalContentTypesOrderByIdDesc() - { - var contentTypes = GetHierarchicalContentTypes(); - contentTypes = contentTypes.OrderByDescending(c => c.Id).ToList(); - - contentTypes.Sort(delegate(ContentTypeDefinition c1, ContentTypeDefinition c2) - { - return c1.IsChildOf(c2) ? 1 : -1; - }); - - var siteModel = SPMeta2Model - .NewSiteModel(site => - { - site.AddContentTypes(contentTypes); - }); - - TestModel(siteModel); - } - - #endregion - - #region utils - - protected class ContentTypeEnvironment - { - public FieldDefinition First { get; set; } - public FieldDefinition Second { get; set; } - public FieldDefinition Third { get; set; } - - public ModelNode FirstLink { get; set; } - public ModelNode SecondLink { get; set; } - public ModelNode ThirdLink { get; set; } - - public ContentTypeDefinition ContentType { get; set; } - - public SiteModelNode SiteModel { get; set; } - } - - private ContentTypeEnvironment GetContentTypeSandbox( - Action siteModelConfig, - Action contentTypeModelConfig) - { - var result = new ContentTypeEnvironment(); - - // site model - - FieldDefinition fldFirst = null; - FieldDefinition fldSecond = null; - FieldDefinition fldThird = null; - - var siteModel = SPMeta2Model - .NewSiteModel(site => - { - site - .AddRandomField(ct => { fldFirst = ct.Value as FieldDefinition; }) - .AddRandomField(ct => { fldSecond = ct.Value as FieldDefinition; }) - .AddRandomField(ct => { fldThird = ct.Value as FieldDefinition; }) - .AddRandomContentType(contentType => - { - fldFirst.Title = "first_" + fldFirst.Title; - fldSecond.Title = "second_" + fldSecond.Title; - fldThird.Title = "third_" + fldThird.Title; - - result.First = fldFirst; - result.Second = fldSecond; - result.Third = fldThird; - - result.ContentType = contentType.Value as ContentTypeDefinition; - - contentType - .AddContentTypeFieldLink(fldFirst, link => - { - result.FirstLink = link; - //link.Options.RequireSelfProcessing = link.Value.RequireSelfProcessing = true; - link.Options.RequireSelfProcessing = true; - }) - .AddContentTypeFieldLink(fldSecond, link => - { - result.SecondLink = link; - //link.Options.RequireSelfProcessing = link.Value.RequireSelfProcessing = true; - link.Options.RequireSelfProcessing = true; - }) - .AddContentTypeFieldLink(fldThird, link => - { - result.ThirdLink = link; - //link.Options.RequireSelfProcessing = link.Value.RequireSelfProcessing = true; - link.Options.RequireSelfProcessing = true; - }); - - if (contentTypeModelConfig != null) - contentTypeModelConfig(contentType, result); - }); - }); - - result.SiteModel = siteModel; - - if (siteModelConfig != null) - siteModelConfig(result.SiteModel, result); - - return result; - } - - #endregion - - #region content type fields links - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] - public void CanDeploy_CanHideContentTypeFieldLinks() - { - var env = GetContentTypeSandbox( - (siteModel, e) => - { - - }, - (contentTypeModel, e) => - { - contentTypeModel - .AddHideContentTypeFieldLinks(new HideContentTypeFieldLinksDefinition - { + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.ParentChild")] + public void CanDeploy_HierarchicalContentTypesOrderByIdAcs() + { + var contentTypes = GetHierarchicalContentTypes(); + + contentTypes.Sort(delegate(ContentTypeDefinition c1, ContentTypeDefinition c2) + { + return c1.IsChildOf(c2) ? -1 : 1; + }); + + var siteModel = SPMeta2Model + .NewSiteModel(site => + { + site.AddContentTypes(contentTypes); + }); + + TestModel(siteModel); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.ParentChild")] + public void CanDeploy_HierarchicalContentTypesOrderByIdDesc() + { + var contentTypes = GetHierarchicalContentTypes(); + contentTypes = contentTypes.OrderByDescending(c => c.Id).ToList(); + + contentTypes.Sort(delegate(ContentTypeDefinition c1, ContentTypeDefinition c2) + { + return c1.IsChildOf(c2) ? 1 : -1; + }); + + var siteModel = SPMeta2Model + .NewSiteModel(site => + { + site.AddContentTypes(contentTypes); + }); + + TestModel(siteModel); + } + + #endregion + + #region utils + + protected class ContentTypeEnvironment + { + public FieldDefinition First { get; set; } + public FieldDefinition Second { get; set; } + public FieldDefinition Third { get; set; } + + public ModelNode FirstLink { get; set; } + public ModelNode SecondLink { get; set; } + public ModelNode ThirdLink { get; set; } + + public ContentTypeDefinition ContentType { get; set; } + + public SiteModelNode SiteModel { get; set; } + } + + private ContentTypeEnvironment GetContentTypeSandbox( + Action siteModelConfig, + Action contentTypeModelConfig) + { + var result = new ContentTypeEnvironment(); + + // site model + + FieldDefinition fldFirst = null; + FieldDefinition fldSecond = null; + FieldDefinition fldThird = null; + + var siteModel = SPMeta2Model + .NewSiteModel(site => + { + site + .AddRandomField(ct => { fldFirst = ct.Value as FieldDefinition; }) + .AddRandomField(ct => { fldSecond = ct.Value as FieldDefinition; }) + .AddRandomField(ct => { fldThird = ct.Value as FieldDefinition; }) + .AddRandomContentType(contentType => + { + fldFirst.Title = "first_" + fldFirst.Title; + fldSecond.Title = "second_" + fldSecond.Title; + fldThird.Title = "third_" + fldThird.Title; + + result.First = fldFirst; + result.Second = fldSecond; + result.Third = fldThird; + + result.ContentType = contentType.Value as ContentTypeDefinition; + + contentType + .AddContentTypeFieldLink(fldFirst, link => + { + result.FirstLink = link; + //link.Options.RequireSelfProcessing = link.Value.RequireSelfProcessing = true; + link.Options.RequireSelfProcessing = true; + }) + .AddContentTypeFieldLink(fldSecond, link => + { + result.SecondLink = link; + //link.Options.RequireSelfProcessing = link.Value.RequireSelfProcessing = true; + link.Options.RequireSelfProcessing = true; + }) + .AddContentTypeFieldLink(fldThird, link => + { + result.ThirdLink = link; + //link.Options.RequireSelfProcessing = link.Value.RequireSelfProcessing = true; + link.Options.RequireSelfProcessing = true; + }); + + if (contentTypeModelConfig != null) + contentTypeModelConfig(contentType, result); + }); + }); + + result.SiteModel = siteModel; + + if (siteModelConfig != null) + siteModelConfig(result.SiteModel, result); + + return result; + } + + #endregion + + #region content type fields links + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] + public void CanDeploy_CanHideContentTypeFieldLinks() + { + var env = GetContentTypeSandbox( + (siteModel, e) => + { + + }, + (contentTypeModel, e) => + { + contentTypeModel + .AddHideContentTypeFieldLinks(new HideContentTypeFieldLinksDefinition + { Fields = new List { new FieldLinkValue { InternalName = e.Second.InternalName }, new FieldLinkValue { InternalName = e.First.InternalName }, - } - }); - }); - - TestModel(env.SiteModel); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] - public void CanDeploy_CanRemoveContentTypeFieldLinks() - { - var env = GetContentTypeSandbox( - (siteModel, e) => - { - - }, - (contentTypeModel, e) => - { - contentTypeModel - .AddRemoveContentTypeFieldLinks(new RemoveContentTypeFieldLinksDefinition - { + } + }); + }); + + TestModel(env.SiteModel); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] + public void CanDeploy_CanRemoveContentTypeFieldLinks() + { + var env = GetContentTypeSandbox( + (siteModel, e) => + { + + }, + (contentTypeModel, e) => + { + contentTypeModel + .AddRemoveContentTypeFieldLinks(new RemoveContentTypeFieldLinksDefinition + { Fields = new List { new FieldLinkValue { InternalName = e.Second.InternalName }, new FieldLinkValue { InternalName = e.First.InternalName }, - } - }, m => - { - m.OnProvisioned(ctx => - { - // disable validation on content type field links as they would be deleted by 'RemoveContentTypeFieldLinksDefinition' - - //e.FirstLink.Options.RequireSelfProcessing = e.FirstLink.Value.RequireSelfProcessing = false; - //e.SecondLink.Options.RequireSelfProcessing = e.SecondLink.Value.RequireSelfProcessing = false; - //e.ThirdLink.Options.RequireSelfProcessing = e.ThirdLink.Value.RequireSelfProcessing = false; - - e.FirstLink.Options.RequireSelfProcessing = false; - e.SecondLink.Options.RequireSelfProcessing = false; - e.ThirdLink.Options.RequireSelfProcessing = false; - }); - }); - }); - - TestModel(env.SiteModel); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] - public void CanDeploy_CanSetupUniqueContentTypeFieldsOrder() - { - var env = GetContentTypeSandbox( - (siteModel, e) => - { - - }, - (contentTypeModel, e) => - { - contentTypeModel - .AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition - { - + } + }, m => + { + m.OnProvisioned(ctx => + { + // disable validation on content type field links as they would be deleted by 'RemoveContentTypeFieldLinksDefinition' + + //e.FirstLink.Options.RequireSelfProcessing = e.FirstLink.Value.RequireSelfProcessing = false; + //e.SecondLink.Options.RequireSelfProcessing = e.SecondLink.Value.RequireSelfProcessing = false; + //e.ThirdLink.Options.RequireSelfProcessing = e.ThirdLink.Value.RequireSelfProcessing = false; + + e.FirstLink.Options.RequireSelfProcessing = false; + e.SecondLink.Options.RequireSelfProcessing = false; + e.ThirdLink.Options.RequireSelfProcessing = false; + }); + }); + }); + + TestModel(env.SiteModel); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] + public void CanDeploy_CanSetupUniqueContentTypeFieldsOrder() + { + var env = GetContentTypeSandbox( + (siteModel, e) => + { + + }, + (contentTypeModel, e) => + { + contentTypeModel + .AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition + { + Fields = new List { new FieldLinkValue { InternalName = e.Second.InternalName }, new FieldLinkValue { InternalName = e.First.InternalName }, - } - }); - }); - - TestModel(env.SiteModel); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] - public void CanDeploy_CanSetupUniqueContentTypeFieldsOrder_At_OOTB_List_Scope() - { - var fieldDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.Hidden = false; - - def.ShowInDisplayForm = true; - def.ShowInEditForm = true; - def.ShowInListSettings = true; - def.ShowInNewForm = true; - def.ShowInViewForms = true; - - def.AddFieldOptions = BuiltInAddFieldOptions.AddToAllContentTypes - | BuiltInAddFieldOptions.AddFieldInternalNameHint; - }); - - var listDef = ModelGeneratorService.GetRandomDefinition(def => - { - def.ContentTypesEnabled = false; - def.TemplateType = BuiltInListTemplateTypeId.GenericList; - }); - - var contentTypeLinkDef = new ContentTypeLinkDefinition - { - ContentTypeName = BuiltInContentTypeNames.Item, - ContentTypeId = BuiltInContentTypeId.Item - }; - - var webModel = SPMeta2Model.NewWebModel(web => - { - // adding field first - web.AddList(listDef, list => - { - list.AddField(fieldDef, field => - { - - }); - }); - - // then working with the content type - web.AddList(listDef.Inherit(), list => - { - list.AddContentTypeLink(contentTypeLinkDef, contenTypeLink => - { - contenTypeLink.RegExcludeFromEventsValidation(); - - contenTypeLink.AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition - { - + } + }); + }); + + TestModel(env.SiteModel); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] + public void CanDeploy_CanSetupUniqueContentTypeFieldsOrder_At_OOTB_List_Scope() + { + var fieldDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.Hidden = false; + + def.ShowInDisplayForm = true; + def.ShowInEditForm = true; + def.ShowInListSettings = true; + def.ShowInNewForm = true; + def.ShowInViewForms = true; + + def.AddFieldOptions = BuiltInAddFieldOptions.AddToAllContentTypes + | BuiltInAddFieldOptions.AddFieldInternalNameHint; + }); + + var listDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ContentTypesEnabled = false; + def.TemplateType = BuiltInListTemplateTypeId.GenericList; + }); + + var contentTypeLinkDef = new ContentTypeLinkDefinition + { + ContentTypeName = BuiltInContentTypeNames.Item, + ContentTypeId = BuiltInContentTypeId.Item + }; + + var webModel = SPMeta2Model.NewWebModel(web => + { + // adding field first + web.AddList(listDef, list => + { + list.AddField(fieldDef, field => + { + + }); + }); + + // then working with the content type + web.AddList(listDef.Inherit(), list => + { + list.AddContentTypeLink(contentTypeLinkDef, contenTypeLink => + { + contenTypeLink.RegExcludeFromEventsValidation(); + + contenTypeLink.AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition + { + Fields = new List { new FieldLinkValue {InternalName = fieldDef.InternalName}, new FieldLinkValue {InternalName = "Title"}, - } - }); - }); - }); - }); - - TestModel(webModel); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] - public void CanDeploy_CanSetupUniqueContentTypeFieldsOrder_At_List_Scope() - { - // Support 'UniqueContentTypeFieldsOrderDefinition' at list level content types #742 - // https://github.com/SubPointSolutions/spmeta2/issues/742 - - WithDisabledPropertyUpdateValidation(() => - { - var first = string.Empty; - var second = string.Empty; - - var env = GetContentTypeSandbox( - (siteModel, e) => - { - - }, - (contentTypeModel, e) => - { - first = e.First.InternalName; - second = e.Second.InternalName; - - contentTypeModel - .AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition - { + } + }); + }); + }); + }); + + TestModel(webModel); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.FieldLinks")] + public void CanDeploy_CanSetupUniqueContentTypeFieldsOrder_At_List_Scope() + { + // Support 'UniqueContentTypeFieldsOrderDefinition' at list level content types #742 + // https://github.com/SubPointSolutions/spmeta2/issues/742 + + WithDisabledPropertyUpdateValidation(() => + { + var first = string.Empty; + var second = string.Empty; + + var env = GetContentTypeSandbox( + (siteModel, e) => + { + + }, + (contentTypeModel, e) => + { + first = e.First.InternalName; + second = e.Second.InternalName; + + contentTypeModel + .AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition + { Fields = new List { new FieldLinkValue {InternalName = e.Second.InternalName}, new FieldLinkValue {InternalName = e.First.InternalName}, - } - }); - }); - - var webModel = SPMeta2Model.NewWebModel(web => - { - web.AddRandomList(list => - { - (list.Value as ListDefinition).ContentTypesEnabled = true; - - list.AddContentTypeLink(env.ContentType, contenTypeLink => - { - contenTypeLink.AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition - { - + } + }); + }); + + var webModel = SPMeta2Model.NewWebModel(web => + { + web.AddRandomList(list => + { + (list.Value as ListDefinition).ContentTypesEnabled = true; + + list.AddContentTypeLink(env.ContentType, contenTypeLink => + { + contenTypeLink.AddUniqueContentTypeFieldsOrder(new UniqueContentTypeFieldsOrderDefinition + { + Fields = new List { new FieldLinkValue {InternalName = first}, new FieldLinkValue {InternalName = second}, - } - }); - }); - }); - }); - - TestModel(env.SiteModel, webModel); - }); - } - - #endregion - - #region doc templates - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.DocumentTemplate")] - public void CanDeploy_ContentType_WithDocTemplate_In_ResourceFolder() - { - var siteContentType = ModelGeneratorService.GetRandomDefinition(); - var documentTemplate = ModelGeneratorService.GetRandomDefinition(def => - { - def.Content = DocumentTemplates.SPMeta2_MSWord_Template; - def.FileName = Rnd.String() + ".dotx"; - }); - - - siteContentType.DocumentTemplate = documentTemplate.FileName; - - var siteModel = SPMeta2Model.NewSiteModel(site => - { - site.AddContentType(siteContentType, contentType => - { - contentType.AddModuleFile(documentTemplate); - }); - }); - - var contentModel = SPMeta2Model.NewWebModel(web => - { - web.AddRandomDocumentLibrary(list => - { - list.AddContentTypeLink(siteContentType); - }); - }); - - TestModels(new ModelNode[] { siteModel, contentModel }); - } - - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.DocumentTemplate")] - public void CanDeploy_ContentType_WithDocTemplate_In_RootWeb_DocumentLibrary() - { - var siteContentType = ModelGeneratorService.GetRandomDefinition(); - - var documentTemplate = ModelGeneratorService.GetRandomDefinition(def => - { - def.Content = DocumentTemplates.SPMeta2_MSWord_Template; - def.FileName = Rnd.String() + ".dotx"; - }); - - var documentTemplateLibrary = ModelGeneratorService.GetRandomDefinition(def => - { - def.TemplateType = BuiltInListTemplateTypeId.DocumentLibrary; - }); - + } + }); + }); + }); + }); + + TestModel(env.SiteModel, webModel); + }); + } + + #endregion + + #region doc templates + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.DocumentTemplate")] + public void CanDeploy_ContentType_WithDocTemplate_In_ResourceFolder() + { + var siteContentType = ModelGeneratorService.GetRandomDefinition(); + var documentTemplate = ModelGeneratorService.GetRandomDefinition(def => + { + def.Content = DocumentTemplates.SPMeta2_MSWord_Template; + def.FileName = Rnd.String() + ".dotx"; + }); + + + siteContentType.DocumentTemplate = documentTemplate.FileName; + + var siteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddContentType(siteContentType, contentType => + { + contentType.AddModuleFile(documentTemplate); + }); + }); + + var contentModel = SPMeta2Model.NewWebModel(web => + { + web.AddRandomDocumentLibrary(list => + { + list.AddContentTypeLink(siteContentType); + }); + }); + + TestModels(new ModelNode[] { siteModel, contentModel }); + } + + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.DocumentTemplate")] + public void CanDeploy_ContentType_WithDocTemplate_In_RootWeb_DocumentLibrary() + { + var siteContentType = ModelGeneratorService.GetRandomDefinition(); + + var documentTemplate = ModelGeneratorService.GetRandomDefinition(def => + { + def.Content = DocumentTemplates.SPMeta2_MSWord_Template; + def.FileName = Rnd.String() + ".dotx"; + }); + + var documentTemplateLibrary = ModelGeneratorService.GetRandomDefinition(def => + { + def.TemplateType = BuiltInListTemplateTypeId.DocumentLibrary; + }); + siteContentType.DocumentTemplate = UrlUtility.CombineUrl(new[]{ "~sitecollection", #pragma warning disable 618 documentTemplateLibrary.Url, #pragma warning restore 618 documentTemplate.FileName - }); - - var siteModel = SPMeta2Model.NewSiteModel(site => - { - site.AddContentType(siteContentType); - }); - - var webModel = SPMeta2Model.NewWebModel(web => - { - web.AddList(documentTemplateLibrary, list => - { - list.AddModuleFile(documentTemplate); - }); - }); - - var contentModel = SPMeta2Model.NewWebModel(web => - { - web.AddRandomDocumentLibrary(list => - { - list.AddContentTypeLink(siteContentType); - }); - }); - - TestModels(new ModelNode[] { webModel, siteModel, contentModel }); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.DocumentTemplate")] - public void CanDeploy_ContentType_WithDocTemplate_In_SubWeb_DocumentLibrary() - { - var siteContentType = ModelGeneratorService.GetRandomDefinition(); - - var documentTemplate = ModelGeneratorService.GetRandomDefinition(def => - { - def.Content = DocumentTemplates.SPMeta2_MSWord_Template; - def.FileName = Rnd.String() + ".dotx"; - }); - - var documentTemplateLibrary = ModelGeneratorService.GetRandomDefinition(def => - { - def.TemplateType = BuiltInListTemplateTypeId.DocumentLibrary; - }); - - var subWebDef = ModelGeneratorService.GetRandomDefinition(); - + }); + + var siteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddContentType(siteContentType); + }); + + var webModel = SPMeta2Model.NewWebModel(web => + { + web.AddList(documentTemplateLibrary, list => + { + list.AddModuleFile(documentTemplate); + }); + }); + + var contentModel = SPMeta2Model.NewWebModel(web => + { + web.AddRandomDocumentLibrary(list => + { + list.AddContentTypeLink(siteContentType); + }); + }); + + TestModels(new ModelNode[] { webModel, siteModel, contentModel }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.DocumentTemplate")] + public void CanDeploy_ContentType_WithDocTemplate_In_SubWeb_DocumentLibrary() + { + var siteContentType = ModelGeneratorService.GetRandomDefinition(); + + var documentTemplate = ModelGeneratorService.GetRandomDefinition(def => + { + def.Content = DocumentTemplates.SPMeta2_MSWord_Template; + def.FileName = Rnd.String() + ".dotx"; + }); + + var documentTemplateLibrary = ModelGeneratorService.GetRandomDefinition(def => + { + def.TemplateType = BuiltInListTemplateTypeId.DocumentLibrary; + }); + + var subWebDef = ModelGeneratorService.GetRandomDefinition(); + siteContentType.DocumentTemplate = UrlUtility.CombineUrl(new[]{ "~sitecollection", subWebDef.Url, @@ -599,102 +599,185 @@ public void CanDeploy_ContentType_WithDocTemplate_In_SubWeb_DocumentLibrary() documentTemplateLibrary.Url, #pragma warning restore 618 documentTemplate.FileName - }); - - var siteModel = SPMeta2Model.NewSiteModel(site => - { - site.AddContentType(siteContentType); - }); - - var webModel = SPMeta2Model.NewWebModel(web => - { - web.AddWeb(subWebDef, subWeb => - { - subWeb.AddList(documentTemplateLibrary, list => - { - list.AddModuleFile(documentTemplate); - }); - }); - - - }); - - var contentModel = SPMeta2Model.NewWebModel(web => - { - web.AddRandomDocumentLibrary(list => - { - list.AddContentTypeLink(siteContentType); - }); - }); - - TestModels(new ModelNode[] { webModel, siteModel, contentModel }); - } - - #endregion - - #region localization - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.Localization")] - public void CanDeploy_Localized_Site_ContentType() - { - var definition = GetLocalizedDefinition(); - - var model = SPMeta2Model.NewSiteModel(site => - { - site.AddContentType(definition); - }); - - TestModel(model); - } - - [TestMethod] - [TestCategory("Regression.Scenarios.ContentTypes.Localization")] - public void CanDeploy_Localized_Web_ContentType() - { - var contentType = GetLocalizedDefinition(); - var subWebContentType = GetLocalizedDefinition(); - - var model = SPMeta2Model.NewWebModel(web => - { - web.AddContentType(contentType); - - web.AddRandomWeb(subWeb => - { - subWeb.AddContentType(subWebContentType); - }); - }); - - TestModel(model); - } - - #endregion - - #region utils - - protected ContentTypeDefinition GetLocalizedDefinition() - { - var definition = ModelGeneratorService.GetRandomDefinition(); - var localeIds = Rnd.LocaleIds(); - - foreach (var localeId in localeIds) - { - definition.NameResource.Add(new ValueForUICulture - { - CultureId = localeId, - Value = string.Format("LocalizedName_{0}", localeId) - }); - - definition.DescriptionResource.Add(new ValueForUICulture - { - CultureId = localeId, - Value = string.Format("LocalizedDescription_{0}", localeId) - }); - } - - return definition; - } - - #endregion - } -} + }); + + var siteModel = SPMeta2Model.NewSiteModel(site => + { + site.AddContentType(siteContentType); + }); + + var webModel = SPMeta2Model.NewWebModel(web => + { + web.AddWeb(subWebDef, subWeb => + { + subWeb.AddList(documentTemplateLibrary, list => + { + list.AddModuleFile(documentTemplate); + }); + }); + + + }); + + var contentModel = SPMeta2Model.NewWebModel(web => + { + web.AddRandomDocumentLibrary(list => + { + list.AddContentTypeLink(siteContentType); + }); + }); + + TestModels(new ModelNode[] { webModel, siteModel, contentModel }); + } + + #endregion + + #region localization + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.Localization")] + public void CanDeploy_Localized_Site_ContentType() + { + var definition = GetLocalizedDefinition(); + + var model = SPMeta2Model.NewSiteModel(site => + { + site.AddContentType(definition); + }); + + TestModel(model); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.Localization")] + public void CanDeploy_Localized_Web_ContentType() + { + var contentType = GetLocalizedDefinition(); + var subWebContentType = GetLocalizedDefinition(); + + var model = SPMeta2Model.NewWebModel(web => + { + web.AddContentType(contentType); + + web.AddRandomWeb(subWeb => + { + subWeb.AddContentType(subWebContentType); + }); + }); + + TestModel(model); + } + + #endregion + + #region renaming + + [TestMethod] + [TestCategory("Regression.Scenarios.ContentTypes.Renaming")] + public void CanDeploy_ContentType_And_Rename() + { + // Enhance ContentTypeDefinition - support Name renaming #924 + // https://github.com/SubPointSolutions/spmeta2/issues/924 + + // we should be able to deploy and then rename content types + // 3 waves of deployment: original, and two renames + // all should work, including model validations with the new Names + + // we need to add content type field links to ensure two paths: + // 1) model handler provisions content types + // 2) model handler resolves content type to pass further to the provision flow + + var originalContentTypes = new List(); + + originalContentTypes.Add(ModelGeneratorService.GetRandomDefinition()); + originalContentTypes.Add(ModelGeneratorService.GetRandomDefinition()); + + var firstRenames = originalContentTypes.Select(d => + { + return d.Inherit(def => + { + def.Name = Rnd.String(); + }); + }); + + var secondRenames = originalContentTypes.Select(d => + { + return d.Inherit(def => + { + def.Name = Rnd.String(); + }); + }); + + // deploy and test original content types + var originalModel = SPMeta2Model.NewSiteModel(site => + { + foreach (var ct in originalContentTypes) + { + site.AddContentType(ct, contentType => + { + contentType.AddContentTypeFieldLink(BuiltInFieldId.Title); + }); + } + }); + + TestModel(originalModel); + + // deploy and test first renames + var firstRenamesModel = SPMeta2Model.NewSiteModel(site => + { + foreach (var ct in firstRenames) + { + site.AddContentType(ct, contentType => + { + contentType.AddContentTypeFieldLink(BuiltInFieldId.Title); + }); + } + }); + + TestModel(firstRenamesModel); + + // deploy and test first renames + var secondRenamesModel = SPMeta2Model.NewSiteModel(site => + { + foreach (var ct in secondRenames) + { + site.AddContentType(ct, contentType => + { + contentType.AddContentTypeFieldLink(BuiltInFieldId.Title); + }); + } + }); + + TestModel(secondRenamesModel); + } + + #endregion + + #region utils + + protected ContentTypeDefinition GetLocalizedDefinition() + { + var definition = ModelGeneratorService.GetRandomDefinition(); + var localeIds = Rnd.LocaleIds(); + + foreach (var localeId in localeIds) + { + definition.NameResource.Add(new ValueForUICulture + { + CultureId = localeId, + Value = string.Format("LocalizedName_{0}", localeId) + }); + + definition.DescriptionResource.Add(new ValueForUICulture + { + CultureId = localeId, + Value = string.Format("LocalizedDescription_{0}", localeId) + }); + } + + return definition; + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/ContentTypeModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/ContentTypeModelHandler.cs index d24fa320c..3b54023c4 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/ContentTypeModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/ContentTypeModelHandler.cs @@ -105,6 +105,7 @@ public override void DeployModel(object modelHost, DefinitionBase model) // by ID, by Name var targetContentType = tmpWeb.ContentTypes[contentTypeId]; + // fallback to name if (targetContentType == null) { targetContentType = tmpWeb.ContentTypes From 2f5475cdd65004f48c2e24036eac21f093d28338 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Thu, 27 Oct 2016 15:31:08 -0700 Subject: [PATCH 11/20] + Enhance FarmSolutionDefinition provision #324 + LCID fixes, nullable by default to avoid defined localization --- .../ModelHandlers/FarmSolutionModelHandler.cs | 228 +++++++++--------- .../Definitions/FarmSolutionDefinition.cs | 129 +++++----- 2 files changed, 184 insertions(+), 173 deletions(-) diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs index 06fbe72aa..b92b854a4 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs @@ -1,114 +1,122 @@ -using System.IO; -using Microsoft.SharePoint; -using Microsoft.SharePoint.Administration; -using SPMeta2.Common; -using SPMeta2.Definitions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using SPMeta2.Definitions.Base; -using SPMeta2.Services; -using SPMeta2.SSOM.ModelHosts; -using SPMeta2.Utils; - -namespace SPMeta2.SSOM.ModelHandlers -{ - public class FarmSolutionModelHandler : SSOMModelHandlerBase - { - #region properties - - public override Type TargetType - { - get { return typeof(FarmSolutionDefinition); } - } - - #endregion - - #region methods - - public override void DeployModel(object modelHost, DefinitionBase model) - { - var farmModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); - var solutionModel = model.WithAssertAndCast("model", value => value.RequireNotNull()); - - DeploySolution(farmModelHost, solutionModel); - } - - protected SPSolution FindExistingSolution(FarmModelHost modelHost, FarmSolutionDefinition definition) - { - TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, - "Resolving farm solution by SolutionId: [{0}] and Name: [{1}]", +using System.IO; +using Microsoft.SharePoint; +using Microsoft.SharePoint.Administration; +using SPMeta2.Common; +using SPMeta2.Definitions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using SPMeta2.Definitions.Base; +using SPMeta2.Services; +using SPMeta2.SSOM.ModelHosts; +using SPMeta2.Utils; + +namespace SPMeta2.SSOM.ModelHandlers +{ + public class FarmSolutionModelHandler : SSOMModelHandlerBase + { + #region properties + + public override Type TargetType + { + get { return typeof(FarmSolutionDefinition); } + } + + #endregion + + #region methods + + public override void DeployModel(object modelHost, DefinitionBase model) + { + var farmModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + var solutionModel = model.WithAssertAndCast("model", value => value.RequireNotNull()); + + DeploySolution(farmModelHost, solutionModel); + } + + protected SPSolution FindExistingSolution(FarmModelHost modelHost, FarmSolutionDefinition definition) + { + TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, + "Resolving farm solution by SolutionId: [{0}] and Name: [{1}]", new object[] { definition.SolutionId, definition.FileName - }); - - var farm = modelHost.HostFarm; - - return farm.Solutions.FirstOrDefault(s => - s.Name.ToUpper() == definition.FileName.ToUpper() || - definition.SolutionId != Guid.Empty && s.SolutionId == definition.SolutionId); - } - - private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition definition) - { - var farm = modelHost.HostFarm; - var existringSolution = FindExistingSolution(modelHost, definition); - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioning, - Object = existringSolution, - ObjectType = typeof(SPSolution), - ObjectDefinition = definition, - ModelHost = modelHost - }); - - var tmpWspDirectory = string.Format("{0}_{1}", Path.GetFileNameWithoutExtension(definition.FileName), Guid.NewGuid().ToString("N")); - var tmpWspDirectoryPath = Path.Combine(Path.GetTempPath(), tmpWspDirectory); - - Directory.CreateDirectory(tmpWspDirectoryPath); - - var tmpWspFilPath = Path.Combine(tmpWspDirectoryPath, definition.FileName); - File.WriteAllBytes(tmpWspFilPath, definition.Content); - - if (existringSolution == null) - { - TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new farm solution"); - existringSolution = farm.Solutions.Add(tmpWspFilPath, (uint)definition.LCID); - } - else - { - TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Upgrading existing farm solution"); - - if (existringSolution.Deployed) - { - existringSolution.Upgrade(tmpWspFilPath); - } - else - { - // TODO - // https://github.com/SubPointSolutions/spmeta2/issues/324 - } - } - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = existringSolution, - ObjectType = typeof(SPSolution), - ObjectDefinition = definition, - ModelHost = modelHost - }); - } - - #endregion - } -} + }); + + var farm = modelHost.HostFarm; + + return farm.Solutions.FirstOrDefault(s => + s.Name.ToUpper() == definition.FileName.ToUpper() || + definition.SolutionId != Guid.Empty && s.SolutionId == definition.SolutionId); + } + + private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition definition) + { + var farm = modelHost.HostFarm; + var existringSolution = FindExistingSolution(modelHost, definition); + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioning, + Object = existringSolution, + ObjectType = typeof(SPSolution), + ObjectDefinition = definition, + ModelHost = modelHost + }); + + var tmpWspDirectory = string.Format("{0}_{1}", Path.GetFileNameWithoutExtension(definition.FileName), Guid.NewGuid().ToString("N")); + var tmpWspDirectoryPath = Path.Combine(Path.GetTempPath(), tmpWspDirectory); + + Directory.CreateDirectory(tmpWspDirectoryPath); + + var tmpWspFilPath = Path.Combine(tmpWspDirectoryPath, definition.FileName); + File.WriteAllBytes(tmpWspFilPath, definition.Content); + + if (existringSolution == null) + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new farm solution"); + + if (definition.LCID.HasValue) + { + existringSolution = farm.Solutions.Add(tmpWspFilPath, (uint)definition.LCID); + } + else + { + existringSolution = farm.Solutions.Add(tmpWspFilPath); + } + } + else + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Upgrading existing farm solution"); + + if (existringSolution.Deployed) + { + existringSolution.Upgrade(tmpWspFilPath); + } + else + { + // TODO + // https://github.com/SubPointSolutions/spmeta2/issues/324 + } + } + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = existringSolution, + ObjectType = typeof(SPSolution), + ObjectDefinition = definition, + ModelHost = modelHost + }); + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs b/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs index a63011256..4edbeb883 100644 --- a/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs +++ b/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs @@ -1,63 +1,66 @@ -using System; -using System.Runtime.Serialization; -using SPMeta2.Attributes; -using SPMeta2.Attributes.Capabilities; -using SPMeta2.Attributes.Regression; -using SPMeta2.Definitions.Base; -using SPMeta2.Utils; - -namespace SPMeta2.Definitions -{ - /// - /// Allows to define and deploy SharePoint farm solution. - /// - /// - - [SPObjectType(SPObjectModelType.SSOM, "Microsoft.SharePoint.Administration.SPSolution", "Microsoft.SharePoint")] - - [DefaultParentHost(typeof(FarmDefinition))] - [DefaultRootHost(typeof(FarmDefinition))] - - [Serializable] - [DataContract] - [ExpectWithExtensionMethod] - - [ParentHostCapability(typeof(FarmDefinition))] - [ExpectManyInstances] - public class FarmSolutionDefinition : SolutionDefinitionBase - { - #region constructors - - public FarmSolutionDefinition() - { - LCID = 1033; - Content = new byte[0]; - } - - #endregion - - #region properties - - /// - /// Locale for the current solution. - /// - /// - [DataMember] - public int LCID { get; set; } - - #endregion - - #region methods - - public override string ToString() - { - return new ToStringResult(this) - .AddPropertyValue(p => p.FileName) - .AddPropertyValue(p => p.SolutionId) - .AddPropertyValue(p => p.LCID) - .ToString(); - } - - #endregion - } -} +using System; +using System.Runtime.Serialization; +using SPMeta2.Attributes; +using SPMeta2.Attributes.Capabilities; +using SPMeta2.Attributes.Regression; +using SPMeta2.Definitions.Base; +using SPMeta2.Utils; + +namespace SPMeta2.Definitions +{ + /// + /// Allows to define and deploy SharePoint farm solution. + /// + /// + + [SPObjectType(SPObjectModelType.SSOM, "Microsoft.SharePoint.Administration.SPSolution", "Microsoft.SharePoint")] + + [DefaultParentHost(typeof(FarmDefinition))] + [DefaultRootHost(typeof(FarmDefinition))] + + [Serializable] + [DataContract] + [ExpectWithExtensionMethod] + + [ParentHostCapability(typeof(FarmDefinition))] + [ExpectManyInstances] + public class FarmSolutionDefinition : SolutionDefinitionBase + { + #region constructors + + public FarmSolutionDefinition() + { + // made int? + // no locale by default + //LCID = 1033; + + Content = new byte[0]; + } + + #endregion + + #region properties + + /// + /// Locale for the current solution. + /// + /// + [DataMember] + public int? LCID { get; set; } + + #endregion + + #region methods + + public override string ToString() + { + return new ToStringResult(this) + .AddPropertyValue(p => p.FileName) + .AddPropertyValue(p => p.SolutionId) + .AddPropertyValue(p => p.LCID) + .ToString(); + } + + #endregion + } +} From 4fe2e4b040037c828bd04de79968c4999f863568 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Thu, 27 Oct 2016 22:45:03 -0700 Subject: [PATCH 12/20] + Enhance FarmSolutionDefinition provision #324 + added new tests under Regression.Scenarios.FarmSolution --- .../Scenarios/FarmSolutionScenariosTest.cs | 175 ++++++++++++++ .../SPMeta2.Regression.Tests.csproj | 1 + .../ModelHandlers/FarmSolutionModelHandler.cs | 228 ++++++++++++++++-- .../Definitions/FarmSolutionDefinition.cs | 57 ++++- 4 files changed, 437 insertions(+), 24 deletions(-) create mode 100644 SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs new file mode 100644 index 000000000..fd58c955b --- /dev/null +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SPMeta2.BuiltInDefinitions; +using SPMeta2.Containers; +using SPMeta2.Containers.Standard; +using SPMeta2.Definitions; +using SPMeta2.Enumerations; +using SPMeta2.Models; +using SPMeta2.Regression.Tests.Definitions; +using SPMeta2.Regression.Tests.Impl.Scenarios.Base; +using SPMeta2.Standard.Definitions; +using SPMeta2.Syntax.Default; +using SPMeta2.Validation.Validators.Relationships; + +namespace SPMeta2.Regression.Tests.Impl.Scenarios +{ + [TestClass] + public class FarmSolutionScenariosTest : SPMeta2RegresionScenarioTestBase + { + #region internal + + [ClassInitializeAttribute] + public static void Init(TestContext context) + { + InternalInit(); + } + + [ClassCleanupAttribute] + public static void Cleanup() + { + InternalCleanup(); + } + + #endregion + + #region test + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Default() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Deploy() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDeploy = true; + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Delete() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDelete = true; + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Retract() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldRetract = true; + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Delete_Deploy() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDelete = true; + def.ShouldDeploy = true; + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Retract_Deploy() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldRetract = true; + def.ShouldDeploy = true; + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution")] + public void CanDeploy_FarmSolution_As_Retract_Delete_Deploy() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldRetract = true; + def.ShouldDelete = true; + def.ShouldDeploy = true; + }); + + TestFarmSolutionModel(solutionDef); + }); + } + + #endregion + + #region utils + + protected virtual void TestFarmSolutionModel(FarmSolutionDefinition solutionDef) + { + var newSolutiondef = solutionDef.Inherit(); + + var originalModel = SPMeta2Model.NewFarmModel(farm => + { + farm.AddFarmSolution(solutionDef); + }); + + var newModel = SPMeta2Model.NewFarmModel(farm => + { + farm.AddFarmSolution(newSolutiondef); + }); + + TestModel(originalModel); + TestModel(newModel); + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj b/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj index 8218eb09b..5df523879 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj +++ b/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj @@ -162,6 +162,7 @@ + diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs index b92b854a4..28ad6ddce 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs @@ -12,13 +12,34 @@ using SPMeta2.Services; using SPMeta2.SSOM.ModelHosts; using SPMeta2.Utils; +using System.Threading; namespace SPMeta2.SSOM.ModelHandlers { public class FarmSolutionModelHandler : SSOMModelHandlerBase { + #region constructors + + public FarmSolutionModelHandler() + { + + } + + #endregion + + #region static + + static FarmSolutionModelHandler() + { + SolutionDeploymentTimeoutInMillisecond = 1000; + } + + #endregion + #region properties + public static int SolutionDeploymentTimeoutInMillisecond { get; set; } + public override Type TargetType { get { return typeof(FarmSolutionDefinition); } @@ -56,18 +77,198 @@ protected SPSolution FindExistingSolution(FarmModelHost modelHost, FarmSolutionD private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition definition) { var farm = modelHost.HostFarm; - var existringSolution = FindExistingSolution(modelHost, definition); + var existingSolution = FindExistingSolution(modelHost, definition); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, - Object = existringSolution, + Object = existingSolution, + ObjectType = typeof(SPSolution), + ObjectDefinition = definition, + ModelHost = modelHost + }); + + // should retract? + if (existingSolution != null && definition.ShouldRetract == true) + { + RetractSolution(modelHost, definition, existingSolution); + } + + // should delete? + if (existingSolution != null && definition.ShouldDelete == true) + { + DeleteSolution(modelHost, definition, existingSolution); + } + + // add solution to the farm + existingSolution = AddSolution(modelHost, definition); + + // should update? + if (existingSolution != null && definition.ShouldUpdate == true) + { + UpdateSolution(modelHost, definition, existingSolution); + } + + // should deploy? + if (existingSolution != null && definition.ShouldDeploy == true) + { + DeploySolution(modelHost, definition, existingSolution); + } + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = existingSolution, ObjectType = typeof(SPSolution), ObjectDefinition = definition, ModelHost = modelHost }); + } + + protected virtual void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) + { + if (!existingSolution.Deployed) + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying farm solution:[{0}]", existingSolution.Name)); + + var isNowDeployment = false; + + if (definition.DeploymentDate.HasValue) + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying solution on date [{0}]", definition.DeploymentDate.Value)); + + existingSolution.Deploy(definition.DeploymentDate.Value, + definition.DeploymentGlobalInstallWPPackDlls, + definition.DeploymentForce); + } + else + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying solution NOW.")); + + existingSolution.Deploy(DateTime.Now, + definition.DeploymentGlobalInstallWPPackDlls, + definition.DeploymentForce); + + isNowDeployment = true; + } + + var deployed = existingSolution.Deployed; + + if (isNowDeployment) + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be true")); + + while (!deployed) + { + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); + Thread.Sleep(SolutionDeploymentTimeoutInMillisecond); + + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...", + existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + + deployed = existingSolution.Deployed; + } + + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false")); + var jobExists = existingSolution.JobExists; + + while (jobExists) + { + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); + Thread.Sleep(SolutionDeploymentTimeoutInMillisecond); + + + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...", + existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + + jobExists = existingSolution.JobExists; + } + + TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed is true AND .JobExists is false")); + } + else + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Future deployment. Passing wait.")); + } + } + else + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Farm solution:[{0}] was already deployed.", existingSolution.Name)); + } + } + + protected virtual void UpdateSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) + { + + } + + protected virtual void DeleteSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existringSolution) + { + existringSolution.Delete(); + } + + protected virtual void RetractSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Retracting solution [{0}]", existingSolution.Name)); + + if (existingSolution.Deployed) + { + var deployed = existingSolution.Deployed; + existingSolution.Retract(DateTime.Now); + + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false")); + + while (deployed) + { + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); + Thread.Sleep(SolutionDeploymentTimeoutInMillisecond); + + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...", + existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + + deployed = existingSolution.Deployed; + } + + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .JobExists status to be false")); + var jobExists = existingSolution.JobExists; + + while (jobExists) + { + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); + Thread.Sleep(SolutionDeploymentTimeoutInMillisecond); + + + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...", + existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + + jobExists = existingSolution.JobExists; + } + + TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed and .JobExists are false")); + } + else + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Solution was already retracted.")); + } + } + + protected virtual SPSolution AddSolution(FarmModelHost modelHost, FarmSolutionDefinition definition) + { + var farm = modelHost.HostFarm; + + var existringSolution = FindExistingSolution(modelHost, definition); var tmpWspDirectory = string.Format("{0}_{1}", Path.GetFileNameWithoutExtension(definition.FileName), Guid.NewGuid().ToString("N")); var tmpWspDirectoryPath = Path.Combine(Path.GetTempPath(), tmpWspDirectory); @@ -92,29 +293,10 @@ private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition defi } else { - TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Upgrading existing farm solution"); - - if (existringSolution.Deployed) - { - existringSolution.Upgrade(tmpWspFilPath); - } - else - { - // TODO - // https://github.com/SubPointSolutions/spmeta2/issues/324 - } + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Farm solution exists"); } - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = existringSolution, - ObjectType = typeof(SPSolution), - ObjectDefinition = definition, - ModelHost = modelHost - }); + return existringSolution; } #endregion diff --git a/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs b/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs index 4edbeb883..6f77974a5 100644 --- a/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs +++ b/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs @@ -30,11 +30,14 @@ public class FarmSolutionDefinition : SolutionDefinitionBase public FarmSolutionDefinition() { - // made int? + // changed to int? // no locale by default //LCID = 1033; Content = new byte[0]; + + DeploymentGlobalInstallWPPackDlls = true; + DeploymentForce = true; } #endregion @@ -46,8 +49,60 @@ public FarmSolutionDefinition() /// /// [DataMember] + [ExpectValidation] public int? LCID { get; set; } + /// + /// Indicates if solution has to be retracted + /// + [DataMember] + [ExpectValidation] + public bool? ShouldRetract { get; set; } + + /// + /// Indicates if solution has to be deleted + /// + [DataMember] + [ExpectValidation] + public bool? ShouldDelete { get; set; } + + /// + /// Indicates if solution has to be deployed + /// + [DataMember] + [ExpectValidation] + public bool? ShouldDeploy { get; set; } + + /// + /// Indicates if solution has to be updated + /// + [DataMember] + [ExpectValidation] + public bool? ShouldUpdate { get; set; } + + /// + /// Deployment date. NULL for 'right now' + /// + [DataMember] + [ExpectValidation] + public DateTime? DeploymentDate { get; set; } + + /// + /// Passed to SPSolution.Deploy() method. + /// TRUE by default + /// + [DataMember] + [ExpectValidation] + public bool DeploymentGlobalInstallWPPackDlls { get; set; } + + /// + /// Passed to SPSolution.Deploy() method. + /// TRUE by default + /// + [DataMember] + [ExpectValidation] + public bool DeploymentForce { get; set; } + #endregion #region methods From 19cf42b31fb7e5fb7950c8cc779ee7626123ea8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Bl=C3=BCher?= Date: Fri, 28 Oct 2016 13:27:33 +0200 Subject: [PATCH 13/20] Added ModelHandler for pushChangesToList (cherry picked from commit 5afea6eaceea0a047e2c97201549dcf4f8f91961) --- .../ModelHandlers/FieldModelHandler.cs | 21 ++++++++++++------- .../ModelHandlers/FieldModelHandler.cs | 14 ++++++------- .../SPMeta2/Definitions/FieldDefinition.cs | 4 ++++ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs b/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs index 181908d1f..d0a32c2d1 100644 --- a/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs +++ b/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs @@ -16,7 +16,7 @@ namespace SPMeta2.CSOM.ModelHandlers { public class FieldModelHandler : CSOMModelHandlerBase { - #region construactors + #region constructors static FieldModelHandler() { @@ -52,10 +52,6 @@ protected static XElement GetNewMinimalSPFieldTemplate() new XAttribute(BuiltInFieldAttributes.CanToggleHidden, "TRUE")); } - #endregion - - #region methods - protected virtual bool PreloadProperties(Field field) { return false; @@ -196,9 +192,18 @@ public override void DeployModel(object modelHost, DefinitionBase model) ModelHost = modelHost }); - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "UpdateAndPushChanges(true)"); - currentField.UpdateAndPushChanges(true); - + if (fieldModel.PushChangesToLists.HasValue) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, $"UpdateAndPushChanges({fieldModel.PushChangesToLists.Value})"); + currentField.UpdateAndPushChanges(fieldModel.PushChangesToLists.Value); + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "UpdateAndPushChanges(true)"); + // Why does SSOM handler distinguish between list and web/site fields and csom doesn't? + currentField.UpdateAndPushChanges(true); + } + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()"); context.ExecuteQueryWithTrace(); diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs index cbf661c2a..6e7027dba 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs @@ -1,24 +1,22 @@ using System; using System.Linq; using System.Xml.Linq; + using Microsoft.SharePoint; + using SPMeta2.Common; using SPMeta2.Definitions; -using SPMeta2.Definitions.Base; using SPMeta2.Enumerations; -using SPMeta2.ModelHandlers; +using SPMeta2.Exceptions; using SPMeta2.Services; using SPMeta2.SSOM.ModelHosts; using SPMeta2.Utils; -using System.Globalization; -using SPMeta2.Exceptions; -using System.Diagnostics; namespace SPMeta2.SSOM.ModelHandlers { public class FieldModelHandler : SSOMModelHandlerBase { - #region construactors + #region constructors static FieldModelHandler() { @@ -90,7 +88,7 @@ public override void DeployModel(object modelHost, DefinitionBase model) var fieldModel = model.WithAssertAndCast("model", value => value.RequireNotNull()); - SPField field = null; + SPField field; var isListField = false; @@ -134,7 +132,7 @@ public override void DeployModel(object modelHost, DefinitionBase model) } else { - field.Update(true); + field.Update(!fieldModel.PushChangesToLists.HasValue || fieldModel.PushChangesToLists.Value); } } diff --git a/SPMeta2/SPMeta2/Definitions/FieldDefinition.cs b/SPMeta2/SPMeta2/Definitions/FieldDefinition.cs index 26084d5ea..e8d6d144e 100644 --- a/SPMeta2/SPMeta2/Definitions/FieldDefinition.cs +++ b/SPMeta2/SPMeta2/Definitions/FieldDefinition.cs @@ -281,6 +281,10 @@ public FieldDefinition() [DataMember] public bool? EnforceUniqueValues { get; set; } + [ExpectValidation] + [DataMember] + public bool? PushChangesToLists { get; set; } + [ExpectValidation] [ExpectUpdate] [DataMember] From b8823c91361cad275be1d038288eba269f2308c9 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Fri, 28 Oct 2016 17:28:33 -0700 Subject: [PATCH 14/20] + Enhance FieldDefinition with 'pushChangesToLists' option #922 + Added PushChangesToLists prop + Green tests under "Regression.Scenarios.Fields.PushChangesToLists" category --- .../ModelHandlers/FieldModelHandler.cs | 6 ++++-- .../ClientFieldDefinitionValidator.cs | 3 +++ .../Validation/FieldDefinitionValidator.cs | 3 +++ .../Impl/Scenarios/FieldScenariosTest.cs | 2 ++ .../ModelHandlers/FieldModelHandler.cs | 17 ++++++++++++++++- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs b/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs index d0a32c2d1..f68242070 100644 --- a/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs +++ b/SPMeta2/SPMeta2.CSOM/ModelHandlers/FieldModelHandler.cs @@ -194,7 +194,9 @@ public override void DeployModel(object modelHost, DefinitionBase model) if (fieldModel.PushChangesToLists.HasValue) { - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, $"UpdateAndPushChanges({fieldModel.PushChangesToLists.Value})"); + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, + string.Format("UpdateAndPushChanges({0})", fieldModel.PushChangesToLists)); + currentField.UpdateAndPushChanges(fieldModel.PushChangesToLists.Value); } else @@ -203,7 +205,7 @@ public override void DeployModel(object modelHost, DefinitionBase model) // Why does SSOM handler distinguish between list and web/site fields and csom doesn't? currentField.UpdateAndPushChanges(true); } - + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "ExecuteQuery()"); context.ExecuteQueryWithTrace(); diff --git a/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientFieldDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientFieldDefinitionValidator.cs index ec1b72058..06f20e63c 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientFieldDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM/Validation/ClientFieldDefinitionValidator.cs @@ -361,6 +361,9 @@ protected void ValidateField(AssertPair assert, Field sp assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } + + assert.SkipProperty(m => m.PushChangesToLists, + "Covered by 'Regression.Scenarios.Fields.PushChangesToLists' test category"); } } } diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Validation/FieldDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM/Validation/FieldDefinitionValidator.cs index 5b2383cc2..a547cf45c 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Validation/FieldDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Validation/FieldDefinitionValidator.cs @@ -339,6 +339,9 @@ protected void ValidateField(AssertPair assert, SPFiel { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } + + assert.SkipProperty(m => m.PushChangesToLists, + "Covered by 'Regression.Scenarios.Fields.PushChangesToLists' test category"); } } } diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs index 49b2e62eb..1275dac27 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FieldScenariosTest.cs @@ -1089,6 +1089,8 @@ private void InternalDeploySiteFieldWithPushChangesToLists(bool pushChangesToLis def.ValidationFormula = string.Empty; def.Title = newFieldTitle; + + def.PushChangesToLists = pushChangesToLists; }); var oldListDef = ModelGeneratorService.GetRandomDefinition(def => diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs index 6e7027dba..7bd709c23 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FieldModelHandler.cs @@ -128,11 +128,26 @@ public override void DeployModel(object modelHost, DefinitionBase model) // no promotion for the list field, and force push for the site fields if (isListField) { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Update() for list field"); field.Update(); } else { - field.Update(!fieldModel.PushChangesToLists.HasValue || fieldModel.PushChangesToLists.Value); + + if (fieldModel.PushChangesToLists.HasValue) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, + string.Format("UpdateAndPushChanges({0})", fieldModel.PushChangesToLists)); + + field.Update(fieldModel.PushChangesToLists.Value); + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Update(true)"); + field.Update(true); + } + + } } From 408c08904c3b7e5b63574df24f81485afd57ff92 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Fri, 28 Oct 2016 23:08:36 -0700 Subject: [PATCH 15/20] + Enhance FarmSolutionDefinition provision #324 + green tests under "Regression.Scenarios.FarmSolution" --- .../SSOMProvisionRunner.cs | 12 + .../Services/RegressionTestService.cs | 17 +- .../FarmSolutionDefinitionValidator.cs | 256 ++++++++++-- .../Scenarios/FarmSolutionScenariosTest.cs | 385 +++++++++++++++++- .../ModelHandlers/FarmSolutionModelHandler.cs | 149 ++++++- .../Definitions/FarmSolutionDefinition.cs | 26 +- .../Extensions/DefinitionBaseExtensions.cs | 67 +++ SPMeta2/SPMeta2/SPMeta2.csproj | 1 + 8 files changed, 841 insertions(+), 72 deletions(-) create mode 100644 SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs diff --git a/SPMeta2/SPMeta2.Containers.SSOM/SSOMProvisionRunner.cs b/SPMeta2/SPMeta2.Containers.SSOM/SSOMProvisionRunner.cs index a1c726aea..505ae73d6 100644 --- a/SPMeta2/SPMeta2.Containers.SSOM/SSOMProvisionRunner.cs +++ b/SPMeta2/SPMeta2.Containers.SSOM/SSOMProvisionRunner.cs @@ -4,6 +4,7 @@ using System.IO; using System.IO.MemoryMappedFiles; using System.Linq; +using System.Reflection; using Microsoft.Office.SecureStoreService.Server; using Microsoft.Office.Server.Audience; using Microsoft.Office.Server.Search.Portability; @@ -102,6 +103,17 @@ private void InitServices() args.CurrentNode.Value })); }; + + foreach (var modelHandler in _provisionService.ModelHandlers.Values) + { + var isQA = modelHandler.GetType() + .GetProperty("IsQARun", BindingFlags.NonPublic | BindingFlags.Instance); + + if (isQA != null) + { + isQA.SetValue(modelHandler, true); ; + } + } } private void LoadEnvironmentConfig() diff --git a/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs b/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs index 3ec108bcf..fbe9ab6a6 100644 --- a/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs +++ b/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs @@ -370,12 +370,21 @@ protected virtual Action> Create hook.OnProvisioned = true; - AssertService.IsNotNull(context.Object); - AssertService.IsNotNull(context.ObjectDefinition); + var farmDef = context.ObjectDefinition as FarmSolutionDefinition; - AssertService.IsNotNull(context.ModelHost); + if (farmDef != null && farmDef.ShouldDelete == true) + { + // by passing checking the object within onb provisioed event + // farm solution is expected to be deleted + } + else + { + AssertService.IsNotNull(context.Object); + AssertService.IsNotNull(context.ObjectDefinition); - AssertService.IsInstanceOfType(context.Object, typeof(TObjectType)); + AssertService.IsNotNull(context.ModelHost); + AssertService.IsInstanceOfType(context.Object, typeof(TObjectType)); + } }); } diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Validation/FarmSolutionDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM/Validation/FarmSolutionDefinitionValidator.cs index 24b3242a7..582525a2c 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Validation/FarmSolutionDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Validation/FarmSolutionDefinitionValidator.cs @@ -1,26 +1,230 @@ -using SPMeta2.Definitions; -using SPMeta2.SSOM.ModelHandlers; - -using SPMeta2.Utils; -using SPMeta2.SSOM.ModelHosts; - -namespace SPMeta2.Regression.SSOM.Validation -{ - public class FarmSolutionDefinitionValidator : FarmSolutionModelHandler - { - public override void DeployModel(object modelHost, DefinitionBase model) - { - var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - var farmModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); - - var solution = FindExistingSolution(farmModelHost, definition); - - ServiceFactory.AssertService - .NewAssert(definition, definition, solution) - .ShouldNotBeNull(solution) - .SkipProperty(m => m.FileName, "Skipping FileName property.") - .ShouldBeEqual(m => m.SolutionId, o => o.SolutionId) - .SkipProperty(m => m.Content, "Skipping Content property."); - } - } -} +using SPMeta2.Definitions; +using SPMeta2.SSOM.ModelHandlers; + +using SPMeta2.Utils; +using SPMeta2.SSOM.ModelHosts; +using SPMeta2.Containers.Assertion; +using SPMeta2.Extensions; + +namespace SPMeta2.Regression.SSOM.Validation +{ + public class FarmSolutionDefinitionValidator : FarmSolutionModelHandler + { + #region constructors + public FarmSolutionDefinitionValidator() + { + + } + + #endregion + + #region methods + public override void DeployModel(object modelHost, DefinitionBase model) + { + var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + var farmModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + + var solution = FindExistingSolution(farmModelHost, definition); + + var assert = ServiceFactory.AssertService + .NewAssert(definition, definition, solution); + + if (definition.ShouldDelete == true + && !definition.ShouldDeploy.HasValue) + { + // DELETE OPERATION + + // solution has to be NULL + assert.ShouldBeNull(solution); + + assert.SkipProperty(m => m.UpgradeDate, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentDate, "ShouldDelete = true"); + + assert.SkipProperty(m => m.DeploymentForce, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentGlobalInstallWPPackDlls, "ShouldDelete = true"); + assert.SkipProperty(m => m.LCID, "ShouldDelete = true"); + + assert.SkipProperty(m => m.Content, "ShouldDelete = true"); + assert.SkipProperty(m => m.FileName, "ShouldDelete = true"); + assert.SkipProperty(m => m.SolutionId, "ShouldDelete = true"); + + assert.SkipProperty(m => m.ShouldAdd, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDelete, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDeploy, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldRetract, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldUpgrade, "ShouldDelete = true"); + + return; + } + + if (definition.ShouldRetract == true) + { + // RETRACT OPERATION + assert.ShouldNotBeNull(solution); + + assert.SkipProperty(m => m.UpgradeDate, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentDate, "ShouldDelete = true"); + + assert.SkipProperty(m => m.DeploymentForce, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentGlobalInstallWPPackDlls, "ShouldDelete = true"); + assert.SkipProperty(m => m.LCID, "ShouldDelete = true"); + + assert.SkipProperty(m => m.Content, "ShouldDelete = true"); + assert.SkipProperty(m => m.FileName, "ShouldDelete = true"); + assert.SkipProperty(m => m.SolutionId, "ShouldDelete = true"); + + assert.SkipProperty(m => m.ShouldAdd, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDelete, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDeploy, "ShouldDelete = true"); + //assert.SkipProperty(m => m.ShouldRetract, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldUpgrade, "ShouldDelete = true"); + + // should be deployed state + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(def => def.ShouldRetract); + + var isValid = d.Deployed == false + && definition.HasPropertyBagValue("HadRetractHit"); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + + return; + } + + if (definition.ShouldUpgrade == true) + { + // UPGRADE OPERATION + assert.ShouldNotBeNull(solution); + + assert.SkipProperty(m => m.UpgradeDate, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentDate, "ShouldDelete = true"); + + assert.SkipProperty(m => m.DeploymentForce, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentGlobalInstallWPPackDlls, "ShouldDelete = true"); + assert.SkipProperty(m => m.LCID, "ShouldDelete = true"); + + assert.SkipProperty(m => m.Content, "ShouldDelete = true"); + assert.SkipProperty(m => m.FileName, "ShouldDelete = true"); + assert.SkipProperty(m => m.SolutionId, "ShouldDelete = true"); + + assert.SkipProperty(m => m.ShouldAdd, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDelete, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDeploy, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldRetract, "ShouldDelete = true"); + //assert.SkipProperty(m => m.ShouldUpgrade, "ShouldDelete = true"); + + // should be deployed state + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(def => def.ShouldUpgrade); + + var isValid = definition.HasPropertyBagValue("HadUpgradetHit"); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + + return; + } + + if (definition.ShouldDeploy == true) + { + // DEPLOY OPERATION + assert.ShouldNotBeNull(solution); + + assert.SkipProperty(m => m.UpgradeDate, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentDate, "ShouldDelete = true"); + + assert.SkipProperty(m => m.DeploymentForce, "ShouldDelete = true"); + assert.SkipProperty(m => m.DeploymentGlobalInstallWPPackDlls, "ShouldDelete = true"); + assert.SkipProperty(m => m.LCID, "ShouldDelete = true"); + + assert.SkipProperty(m => m.Content, "ShouldDelete = true"); + assert.SkipProperty(m => m.FileName, "ShouldDelete = true"); + assert.SkipProperty(m => m.SolutionId, "ShouldDelete = true"); + + assert.SkipProperty(m => m.ShouldAdd, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldDelete, "ShouldDelete = true"); + //assert.SkipProperty(m => m.ShouldDeploy, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldRetract, "ShouldDelete = true"); + assert.SkipProperty(m => m.ShouldUpgrade, "ShouldDelete = true"); + + // should be deployed state + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(def => def.ShouldDeploy); + + var isValid = d.Deployed + && definition.HasPropertyBagValue("HadDeploymentHit"); + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + + return; + } + + assert.ShouldNotBeNull(solution) + //.ShouldBeEqual(m => m.FileName, o => o.Name) + .SkipProperty(m => m.FileName, "Skipping Name props. It might be different as the same SolutionId could be deployment in the farm.") + .ShouldBeEqual(m => m.SolutionId, o => o.SolutionId) + .SkipProperty(m => m.Content, "Skipping Content property."); + + assert.SkipProperty(m => m.ShouldAdd, "ShouldAdd"); + assert.SkipProperty(m => m.ShouldDelete, "ShouldDelete"); + assert.SkipProperty(m => m.ShouldDeploy, "ShouldDeploy"); + assert.SkipProperty(m => m.ShouldRetract, "ShouldRetract"); + assert.SkipProperty(m => m.ShouldUpgrade, "ShouldUpgrade"); + + assert.SkipProperty(m => m.DeploymentForce); + assert.SkipProperty(m => m.DeploymentGlobalInstallWPPackDlls); + + if (definition.LCID.HasValue) + { + // TODO + } + else + { + assert.SkipProperty(m => m.LCID, "LCID is NULL"); + } + + + if (definition.DeploymentDate.HasValue) + { + // TODO + } + else + { + assert.SkipProperty(m => m.DeploymentDate, "DeploymentDate is NULL"); + } + + if (definition.UpgradeDate.HasValue) + { + // TODO + } + else + { + assert.SkipProperty(m => m.UpgradeDate, "UpgradeDate is NULL"); + } + } + #endregion + } +} diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs index fd58c955b..a8ef17614 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/FarmSolutionScenariosTest.cs @@ -21,6 +21,16 @@ namespace SPMeta2.Regression.Tests.Impl.Scenarios [TestClass] public class FarmSolutionScenariosTest : SPMeta2RegresionScenarioTestBase { + #region constructors + + public FarmSolutionScenariosTest() + { + RegressionService.ProvisionGenerationCount = 1; + RegressionService.ShowOnlyFalseResults = false; + } + + #endregion + #region internal [ClassInitializeAttribute] @@ -37,10 +47,10 @@ public static void Cleanup() #endregion - #region test + #region default [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] + [TestCategory("Regression.Scenarios.FarmSolution.Default")] public void CanDeploy_FarmSolution_As_Default() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => @@ -54,96 +64,350 @@ public void CanDeploy_FarmSolution_As_Default() }); } + #endregion + + #region add operations + [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] - public void CanDeploy_FarmSolution_As_Deploy() + [TestCategory("Regression.Scenarios.FarmSolution.Add")] + public void CanDeploy_FarmSolution_As_Add_FromDeleted_State() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => { var solutionDef = ModelGeneratorService.GetRandomDefinition(def => { - def.ShouldDeploy = true; + + }); + + PrepareDeletedState(solutionDef); + + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Add")] + public void CanDeploy_FarmSolution_As_Add_FromRetracted_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + + }); + + PrepareRetractedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Add")] + public void CanDeploy_FarmSolution_As_Add_FromAdded_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + }); + PrepareAddedState(solutionDef); TestFarmSolutionModel(solutionDef); }); } [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] - public void CanDeploy_FarmSolution_As_Delete() + [TestCategory("Regression.Scenarios.FarmSolution.Add")] + public void CanDeploy_FarmSolution_As_Add_FromDeployed_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + + }); + + PrepareDeployedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + #endregion + + #region delete operations + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Delete")] + public void CanDeploy_FarmSolution_As_Delete_FromDeleted_State() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => { var solutionDef = ModelGeneratorService.GetRandomDefinition(def => { def.ShouldDelete = true; + def.ShouldAdd = false; }); + PrepareDeletedState(solutionDef); + TestFarmSolutionModel(solutionDef); }); } [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] - public void CanDeploy_FarmSolution_As_Retract() + [TestCategory("Regression.Scenarios.FarmSolution.Delete")] + public void CanDeploy_FarmSolution_As_Delete_FromRetracted_State() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => { var solutionDef = ModelGeneratorService.GetRandomDefinition(def => { - def.ShouldRetract = true; + def.ShouldDelete = true; + def.ShouldAdd = false; }); + PrepareRetractedState(solutionDef); TestFarmSolutionModel(solutionDef); }); } [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] - public void CanDeploy_FarmSolution_As_Delete_Deploy() + [TestCategory("Regression.Scenarios.FarmSolution.Delete")] + public void CanDeploy_FarmSolution_As_Delete_FromAdded_State() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => { var solutionDef = ModelGeneratorService.GetRandomDefinition(def => { def.ShouldDelete = true; - def.ShouldDeploy = true; + def.ShouldAdd = false; }); + PrepareAddedState(solutionDef); TestFarmSolutionModel(solutionDef); }); } [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] - public void CanDeploy_FarmSolution_As_Retract_Deploy() + [TestCategory("Regression.Scenarios.FarmSolution.Delete")] + public void CanDeploy_FarmSolution_As_Delete_FromDeployed_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDelete = true; + def.ShouldAdd = false; + }); + + PrepareDeployedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + #endregion + + #region retract operations + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Retract")] + public void CanDeploy_FarmSolution_As_Retract_FromDeleted_State() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => { var solutionDef = ModelGeneratorService.GetRandomDefinition(def => { def.ShouldRetract = true; - def.ShouldDeploy = true; }); + PrepareDeletedState(solutionDef); + TestFarmSolutionModel(solutionDef); }); } [TestMethod] - [TestCategory("Regression.Scenarios.FarmSolution")] - public void CanDeploy_FarmSolution_As_Retract_Delete_Deploy() + [TestCategory("Regression.Scenarios.FarmSolution.Retract")] + public void CanDeploy_FarmSolution_As_Retract_FromRetracted_State() { WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => { var solutionDef = ModelGeneratorService.GetRandomDefinition(def => { def.ShouldRetract = true; - def.ShouldDelete = true; + }); + + PrepareRetractedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Retract")] + public void CanDeploy_FarmSolution_As_Retract_FromAdded_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldRetract = true; + }); + + PrepareAddedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Retract")] + public void CanDeploy_FarmSolution_As_Retract_FromDeployed_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldRetract = true; + }); + + PrepareDeployedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + #endregion + + + #region deploy operations + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Deploy")] + public void CanDeploy_FarmSolution_As_Deploy_FromDeleted_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { def.ShouldDeploy = true; }); + PrepareDeletedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Deploy")] + public void CanDeploy_FarmSolution_As_Deploy_FromRetracted_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDeploy = true; + }); + + PrepareRetractedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Deploy")] + public void CanDeploy_FarmSolution_As_Deploy_FromAdded_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDeploy = true; + }); + + PrepareAddedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Deploy")] + public void CanDeploy_FarmSolution_As_Deploy_FromDeployed_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldDeploy = true; + }); + + PrepareDeployedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + #endregion + + #region upgrade operations + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Upgrade")] + public void CanDeploy_FarmSolution_As_Upgrade_FromDeleted_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldUpgrade = true; + }); + + PrepareDeletedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Upgrade")] + public void CanDeploy_FarmSolution_As_Upgrade_FromRetracted_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldUpgrade = true; + }); + + PrepareRetractedState(solutionDef); + TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Upgrade")] + public void CanDeploy_FarmSolution_As_Upgrade_FromAdded_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldUpgrade = true; + }); + + PrepareAddedState(solutionDef); + //TestFarmSolutionModel(solutionDef); + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.FarmSolution.Upgrade")] + public void CanDeploy_FarmSolution_As_Upgrade_FromDeployed_State() + { + WithExpectedUnsupportedCSOMnO365RunnerExceptions(() => + { + var solutionDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.ShouldUpgrade = true; + }); + + PrepareDeployedState(solutionDef); TestFarmSolutionModel(solutionDef); }); } @@ -152,6 +416,89 @@ public void CanDeploy_FarmSolution_As_Retract_Delete_Deploy() #region utils + private void PrepareDeployedState(FarmSolutionDefinition solutionDef) + { + var deployDef = solutionDef.Inherit(def => + { + def.ShouldDelete = null; + def.ShouldRetract = null; + def.ShouldUpgrade = null; + + def.ShouldAdd = true; + def.ShouldDeploy = true; + }); + + TestFarmSolutionModel(deployDef); + } + + private void PrepareAddedState(FarmSolutionDefinition solutionDef) + { + var addDef = solutionDef.Inherit(def => + { + def.ShouldDelete = null; + def.ShouldDeploy = null; + def.ShouldUpgrade = null; + + def.ShouldAdd = true; + def.ShouldRetract = null; + }); + + TestFarmSolutionModel(addDef); + + var retractDef = solutionDef.Inherit(def => + { + def.ShouldDelete = null; + def.ShouldDeploy = null; + def.ShouldUpgrade = null; + + def.ShouldAdd = true; + def.ShouldRetract = true; + }); + + TestFarmSolutionModel(retractDef); + } + + private void PrepareRetractedState(FarmSolutionDefinition solutionDef) + { + var deployDef = solutionDef.Inherit(def => + { + def.ShouldDelete = null; + def.ShouldRetract = null; + def.ShouldUpgrade = null; + + def.ShouldAdd = true; + def.ShouldDeploy = true; + }); + + var retractDef = solutionDef.Inherit(def => + { + def.ShouldDelete = null; + def.ShouldDeploy = null; + def.ShouldUpgrade = null; + + def.ShouldAdd = true; + def.ShouldRetract = true; + }); + + TestFarmSolutionModel(deployDef); + TestFarmSolutionModel(retractDef); + } + + private void PrepareDeletedState(FarmSolutionDefinition solutionDef) + { + var deletedDef = solutionDef.Inherit(def => + { + def.ShouldDeploy = null; + def.ShouldRetract = true; + def.ShouldUpgrade = null; + + def.ShouldAdd = false; + def.ShouldDelete = true; + }); + + TestFarmSolutionModel(deletedDef); + } + protected virtual void TestFarmSolutionModel(FarmSolutionDefinition solutionDef) { var newSolutiondef = solutionDef.Inherit(); diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs index 28ad6ddce..fbed68775 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FarmSolutionModelHandler.cs @@ -13,6 +13,7 @@ using SPMeta2.SSOM.ModelHosts; using SPMeta2.Utils; using System.Threading; +using SPMeta2.Extensions; namespace SPMeta2.SSOM.ModelHandlers { @@ -39,6 +40,7 @@ static FarmSolutionModelHandler() #region properties public static int SolutionDeploymentTimeoutInMillisecond { get; set; } + protected bool IsQARun { get; set; } public override Type TargetType { @@ -54,7 +56,7 @@ public override void DeployModel(object modelHost, DefinitionBase model) var farmModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); var solutionModel = model.WithAssertAndCast("model", value => value.RequireNotNull()); - DeploySolution(farmModelHost, solutionModel); + DeploySolutionDefinition(farmModelHost, solutionModel); } protected SPSolution FindExistingSolution(FarmModelHost modelHost, FarmSolutionDefinition definition) @@ -69,12 +71,16 @@ protected SPSolution FindExistingSolution(FarmModelHost modelHost, FarmSolutionD var farm = modelHost.HostFarm; + // always get anew instance of the farm + // that would refresh the .Solution colleciton with the right state of the solutions + farm = SPFarm.Local; + return farm.Solutions.FirstOrDefault(s => s.Name.ToUpper() == definition.FileName.ToUpper() || definition.SolutionId != Guid.Empty && s.SolutionId == definition.SolutionId); } - private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition definition) + private void DeploySolutionDefinition(FarmModelHost modelHost, FarmSolutionDefinition definition) { var farm = modelHost.HostFarm; var existingSolution = FindExistingSolution(modelHost, definition); @@ -94,26 +100,38 @@ private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition defi if (existingSolution != null && definition.ShouldRetract == true) { RetractSolution(modelHost, definition, existingSolution); + existingSolution = FindExistingSolution(modelHost, definition); + } + else if (existingSolution == null && definition.ShouldRetract == true) + { + // set up flag for nn existing solution + if (IsQARun) + definition.SetPropertyBagValue("HadRetractHit"); } + // should delete? if (existingSolution != null && definition.ShouldDelete == true) { DeleteSolution(modelHost, definition, existingSolution); + existingSolution = FindExistingSolution(modelHost, definition); } - // add solution to the farm - existingSolution = AddSolution(modelHost, definition); - - // should update? - if (existingSolution != null && definition.ShouldUpdate == true) + // should add? + if (definition.ShouldAdd == true) { - UpdateSolution(modelHost, definition, existingSolution); + // add solution to the farm + existingSolution = AddSolution(modelHost, definition); } - // should deploy? - if (existingSolution != null && definition.ShouldDeploy == true) + if (existingSolution != null && definition.ShouldUpgrade == true) + { + // should upgrade? + UpgradeSolution(modelHost, definition, existingSolution); + } + else if (existingSolution != null && definition.ShouldDeploy == true) { + // should deploy? DeploySolution(modelHost, definition, existingSolution); } @@ -131,6 +149,8 @@ private void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition defi protected virtual void DeploySolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) { + definition.SetPropertyBagValue("HadDeploymentHit"); + if (!existingSolution.Deployed) { TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deploying farm solution:[{0}]", existingSolution.Name)); @@ -156,7 +176,7 @@ protected virtual void DeploySolution(FarmModelHost modelHost, FarmSolutionDefin isNowDeployment = true; } - var deployed = existingSolution.Deployed; + var deployed = existingSolution.DeploymentState != SPSolutionDeploymentState.NotDeployed; if (isNowDeployment) { @@ -172,7 +192,8 @@ protected virtual void DeploySolution(FarmModelHost modelHost, FarmSolutionDefin string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...", existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); - deployed = existingSolution.Deployed; + existingSolution = FindExistingSolution(modelHost, definition); + deployed = existingSolution.DeploymentState != SPSolutionDeploymentState.NotDeployed; } TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false")); @@ -189,6 +210,7 @@ protected virtual void DeploySolution(FarmModelHost modelHost, FarmSolutionDefin string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...", existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + existingSolution = FindExistingSolution(modelHost, definition); jobExists = existingSolution.JobExists; } @@ -205,28 +227,106 @@ protected virtual void DeploySolution(FarmModelHost modelHost, FarmSolutionDefin } } - protected virtual void UpdateSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) + protected virtual void UpgradeSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) { + definition.SetPropertyBagValue("HadUpgradetHit"); + + // ensure deployment state first + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Ensuring deployment state. Solution must be deployed before upgrading.")); + DeploySolution(modelHost, definition, existingSolution); + + // upgrade + var tmpWspDirectory = string.Format("{0}_{1}", Path.GetFileNameWithoutExtension(definition.FileName), Guid.NewGuid().ToString("N")); + var tmpWspDirectoryPath = Path.Combine(Path.GetTempPath(), tmpWspDirectory); + + Directory.CreateDirectory(tmpWspDirectoryPath); + + var tmpWspFilPath = Path.Combine(tmpWspDirectoryPath, definition.FileName); + File.WriteAllBytes(tmpWspFilPath, definition.Content); + + var isNowDeployment = false; + + if (definition.UpgradeDate.HasValue) + { + existingSolution.Upgrade(tmpWspFilPath, definition.UpgradeDate.Value); + } + else + { + existingSolution.Upgrade(tmpWspFilPath, DateTime.Now); + isNowDeployment = true; + } + + var deployed = existingSolution.Deployed; + + if (isNowDeployment) + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be true")); + + while (!deployed) + { + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); + Thread.Sleep(SolutionDeploymentTimeoutInMillisecond); + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...", + existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + + existingSolution = FindExistingSolution(modelHost, definition); + deployed = existingSolution.DeploymentState != SPSolutionDeploymentState.NotDeployed; + } + + existingSolution = FindExistingSolution(modelHost, definition); + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false")); + var jobExists = existingSolution.JobExists; + + while (jobExists) + { + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); + Thread.Sleep(SolutionDeploymentTimeoutInMillisecond); + + + TraceService.Information((int)LogEventId.CoreCalls, + string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...", + existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + + existingSolution = FindExistingSolution(modelHost, definition); + jobExists = existingSolution.JobExists; + } + + TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed is true AND .JobExists is false")); + } + else + { + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Future upgrade. Passing wait.")); + } } - protected virtual void DeleteSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existringSolution) + protected virtual void DeleteSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) { - existringSolution.Delete(); + if (IsQARun) + definition.SetPropertyBagValue("HadDeleteHit"); + + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Deleting solution [{0}]", existingSolution.Name)); + existingSolution.Delete(); } protected virtual void RetractSolution(FarmModelHost modelHost, FarmSolutionDefinition definition, SPSolution existingSolution) { + if (IsQARun) + definition.SetPropertyBagValue("HadRetractHit"); + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Retracting solution [{0}]", existingSolution.Name)); if (existingSolution.Deployed) { - var deployed = existingSolution.Deployed; + var retracted = existingSolution.DeploymentState == SPSolutionDeploymentState.NotDeployed; existingSolution.Retract(DateTime.Now); TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .Deployed status to be false")); - while (deployed) + while (!retracted) { TraceService.Information((int)LogEventId.CoreCalls, string.Format("Sleeping [{0}] milliseconds...", SolutionDeploymentTimeoutInMillisecond)); @@ -236,9 +336,12 @@ protected virtual void RetractSolution(FarmModelHost modelHost, FarmSolutionDefi string.Format("Checkin .Deployed for solution [{0}] in [{1}] milliseconds...", existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); - deployed = existingSolution.Deployed; + existingSolution = FindExistingSolution(modelHost, definition); + retracted = existingSolution.DeploymentState == SPSolutionDeploymentState.NotDeployed; } + existingSolution = FindExistingSolution(modelHost, definition); + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Checking .JobExists status to be false")); var jobExists = existingSolution.JobExists; @@ -253,9 +356,12 @@ protected virtual void RetractSolution(FarmModelHost modelHost, FarmSolutionDefi string.Format("Checkin .JobExists for solution [{0}] in [{1}] milliseconds...", existingSolution.Name, SolutionDeploymentTimeoutInMillisecond)); + existingSolution = FindExistingSolution(modelHost, definition); jobExists = existingSolution.JobExists; } + existingSolution = FindExistingSolution(modelHost, definition); + TraceService.Information((int)LogEventId.CoreCalls, string.Format(".Deployed and .JobExists are false")); } else @@ -266,6 +372,11 @@ protected virtual void RetractSolution(FarmModelHost modelHost, FarmSolutionDefi protected virtual SPSolution AddSolution(FarmModelHost modelHost, FarmSolutionDefinition definition) { + if (IsQARun) + definition.SetPropertyBagValue("HadAddHit"); + + TraceService.Information((int)LogEventId.CoreCalls, string.Format("Adding solution [{0}]", definition.FileName)); + var farm = modelHost.HostFarm; var existringSolution = FindExistingSolution(modelHost, definition); @@ -293,7 +404,7 @@ protected virtual SPSolution AddSolution(FarmModelHost modelHost, FarmSolutionDe } else { - TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Farm solution exists"); + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Farm solution exists. No need to add."); } return existringSolution; diff --git a/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs b/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs index 6f77974a5..1f144f965 100644 --- a/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs +++ b/SPMeta2/SPMeta2/Definitions/FarmSolutionDefinition.cs @@ -9,9 +9,11 @@ namespace SPMeta2.Definitions { /// - /// Allows to define and deploy SharePoint farm solution. - /// + /// Allows to define and deploy SharePoint farm solution /// + /// Supports Retract, Delete, Add, Deploy/Update workflows with the ShouldXXX properties + /// By default always ShouldAdd always true. + /// [SPObjectType(SPObjectModelType.SSOM, "Microsoft.SharePoint.Administration.SPSolution", "Microsoft.SharePoint")] @@ -38,6 +40,8 @@ public FarmSolutionDefinition() DeploymentGlobalInstallWPPackDlls = true; DeploymentForce = true; + + ShouldAdd = true; } #endregion @@ -59,6 +63,13 @@ public FarmSolutionDefinition() [ExpectValidation] public bool? ShouldRetract { get; set; } + /// + /// Indicates if solution has to be added + /// + [DataMember] + [ExpectValidation] + public bool? ShouldAdd { get; set; } + /// /// Indicates if solution has to be deleted /// @@ -74,11 +85,11 @@ public FarmSolutionDefinition() public bool? ShouldDeploy { get; set; } /// - /// Indicates if solution has to be updated + /// Indicates if solution has to be upgraded /// [DataMember] [ExpectValidation] - public bool? ShouldUpdate { get; set; } + public bool? ShouldUpgrade { get; set; } /// /// Deployment date. NULL for 'right now' @@ -87,6 +98,13 @@ public FarmSolutionDefinition() [ExpectValidation] public DateTime? DeploymentDate { get; set; } + /// + /// Upgrade date. NULL for 'right now' + /// + [DataMember] + [ExpectValidation] + public DateTime? UpgradeDate { get; set; } + /// /// Passed to SPSolution.Deploy() method. /// TRUE by default diff --git a/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs b/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs new file mode 100644 index 000000000..5b80d3fb8 --- /dev/null +++ b/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SPMeta2.Definitions; +using SPMeta2.Models; + +namespace SPMeta2.Extensions +{ + public static class DefinitionBaseExtensions + { + #region property bag + + public static DefinitionBase SetPropertyBagValue(this DefinitionBase definition, string name) + { + return SetPropertyBagValue(definition, name, true); + } + + public static DefinitionBase SetPropertyBagValue(this DefinitionBase definition, string name, object value) + { + return SetPropertyBagValue(definition, name, value != null ? definition.ToString() : string.Empty); + } + + public static DefinitionBase SetPropertyBagValue(this DefinitionBase definition, string name, string value) + { + var prop = FindPropertyBagValue(definition, name); + + if (prop == null) + { + prop = new PropertyBagValue + { + Name = name, + Value = value + }; + + definition.PropertyBag.Add(prop); + } + + prop.Value = value; + + return definition; + } + + public static string GetPropertyBagValue(this DefinitionBase definition, string name, string value) + { + var prop = FindPropertyBagValue(definition, name); + + if (prop != null) + return prop.Value; + + return null; + } + + public static PropertyBagValue FindPropertyBagValue(this DefinitionBase definition, string name) + { + return definition.PropertyBag.FirstOrDefault(p => p.Name.ToUpper() == name.ToUpper()); + } + + public static bool HasPropertyBagValue(this DefinitionBase definition, string name) + { + return FindPropertyBagValue(definition, name) != null; + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2/SPMeta2.csproj b/SPMeta2/SPMeta2/SPMeta2.csproj index 8ee08216f..b4494e356 100644 --- a/SPMeta2/SPMeta2/SPMeta2.csproj +++ b/SPMeta2/SPMeta2/SPMeta2.csproj @@ -343,6 +343,7 @@ + From 06e2f4f1679f9d8af1f2edc16275890677ebfdfd Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Fri, 28 Oct 2016 23:11:43 -0700 Subject: [PATCH 16/20] + NET35 build fix --- .../SPMeta2.Regression.Tests/Impl/Utils/ConvertUtilsTests.cs | 2 +- SPMeta2/SPMeta2.Regression.Tests/Utils/X509Utils.cs | 2 +- SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Utils/ConvertUtilsTests.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Utils/ConvertUtilsTests.cs index 47d4d26c2..688558847 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Impl/Utils/ConvertUtilsTests.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Utils/ConvertUtilsTests.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading.Tasks; + namespace SPMeta2.Regression.Tests.Impl.Utils { diff --git a/SPMeta2/SPMeta2.Regression.Tests/Utils/X509Utils.cs b/SPMeta2/SPMeta2.Regression.Tests/Utils/X509Utils.cs index 05d7f7685..b26ded650 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Utils/X509Utils.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Utils/X509Utils.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Text; -using System.Threading.Tasks; + namespace SPMeta2.Regression.Tests.Utils { diff --git a/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs b/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs index 5b80d3fb8..d79be0a0c 100644 --- a/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs +++ b/SPMeta2/SPMeta2/Extensions/DefinitionBaseExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Threading.Tasks; + using SPMeta2.Definitions; using SPMeta2.Models; From c0b8a53dff51705ac78210bb7ca72a860090d1f3 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Sat, 29 Oct 2016 19:16:29 -0700 Subject: [PATCH 17/20] + Add DesignPackageDefinition - design package provision support #166 + SSOM impl --- .../DesignPackageDefinitionGenerator.cs | 10 +- .../Consts/DefaultContainers.cs | 150 +++++----- .../Containers/DesignPackages/ci-1-1.0.wsp | Bin 0 -> 63826 bytes .../Containers/DesignPackages/ci-1-1.1.wsp | Bin 0 -> 63812 bytes .../Containers/DesignPackages/ci-1-1.2.wsp | Bin 0 -> 63847 bytes .../Containers/DesignPackages/ci-1-1.3.wsp | Bin 0 -> 63845 bytes .../Containers/DesignPackages/ci-1-1.4.wsp | Bin 0 -> 63859 bytes .../Containers/DesignPackages/ci-1-1.5.wsp | Bin 0 -> 63851 bytes .../SPMeta2.Containers.csproj | 18 ++ .../DesignPackageDefinitionValidator.cs | 46 +++- .../Extensions/SPUserSolutionExtensions.cs | 34 +-- .../DesignPackageModelHandler.cs | 134 +++++++-- .../SandboxSolutionModelHandler.cs | 257 +++++++++--------- .../Definitions/DesignPackageDefinition.cs | 46 +++- .../Base/SolutionDefinitionBase.cs | 89 +++--- SPMeta2/SPMeta2/Utils/ReflectionUtils.cs | 12 + 16 files changed, 504 insertions(+), 292 deletions(-) create mode 100644 SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.0.wsp create mode 100644 SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.1.wsp create mode 100644 SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.2.wsp create mode 100644 SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.3.wsp create mode 100644 SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.4.wsp create mode 100644 SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.5.wsp diff --git a/SPMeta2/SPMeta2.Containers.Standard/DefinitionGenerators/DesignPackageDefinitionGenerator.cs b/SPMeta2/SPMeta2.Containers.Standard/DefinitionGenerators/DesignPackageDefinitionGenerator.cs index f70d92460..6d65cf649 100644 --- a/SPMeta2/SPMeta2.Containers.Standard/DefinitionGenerators/DesignPackageDefinitionGenerator.cs +++ b/SPMeta2/SPMeta2.Containers.Standard/DefinitionGenerators/DesignPackageDefinitionGenerator.cs @@ -1,11 +1,13 @@ using System; using System.Collections.Generic; +using SPMeta2.Containers.Consts; using SPMeta2.Containers.Services.Base; using SPMeta2.Definitions; using SPMeta2.Definitions.Base; using SPMeta2.Enumerations; using SPMeta2.Standard.Definitions; using SPMeta2.Syntax.Default; +using System.IO; namespace SPMeta2.Containers.Standard.DefinitionGenerators { @@ -15,7 +17,13 @@ public override DefinitionBase GenerateRandomDefinition(Action a { return WithEmptyDefinition(def => { - // TODO + def.FileName = string.Format("{0}.wsp", Rnd.String()); + + def.Install = true; + def.Apply = false; + + def.SolutionId = DefaultContainers.DesignPackage.SolutionId; + def.Content = File.ReadAllBytes(DefaultContainers.DesignPackage.Package_v10_FilePath); }); } } diff --git a/SPMeta2/SPMeta2.Containers/Consts/DefaultContainers.cs b/SPMeta2/SPMeta2.Containers/Consts/DefaultContainers.cs index 1406f8c84..724827d8a 100644 --- a/SPMeta2/SPMeta2.Containers/Consts/DefaultContainers.cs +++ b/SPMeta2/SPMeta2.Containers/Consts/DefaultContainers.cs @@ -1,21 +1,21 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - - -namespace SPMeta2.Containers.Consts -{ - public static class DefaultContainers - { - public static class WebTemplates - { - public static class M2CustomTeamSite - { - public static Guid SolutionId = new Guid("{52b034ae-13e4-4147-b8f1-469f2b21f2d7}"); - public static string FilePath = @"Containers\WebTemplates\M2CustomTeamSite.wsp"; - - public static string WebTemplateName = "{7DA6B762-9AB9-4D81-870A-E93B586B7534}#M2CustomTeamSite"; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + + +namespace SPMeta2.Containers.Consts +{ + public static class DefaultContainers + { + public static class WebTemplates + { + public static class M2CustomTeamSite + { + public static Guid SolutionId = new Guid("{52b034ae-13e4-4147-b8f1-469f2b21f2d7}"); + public static string FilePath = @"Containers\WebTemplates\M2CustomTeamSite.wsp"; + + public static string WebTemplateName = "{7DA6B762-9AB9-4D81-870A-E93B586B7534}#M2CustomTeamSite"; } public static class M2CustomWebAsTemplate @@ -24,54 +24,66 @@ public static class M2CustomWebAsTemplate public static string FilePath = @"Containers\WebTemplates\M2CustomWebAsTemplate.wsp"; public static string WebTemplateName = "M2CustomWebAsTemplate"; - } - } - - public static class Sandbox - { - public static string FilePath = @"Containers\Sandbox\SPMeta2.Containers.SandboxSolutionContainer.wsp"; - public static Guid SolutionId = new Guid("e9a61998-07f2-45e9-ae43-9e93fa6b11bb"); - - public static Guid SiteFeatureId = new Guid("32dc6bed-0298-4fca-a72f-e9b9c0d6f09a"); - public static Guid WebFeatureId = new Guid("b997a462-8efb-44cf-92c0-457e75c81798"); - public static Guid WebPartFeatureId = new Guid("9acf0f59-3cdc-412b-a647-4185dd4cd9bc"); - } - - public static class FarmSolution - { - public static string FilePath = @"Containers\Farm\SPMeta2.Containers.FarmSolutionContainer.wsp"; - public static Guid SolutionId = new Guid("a4a2146d-57d1-48bd-a02e-ba97b371903d"); - } - - public static class Apps - { - public static Guid ProductId = new Guid("{e81b6820-5d57-4d17-a098-5f4317f6c400}"); - public static Guid FeatureId = new Guid("{e81b6820-5d57-4d17-a098-5f4317f6c401}"); - - public static string M2ClientWebPart1Name = "M2ClientWebPart1"; - public static string M2ClientWebPart2Name = "M2ClientWebPart2"; - - public static string GenericVersionableAppFilePath = @"Containers\Apps\{0}\SPMeta2.Containers.AppContainer.app"; - - public static class v0 - { - public static string FilePath = @"Containers\Apps\1.0.0.0\SPMeta2.Containers.AppContainer.app"; - } - - public static class v1 - { - public static string FilePath = @"Containers\Apps\1.0.0.1\SPMeta2.Containers.AppContainer.app"; - } - - public static class v2 - { - public static string FilePath = @"Containers\Apps\1.0.0.2\SPMeta2.Containers.AppContainer.app"; - } - - public static class v3 - { - public static string FilePath = @"Containers\Apps\1.0.0.3\SPMeta2.Containers.AppContainer.app"; - } - } - } -} + } + } + + public static class DesignPackage + { + public static Guid SolutionId = new Guid("9083433c-2c01-4ce2-974d-dda6f70acc9f"); + + public static string Package_v10_FilePath = @"Containers\DesignPackages\ci-1-1.0.wsp"; + public static string Package_v11_FilePath = @"Containers\DesignPackages\ci-1-1.1.wsp"; + public static string Package_v12_FilePath = @"Containers\DesignPackages\ci-1-1.2.wsp"; + public static string Package_v13_FilePath = @"Containers\DesignPackages\ci-1-1.3.wsp"; + public static string Package_v14_FilePath = @"Containers\DesignPackages\ci-1-1.4.wsp"; + public static string Package_v15_FilePath = @"Containers\DesignPackages\ci-1-1.5.wsp"; + } + + public static class Sandbox + { + public static string FilePath = @"Containers\Sandbox\SPMeta2.Containers.SandboxSolutionContainer.wsp"; + public static Guid SolutionId = new Guid("e9a61998-07f2-45e9-ae43-9e93fa6b11bb"); + + public static Guid SiteFeatureId = new Guid("32dc6bed-0298-4fca-a72f-e9b9c0d6f09a"); + public static Guid WebFeatureId = new Guid("b997a462-8efb-44cf-92c0-457e75c81798"); + public static Guid WebPartFeatureId = new Guid("9acf0f59-3cdc-412b-a647-4185dd4cd9bc"); + } + + public static class FarmSolution + { + public static string FilePath = @"Containers\Farm\SPMeta2.Containers.FarmSolutionContainer.wsp"; + public static Guid SolutionId = new Guid("a4a2146d-57d1-48bd-a02e-ba97b371903d"); + } + + public static class Apps + { + public static Guid ProductId = new Guid("{e81b6820-5d57-4d17-a098-5f4317f6c400}"); + public static Guid FeatureId = new Guid("{e81b6820-5d57-4d17-a098-5f4317f6c401}"); + + public static string M2ClientWebPart1Name = "M2ClientWebPart1"; + public static string M2ClientWebPart2Name = "M2ClientWebPart2"; + + public static string GenericVersionableAppFilePath = @"Containers\Apps\{0}\SPMeta2.Containers.AppContainer.app"; + + public static class v0 + { + public static string FilePath = @"Containers\Apps\1.0.0.0\SPMeta2.Containers.AppContainer.app"; + } + + public static class v1 + { + public static string FilePath = @"Containers\Apps\1.0.0.1\SPMeta2.Containers.AppContainer.app"; + } + + public static class v2 + { + public static string FilePath = @"Containers\Apps\1.0.0.2\SPMeta2.Containers.AppContainer.app"; + } + + public static class v3 + { + public static string FilePath = @"Containers\Apps\1.0.0.3\SPMeta2.Containers.AppContainer.app"; + } + } + } +} diff --git a/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.0.wsp b/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.0.wsp new file mode 100644 index 0000000000000000000000000000000000000000..32b5e4c71026f38d935313a8ae1ac11067a4bd22 GIT binary patch literal 63826 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 dgNPZRPcK?3CN;mux+QJmdOd$tN8 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 O9@&!XoQ|@HzWog$W5K-u literal 0 HcmV?d00001 diff --git a/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.2.wsp b/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.2.wsp new file mode 100644 index 0000000000000000000000000000000000000000..4e2167eabea56bd51ba24be1aad1e180d64308ba GIT binary patch literal 63847 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 literal 0 HcmV?d00001 diff --git a/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.3.wsp b/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.3.wsp new file mode 100644 index 0000000000000000000000000000000000000000..6ab25886ce6c2ff4a8df7accd7d2879ebd654f30 GIT binary patch literal 63845 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 YZb=iR;WEt)Wi8@DNA5nX`v>v=03D6cs{jB1 literal 0 HcmV?d00001 diff --git a/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.4.wsp b/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.4.wsp new file mode 100644 index 0000000000000000000000000000000000000000..936fc4938497a7c8bf9835a68299003c0faa5dd4 GIT binary patch literal 63859 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 literal 0 HcmV?d00001 diff --git a/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.5.wsp b/SPMeta2/SPMeta2.Containers/Containers/DesignPackages/ci-1-1.5.wsp new file mode 100644 index 0000000000000000000000000000000000000000..b89b9d44adbca8fe680bd4278362129e2d16333f GIT binary patch literal 63851 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 Always + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + Always diff --git a/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs index d89f6b665..c7b8b50f1 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs @@ -3,10 +3,13 @@ using Microsoft.SharePoint.Publishing; using SPMeta2.Common; using SPMeta2.Definitions; +using SPMeta2.Regression.SSOM.Extensions; +using SPMeta2.Regression.SSOM.Validation; using SPMeta2.SSOM.ModelHosts; using SPMeta2.SSOM.Standard.ModelHandlers; using SPMeta2.Standard.Definitions; using SPMeta2.Utils; +using SPMeta2.Containers.Assertion; namespace SPMeta2.Regression.SSOM.Standard.Validation { @@ -19,13 +22,46 @@ public override void DeployModel(object modelHost, DefinitionBase model) var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - // TODO + var spObject = FindExistingSolutionById(siteModelHost, definition.SolutionId); - DesignPackageInfo spObject = null; + var assert = ServiceFactory.AssertService.NewAssert(definition, definition, spObject) + .ShouldNotBeNull(spObject) + .ShouldBeEqual(m => m.SolutionId, o => o.SolutionId) + .SkipProperty(m => m.FileName, "Solution should be deployed fine.") + .SkipProperty(m => m.Content, "Solution should be deployed fine."); - var assert = ServiceFactory.AssertService - .NewAssert(definition, spObject) - .ShouldNotBeNull(spObject); + if (definition.Apply) + { + // TODO + } + else + { + assert.SkipProperty(m => m.Apply, "Apply is false"); + } + + if (definition.Install) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.Install); + var isValid = spObject != null; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.Install, "Install is false"); + } + + assert.SkipProperty(m => m.MajorVersion, string.Empty); + assert.SkipProperty(m => m.MinorVersion, string.Empty); } #endregion diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Extensions/SPUserSolutionExtensions.cs b/SPMeta2/SPMeta2.Regression.SSOM/Extensions/SPUserSolutionExtensions.cs index b4e45e72a..1cee5065d 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Extensions/SPUserSolutionExtensions.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Extensions/SPUserSolutionExtensions.cs @@ -1,17 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Microsoft.SharePoint; - -namespace SPMeta2.Regression.SSOM.Extensions -{ - internal static class SPUserSolutionExtensions - { - public static bool IsActivated(this SPUserSolution solution) - { - return solution.Status == SPUserSolutionStatus.Activated; - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Microsoft.SharePoint; + +namespace SPMeta2.Regression.SSOM.Extensions +{ + public static class SPUserSolutionExtensions + { + public static bool IsActivated(this SPUserSolution solution) + { + return solution.Status == SPUserSolutionStatus.Activated; + } + } +} diff --git a/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs b/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs index 54c0c8960..c3a2bb347 100644 --- a/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs @@ -13,10 +13,11 @@ using SPMeta2.Standard.Definitions; using SPMeta2.Utils; using Microsoft.Office.Server.UserProfiles; +using SPMeta2.Services; namespace SPMeta2.SSOM.Standard.ModelHandlers { - public class DesignPackageModelHandler : SSOMModelHandlerBase + public class DesignPackageModelHandler : SandboxSolutionModelHandler { #region properties @@ -34,42 +35,133 @@ public override void DeployModel(object modelHost, DefinitionBase model) var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - DeployDefinition(modelHost, siteModelHost, definition); + DeployDesignPackage(modelHost, siteModelHost, definition); } - private void DeployDefinition(object modelHost, SiteModelHost siteModelHost, DesignPackageDefinition definition) + private void DeployDesignPackage(object modelHost, SiteModelHost siteModelHost, DesignPackageDefinition definition) { var site = siteModelHost.HostSite; - - // TODO, implementation - // Add DesignPackage provision support #166 - // https://github.com/SubPointSolutions/spmeta2/issues/166 - - DesignPackageDefinition currrentArtifact = null; + var sandboxSolution = FindExistingSolutionById(siteModelHost, definition.SolutionId); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, - Object = currrentArtifact, - ObjectType = typeof(DesignPackageDefinition), + Object = sandboxSolution, + ObjectType = typeof(SPUserSolution), ObjectDefinition = definition, ModelHost = modelHost }); - // TODO, implementation + if (sandboxSolution != null) + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, + "Processing existing design package"); + } + else + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, + "Processing new design package"); + } - InvokeOnModelEvent(this, new ModelEventArgs + var designPackageInfo = new DesignPackageInfo(definition.FileName, + definition.SolutionId, + definition.MajorVersion, + definition.MinorVersion); + + if (definition.Install) { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = currrentArtifact, - ObjectType = typeof(DesignPackageDefinition), - ObjectDefinition = definition, - ModelHost = modelHost - }); + // removing first + if (sandboxSolution != null) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting existing sandbox solution"); + siteModelHost.HostSite.Solutions.Remove(sandboxSolution); + + var catalog = siteModelHost.HostSite.RootWeb.GetCatalog(SPListTemplateType.SolutionCatalog); + + try + { + var solutionFile = catalog.RootFolder.Files[sandboxSolution.Name]; + + if (solutionFile.Exists) + solutionFile.Delete(); + } + catch + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, + "Error while deleting design package"); + } + } + + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deploying design package file to the root folder of the root web"); + + var rootFolder = site.RootWeb.RootFolder; + var file = rootFolder.Files.Add(definition.FileName, definition.Content, true); + + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, + string.Format("Installing design package from URL:[{0}]", file.ServerRelativeUrl)); + + DesignPackage.Install(site, designPackageInfo, file.ServerRelativeUrl); + + if (definition.Apply) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Applying design package"); + DesignPackage.Apply(site, designPackageInfo); + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Apply == false. Skipping design package activation"); + } + + sandboxSolution = FindExistingSolutionById(siteModelHost, definition.SolutionId); + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = sandboxSolution, + ObjectType = typeof(SPUserSolution), + ObjectDefinition = definition, + ModelHost = modelHost + }); + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activate = false. Continue provision"); + + if (sandboxSolution != null) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Solution is NOT NULL. Checking Apply status"); + + if (definition.Apply) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Applying design package"); + DesignPackage.Apply(site, designPackageInfo); + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, + "Apply == false. Skipping design package activation"); + } + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Solution is NULL. Skipping Apply status"); + } + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = sandboxSolution, + ObjectType = typeof(SPUserSolution), + ObjectDefinition = definition, + ModelHost = modelHost + }); + } } #endregion diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/SandboxSolutionModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/SandboxSolutionModelHandler.cs index a87b00c5d..c8581eca8 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/SandboxSolutionModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/SandboxSolutionModelHandler.cs @@ -1,123 +1,134 @@ -using SPMeta2.Common; -using SPMeta2.Definitions; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using SPMeta2.Services; -using SPMeta2.Utils; -using SPMeta2.SSOM.ModelHosts; -using Microsoft.SharePoint; - -namespace SPMeta2.SSOM.ModelHandlers -{ - public class SandboxSolutionModelHandler : SSOMModelHandlerBase - { - #region properties - - public override Type TargetType - { - get { return typeof(SandboxSolutionDefinition); } - } - - #endregion - - #region methods - - public override void DeployModel(object modelHost, DefinitionBase model) - { - var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); - var sandboxSolutionDefinition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - - DeploySandboxSolution(modelHost, siteModelHost, sandboxSolutionDefinition); - } - - private void DeploySandboxSolution(object modelHost, SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) - { - var existingSolutions = FindExistingSolutionFile(siteModelHost, sandboxSolutionDefinition); - var sandboxSolution = FindExistingSolution(siteModelHost, sandboxSolutionDefinition); - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioning, - Object = sandboxSolution, - ObjectType = typeof(SPUserSolution), - ObjectDefinition = sandboxSolutionDefinition, - ModelHost = modelHost - }); - - if (sandboxSolution != null) - TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing sandbox solution"); - - if (sandboxSolution != null && sandboxSolution.Status == SPUserSolutionStatus.Activated) - { - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting existing sandbox solution"); - siteModelHost.HostSite.Solutions.Remove(sandboxSolution); - } - - var solutionGallery = (SPDocumentLibrary)siteModelHost.HostSite.GetCatalog(SPListTemplateType.SolutionCatalog); - var file = solutionGallery.RootFolder.Files.Add(sandboxSolutionDefinition.FileName, sandboxSolutionDefinition.Content, true); - - if (sandboxSolutionDefinition.Activate) - { - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activating sandbox solution"); - - var userSolution = siteModelHost.HostSite.Solutions.Add(file.Item.ID); - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = userSolution, - ObjectType = typeof(SPUserSolution), - ObjectDefinition = sandboxSolutionDefinition, - ModelHost = modelHost - }); - } - else - { - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activate = false. Continue provision"); - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = sandboxSolution, - ObjectType = typeof(SPUserSolution), - ObjectDefinition = sandboxSolutionDefinition, - ModelHost = modelHost - }); - } - } - - protected SPUserSolution FindExistingSolution(SiteModelHost siteModelHost, - SandboxSolutionDefinition sandboxSolutionDefinition) - { - TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by SolutionId: [{0}]", sandboxSolutionDefinition.SolutionId); - - return siteModelHost.HostSite.Solutions.OfType() - .FirstOrDefault(f => f.SolutionId == sandboxSolutionDefinition.SolutionId); - } - - protected SPFile FindExistingSolutionFile(SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) - { - TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by FileName: [{0}]", sandboxSolutionDefinition.FileName); - - - var site = siteModelHost.HostSite; - var solutionGallery = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog); - - return solutionGallery.RootFolder - .Files - .OfType() - .FirstOrDefault(f => f.Name.ToUpper() == sandboxSolutionDefinition.FileName.ToUpper()); - } - - #endregion - } -} +using SPMeta2.Common; +using SPMeta2.Definitions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using SPMeta2.Services; +using SPMeta2.Utils; +using SPMeta2.SSOM.ModelHosts; +using Microsoft.SharePoint; + +namespace SPMeta2.SSOM.ModelHandlers +{ + public class SandboxSolutionModelHandler : SSOMModelHandlerBase + { + #region properties + + public override Type TargetType + { + get { return typeof(SandboxSolutionDefinition); } + } + + #endregion + + #region methods + + public override void DeployModel(object modelHost, DefinitionBase model) + { + var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + var sandboxSolutionDefinition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + + DeploySandboxSolution(modelHost, siteModelHost, sandboxSolutionDefinition); + } + + private void DeploySandboxSolution(object modelHost, SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) + { + var existingSolutions = FindExistingSolutionFile(siteModelHost, sandboxSolutionDefinition); + var sandboxSolution = FindExistingSolution(siteModelHost, sandboxSolutionDefinition); + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioning, + Object = sandboxSolution, + ObjectType = typeof(SPUserSolution), + ObjectDefinition = sandboxSolutionDefinition, + ModelHost = modelHost + }); + + if (sandboxSolution != null) + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing sandbox solution"); + + if (sandboxSolution != null && sandboxSolution.Status == SPUserSolutionStatus.Activated) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting existing sandbox solution"); + siteModelHost.HostSite.Solutions.Remove(sandboxSolution); + } + + var solutionGallery = (SPDocumentLibrary)siteModelHost.HostSite.GetCatalog(SPListTemplateType.SolutionCatalog); + var file = solutionGallery.RootFolder.Files.Add(sandboxSolutionDefinition.FileName, sandboxSolutionDefinition.Content, true); + + if (sandboxSolutionDefinition.Activate) + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activating sandbox solution"); + + var userSolution = siteModelHost.HostSite.Solutions.Add(file.Item.ID); + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = userSolution, + ObjectType = typeof(SPUserSolution), + ObjectDefinition = sandboxSolutionDefinition, + ModelHost = modelHost + }); + } + else + { + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activate = false. Continue provision"); + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = sandboxSolution, + ObjectType = typeof(SPUserSolution), + ObjectDefinition = sandboxSolutionDefinition, + ModelHost = modelHost + }); + } + } + + protected virtual SPUserSolution FindExistingSolution(SiteModelHost siteModelHost, + SandboxSolutionDefinition sandboxSolutionDefinition) + { + return FindExistingSolutionById(siteModelHost, sandboxSolutionDefinition.SolutionId); + } + + protected virtual SPUserSolution FindExistingSolutionById(SiteModelHost siteModelHost, + Guid solutionId) + { + TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by SolutionId: [{0}]", solutionId); + + // cler m_SiteSolutions flat to get always a fresh colletion + // m_SiteSolutions + var site = siteModelHost.HostSite; + ReflectionUtils.SetNonPublicFieldValue(site, "m_SiteSolutions", null); + + return siteModelHost.HostSite.Solutions.OfType() + .FirstOrDefault(f => f.SolutionId == solutionId); + } + + protected virtual SPFile FindExistingSolutionFile(SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) + { + TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by FileName: [{0}]", sandboxSolutionDefinition.FileName); + + + var site = siteModelHost.HostSite; + var solutionGallery = (SPDocumentLibrary)site.GetCatalog(SPListTemplateType.SolutionCatalog); + + return solutionGallery.RootFolder + .Files + .OfType() + .FirstOrDefault(f => f.Name.ToUpper() == sandboxSolutionDefinition.FileName.ToUpper()); + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2.Standard/Definitions/DesignPackageDefinition.cs b/SPMeta2/SPMeta2.Standard/Definitions/DesignPackageDefinition.cs index 233333663..f8cc8021b 100644 --- a/SPMeta2/SPMeta2.Standard/Definitions/DesignPackageDefinition.cs +++ b/SPMeta2/SPMeta2.Standard/Definitions/DesignPackageDefinition.cs @@ -10,14 +10,15 @@ using SPMeta2.Utils; using System.Runtime.Serialization; using SPMeta2.Attributes.Capabilities; +using SPMeta2.Definitions.Base; namespace SPMeta2.Standard.Definitions { /// /// Allows to define and deploy SharePoint design package. /// - [SPObjectType(SPObjectModelType.SSOM, "Microsoft.SharePoint.Publishing.DesignPackageInfo", "Microsoft.SharePoint.Publishing")] - [SPObjectType(SPObjectModelType.CSOM, "Microsoft.SharePoint.Client.Publishing.DesignPackageInfo", "Microsoft.SharePoint.Client.Publishing")] + [SPObjectType(SPObjectModelType.SSOM, "Microsoft.SharePoint.SPUserSolution", "Microsoft.SharePoint")] + [SPObjectType(SPObjectModelType.CSOM, "Microsoft.SharePoint.Client.File", "Microsoft.SharePoint.Client")] [DefaultParentHost(typeof(SiteDefinition))] [DefaultRootHost(typeof(SiteDefinition))] @@ -31,27 +32,45 @@ namespace SPMeta2.Standard.Definitions [ExpectManyInstances] - public class DesignPackageDefinition : DefinitionBase + public class DesignPackageDefinition : SolutionDefinitionBase { + #region ccontructors + + public DesignPackageDefinition() + { + Content = new byte[0]; + + Install = true; + Apply = false; + } + + #endregion + #region properties - [ExpectRequired] + [ExpectValidation] [DataMember] - [IdentityKey] - public string PackageName { get; set; } + public int MajorVersion { get; set; } - [ExpectRequired] - [DataMember] [ExpectValidation] - public Guid PackageGuid { get; set; } + [DataMember] + public int MinorVersion { get; set; } + /// + /// Represents DesignPackage.Install() call + /// True by default. + /// [ExpectValidation] [DataMember] - public int? MajorVersion { get; set; } + public bool Install { get; set; } + /// + /// Represents DesignPackage.Apply() call + /// False by default. + /// [ExpectValidation] [DataMember] - public int? MinorVersion { get; set; } + public bool Apply { get; set; } #endregion @@ -60,7 +79,10 @@ public class DesignPackageDefinition : DefinitionBase public override string ToString() { return new ToStringResult(this) - .AddPropertyValue(p => p.PackageName) + .AddPropertyValue(p => p.FileName) + .AddPropertyValue(p => p.SolutionId) + .AddPropertyValue(p => p.Install) + .AddPropertyValue(p => p.Apply) .ToString(); } diff --git a/SPMeta2/SPMeta2/Definitions/Base/SolutionDefinitionBase.cs b/SPMeta2/SPMeta2/Definitions/Base/SolutionDefinitionBase.cs index 1ba3869c9..0f218b8e7 100644 --- a/SPMeta2/SPMeta2/Definitions/Base/SolutionDefinitionBase.cs +++ b/SPMeta2/SPMeta2/Definitions/Base/SolutionDefinitionBase.cs @@ -1,44 +1,45 @@ -using System; -using System.Runtime.Serialization; -using SPMeta2.Attributes.Identity; -using SPMeta2.Attributes.Regression; - -namespace SPMeta2.Definitions.Base -{ - - /// - /// Base definition for farm and sandbox solution definitions. - /// - [DataContract] - public abstract class SolutionDefinitionBase : DefinitionBase - { - #region properties - - /// - /// Target solutions file name. - /// - /// - [ExpectValidation] - [ExpectRequired] - [DataMember] - public string FileName { get; set; } - - /// - /// Target sandbox solution content. - /// - [ExpectValidation] - [ExpectRequired] - [DataMember] - public byte[] Content { get; set; } - - /// - /// Target ID of the solution. - /// - [ExpectValidation] - [DataMember] - [IdentityKey] - public Guid SolutionId { get; set; } - - #endregion - } -} +using System; +using System.Runtime.Serialization; +using SPMeta2.Attributes.Identity; +using SPMeta2.Attributes.Regression; + +namespace SPMeta2.Definitions.Base +{ + + /// + /// Base definition for farm and sandbox solution definitions. + /// + [DataContract] + public abstract class SolutionDefinitionBase : DefinitionBase + { + #region properties + + /// + /// Target solutions file name. + /// + /// + [ExpectValidation] + [ExpectRequired] + [DataMember] + public string FileName { get; set; } + + /// + /// Target sandbox solution content. + /// + [ExpectValidation] + [ExpectRequired] + [DataMember] + public byte[] Content { get; set; } + + /// + /// Target ID of the solution. + /// + [ExpectValidation] + [DataMember] + [IdentityKey] + [ExpectRequired] + public Guid SolutionId { get; set; } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2/Utils/ReflectionUtils.cs b/SPMeta2/SPMeta2/Utils/ReflectionUtils.cs index 26af33e1a..fbdc7e247 100644 --- a/SPMeta2/SPMeta2/Utils/ReflectionUtils.cs +++ b/SPMeta2/SPMeta2/Utils/ReflectionUtils.cs @@ -23,6 +23,18 @@ public static class ReflectionUtils { #region methods + #region set helpers + + public static void SetNonPublicFieldValue(object obj, string fieldName, object value) + { + var prop = obj.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance); + + if (prop != null) + prop.SetValue(obj, value); + } + + #endregion + #region get prop methods public static IEnumerable GetPropertiesWithCustomAttribute(object obj) From 48302ee32716f744602f28ac50a98134db607929 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Sat, 29 Oct 2016 21:40:23 -0700 Subject: [PATCH 18/20] + Add DesignPackageDefinition - design package provision support #166 + CSOM impl --- .../DesignPackageModelHandler.cs | 157 ++++++- .../SandboxSolutionModelHandler.cs | 433 +++++++++--------- .../Services/RegressionTestService.cs | 5 + .../DesignPackageDefinitionValidator.cs | 79 +++- .../DesignPackageDefinitionValidator.cs | 22 +- .../Scenarios/DesignPackageScenariosTest.cs | 110 +++++ .../SPMeta2.Regression.Tests.csproj | 1 + .../DesignPackageModelHandler.cs | 15 +- 8 files changed, 589 insertions(+), 233 deletions(-) create mode 100644 SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/DesignPackageScenariosTest.cs diff --git a/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs b/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs index be3bc7c8e..deb4b003a 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using Microsoft.SharePoint.Client.Publishing; using SPMeta2.Common; @@ -13,10 +14,11 @@ using Microsoft.SharePoint.Client.DocumentSet; using Microsoft.SharePoint.Client; using SPMeta2.Exceptions; +using File = Microsoft.SharePoint.Client.File; namespace SPMeta2.CSOM.Standard.ModelHandlers { - public class DesignPackageModelHandler : CSOMModelHandlerBase + public class DesignPackageModelHandler : SandboxSolutionModelHandler { #region properties @@ -31,40 +33,171 @@ public override Type TargetType public override void DeployModel(object modelHost, DefinitionBase model) { - var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); DeployArtifact(siteModelHost, definition); } - private void DeployArtifact(SiteModelHandler modelHost, DesignPackageDefinition definition) + private void DeployArtifact(SiteModelHost modelHost, DesignPackageDefinition definition) { - // TODO, implementation - // Add DesignPackage provision support #166 - // https://github.com/SubPointSolutions/spmeta2/issues/166 + var site = modelHost.HostSite; + var context = site.Context; - DesignPackageInfo currentArtifact = null; + //var existingSolutionFile = FindExistingSolutionFile(siteModelHost, definition); + var existingSolution = FindExistingSolutionById(modelHost, definition.SolutionId); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, - Object = currentArtifact, - ObjectType = typeof(DesignPackageInfo), + Object = existingSolution, + ObjectType = typeof(File), ObjectDefinition = definition, ModelHost = modelHost }); - // TODO + // uninstalling existing one + if (existingSolution != null && definition.Install) + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, + "Processing existing sandbox solution"); + + var fileItem = existingSolution.ListItemAllFields; + context.Load(fileItem); + context.ExecuteQueryWithTrace(); + + var currentFileName = fileItem["FileLeafRef"].ToString(); + + //if (!currentFileName.Contains(definition.FileName)) + // currentFileName = currentFileName.Replace(string.Format("-v{0}.{1}.wsp", 1, 0), string.Empty); + //else + // currentFileName = definition.FileName; + + var packageFileName = Path.GetFileNameWithoutExtension(currentFileName); + var packageFileNameParts = packageFileName.Split('-'); + + var packageName = packageFileNameParts[0]; + + var versionParts = packageFileNameParts[1].Replace("v", string.Empty) + .Split('.'); + + var packageMajorVersion = int.Parse(versionParts[0]); + var packageMinorVersion = int.Parse(versionParts[1]); + + var info = new DesignPackageInfo + { + PackageGuid = definition.SolutionId, + MajorVersion = packageMajorVersion, + MinorVersion = packageMinorVersion, + PackageName = packageName, + + }; + + // cleaning up AppliedDesignGuid at root web to enable 'force' uninstall + var rootWeb = site.RootWeb; + rootWeb.AllProperties["AppliedDesignGuid"] = null; + rootWeb.Update(); + + context.ExecuteQueryWithTrace(); + + // deactivate and remove + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, + "Deleting existing sandbox solution via DesignPackage.UnInstall()"); + DesignPackage.UnInstall(context, site, info); + + try + { + context.ExecuteQueryWithTrace(); + } + catch (Exception uninstallException) + { + // pass this one + // bug in SharePoint's DesignPackage.UnInstall method + if (!uninstallException.ToString().Contains("33e33eca-7712-4f3d-ab83-6848789fc9b6")) + { + throw; + } + } + } + + // installing new + if (definition.Install) + { + var folder = site.RootWeb.RootFolder; + + context.Load(folder); + context.ExecuteQueryWithTrace(); + + var fileCreatingInfo = new FileCreationInformation + { + Url = definition.FileName, + Overwrite = true + }; + + if (definition.Content.Length < 1024 * 1024 * 1.5) + { + fileCreatingInfo.Content = definition.Content; + } + else + { + fileCreatingInfo.ContentStream = new MemoryStream(definition.Content); + } + + + var newFile = folder.Files.Add(fileCreatingInfo); + + context.Load(newFile); + context.Load(newFile, f => f.ServerRelativeUrl); + + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Uploading new sandbox solution to root site folder"); + context.ExecuteQueryWithTrace(); + + var info = new DesignPackageInfo + { + PackageGuid = definition.SolutionId, + MajorVersion = definition.MajorVersion, + MinorVersion = definition.MinorVersion, + PackageName = Path.GetFileNameWithoutExtension(definition.FileName) + }; + + // activate and remove + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "DesignPackage.Install()"); + DesignPackage.Install(context, site, info, newFile.ServerRelativeUrl); + context.ExecuteQueryWithTrace(); + + // clean up the file + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting sandbox file from root site folder"); + newFile.DeleteObject(); + context.ExecuteQueryWithTrace(); + + existingSolution = FindExistingSolutionById(modelHost, definition.SolutionId); + } + + if (definition.Apply) + { + var info = new DesignPackageInfo + { + PackageGuid = definition.SolutionId, + MajorVersion = definition.MajorVersion, + MinorVersion = definition.MinorVersion, + PackageName = Path.GetFileNameWithoutExtension(definition.FileName) + }; + + // apply + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "DesignPackage.Apply()"); + DesignPackage.Apply(context, site, info); + context.ExecuteQueryWithTrace(); + } InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, - Object = currentArtifact, - ObjectType = typeof(DesignPackageInfo), + Object = existingSolution, + ObjectType = typeof(File), ObjectDefinition = definition, ModelHost = modelHost }); diff --git a/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/SandboxSolutionModelHandler.cs b/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/SandboxSolutionModelHandler.cs index 8d7bd3106..95e35e2d8 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/SandboxSolutionModelHandler.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/ModelHandlers/SandboxSolutionModelHandler.cs @@ -1,210 +1,223 @@ -using System; -using System.IO; -using System.Linq; -using Microsoft.SharePoint.Client; -using Microsoft.SharePoint.Client.Publishing; -using SPMeta2.Common; -using SPMeta2.CSOM.Extensions; -using SPMeta2.CSOM.ModelHandlers; -using SPMeta2.CSOM.ModelHosts; -using SPMeta2.Definitions; -using SPMeta2.Exceptions; -using SPMeta2.Services; -using SPMeta2.Utils; -using File = Microsoft.SharePoint.Client.File; - -namespace SPMeta2.CSOM.Standard.ModelHandlers -{ - public class SandboxSolutionModelHandler : CSOMModelHandlerBase - { - #region properties - - public override Type TargetType - { - get { return typeof(SandboxSolutionDefinition); } - } - - #endregion - - #region methods - - public override void DeployModel(object modelHost, DefinitionBase model) - { - var sandboxSolutionDefinition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - - ValidateDefinition(sandboxSolutionDefinition); - - var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); - - DeploySandboxSolution(modelHost, siteModelHost, sandboxSolutionDefinition); - } - - private void ValidateDefinition(SandboxSolutionDefinition sandboxSolutionDefinition) - { - if (!sandboxSolutionDefinition.Activate) - throw new SPMeta2NotSupportedException("SandboxSolutionDefinition.Activate must be true. (DesignPackage API requires it)."); - - if (sandboxSolutionDefinition.SolutionId == default(Guid)) - throw new SPMeta2NotSupportedException("SandboxSolutionDefinition.SolutionId must be defined for CSOM based provision (DesignPackage API requires it)."); - - var fileName = Path.GetFileNameWithoutExtension(sandboxSolutionDefinition.FileName); - - if (fileName.Contains(".")) - throw new SPMeta2NotSupportedException("SandboxSolutionDefinition.FileName must not contain dots. (DesignPackage API requires it)."); - } - - private void DeploySandboxSolution(object modelHost, SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) - { - var site = siteModelHost.HostSite; - var context = site.Context; - - var existingSolutionFile = FindExistingSolutionFile(siteModelHost, sandboxSolutionDefinition); - var existingSolution = FindExistingSolution(siteModelHost, sandboxSolutionDefinition); - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioning, - Object = existingSolutionFile, - ObjectType = typeof(File), - ObjectDefinition = sandboxSolutionDefinition, - ModelHost = modelHost - }); - - if (existingSolution != null) - { - TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing sandbox solution"); - - var fileItem = existingSolution.ListItemAllFields; - context.Load(fileItem); - context.ExecuteQueryWithTrace(); - - var currentFileName = fileItem["FileLeafRef"].ToString(); - - if (!currentFileName.Contains(sandboxSolutionDefinition.FileName)) - { - currentFileName = currentFileName.Replace(string.Format("-v{0}.{1}.wsp", 1, 0), string.Empty); - } - else - { - currentFileName = sandboxSolutionDefinition.FileName; - } - - var info = new DesignPackageInfo - { - PackageGuid = sandboxSolutionDefinition.SolutionId, - MajorVersion = 1, - MinorVersion = 0, - PackageName = Path.GetFileNameWithoutExtension(currentFileName) - }; - - // deactivate and remove - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting existing sandbox solution via DesignPackage.UnInstall()"); - DesignPackage.UnInstall(context, site, info); - - context.ExecuteQueryWithTrace(); - } - - //var solutionGallery = site.RootWeb.Lists.GetByTitle("Site Assets"); - //var folder = solutionGallery.RootFolder; - var folder = site.RootWeb.RootFolder; - - context.Load(folder); - context.ExecuteQueryWithTrace(); - - var fileCreatingInfo = new FileCreationInformation - { - Url = sandboxSolutionDefinition.FileName, - Overwrite = true - }; - - if (sandboxSolutionDefinition.Content.Length < 1024 * 1024 * 1.5) - { - fileCreatingInfo.Content = sandboxSolutionDefinition.Content; - } - else - { - fileCreatingInfo.ContentStream = new System.IO.MemoryStream(sandboxSolutionDefinition.Content); - } - - - var newFile = folder.Files.Add(fileCreatingInfo); - - context.Load(newFile); - context.Load(newFile, f => f.ServerRelativeUrl); - - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Uploading new sandbox solution to root site folder"); - context.ExecuteQueryWithTrace(); - - if (sandboxSolutionDefinition.Activate) - { - var info = new DesignPackageInfo - { - PackageGuid = sandboxSolutionDefinition.SolutionId, - MajorVersion = 1, - MinorVersion = 0, - PackageName = Path.GetFileNameWithoutExtension(sandboxSolutionDefinition.FileName) - }; - - // activate and remove - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activating sandbox solution via DesignPackage.Install()"); - DesignPackage.Install(context, site, info, newFile.ServerRelativeUrl); - context.ExecuteQueryWithTrace(); - - // clean up the file - TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting sandbox file from root site folder"); - newFile.DeleteObject(); - context.ExecuteQueryWithTrace(); - } - - InvokeOnModelEvent(this, new ModelEventArgs - { - CurrentModelNode = null, - Model = null, - EventType = ModelEventType.OnProvisioned, - Object = newFile, - ObjectType = typeof(File), - ObjectDefinition = sandboxSolutionDefinition, - ModelHost = modelHost - }); - } - - protected File FindExistingSolution(SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) - { - TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by SolutionId: [{0}]", sandboxSolutionDefinition.SolutionId); - - var site = siteModelHost.HostSite; - var context = site.Context; - - var solutionGallery = site.GetCatalog((int)ListTemplateType.SolutionCatalog); - var files = solutionGallery.GetItems(CamlQuery.CreateAllItemsQuery()); - - context.Load(files); - context.ExecuteQueryWithTrace(); - - var fileItem = files.ToList().FirstOrDefault(f => new Guid(f["SolutionId"].ToString()) == sandboxSolutionDefinition.SolutionId); - return fileItem != null ? fileItem.File : null; - } - - protected File FindExistingSolutionFile(SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) - { - TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by FileName: [{0}]", sandboxSolutionDefinition.FileName); - - var site = siteModelHost.HostSite; - var context = site.Context; - - var solutionGallery = site.GetCatalog((int)ListTemplateType.SolutionCatalog); - var files = solutionGallery.GetItems(CamlQuery.CreateAllItemsQuery()); - - context.Load(files); - context.ExecuteQueryWithTrace(); - - var fileItem = files.ToList().FirstOrDefault(f => f["FileLeafRef"].ToString() == sandboxSolutionDefinition.FileName); - - return fileItem != null ? fileItem.File : null; - } - - #endregion - } -} +using System; +using System.IO; +using System.Linq; +using Microsoft.SharePoint.Client; +using Microsoft.SharePoint.Client.Publishing; +using SPMeta2.Common; +using SPMeta2.CSOM.Extensions; +using SPMeta2.CSOM.ModelHandlers; +using SPMeta2.CSOM.ModelHosts; +using SPMeta2.Definitions; +using SPMeta2.Exceptions; +using SPMeta2.Services; +using SPMeta2.Utils; +using File = Microsoft.SharePoint.Client.File; + +namespace SPMeta2.CSOM.Standard.ModelHandlers +{ + public class SandboxSolutionModelHandler : CSOMModelHandlerBase + { + #region properties + + public override Type TargetType + { + get { return typeof(SandboxSolutionDefinition); } + } + + #endregion + + #region methods + + public override void DeployModel(object modelHost, DefinitionBase model) + { + var sandboxSolutionDefinition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + + ValidateDefinition(sandboxSolutionDefinition); + + var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); + + DeploySandboxSolution(modelHost, siteModelHost, sandboxSolutionDefinition); + } + + private void ValidateDefinition(SandboxSolutionDefinition sandboxSolutionDefinition) + { + if (!sandboxSolutionDefinition.Activate) + throw new SPMeta2NotSupportedException("SandboxSolutionDefinition.Activate must be true. (DesignPackage API requires it)."); + + if (sandboxSolutionDefinition.SolutionId == default(Guid)) + throw new SPMeta2NotSupportedException("SandboxSolutionDefinition.SolutionId must be defined for CSOM based provision (DesignPackage API requires it)."); + + var fileName = Path.GetFileNameWithoutExtension(sandboxSolutionDefinition.FileName); + + if (fileName.Contains(".")) + throw new SPMeta2NotSupportedException("SandboxSolutionDefinition.FileName must not contain dots. (DesignPackage API requires it)."); + } + + private void DeploySandboxSolution(object modelHost, SiteModelHost siteModelHost, SandboxSolutionDefinition sandboxSolutionDefinition) + { + var site = siteModelHost.HostSite; + var context = site.Context; + + var existingSolutionFile = FindExistingSolutionFile(siteModelHost, sandboxSolutionDefinition); + var existingSolution = FindExistingSolution(siteModelHost, sandboxSolutionDefinition); + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioning, + Object = existingSolutionFile, + ObjectType = typeof(File), + ObjectDefinition = sandboxSolutionDefinition, + ModelHost = modelHost + }); + + if (existingSolution != null) + { + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing sandbox solution"); + + var fileItem = existingSolution.ListItemAllFields; + context.Load(fileItem); + context.ExecuteQueryWithTrace(); + + var currentFileName = fileItem["FileLeafRef"].ToString(); + + if (!currentFileName.Contains(sandboxSolutionDefinition.FileName)) + { + currentFileName = currentFileName.Replace(string.Format("-v{0}.{1}.wsp", 1, 0), string.Empty); + } + else + { + currentFileName = sandboxSolutionDefinition.FileName; + } + + var info = new DesignPackageInfo + { + PackageGuid = sandboxSolutionDefinition.SolutionId, + MajorVersion = 1, + MinorVersion = 0, + PackageName = Path.GetFileNameWithoutExtension(currentFileName) + }; + + // deactivate and remove + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting existing sandbox solution via DesignPackage.UnInstall()"); + DesignPackage.UnInstall(context, site, info); + + context.ExecuteQueryWithTrace(); + } + + //var solutionGallery = site.RootWeb.Lists.GetByTitle("Site Assets"); + //var folder = solutionGallery.RootFolder; + var folder = site.RootWeb.RootFolder; + + context.Load(folder); + context.ExecuteQueryWithTrace(); + + var fileCreatingInfo = new FileCreationInformation + { + Url = sandboxSolutionDefinition.FileName, + Overwrite = true + }; + + if (sandboxSolutionDefinition.Content.Length < 1024 * 1024 * 1.5) + { + fileCreatingInfo.Content = sandboxSolutionDefinition.Content; + } + else + { + fileCreatingInfo.ContentStream = new System.IO.MemoryStream(sandboxSolutionDefinition.Content); + } + + + var newFile = folder.Files.Add(fileCreatingInfo); + + context.Load(newFile); + context.Load(newFile, f => f.ServerRelativeUrl); + + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Uploading new sandbox solution to root site folder"); + context.ExecuteQueryWithTrace(); + + if (sandboxSolutionDefinition.Activate) + { + var info = new DesignPackageInfo + { + PackageGuid = sandboxSolutionDefinition.SolutionId, + MajorVersion = 1, + MinorVersion = 0, + PackageName = Path.GetFileNameWithoutExtension(sandboxSolutionDefinition.FileName) + }; + + // activate and remove + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Activating sandbox solution via DesignPackage.Install()"); + DesignPackage.Install(context, site, info, newFile.ServerRelativeUrl); + context.ExecuteQueryWithTrace(); + + // clean up the file + TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deleting sandbox file from root site folder"); + newFile.DeleteObject(); + context.ExecuteQueryWithTrace(); + } + + InvokeOnModelEvent(this, new ModelEventArgs + { + CurrentModelNode = null, + Model = null, + EventType = ModelEventType.OnProvisioned, + Object = newFile, + ObjectType = typeof(File), + ObjectDefinition = sandboxSolutionDefinition, + ModelHost = modelHost + }); + } + + protected File FindExistingSolution(SiteModelHost siteModelHost, + SandboxSolutionDefinition sandboxSolutionDefinition) + { + return FindExistingSolutionById(siteModelHost, sandboxSolutionDefinition.SolutionId); + } + + protected File FindExistingSolutionById(SiteModelHost siteModelHost, Guid solutionId) + { + TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by SolutionId: [{0}]", solutionId); + + var site = siteModelHost.HostSite; + var context = site.Context; + + var solutionGallery = site.GetCatalog((int)ListTemplateType.SolutionCatalog); + var files = solutionGallery.GetItems(CamlQuery.CreateAllItemsQuery()); + + context.Load(files); + context.ExecuteQueryWithTrace(); + + var fileItem = files.ToList().FirstOrDefault(f => new Guid(f["SolutionId"].ToString()) == solutionId); + return fileItem != null ? fileItem.File : null; + } + + + protected File FindExistingSolutionFile(SiteModelHost siteModelHost, + SandboxSolutionDefinition sandboxSolutionDefinition) + { + return FindExistingSolutionFileByName(siteModelHost, sandboxSolutionDefinition.FileName); + } + + protected File FindExistingSolutionFileByName(SiteModelHost siteModelHost, string fileName) + { + TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Resolving sandbox solution by FileName: [{0}]", fileName); + + var site = siteModelHost.HostSite; + var context = site.Context; + + var solutionGallery = site.GetCatalog((int)ListTemplateType.SolutionCatalog); + var files = solutionGallery.GetItems(CamlQuery.CreateAllItemsQuery()); + + context.Load(files); + context.ExecuteQueryWithTrace(); + + var fileItem = files.ToList().FirstOrDefault(f => f["FileLeafRef"].ToString() == fileName); + + return fileItem != null ? fileItem.File : null; + } + + #endregion + } +} diff --git a/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs b/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs index fbe9ab6a6..e1e254520 100644 --- a/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs +++ b/SPMeta2/SPMeta2.Containers/Services/RegressionTestService.cs @@ -379,6 +379,11 @@ protected virtual Action> Create } else { + if (context.Object == null) + { + Console.WriteLine(""); + } + AssertService.IsNotNull(context.Object); AssertService.IsNotNull(context.ObjectDefinition); diff --git a/SPMeta2/SPMeta2.Regression.CSOM.Standard/Validation/DesignPackageDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.CSOM.Standard/Validation/DesignPackageDefinitionValidator.cs index 3f6b861ac..bc5ad6896 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM.Standard/Validation/DesignPackageDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM.Standard/Validation/DesignPackageDefinitionValidator.cs @@ -1,9 +1,11 @@ using Microsoft.SharePoint.Client; using Microsoft.SharePoint.Client.Publishing; +using SPMeta2.Containers.Assertion; using SPMeta2.CSOM.Extensions; using SPMeta2.CSOM.ModelHosts; using SPMeta2.CSOM.Standard.ModelHandlers; using SPMeta2.Definitions; +using SPMeta2.Regression.CSOM.Standard.Extensions; using SPMeta2.Standard.Definitions; using SPMeta2.Utils; @@ -18,14 +20,79 @@ public override void DeployModel(object modelHost, DefinitionBase model) var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); - // TODO - var context = siteModelHost.HostSite.Context; + var spObject = this.FindExistingSolutionById(siteModelHost, definition.SolutionId); + var context = spObject.Context; - DesignPackageInfo spObject = null; + var site = siteModelHost.HostSite; + var rootWeb = site.RootWeb; - var assert = ServiceFactory.AssertService - .NewAssert(definition, spObject) - .ShouldNotBeNull(spObject); + var fileItem = spObject.ListItemAllFields; + + context.Load(fileItem); + context.Load(rootWeb, w => w.AllProperties); + + context.ExecuteQueryWithTrace(); + + var assert = ServiceFactory.AssertService.NewAssert(definition, fileItem); + + assert + .ShouldNotBeNull(fileItem) + + //.ShouldBeEqual(d => d, o => o.GetSolutionActivationStatus()) + .ShouldBeEqual(d => d.SolutionId, o => o.GetSolutionId()) + + .SkipProperty(d => d.Content, "Content is fine.") + .SkipProperty(d => d.FileName, "Randomly generated by CSOM activation."); + + if (definition.Apply) + { + assert.ShouldBeEqual((p, s, d) => + { + // once applied, design package sets AppliedDesignGuid property in the root web + // checking is all good + var installedPackageId = ConvertUtils.ToGuid(rootWeb.AllProperties["AppliedDesignGuid"]); + + var srcProp = s.GetExpressionValue(m => m.Apply); + var isValid = spObject != null + && installedPackageId == definition.SolutionId; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(m => m.Apply, "Apply is false"); + } + + if (definition.Install) + { + assert.ShouldBeEqual((p, s, d) => + { + var srcProp = s.GetExpressionValue(m => m.Install); + var isValid = spObject != null; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); + } + else + { + assert.SkipProperty(d => d.Install, "Install is false"); + } + + assert.SkipProperty(m => m.MajorVersion, string.Empty); + assert.SkipProperty(m => m.MinorVersion, string.Empty); } #endregion diff --git a/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs b/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs index c7b8b50f1..87001ad13 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM.Standard/Validation/DesignPackageDefinitionValidator.cs @@ -22,6 +22,9 @@ public override void DeployModel(object modelHost, DefinitionBase model) var siteModelHost = modelHost.WithAssertAndCast("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast("model", value => value.RequireNotNull()); + var site = siteModelHost.HostSite; + var rootWeb = site.RootWeb; + var spObject = FindExistingSolutionById(siteModelHost, definition.SolutionId); var assert = ServiceFactory.AssertService.NewAssert(definition, definition, spObject) @@ -32,7 +35,24 @@ public override void DeployModel(object modelHost, DefinitionBase model) if (definition.Apply) { - // TODO + assert.ShouldBeEqual((p, s, d) => + { + // once applied, design package sets AppliedDesignGuid property in the root web + // checking is all good + var installedPackageId = ConvertUtils.ToGuid(rootWeb.AllProperties["AppliedDesignGuid"]); + + var srcProp = s.GetExpressionValue(m => m.Apply); + var isValid = spObject != null + && installedPackageId == definition.SolutionId; + + return new PropertyValidationResult + { + Tag = p.Tag, + Src = srcProp, + Dst = null, + IsValid = isValid + }; + }); } else { diff --git a/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/DesignPackageScenariosTest.cs b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/DesignPackageScenariosTest.cs new file mode 100644 index 000000000..9005159d7 --- /dev/null +++ b/SPMeta2/SPMeta2.Regression.Tests/Impl/Scenarios/DesignPackageScenariosTest.cs @@ -0,0 +1,110 @@ +using System.Diagnostics; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SPMeta2.Containers; +using SPMeta2.Containers.Services; +using SPMeta2.Definitions; +using SPMeta2.Exceptions; +using SPMeta2.Regression.Tests.Base; +using SPMeta2.Regression.Tests.Impl.Scenarios.Base; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using SPMeta2.Syntax.Default; +using System.IO; +using SPMeta2.Enumerations; +using SPMeta2.Models; +using SPMeta2.Standard.Definitions; +using SPMeta2.Standard.Syntax; + +namespace SPMeta2.Regression.Tests.Impl.Scenarios +{ + [TestClass] + public class DesignPackageScenariosTest : SPMeta2RegresionScenarioTestBase + { + public DesignPackageScenariosTest() + { + RegressionService.ProvisionGenerationCount = 2; + } + + #region internal + + [ClassInitializeAttribute] + public static void Init(TestContext context) + { + InternalInit(); + } + + [ClassCleanupAttribute] + public static void Cleanup() + { + InternalCleanup(); + } + + #endregion + + #region default + + [TestMethod] + [TestCategory("Regression.Scenarios.DesignPackage")] + public void CanDeploy_Simple_DesignPackage() + { + var siteFeature = BuiltInSiteFeatures.SharePointServerPublishingInfrastructure.Inherit(f => f.Enable()); + + var webFeature = BuiltInWebFeatures.SharePointServerPublishing.Inherit(f => f.Enable()); + + var designPackageDef = ModelGeneratorService.GetRandomDefinition(def => + { + + }); + + var siteModel = SPMeta2Model.NewSiteModel(site => site.AddSiteFeature(siteFeature)); + var rootWebModel = SPMeta2Model.NewWebModel(web => + { + web.AddWebFeature(webFeature); + }); + + var designPackageModel = SPMeta2Model.NewSiteModel(site => site.AddDesignPackage(designPackageDef)); + + TestModels(new ModelNode[] + { + siteModel, + rootWebModel, + designPackageModel + }); + } + + [TestMethod] + [TestCategory("Regression.Scenarios.DesignPackage")] + public void CanDeploy_Simple_DesignPackage_As_Apply() + { + var siteFeature = BuiltInSiteFeatures.SharePointServerPublishingInfrastructure.Inherit(f => f.Enable()); + + var webFeature = BuiltInWebFeatures.SharePointServerPublishing.Inherit(f => f.Enable()); + + var designPackageDef = ModelGeneratorService.GetRandomDefinition(def => + { + def.Apply = true; + }); + + var siteModel = SPMeta2Model.NewSiteModel(site => site.AddSiteFeature(siteFeature)); + var rootWebModel = SPMeta2Model.NewWebModel(web => + { + web.AddWebFeature(webFeature); + }); + + var designPackageModel = SPMeta2Model.NewSiteModel(site => site.AddDesignPackage(designPackageDef)); + + TestModels(new ModelNode[] + { + siteModel, + rootWebModel, + designPackageModel + }); + } + + + #endregion + } +} diff --git a/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj b/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj index 5df523879..cd8ce74bc 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj +++ b/SPMeta2/SPMeta2.Regression.Tests/SPMeta2.Regression.Tests.csproj @@ -163,6 +163,7 @@ + diff --git a/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs b/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs index c3a2bb347..159103a89 100644 --- a/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM.Standard/ModelHandlers/DesignPackageModelHandler.cs @@ -97,12 +97,13 @@ private void DeployDesignPackage(object modelHost, SiteModelHost siteModelHost, TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Deploying design package file to the root folder of the root web"); var rootFolder = site.RootWeb.RootFolder; - var file = rootFolder.Files.Add(definition.FileName, definition.Content, true); + var tmpDesignPackageFile = rootFolder.Files.Add(definition.FileName, definition.Content, true); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, - string.Format("Installing design package from URL:[{0}]", file.ServerRelativeUrl)); + string.Format("Installing design package from URL:[{0}]", tmpDesignPackageFile.ServerRelativeUrl)); - DesignPackage.Install(site, designPackageInfo, file.ServerRelativeUrl); + DesignPackage.Install(site, designPackageInfo, tmpDesignPackageFile.ServerRelativeUrl); + sandboxSolution = FindExistingSolutionById(siteModelHost, definition.SolutionId); if (definition.Apply) { @@ -114,7 +115,11 @@ private void DeployDesignPackage(object modelHost, SiteModelHost siteModelHost, TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Apply == false. Skipping design package activation"); } - sandboxSolution = FindExistingSolutionById(siteModelHost, definition.SolutionId); + // cleanup + if (tmpDesignPackageFile.Exists) + { + tmpDesignPackageFile.Delete(); + } InvokeOnModelEvent(this, new ModelEventArgs { @@ -151,6 +156,8 @@ private void DeployDesignPackage(object modelHost, SiteModelHost siteModelHost, TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Solution is NULL. Skipping Apply status"); } + sandboxSolution = FindExistingSolutionById(siteModelHost, definition.SolutionId); + InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, From b16aaae5cf37a587c7d8fe884a834473b2274fb9 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Mon, 31 Oct 2016 04:07:07 -0700 Subject: [PATCH 19/20] + Enhance 'FolderDefinition' provision with specific content type #600 + bugfixes for SSOM, all green tests for folder cases --- .../ModelHandlers/FolderModelHandler.cs | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FolderModelHandler.cs b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FolderModelHandler.cs index d4b92db1a..194d5d000 100644 --- a/SPMeta2/SPMeta2.SSOM/ModelHandlers/FolderModelHandler.cs +++ b/SPMeta2/SPMeta2.SSOM/ModelHandlers/FolderModelHandler.cs @@ -41,7 +41,7 @@ public override void WithResolvingModelHost(ModelHostResolveContext modelHostCon if (folderModelHost.CurrentLibrary != null) { - var currentFolder = EnsureLibraryFolder(folderModelHost, folderModel); + var currentFolder = FindCurrentLibraryFolder(folderModelHost, folderModel); var newContext = new FolderModelHost { @@ -55,7 +55,7 @@ public override void WithResolvingModelHost(ModelHostResolveContext modelHostCon } else if (folderModelHost.CurrentList != null) { - var currentListItem = EnsureListFolder(folderModelHost, folderModel); + var currentListItem = FindCurrentListFolder(folderModelHost, folderModel); var newContext = new FolderModelHost { @@ -136,6 +136,16 @@ protected SPFolder GetLibraryFolder(FolderModelHost folderModelHost, FolderDefin return folder; } + private SPListItem FindCurrentListFolder(FolderModelHost folderModelHost, FolderDefinition folderModel) + { + TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "FindCurrentListFolder()"); + + var list = folderModelHost.CurrentList; + var currentFolder = GetListFolder(folderModelHost, folderModel); + + return currentFolder.Item; + } + private SPListItem EnsureListFolder(FolderModelHost folderModelHost, FolderDefinition folderModel) { TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "EnsureListFolder()"); @@ -210,7 +220,14 @@ private SPListItem EnsureListFolder(FolderModelHost folderModelHost, FolderDefin return currentFolderItem; } + private SPFolder FindCurrentLibraryFolder(FolderModelHost folderModelHost, FolderDefinition folderModel) + { + TraceService.Information((int)LogEventId.ModelProvisionCoreCall, "FindCurrentLibraryFolder()"); + + var currentFolder = GetLibraryFolder(folderModelHost, folderModel); + return currentFolder; + } private SPFolder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefinition folderModel) { @@ -234,13 +251,18 @@ private SPFolder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefi if (currentFolder == null || !currentFolder.Exists) { - TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new library folder"); + TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, + "Processing new library folder"); currentFolder = parentFolder.SubFolders.Add(folderModel.Name); currentFolder.Update(); - MapFolderProperties(currentFolder.Item, folderModel); - currentFolder.Item.Update(); + // if NULL - that's /Forms or other 'hidden folder' within the library + if (currentFolder.Item != null) + { + MapFolderProperties(currentFolder.Item, folderModel); + currentFolder.Item.Update(); + } InvokeOnModelEvent(this, new ModelEventArgs { @@ -255,7 +277,8 @@ private SPFolder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefi } else { - TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing library folder"); + TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, + "Processing existing library folder"); InvokeOnModelEvent(this, new ModelEventArgs { @@ -267,11 +290,15 @@ private SPFolder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefi ObjectDefinition = folderModel, ModelHost = folderModelHost }); - - currentFolder.Update(); - MapFolderProperties(currentFolder.Item, folderModel); - currentFolder.Item.Update(); + //currentFolder.Update(); + + // if NULL - that's /Forms or other 'hidden folder' within the library + if (currentFolder.Item != null) + { + MapFolderProperties(currentFolder.Item, folderModel); + currentFolder.Item.Update(); + } } return currentFolder; From ee512736aebf891307dac611ac90861664e8cfb6 Mon Sep 17 00:00:00 2001 From: "support@subpointsolutions.com" Date: Mon, 31 Oct 2016 05:34:29 -0700 Subject: [PATCH 20/20] SPMeta2 v1.2.95-beta4, October 2016 --- .../Properties/AssemblyInfo.cs | 2 +- .../ModelHandlers/FolderModelHandler.cs | 24 ++++++++++++++----- .../SPMeta2.CSOM/Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../SPMeta2.O365/Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../SPMeta2.SSOM/Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- SPMeta2/SPMeta2/Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- 22 files changed, 39 insertions(+), 27 deletions(-) diff --git a/SPMeta2/SPMeta2.CSOM.Standard/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.CSOM.Standard/Properties/AssemblyInfo.cs index 2ae40049e..a15e9911d 100644 --- a/SPMeta2/SPMeta2.CSOM.Standard/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.CSOM.Standard/Properties/AssemblyInfo.cs @@ -32,4 +32,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.CSOM/ModelHandlers/FolderModelHandler.cs b/SPMeta2/SPMeta2.CSOM/ModelHandlers/FolderModelHandler.cs index b66ad17c4..438d11eaf 100644 --- a/SPMeta2/SPMeta2.CSOM/ModelHandlers/FolderModelHandler.cs +++ b/SPMeta2/SPMeta2.CSOM/ModelHandlers/FolderModelHandler.cs @@ -356,10 +356,16 @@ private Folder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefini var currentFolderItem = currentFolder.ListItemAllFields; - MapProperties(currentFolderItem, folderModel); + // could be NULL, in the /Forms or other hidden folders + if (currentFolderItem != null + && currentFolderItem.ServerObjectIsNull != null + && !currentFolderItem.ServerObjectIsNull.Value) + { + MapProperties(currentFolderItem, folderModel); - currentFolderItem.Update(); - context.ExecuteQueryWithTrace(); + currentFolderItem.Update(); + context.ExecuteQueryWithTrace(); + } #endif } else @@ -376,10 +382,16 @@ private Folder EnsureLibraryFolder(FolderModelHost folderModelHost, FolderDefini var currentFolderItem = currentFolder.ListItemAllFields; - MapProperties(currentFolderItem, folderModel); + // could be NULL, in the /Forms or other hidden folders + if (currentFolderItem != null + && currentFolderItem.ServerObjectIsNull != null + && !currentFolderItem.ServerObjectIsNull.Value) + { + MapProperties(currentFolderItem, folderModel); - currentFolderItem.Update(); - context.ExecuteQueryWithTrace(); + currentFolderItem.Update(); + context.ExecuteQueryWithTrace(); + } #endif } diff --git a/SPMeta2/SPMeta2.CSOM/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.CSOM/Properties/AssemblyInfo.cs index d8d2f270d..9501c1fe1 100644 --- a/SPMeta2/SPMeta2.CSOM/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.CSOM/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Containers.CSOM/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Containers.CSOM/Properties/AssemblyInfo.cs index 36798c040..108e7ff1f 100644 --- a/SPMeta2/SPMeta2.Containers.CSOM/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Containers.CSOM/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.2.16305.1232")] \ No newline at end of file diff --git a/SPMeta2/SPMeta2.Containers.O365/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Containers.O365/Properties/AssemblyInfo.cs index 442b9cf49..706c6dc09 100644 --- a/SPMeta2/SPMeta2.Containers.O365/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Containers.O365/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Containers.O365v16/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Containers.O365v16/Properties/AssemblyInfo.cs index a2d193f07..1bac1ea68 100644 --- a/SPMeta2/SPMeta2.Containers.O365v16/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Containers.O365v16/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.2.16305.1232")] \ No newline at end of file diff --git a/SPMeta2/SPMeta2.Containers.SSOM/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Containers.SSOM/Properties/AssemblyInfo.cs index a7684bfec..4f5b0f14b 100644 --- a/SPMeta2/SPMeta2.Containers.SSOM/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Containers.SSOM/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Containers.Standard/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Containers.Standard/Properties/AssemblyInfo.cs index 38fa3b5fd..477738e72 100644 --- a/SPMeta2/SPMeta2.Containers.Standard/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Containers.Standard/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Containers/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Containers/Properties/AssemblyInfo.cs index 98ac0b3d7..fbbc0bc97 100644 --- a/SPMeta2/SPMeta2.Containers/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Containers/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.O365/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.O365/Properties/AssemblyInfo.cs index e4b025af2..e4884e2eb 100644 --- a/SPMeta2/SPMeta2.O365/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.O365/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression.CSOM.Standard/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression.CSOM.Standard/Properties/AssemblyInfo.cs index 3318c3c11..7b28a3cdf 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM.Standard/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM.Standard/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression.CSOM/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression.CSOM/Properties/AssemblyInfo.cs index 118918056..6afa87f11 100644 --- a/SPMeta2/SPMeta2.Regression.CSOM/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression.CSOM/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression.Impl.Tests/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression.Impl.Tests/Properties/AssemblyInfo.cs index 3f3c34d62..2b02549d0 100644 --- a/SPMeta2/SPMeta2.Regression.Impl.Tests/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression.Impl.Tests/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression.SSOM.Standard/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression.SSOM.Standard/Properties/AssemblyInfo.cs index 7493d05a0..4a4342246 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM.Standard/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM.Standard/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression.SSOM/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression.SSOM/Properties/AssemblyInfo.cs index a5ee5c712..775aefb01 100644 --- a/SPMeta2/SPMeta2.Regression.SSOM/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression.SSOM/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression.Tests/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression.Tests/Properties/AssemblyInfo.cs index b70aa270c..bc387ee0e 100644 --- a/SPMeta2/SPMeta2.Regression.Tests/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression.Tests/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Regression/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Regression/Properties/AssemblyInfo.cs index 62248c274..0c996cf6e 100644 --- a/SPMeta2/SPMeta2.Regression/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Regression/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.16298.0736")] +[assembly: AssemblyFileVersion("1.0.16305.1232")] diff --git a/SPMeta2/SPMeta2.SSOM.Standard/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.SSOM.Standard/Properties/AssemblyInfo.cs index 5c6399771..a0b4cc49f 100644 --- a/SPMeta2/SPMeta2.SSOM.Standard/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.SSOM.Standard/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.SSOM/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.SSOM/Properties/AssemblyInfo.cs index 24660227c..dcbd7f71e 100644 --- a/SPMeta2/SPMeta2.SSOM/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.SSOM/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2.Standard/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2.Standard/Properties/AssemblyInfo.cs index ec1e24334..57f95567c 100644 --- a/SPMeta2/SPMeta2.Standard/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2.Standard/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SPMeta2/Properties/AssemblyInfo.cs b/SPMeta2/SPMeta2/Properties/AssemblyInfo.cs index ea94cd1f8..0eb33d088 100644 --- a/SPMeta2/SPMeta2/Properties/AssemblyInfo.cs +++ b/SPMeta2/SPMeta2/Properties/AssemblyInfo.cs @@ -32,4 +32,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.2.16298.0736")] +[assembly: AssemblyFileVersion("1.2.16305.1232")] diff --git a/SPMeta2/SubPointSolutions.Docs/Properties/AssemblyInfo.cs b/SPMeta2/SubPointSolutions.Docs/Properties/AssemblyInfo.cs index aecad8bb7..2d66eb0e5 100644 --- a/SPMeta2/SubPointSolutions.Docs/Properties/AssemblyInfo.cs +++ b/SPMeta2/SubPointSolutions.Docs/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.16298.0736")] +[assembly: AssemblyFileVersion("1.0.16305.1232")]