private static void MapProperties(Web web, WebDefinition webModel) { web.Title = webModel.Title; web.Description = webModel.Description ?? string.Empty; var supportedRuntime = ReflectionUtils.HasProperty(web, "AlternateCssUrl") && ReflectionUtils.HasProperty(web, "SiteLogoUrl"); if (supportedRuntime) { var context = web.Context; if (!string.IsNullOrEmpty(webModel.AlternateCssUrl)) { context.AddQuery(new ClientActionInvokeMethod(web, "AlternateCssUrl", new object[] { webModel.AlternateCssUrl })); } if (!string.IsNullOrEmpty(webModel.SiteLogoUrl)) { context.AddQuery(new ClientActionInvokeMethod(web, "SiteLogoUrl", new object[] { webModel.SiteLogoUrl })); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.AlternateCssUrl and Web.SiteLogoUrl methods support. Update CSOM runtime to a new version. Provision is skipped"); } }
protected virtual bool SupportSetters(RegionalSettings settings) { // should have at least one setter // Update() is there, but setters aren't var supportedRuntime = ReflectionUtils.HasMethod(settings, "Update") && ReflectionUtils.HasPropertyPublicSetter(settings, "AdjustHijriDays"); if (!supportedRuntime) { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have RegionalSettings.Update() methods support. Update CSOM runtime to a new version. RegionalSettings provision is skipped"); } return(supportedRuntime); }
public override void DeployModel(object modelHost, DefinitionBase model) { var definition = model.WithAssertAndCast <UserCustomActionDefinition>("model", value => value.RequireNotNull()); var spObject = GetCurrentCustomUserAction(modelHost, definition); var shouldCheckRegistrationType = true; if (modelHost is ListModelHost) { //// skipping setup for List script //// System.NotSupportedException: Setting this property is not supported. A value of List has already been set and cannot be changed. shouldCheckRegistrationType = false; } var assert = ServiceFactory.AssertService .NewAssert(definition, definition, spObject) .ShouldBeEqual(m => m.Name, o => o.Name) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.Description, o => o.Description) .ShouldBeEqual(m => m.Group, o => o.Group) .ShouldBeEqual(m => m.Location, o => o.Location) .ShouldBeEqual(m => m.ScriptSrc, o => o.ScriptSrc) .ShouldBeEqual(m => m.ScriptBlock, o => o.ScriptBlock) .ShouldBeEqual(m => m.Sequence, o => o.Sequence) .ShouldBeEqual(m => m.Url, o => o.Url); //.ShouldBeEqual(m => m.RegistrationId, o => o.RegistrationId) //.ShouldBeEqual(m => m.RegistrationType, o => o.GetRegistrationType()); if (shouldCheckRegistrationType) { assert.ShouldBeEqual(m => m.RegistrationType, o => o.GetRegistrationType()); } else { assert.SkipProperty(m => m.RegistrationType, "Skipping validation"); } var context = spObject.Context; var registrationIdIsGuid = ConvertUtils.ToGuid(spObject.RegistrationId); if (registrationIdIsGuid.HasValue) { // this is list scoped user custom action reg // skipping validation assert.SkipProperty(m => m.RegistrationId, "RegistrationId is GUID. List scope user custom action. Skipping validation."); } else { assert.ShouldBeEqual(m => m.RegistrationId, o => o.RegistrationId); } if (!string.IsNullOrEmpty(definition.CommandUIExtension)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.CommandUIExtension); var dstProp = d.GetExpressionValue(ct => ct.CommandUIExtension); var isValid = GetCommandUIString(srcProp.Value.ToString()) == GetCommandUIString(dstProp.Value.ToString()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.CommandUIExtension, "CommandUIExtension is null or empty. Skipping."); } assert .ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Rights); var dstProp = d.GetExpressionValue(ct => ct.Rights); var hasCorrectRights = true; foreach (var srcRight in s.Rights) { var srcPermission = (PermissionKind)Enum.Parse(typeof(PermissionKind), srcRight); var tmpRight = d.Rights.Has(srcPermission); if (tmpRight == false) { hasCorrectRights = false; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = hasCorrectRights }); }); var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource", "CommandUIExtensionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } if (definition.CommandUIExtensionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.CommandUIExtensionResource); var isValid = true; foreach (var userResource in s.CommandUIExtensionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "CommandUIExtensionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = GetCommandUIString(userResource.Value) == GetCommandUIString(value.Value); if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.CommandUIExtensionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); 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.CommandUIExtensionResource, "CommandUIExtensionResource is null or empty. Skipping."); } }
protected void ValidateField(AssertPair <FieldDefinition, Field> assert, Field spObject, FieldDefinition definition) { var context = spObject.Context; CustomFieldTypeValidation(assert, spObject, definition); assert .ShouldNotBeNull(spObject) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.Id, o => o.Id); assert.ShouldBeEqualIfNotNullOrEmpty(m => m.Group, o => o.Group); assert.ShouldBeEqualIfNotNullOrEmpty(m => m.StaticName, o => o.StaticName); assert.SkipProperty(m => m.DefaultFormula, "Not supported in CSOM API yet"); if (!string.IsNullOrEmpty(definition.DefaultFormula)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.DefaultFormula); var isValid = false; var dstXmlNode = XDocument.Parse(d.SchemaXml).Root; var defaultValueNode = dstXmlNode.Descendants("DefaultFormula").FirstOrDefault(); if (defaultValueNode == null) { isValid = false; } else { isValid = defaultValueNode.Value == s.DefaultFormula; } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DefaultFormula, "DefaultFormula is null or empty. Skipping."); } if (definition.AddFieldOptions.HasFlag(BuiltInAddFieldOptions.DefaultValue)) { assert.SkipProperty(m => m.AddFieldOptions, "BuiltInAddFieldOptions.DefaultValue. Skipping."); } else { // TODO } if (definition.AddToDefaultView) { if (IsListScopedField) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.AddToDefaultView); var field = HostList.Fields.GetById(definition.Id); var defaultView = HostList.DefaultView; context.Load(defaultView); context.Load(defaultView, v => v.ViewFields); context.Load(field); context.ExecuteQueryWithTrace(); var isValid = HostList.DefaultView .ViewFields .Contains(field.InternalName); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.AddToDefaultView, "IsListScopedField = true. AddToDefaultView is ignored. Skipping."); } } else { assert.SkipProperty(m => m.AddToDefaultView, "AddToDefaultView is false. Skipping."); } if (definition.AdditionalAttributes.Count == 0) { assert.SkipProperty(m => m.AdditionalAttributes, "AdditionalAttributes count is 0. Skipping."); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.AdditionalAttributes); var isValid = true; var dstXmlNode = XDocument.Parse(d.SchemaXml).Root; foreach (var attr in s.AdditionalAttributes) { var sourceAttrName = attr.Name; var sourceAttrValue = attr.Value; var destAttrValue = dstXmlNode.GetAttributeValue(sourceAttrName); isValid = sourceAttrValue == destAttrValue; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } if (string.IsNullOrEmpty(definition.RawXml)) { assert.SkipProperty(m => m.RawXml, "RawXml is NULL or empty. Skipping."); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.RawXml); var isValid = true; var srcXmlNode = XDocument.Parse(s.RawXml).Root; var dstXmlNode = XDocument.Parse(d.SchemaXml).Root; foreach (var attr in srcXmlNode.Attributes()) { var sourceAttrName = attr.Name.LocalName; var sourceAttrValue = attr.Value; var destAttrValue = dstXmlNode.GetAttributeValue(sourceAttrName); isValid = sourceAttrValue == destAttrValue; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } // TODO, R&D to check InternalName changes in list-scoped fields if (spObject.InternalName == definition.InternalName) { assert.ShouldBeEqual(m => m.InternalName, o => o.InternalName); } else { assert.SkipProperty(m => m.InternalName, "Target InternalName is different to source InternalName. Could be an error if this is not a list scoped field"); } assert.ShouldBeEqualIfNotNullOrEmpty(m => m.ValidationFormula, o => o.ValidationFormula); assert.ShouldBeEqualIfNotNullOrEmpty(m => m.ValidationMessage, o => o.ValidationMessage); // taxonomy field seems to prodice issues w/ Required/Description validation if (!SkipRequredPropValidation) { assert.ShouldBeEqual(m => m.Required, o => o.Required); } else { assert.SkipProperty(m => m.Required); } assert.ShouldBeEqualIfNotNullOrEmpty(m => m.Description, o => o.Description); assert.ShouldBeEqual(m => m.Hidden, o => o.Hidden); assert.ShouldBePartOfIfNotNullOrEmpty(m => m.DefaultValue, o => o.DefaultValue); if (!string.IsNullOrEmpty(spObject.JSLink) && (spObject.JSLink == "SP.UI.Taxonomy.js|SP.UI.Rte.js(d)|SP.Taxonomy.js(d)|ScriptForWebTaggingUI.js(d)" || spObject.JSLink == "choicebuttonfieldtemplate.js" || spObject.JSLink == "clienttemplates.js")) { assert.SkipProperty(m => m.JSLink, string.Format("OOTB read-ony JSLink value:[{0}]", spObject.JSLink)); } else { assert.ShouldBePartOf(m => m.JSLink, o => o.JSLink); } assert.ShouldBeEqualIfHasValue(m => m.EnforceUniqueValues, o => o.EnforceUniqueValues); assert.ShouldBeEqualIfHasValue(m => m.ShowInDisplayForm, o => o.GetShowInDisplayForm()); assert.ShouldBeEqualIfHasValue(m => m.ShowInEditForm, o => o.GetShowInEditForm()); assert.ShouldBeEqualIfHasValue(m => m.ShowInListSettings, o => o.GetShowInListSettings()); assert.ShouldBeEqualIfHasValue(m => m.ShowInNewForm, o => o.GetShowInNewForm()); assert.ShouldBeEqualIfHasValue(m => m.ShowInVersionHistory, o => o.GetShowInVersionHistory()); assert.ShouldBeEqualIfHasValue(m => m.ShowInViewForms, o => o.GetShowInViewForms()); assert.ShouldBeEqual(m => m.Indexed, o => o.Indexed); assert.ShouldBeEqualIfHasValue(m => m.AllowDeletion, o => o.GetAllowDeletion()); var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); 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"); }
public override void DeployModel(object modelHost, DefinitionBase model) { var hostClientContext = ExtractHostClientContext(modelHost); var parentWeb = ExtractWeb(modelHost); var definition = model.WithAssertAndCast <WebDefinition>("model", value => value.RequireNotNull()); var currentWebUrl = GetCurrentWebUrl(parentWeb.Context, parentWeb, definition); var spObject = GetExistingWeb(hostClientContext.Site, parentWeb, currentWebUrl); var context = spObject.Context; context.Load(spObject, w => w.HasUniqueRoleAssignments, w => w.Description, w => w.Url, w => w.Language, w => w.WebTemplate, w => w.Configuration, w => w.Title, w => w.Id, w => w.Url ); context.ExecuteQueryWithTrace(); var assert = ServiceFactory.AssertService .NewAssert(definition, spObject) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.LCID, o => o.GetLCID()) .ShouldBeEqual(m => m.UseUniquePermission, o => o.HasUniqueRoleAssignments); if (!string.IsNullOrEmpty(definition.WebTemplate)) { assert.ShouldBeEqual(m => m.WebTemplate, o => o.GetWebTemplate()); assert.SkipProperty(m => m.CustomWebTemplate); } else { assert.SkipProperty(m => m.WebTemplate); assert.SkipProperty(m => m.CustomWebTemplate); } assert.ShouldBeEqualIfNotNullOrEmpty(m => m.Description, o => o.Description); assert.ShouldBeEqual((p, s, d) => { if (!parentWeb.IsObjectPropertyInstantiated("Url")) { parentWeb.Context.Load(parentWeb, o => o.Url); parentWeb.Context.ExecuteQueryWithTrace(); } var srcProp = s.GetExpressionValue(def => def.Url); var dstProp = d.GetExpressionValue(ct => ct.Url); var srcUrl = s.Url; var dstUrl = d.Url; srcUrl = UrlUtility.RemoveStartingSlash(srcUrl); var dstSubUrl = dstUrl.Replace(parentWeb.Url + "/", string.Empty); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = srcUrl == dstSubUrl }); }); var supportsAlternateCssAndSiteImageUrl = ReflectionUtils.HasProperties(spObject, new[] { "AlternateCssUrl", "SiteLogoUrl" }); if (supportsAlternateCssAndSiteImageUrl) { if (!string.IsNullOrEmpty(definition.AlternateCssUrl)) { var alternateCssUrl = ReflectionUtils.GetPropertyValue(spObject, "AlternateCssUrl"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.AlternateCssUrl); var isValid = true; isValid = s.AlternateCssUrl.ToUpper().EndsWith(alternateCssUrl.ToString().ToUpper()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.AlternateCssUrl); } if (!string.IsNullOrEmpty(definition.SiteLogoUrl)) { var siteLogoUrl = ReflectionUtils.GetPropertyValue(spObject, "SiteLogoUrl"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.SiteLogoUrl); var isValid = true; isValid = s.SiteLogoUrl.ToUpper().EndsWith(siteLogoUrl.ToString().ToUpper()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.SiteLogoUrl); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.AlternateCssUrl and Web.SiteLogoUrl methods support. Skipping validation."); assert.SkipProperty(m => m.AlternateCssUrl, "AlternateCssUrl is null or empty. Skipping."); assert.SkipProperty(m => m.SiteLogoUrl, "SiteLogoUrl is null or empty. Skipping."); } var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } }
public override void DeployModel(object modelHost, DefinitionBase model) { var hostClientContext = ExtractHostClientContext(modelHost); var parentWeb = ExtractWeb(modelHost); var definition = model.WithAssertAndCast <WebDefinition>("model", value => value.RequireNotNull()); var currentWebUrl = GetCurrentWebUrl(parentWeb.Context, parentWeb, definition); var spObject = GetExistingWeb(hostClientContext.Site, parentWeb, currentWebUrl); var context = spObject.Context; context.Load(spObject, w => w.HasUniqueRoleAssignments, w => w.Description, w => w.Url, w => w.Language, w => w.WebTemplate, w => w.Configuration, w => w.Title, w => w.Id, w => w.AllProperties ); context.ExecuteQueryWithTrace(); var assert = ServiceFactory.AssertService .NewAssert(definition, spObject) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.LCID, o => o.GetLCID()) .ShouldBeEqual(m => m.UseUniquePermission, o => o.HasUniqueRoleAssignments); if (!string.IsNullOrEmpty(definition.WebTemplate)) { assert.ShouldBeEqual(m => m.WebTemplate, o => o.GetWebTemplate()); assert.SkipProperty(m => m.CustomWebTemplate); } else { assert.SkipProperty(m => m.WebTemplate); assert.SkipProperty(m => m.CustomWebTemplate); } assert.ShouldBeEqualIfNotNullOrEmpty(m => m.Description, o => o.Description); assert.ShouldBeEqual((p, s, d) => { if (!parentWeb.IsObjectPropertyInstantiated("Url")) { parentWeb.Context.Load(parentWeb, o => o.Url); parentWeb.Context.ExecuteQueryWithTrace(); } var srcProp = s.GetExpressionValue(def => def.Url); var dstProp = d.GetExpressionValue(ct => ct.Url); var srcUrl = s.Url; var dstUrl = d.Url; srcUrl = UrlUtility.RemoveStartingSlash(srcUrl); var dstSubUrl = dstUrl.Replace(parentWeb.Url + "/", string.Empty); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = srcUrl == dstSubUrl }); }); var supportsAlternateCssAndSiteImageUrl = ReflectionUtils.HasProperties(spObject, new[] { "AlternateCssUrl", "SiteLogoUrl" }); if (supportsAlternateCssAndSiteImageUrl) { // also check for MembersCanShare / RequestAccessEmail if (definition.MembersCanShare.HasValue) { var membersCanShare = ConvertUtils.ToBool(ReflectionUtils.GetPropertyValue(spObject, "MembersCanShare")).Value; assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.MembersCanShare); var isValid = true; isValid = s.MembersCanShare.Value == membersCanShare; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.MembersCanShare); } if (!string.IsNullOrEmpty(definition.RequestAccessEmail)) { var requestAccessEmail = ReflectionUtils.GetPropertyValue(spObject, "RequestAccessEmail"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.RequestAccessEmail); var isValid = true; isValid = s.RequestAccessEmail.ToUpper() == requestAccessEmail.ToString().ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.RequestAccessEmail); } if (!string.IsNullOrEmpty(definition.AlternateCssUrl)) { var alternateCssUrl = ReflectionUtils.GetPropertyValue(spObject, "AlternateCssUrl"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.AlternateCssUrl); var isValid = true; isValid = s.AlternateCssUrl.ToUpper().EndsWith(alternateCssUrl.ToString().ToUpper()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.AlternateCssUrl); } if (!string.IsNullOrEmpty(definition.SiteLogoUrl)) { var siteLogoUrl = ReflectionUtils.GetPropertyValue(spObject, "SiteLogoUrl"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.SiteLogoUrl); var isValid = s.SiteLogoUrl.ToUpper().EndsWith(siteLogoUrl.ToString().ToUpper()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.SiteLogoUrl); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.AlternateCssUrl and Web.SiteLogoUrl methods support. Skipping validation."); assert.SkipProperty(m => m.AlternateCssUrl, "AlternateCssUrl is null or empty. Skipping."); assert.SkipProperty(m => m.SiteLogoUrl, "SiteLogoUrl is null or empty. Skipping."); assert.SkipProperty(m => m.MembersCanShare, "SiteLogoUrl is null or empty. Skipping."); assert.SkipProperty(m => m.RequestAccessEmail, "SiteLogoUrl is null or empty. Skipping."); } var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } if (definition.IndexedPropertyKeys.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.IndexedPropertyKeys); var isValid = false; if (d.AllProperties.FieldValues.ContainsKey("vti_indexedpropertykeys")) { // check props, TODO // check vti_indexedpropertykeys var indexedPropertyKeys = d.AllProperties["vti_indexedpropertykeys"] .ToString() .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Select(es => Encoding.Unicode.GetString(System.Convert.FromBase64String(es))); // Search if any indexPropertyKey from definition is not in WebModel var differentKeys = s.IndexedPropertyKeys.Select(o => o.Name) .Except(indexedPropertyKeys); isValid = !differentKeys.Any(); } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.IndexedPropertyKeys, "IndexedPropertyKeys is NULL or empty. Skipping."); } }
public override void DeployModel(object modelHost, DefinitionBase model) { var listModelHost = modelHost.WithAssertAndCast <ListModelHost>("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast <ListViewDefinition>("model", value => value.RequireNotNull()); var list = listModelHost.HostList; var context = list.Context; context.Load(list, l => l.Fields); context.Load(list, l => l.Views.Include( v => v.ViewFields, v => v.Title, v => v.DefaultView, v => v.ViewQuery, v => v.RowLimit, v => v.Paged, v => v.Scope, v => v.Hidden, v => v.JSLink, v => v.ServerRelativeUrl, v => v.DefaultViewForContentType, v => v.ContentTypeId, v => v.AggregationsStatus, v => v.Aggregations, v => v.ViewType, v => v.IncludeRootFolder, v => v.HtmlSchemaXml, v => v.ViewData)); context.ExecuteQueryWithTrace(); var spObject = FindViewByTitle(list.Views, definition.Title); var assert = ServiceFactory.AssertService .NewAssert(definition, spObject); assert .ShouldNotBeNull(spObject) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.IsDefault, o => o.DefaultView) .ShouldBeEqual(m => m.Hidden, o => o.Hidden) .ShouldBeEqual(m => m.RowLimit, o => (int)o.RowLimit) .ShouldBeEqual(m => m.IsPaged, o => o.Paged); if (!string.IsNullOrEmpty(definition.Scope)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Scope); var dstProp = d.GetExpressionValue(o => o.Scope); var scopeValue = ListViewScopeTypesConvertService.NormilizeValueToCSOMType(definition.Scope); var isValid = scopeValue == d.Scope.ToString(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.Scope); } if (!string.IsNullOrEmpty(definition.ViewData)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.ViewData); var dstProp = d.GetExpressionValue(o => o.ViewData); var srcViewDate = assert.Src.ViewData.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); var dstViewDate = assert.Dst.ViewData.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); // replacing all new lines srcViewDate = Regex.Replace(srcViewDate, @"\r\n?|\n", string.Empty); dstViewDate = Regex.Replace(dstViewDate, @"\r\n?|\n", string.Empty); var isValid = srcViewDate.ToUpper() == dstViewDate.ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.ViewData); } if (definition.Types.Count() == 0) { assert.SkipProperty(m => m.Types, "Types.Count == 0"); if (!string.IsNullOrEmpty(definition.Type)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Type); var dstProp = d.GetExpressionValue(o => o.ViewType); var isValid = srcProp.Value.ToString().ToUpper() == dstProp.Value.ToString().ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.Type); } } else { assert.SkipProperty(m => m.Type, "Types.Count != 0"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Types); //var dstProp = d.GetExpressionValue(o => o.Type); var isValid = false; ViewType?srcType = null; foreach (var type in s.Types) { var tmpViewType = (ViewType)Enum.Parse(typeof(ViewType), type); if (srcType == null) { srcType = tmpViewType; } else { srcType = srcType | tmpViewType; } } var srcTypeValue = (int)srcType; var dstTypeValue = (int)0; // checking if only reccurence set // test designed that way only if (((int)srcTypeValue & (int)(ViewType.Recurrence)) == (int)ViewType.Recurrence) { // nah, whatever, it works and does the job isValid = d.HtmlSchemaXml.Contains("RecurrenceRowset=\"TRUE\""); } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } assert.SkipProperty(m => m.ViewStyleId, "ViewStyleId unsupported by SP CSOM API yet. Skipping."); assert.SkipProperty(m => m.TabularView, "TabularView unsupported by SP CSOM API yet. Skipping."); assert.SkipProperty(m => m.InlineEdit, "InlineEdit unsupported by SP CSOM API yet. Skipping."); assert.ShouldBeEqualIfNotNullOrEmpty(m => m.JSLink, o => o.JSLink); if (definition.IncludeRootFolder.HasValue) { assert.ShouldBeEqual(m => m.IncludeRootFolder, o => o.IncludeRootFolder); } else { assert.SkipProperty(m => m.IncludeRootFolder, "IncludeRootFolder is null or empty. Skipping."); } if (!string.IsNullOrEmpty(definition.Query)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Query); var dstProp = d.GetExpressionValue(o => o.ViewQuery); var srcViewDate = assert.Src.Query.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); var dstViewDate = assert.Dst.ViewQuery.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); // replacing all new lines srcViewDate = Regex.Replace(srcViewDate, @"\r\n?|\n", string.Empty); dstViewDate = Regex.Replace(dstViewDate, @"\r\n?|\n", string.Empty); var isValid = srcViewDate.ToUpper() == dstViewDate.ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.Query, "Query is null or empty. Skipping."); } assert.ShouldBeEqualIfHasValue(m => m.DefaultViewForContentType, o => o.DefaultViewForContentType); if (string.IsNullOrEmpty(definition.ContentTypeName)) { assert.SkipProperty(m => m.ContentTypeName, "ContentTypeName is null or empty. Skipping."); } else { var contentTypeId = LookupListContentTypeByName(list, definition.ContentTypeName); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.ContentTypeName); var dstProp = d.GetExpressionValue(ct => ct.ContentTypeId); var isValis = contentTypeId.StringValue == d.ContentTypeId.StringValue; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValis }); }); } if (string.IsNullOrEmpty(definition.ContentTypeId)) { assert.SkipProperty(m => m.ContentTypeId, "ContentTypeId is null or empty. Skipping."); } else { var contentTypeId = LookupListContentTypeById(list, definition.ContentTypeId); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.ContentTypeId); var dstProp = d.GetExpressionValue(ct => ct.ContentTypeId); var isValis = contentTypeId.StringValue == d.ContentTypeId.StringValue; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValis }); }); } if (string.IsNullOrEmpty(definition.AggregationsStatus)) { assert.SkipProperty(m => m.AggregationsStatus, "Aggregationsstatus is null or empty. Skipping."); } else { assert.ShouldBeEqual(m => m.AggregationsStatus, o => o.AggregationsStatus); } if (string.IsNullOrEmpty(definition.Aggregations)) { assert.SkipProperty(m => m.Aggregations, "Aggregations is null or empty. Skipping."); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Aggregations); var dstProp = d.GetExpressionValue(ct => ct.Aggregations); var isValid = s.Aggregations .Replace("'", string.Empty) .Replace(" ", string.Empty) .Replace("\"", string.Empty) == d.Aggregations .Replace("'", string.Empty) .Replace(" ", string.Empty) .Replace("\"", string.Empty); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } assert.ShouldBePartOfIfNotNullOrEmpty(m => m.Url, o => o.ServerRelativeUrl); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Fields); var dstProp = d.GetExpressionValue(ct => ct.ViewFields); var hasAllFields = true; foreach (var srcField in s.Fields) { var listField = list.Fields.ToList().FirstOrDefault(f => f.StaticName == srcField); // if list-scoped field we need to check by internal name // internal name is changed for list scoped-fields // that's why to check by BOTH, definition AND real internal name if (!d.ViewFields.ToList().Contains(srcField) && !d.ViewFields.ToList().Contains(listField.InternalName)) { hasAllFields = false; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = hasAllFields }); }); var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); } }
public override void DeployModel(object modelHost, DefinitionBase model) { var webModel = model.WithAssertAndCast <SupportedUICultureDefinition>("model", value => value.RequireNotNull()); var typedHost = modelHost.WithAssertAndCast <WebModelHost>("model", value => value.RequireNotNull()); var web = typedHost.HostWeb; var context = web.Context; context.Load(web); context.Load(web, w => w.SupportedUILanguageIds); context.ExecuteQuery(); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, Object = web, ObjectType = typeof(Web), ObjectDefinition = model, ModelHost = modelHost }); var shouldUpdate = false; var currentLanguages = web.SupportedUILanguageIds; if (!currentLanguages.Contains(webModel.LCID)) { // if running nice CSOM, so that method is there and a few web's props var supportedRuntime = ReflectionUtils.HasProperty(web, "IsMultilingual") && ReflectionUtils.HasMethod(web, "AddSupportedUILanguage"); if (supportedRuntime) { // TODO, wrap up into extensions // that's the trick to get all working on CSOM SP2013 SP1+ // once props are there, we setup them // if not, giving critical messages in logs // pushing IsMultilingual to true if false var objectData = GetPropertyValue(web, "ObjectData"); var objectProperties = GetPropertyValue(objectData, "Properties") as Dictionary <string, object>; var isMultilingual = Convert.ToBoolean(objectProperties["IsMultilingual"]); if (!isMultilingual) { web.Context.AddQuery(new ClientActionSetProperty(web, "IsMultilingual", true)); } // adding languages var query = new ClientActionInvokeMethod(web, "AddSupportedUILanguage", new object[] { webModel.LCID }); context.AddQuery(query); // upating the web web.Update(); shouldUpdate = true; } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.IsMultilingual and Web.AddSupportedUILanguage() methods support. Update CSOM runtime to a new version. SupportedUILanguage provision is skipped"); } } InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = web, ObjectType = typeof(Web), ObjectDefinition = model, ModelHost = modelHost }); if (shouldUpdate) { context.ExecuteQueryWithTrace(); } }
public override void DeployModel(object modelHost, DefinitionBase model) { var definition = model.WithAssertAndCast <DependentLookupFieldDefinition>("model", value => value.RequireNotNull()); var spObject = GetField(modelHost, definition); var assert = ServiceFactory.AssertService.NewAssert(model, definition, spObject); assert .ShouldNotBeNull(spObject) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.InternalName, o => o.InternalName); var context = spObject.Context; // skip base lookup field props assert.SkipProperty(m => m.AddFieldOptions, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.AdditionalAttributes, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.AddToDefaultView, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.AllowDeletion, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.AllowMultipleValues, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.DefaultValue, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.EnforceUniqueValues, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.FieldType, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.Hidden, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.Id, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.Indexed, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.JSLink, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.LookupList, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.LookupListTitle, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.LookupListUrl, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.LookupWebId, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.RawXml, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.Required, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ShowInDisplayForm, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ShowInEditForm, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ShowInListSettings, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ShowInNewForm, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ShowInVersionHistory, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ShowInViewForms, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.StaticName, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ValidationFormula, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.ValidationMessage, "DependentLookupFieldDefinition"); assert.SkipProperty(m => m.RelationshipDeleteBehavior, "RelationshipDeleteBehavior"); // web url if (!string.IsNullOrEmpty(definition.LookupWebUrl)) { // TODO throw new SPMeta2NotImplementedException("definition.LookupWebUrl"); } else { assert.SkipProperty(m => m.LookupWebUrl, "LookupWebUrl"); } if (!string.IsNullOrEmpty(definition.Group)) { assert.ShouldBeEqual(m => m.Group, o => o.Group); } else { assert.SkipProperty(m => m.Group); } if (!string.IsNullOrEmpty(definition.Description)) { assert.ShouldBeEqual(m => m.Description, o => o.Description); } else { assert.SkipProperty(m => m.Description); } if (!string.IsNullOrEmpty(definition.LookupField)) { assert.ShouldBeEqual(m => m.LookupField, o => o.LookupField); } else { assert.SkipProperty(m => m.LookupField); } // binding if (definition.PrimaryLookupFieldId.HasGuidValue()) { var primaryLookupField = GetPrimaryField(modelHost, definition); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.PrimaryLookupFieldId); var isValid = primaryLookupField.Id == definition.PrimaryLookupFieldId.Value; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.PrimaryLookupFieldId, "Value is null or empty."); } if (!string.IsNullOrEmpty(definition.PrimaryLookupFieldInternalName)) { var primaryLookupField = GetPrimaryField(modelHost, definition); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.PrimaryLookupFieldInternalName); var isValid = primaryLookupField.InternalName == definition.PrimaryLookupFieldInternalName; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.PrimaryLookupFieldInternalName); } if (!string.IsNullOrEmpty(definition.PrimaryLookupFieldTitle)) { var primaryLookupField = GetPrimaryField(modelHost, definition); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.PrimaryLookupFieldTitle); var isValid = primaryLookupField.Title == definition.PrimaryLookupFieldTitle; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.PrimaryLookupFieldTitle); } var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } }
public override void DeployModel(object modelHost, DefinitionBase model) { if (modelHost is WebModelHost) { CurrentClientContext = (modelHost as WebModelHost).HostClientContext; } CurrentModelHost = modelHost.WithAssertAndCast <CSOMModelHostBase>("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast <TopNavigationNodeDefinition>("model", value => value.RequireNotNull()); var spObject = LookupNodeForHost(modelHost, definition); var assert = ServiceFactory.AssertService.NewAssert(definition, spObject); assert .ShouldNotBeNull(spObject) //.ShouldBeEndOf(m => m.Url, o => o.Url) .ShouldBeEqual(m => m.IsExternal, o => o.IsExternal) .ShouldBeEqual(m => m.IsVisible, o => o.IsVisible) .ShouldBeEqual(m => m.Title, o => o.Title); var context = spObject.Context; assert.SkipProperty(m => m.Properties, "Skipping. Not supported by CSOM API"); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Url); var dstProp = d.GetExpressionValue(ct => ct.Url); var srcUrl = ResolveTokenizedUrl(CurrentModelHost, definition); var dstUrl = d.Url; srcUrl = HttpUtility.UrlKeyValueDecode(srcUrl); dstUrl = HttpUtility.UrlKeyValueDecode(dstUrl); var isValid = dstUrl.ToUpper().EndsWith(srcUrl.ToUpper()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); } }
public override void DeployModel(object modelHost, DefinitionBase model) { var listModelHost = modelHost.WithAssertAndCast <ListModelHost>("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast <ListViewDefinition>("model", value => value.RequireNotNull()); var list = listModelHost.HostList; var context = list.Context; context.Load(list, l => l.Fields); context.Load(list, l => l.Views.Include( v => v.ViewFields, o => o.Title, o => o.DefaultView, o => o.ViewQuery, o => o.RowLimit, o => o.Paged, o => o.Hidden, o => o.JSLink, o => o.ServerRelativeUrl, o => o.DefaultViewForContentType, o => o.ContentTypeId, o => o.ViewType, o => o.ViewData, v => v.Title)); context.ExecuteQueryWithTrace(); var spObject = FindViewByTitle(list.Views, definition.Title); var assert = ServiceFactory.AssertService .NewAssert(definition, spObject) .ShouldNotBeNull(spObject) .ShouldBeEqual(m => m.Title, o => o.Title) .ShouldBeEqual(m => m.IsDefault, o => o.DefaultView) .ShouldBeEqual(m => m.Hidden, o => o.Hidden) //.ShouldBeEqual(m => m.Query, o => o.ViewQuery) .ShouldBeEqual(m => m.RowLimit, o => (int)o.RowLimit) .ShouldBeEqual(m => m.IsPaged, o => o.Paged); if (!string.IsNullOrEmpty(definition.ViewData)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.ViewData); var dstProp = d.GetExpressionValue(o => o.ViewData); var srcViewDate = assert.Src.ViewData.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); var dstViewDate = assert.Dst.ViewData.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); var isValid = srcViewDate.ToUpper() == dstViewDate.ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.ViewData); } if (!string.IsNullOrEmpty(definition.Type)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Type); var dstProp = d.GetExpressionValue(o => o.ViewType); var isValid = srcProp.Value.ToString().ToUpper() == dstProp.Value.ToString().ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.Type); } assert.SkipProperty(m => m.ViewStyleId, "ViewStyleId unsupported by SP CSOM API yet. Skipping."); if (!string.IsNullOrEmpty(definition.JSLink)) { assert.ShouldBePartOf(m => m.JSLink, o => o.JSLink); } else { assert.SkipProperty(m => m.JSLink, "JSLink is null or empty. Skipping."); } if (!string.IsNullOrEmpty(definition.Query)) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Query); var dstProp = d.GetExpressionValue(o => o.ViewQuery); var srcViewDate = assert.Src.Query.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); var dstViewDate = assert.Dst.ViewQuery.Replace(System.Environment.NewLine, string.Empty).Replace(" /", "/"); var isValid = srcViewDate.ToUpper() == dstViewDate.ToUpper(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.Query, "Query is null or empty. Skipping."); } if (definition.DefaultViewForContentType.HasValue) { assert.ShouldBeEqual(m => m.DefaultViewForContentType, o => o.DefaultViewForContentType); } else { assert.SkipProperty(m => m.DefaultViewForContentType, "DefaultViewForContentType is null or empty. Skipping."); } if (string.IsNullOrEmpty(definition.ContentTypeName)) { assert.SkipProperty(m => m.ContentTypeName, "ContentTypeName is null or empty. Skipping."); } else { var contentTypeId = LookupListContentTypeByName(list, definition.ContentTypeName); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.ContentTypeName); var dstProp = d.GetExpressionValue(ct => ct.ContentTypeId); var isValis = contentTypeId.StringValue == d.ContentTypeId.StringValue; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValis }); }); } if (string.IsNullOrEmpty(definition.ContentTypeId)) { assert.SkipProperty(m => m.ContentTypeId, "ContentTypeId is null or empty. Skipping."); } else { var contentTypeId = LookupListContentTypeById(list, definition.ContentTypeId); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.ContentTypeId); var dstProp = d.GetExpressionValue(ct => ct.ContentTypeId); var isValis = contentTypeId.StringValue == d.ContentTypeId.StringValue; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValis }); }); } if (string.IsNullOrEmpty(definition.Url)) { assert.SkipProperty(m => m.Url, "Url is null or empty. Skipping."); } else { assert.ShouldBePartOf(m => m.Url, o => o.ServerRelativeUrl); } assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Fields); var dstProp = d.GetExpressionValue(ct => ct.ViewFields); var hasAllFields = true; foreach (var srcField in s.Fields) { var listField = list.Fields.ToList().FirstOrDefault(f => f.StaticName == srcField); // if list-scoped field we need to check by internal name // internal name is changed for list scoped-fields // that's why to check by BOTH, definition AND real internal name if (!d.ViewFields.ToList().Contains(srcField) && !d.ViewFields.ToList().Contains(listField.InternalName)) { hasAllFields = false; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = hasAllFields }); }); var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); } }
private static void MapProperties(Web web, WebDefinition webModel) { if (!string.IsNullOrEmpty(webModel.Title)) { web.Title = webModel.Title; } if (!string.IsNullOrEmpty(webModel.Description)) { web.Description = webModel.Description; } var supportedRuntime = ReflectionUtils.HasProperty(web, "AlternateCssUrl") && ReflectionUtils.HasProperty(web, "SiteLogoUrl"); if (supportedRuntime) { var context = web.Context; if (!string.IsNullOrEmpty(webModel.AlternateCssUrl)) { context.AddQuery(new ClientActionInvokeMethod(web, "AlternateCssUrl", new object[] { webModel.AlternateCssUrl })); } if (!string.IsNullOrEmpty(webModel.SiteLogoUrl)) { context.AddQuery(new ClientActionInvokeMethod(web, "SiteLogoUrl", new object[] { webModel.SiteLogoUrl })); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.AlternateCssUrl and Web.SiteLogoUrl methods support. Update CSOM runtime to a new version. Provision is skipped"); } #if !NET35 if (webModel.IndexedPropertyKeys.Any()) { var props = web.AllProperties; // may not be there at all var indexedPropertyValue = props.FieldValues.Keys.Contains("vti_indexedpropertykeys") ? ConvertUtils.ToStringAndTrim(props["vti_indexedpropertykeys"]) : string.Empty; var currentIndexedProperties = IndexedPropertyUtils.GetDecodeValueForSearchIndexProperty(indexedPropertyValue); // setup property bag foreach (var indexedProperty in webModel.IndexedPropertyKeys) { // indexed prop should exist in the prop bag // otherwise it won't be saved by SharePoint (ILSpy / Refletor to see the logic) // http://rwcchen.blogspot.com.au/2014/06/sharepoint-2013-indexed-property-keys.html var propName = indexedProperty.Name; var propValue = string.IsNullOrEmpty(indexedProperty.Value) ? string.Empty : indexedProperty.Value; props[propName] = propValue; } // merge and setup indexed prop keys, preserve existing props foreach (var indexedProperty in webModel.IndexedPropertyKeys) { if (!currentIndexedProperties.Contains(indexedProperty.Name)) { currentIndexedProperties.Add(indexedProperty.Name); } } props["vti_indexedpropertykeys"] = IndexedPropertyUtils.GetEncodedValueForSearchIndexProperty(currentIndexedProperties); } #endif }
public override void DeployModel(object modelHost, DefinitionBase model) { var webModelHost = modelHost.WithAssertAndCast <WebModelHost>("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast <ListDefinition>("model", value => value.RequireNotNull()); var web = webModelHost.HostWeb; var context = web.Context; context.Load(web, w => w.ServerRelativeUrl); var lists = context.LoadQuery <List>(web.Lists.Include(l => l.DefaultViewUrl)); context.ExecuteQueryWithTrace(); #pragma warning disable 618 var spObject = FindListByUrl(lists, definition.GetListUrl()); #pragma warning restore 618 context.Load(spObject); context.Load(spObject, list => list.RootFolder.ServerRelativeUrl); context.Load(spObject, list => list.EnableAttachments); context.Load(spObject, list => list.EnableFolderCreation); context.Load(spObject, list => list.EnableMinorVersions); context.Load(spObject, list => list.EnableModeration); context.Load(spObject, list => list.EnableVersioning); context.Load(spObject, list => list.ForceCheckout); context.Load(spObject, list => list.Hidden); context.Load(spObject, list => list.NoCrawl); context.Load(spObject, list => list.OnQuickLaunch); context.Load(spObject, list => list.DocumentTemplateUrl); context.Load(spObject, list => list.DraftVersionVisibility); context.ExecuteQueryWithTrace(); var assert = ServiceFactory.AssertService.NewAssert(model, definition, spObject); assert .ShouldBeEqual(m => m.Title, o => o.Title) //.ShouldBeEqual(m => m.Description, o => o.Description) //.ShouldBeEqual(m => m.IrmEnabled, o => o.IrmEnabled) //.ShouldBeEqual(m => m.IrmExpire, o => o.IrmExpire) //.ShouldBeEqual(m => m.IrmReject, o => o.IrmReject) //.ShouldBeEndOf(m => m.GetServerRelativeUrl(web), m => m.Url, o => o.GetServerRelativeUrl(), o => o.GetServerRelativeUrl()) .ShouldBeEqual(m => m.ContentTypesEnabled, o => o.ContentTypesEnabled); if (!string.IsNullOrEmpty(definition.Description)) { assert.ShouldBeEqual(m => m.Description, o => o.Description); } else { assert.SkipProperty(m => m.Description, "Description is null or empty. Skipping."); } if (!string.IsNullOrEmpty(definition.DraftVersionVisibility)) { var draftOption = (DraftVisibilityType)Enum.Parse(typeof(DraftVisibilityType), definition.DraftVersionVisibility); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.DraftVersionVisibility); var dstProp = d.GetExpressionValue(m => m.DraftVersionVisibility); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = draftOption == (DraftVisibilityType)dstProp.Value }); }); } else { assert.SkipProperty(m => m.DraftVersionVisibility, "Skipping from validation. DraftVersionVisibility IS NULL"); } if (definition.Hidden.HasValue) { assert.ShouldBeEqual(m => m.Hidden, m => m.Hidden); } else { assert.SkipProperty(m => m.Hidden, "Skipping from validation. Url IS NULL"); } #pragma warning disable 618 if (!string.IsNullOrEmpty(definition.Url)) { assert.ShouldBeEndOf(m => m.GetListUrl(), m => m.Url, o => o.GetServerRelativeUrl(), o => o.GetServerRelativeUrl()); } else { assert.SkipProperty(m => m.Url, "Skipping from validation. Url IS NULL"); } #pragma warning restore 618 if (!string.IsNullOrEmpty(definition.CustomUrl)) { assert.ShouldBeEndOf(m => m.CustomUrl, o => o.GetServerRelativeUrl()); } else { assert.SkipProperty(m => m.CustomUrl, "Skipping from validation. CustomUrl IS NULL"); } // common if (definition.EnableAttachments.HasValue) { assert.ShouldBeEqual(m => m.EnableAttachments, o => o.EnableAttachments); } else { assert.SkipProperty(m => m.EnableAttachments, "Skipping from validation. EnableAttachments IS NULL"); } if (definition.EnableFolderCreation.HasValue) { assert.ShouldBeEqual(m => m.EnableFolderCreation, o => o.EnableFolderCreation); } else { assert.SkipProperty(m => m.EnableFolderCreation, "Skipping from validation. EnableFolderCreation IS NULL"); } if (definition.EnableMinorVersions.HasValue) { assert.ShouldBeEqual(m => m.EnableMinorVersions, o => o.EnableMinorVersions); } else { assert.SkipProperty(m => m.EnableMinorVersions, "Skipping from validation. EnableMinorVersions IS NULL"); } if (definition.EnableModeration.HasValue) { assert.ShouldBeEqual(m => m.EnableModeration, o => o.EnableModeration); } else { assert.SkipProperty(m => m.EnableModeration, "Skipping from validation. EnableModeration IS NULL"); } if (definition.EnableVersioning.HasValue) { assert.ShouldBeEqual(m => m.EnableVersioning, o => o.EnableVersioning); } else { assert.SkipProperty(m => m.EnableVersioning, "Skipping from validation. EnableVersioning IS NULL"); } if (definition.ForceCheckout.HasValue) { assert.ShouldBeEqual(m => m.ForceCheckout, o => o.ForceCheckout); } else { assert.SkipProperty(m => m.ForceCheckout, "Skipping from validation. ForceCheckout IS NULL"); } if (definition.NoCrawl.HasValue) { assert.ShouldBeEqual(m => m.NoCrawl, o => o.NoCrawl); } else { assert.SkipProperty(m => m.NoCrawl, "Skipping from validation. NoCrawl IS NULL"); } if (definition.OnQuickLaunch.HasValue) { assert.ShouldBeEqual(m => m.OnQuickLaunch, o => o.OnQuickLaunch); } else { assert.SkipProperty(m => m.OnQuickLaunch, "Skipping from validation. OnQuickLaunch IS NULL"); } // IRM if (definition.IrmEnabled.HasValue) { assert.ShouldBeEqual(m => m.IrmEnabled, o => o.IrmEnabled); } else { assert.SkipProperty(m => m.IrmEnabled, "Skipping from validation. IrmEnabled IS NULL"); } if (definition.IrmExpire.HasValue) { assert.ShouldBeEqual(m => m.IrmExpire, o => o.IrmExpire); } else { assert.SkipProperty(m => m.IrmExpire, "Skipping from validation. IrmExpire IS NULL"); } if (definition.IrmReject.HasValue) { assert.ShouldBeEqual(m => m.IrmReject, o => o.IrmReject); } else { assert.SkipProperty(m => m.IrmReject, "Skipping from validation. IrmReject IS NULL"); } if (definition.TemplateType > 0) { assert.ShouldBeEqual(m => m.TemplateType, o => (int)o.BaseTemplate); } else { assert.SkipProperty(m => m.TemplateType, "TemplateType == 0. Skipping."); } if (!string.IsNullOrEmpty(definition.TemplateName)) { context.Load(web, tmpWeb => tmpWeb.ListTemplates); context.ExecuteQueryWithTrace(); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Fetching all list templates and matching target one."); var listTemplate = ResolveListTemplate(webModelHost, definition); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.TemplateName); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = (spObject.TemplateFeatureId == listTemplate.FeatureId) && (spObject.BaseTemplate == (int)listTemplate.ListTemplateTypeKind) }); }); } else { assert.SkipProperty(m => m.TemplateName, "TemplateName is null or empty. Skipping."); } if (definition.MajorVersionLimit.HasValue) { /// CSOM is not supported yet as M2 s build with SP2013 SP1+ assemblies. /// https://officespdev.uservoice.com/forums/224641-general/suggestions/6016131-majorversionlimit-majorwithminorversionslimit-pr //assert.ShouldBeEqual(m => m.MajorVersionLimit, o => o.MajorVersionLimit); } else { assert.SkipProperty(m => m.MajorVersionLimit, "Skipping from validation. MajorVersionLimit IS NULL"); } if (definition.MajorWithMinorVersionsLimit.HasValue) { /// CSOM is not supported yet as M2 s build with SP2013 SP1+ assemblies. /// https://officespdev.uservoice.com/forums/224641-general/suggestions/6016131-majorversionlimit-majorwithminorversionslimit-pr // assert.ShouldBeEqual(m => m.MajorWithMinorVersionsLimit, o => o.MajorWithMinorVersionsLimit); } else { assert.SkipProperty(m => m.MajorWithMinorVersionsLimit, "Skipping from validation. MajorWithMinorVersionsLimit IS NULL"); } // template url if (string.IsNullOrEmpty(definition.DocumentTemplateUrl)) { assert.SkipProperty(m => m.DocumentTemplateUrl, string.Format("Skipping DocumentTemplateUrl or library. Skipping.")); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DocumentTemplateUrl); var dstProp = d.DocumentTemplateUrl; var srcUrl = srcProp.Value as string; var dstUrl = dstProp; if (!dstUrl.StartsWith("/")) { dstUrl = "/" + dstUrl; } var isValid = false; if (s.DocumentTemplateUrl.Contains("~sitecollection")) { var siteCollectionUrl = webModelHost.HostSite.ServerRelativeUrl == "/" ? string.Empty : webModelHost.HostSite.ServerRelativeUrl; isValid = srcUrl.Replace("~sitecollection", siteCollectionUrl) == dstUrl; } else if (s.DocumentTemplateUrl.Contains("~site")) { var siteCollectionUrl = web.ServerRelativeUrl == "/" ? string.Empty : web.ServerRelativeUrl; isValid = srcUrl.Replace("~site", siteCollectionUrl) == dstUrl; } else { isValid = dstUrl.EndsWith(srcUrl); } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } }
private void MapListProperties(object modelHost, List list, ListDefinition definition) { var csomModelHost = modelHost.WithAssertAndCast <CSOMModelHostBase>("modelHost", value => value.RequireNotNull()); var context = list.Context; list.Title = definition.Title; list.Description = definition.Description ?? string.Empty; list.ContentTypesEnabled = definition.ContentTypesEnabled; if (definition.Hidden.HasValue) { list.Hidden = definition.Hidden.Value; } if (!string.IsNullOrEmpty(definition.DraftVersionVisibility)) { var draftOption = (DraftVisibilityType)Enum.Parse(typeof(DraftVisibilityType), definition.DraftVersionVisibility); list.DraftVersionVisibility = draftOption; } #if !NET35 // IRM if (definition.IrmEnabled.HasValue) { list.IrmEnabled = definition.IrmEnabled.Value; } if (definition.IrmExpire.HasValue) { list.IrmExpire = definition.IrmExpire.Value; } if (definition.IrmReject.HasValue) { list.IrmReject = definition.IrmReject.Value; } #endif // the rest if (definition.EnableAttachments.HasValue) { list.EnableAttachments = definition.EnableAttachments.Value; } if (definition.EnableFolderCreation.HasValue) { list.EnableFolderCreation = definition.EnableFolderCreation.Value; } if (definition.EnableMinorVersions.HasValue) { list.EnableMinorVersions = definition.EnableMinorVersions.Value; } if (definition.EnableModeration.HasValue) { list.EnableModeration = definition.EnableModeration.Value; } if (definition.EnableVersioning.HasValue) { list.EnableVersioning = definition.EnableVersioning.Value; } if (definition.ForceCheckout.HasValue) { list.ForceCheckout = definition.ForceCheckout.Value; } if (definition.Hidden.HasValue) { list.Hidden = definition.Hidden.Value; } if (definition.NoCrawl.HasValue) { list.NoCrawl = definition.NoCrawl.Value; } if (definition.OnQuickLaunch.HasValue) { list.OnQuickLaunch = definition.OnQuickLaunch.Value; } if (definition.MajorVersionLimit.HasValue) { if (ReflectionUtils.HasProperty(list, "MajorVersionLimit")) { context.AddQuery(new ClientActionSetProperty(list, "MajorVersionLimit", definition.MajorVersionLimit.Value)); } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, string.Format( "CSOM runtime doesn't have [{0}] methods support. Update CSOM runtime to a new version. Provision is skipped", string.Join(", ", new string[] { "MajorVersionLimit" }))); } } if (definition.MajorWithMinorVersionsLimit.HasValue) { if (ReflectionUtils.HasProperty(list, "MajorWithMinorVersionsLimit")) { context.AddQuery(new ClientActionSetProperty(list, "MajorWithMinorVersionsLimit", definition.MajorWithMinorVersionsLimit.Value)); } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, string.Format( "CSOM runtime doesn't have [{0}] methods support. Update CSOM runtime to a new version. Provision is skipped", string.Join(", ", new string[] { "MajorWithMinorVersionsLimit" }))); } } if (definition.ReadSecurity.HasValue) { if (ReflectionUtils.HasProperty(list, "ReadSecurity")) { context.AddQuery(new ClientActionInvokeMethod(list, "ReadSecurity", new object[] { definition.ReadSecurity.Value })); } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have List.ReadSecurity. Update CSOM runtime to a new version. Provision is skipped"); } } if (definition.WriteSecurity.HasValue) { if (ReflectionUtils.HasProperty(list, "WriteSecurity")) { context.AddQuery(new ClientActionInvokeMethod(list, "WriteSecurity", new object[] { definition.WriteSecurity.Value })); } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have List.WriteSecurity. Update CSOM runtime to a new version. Provision is skipped"); } } if (!string.IsNullOrEmpty(definition.DocumentTemplateUrl)) { var urlValue = definition.DocumentTemplateUrl; urlValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext { Value = urlValue, Context = csomModelHost }).Value; if (!urlValue.StartsWith("/") && !urlValue.StartsWith("http:") && !urlValue.StartsWith("https:")) { urlValue = "/" + urlValue; } list.DocumentTemplateUrl = urlValue; } ProcessLocalization(list, definition); #if !NET35 if (definition.IndexedRootFolderPropertyKeys.Any()) { var props = list.RootFolder.Properties; // may not be there at all var indexedPropertyValue = props.FieldValues.Keys.Contains("vti_indexedpropertykeys") ? ConvertUtils.ToStringAndTrim(props["vti_indexedpropertykeys"]) : string.Empty; var currentIndexedProperties = IndexedPropertyUtils.GetDecodeValueForSearchIndexProperty(indexedPropertyValue); // setup property bag foreach (var indexedProperty in definition.IndexedRootFolderPropertyKeys) { // indexed prop should exist in the prop bag // otherwise it won't be saved by SharePoint (ILSpy / Refletor to see the logic) // http://rwcchen.blogspot.com.au/2014/06/sharepoint-2013-indexed-property-keys.html var propName = indexedProperty.Name; var propValue = string.IsNullOrEmpty(indexedProperty.Value) ? string.Empty : indexedProperty.Value; props[propName] = propValue; } // merge and setup indexed prop keys, preserve existing props foreach (var indexedProperty in definition.IndexedRootFolderPropertyKeys) { if (!currentIndexedProperties.Contains(indexedProperty.Name)) { currentIndexedProperties.Add(indexedProperty.Name); } } props["vti_indexedpropertykeys"] = IndexedPropertyUtils.GetEncodedValueForSearchIndexProperty(currentIndexedProperties); list.RootFolder.Update(); } #endif }
public override void DeployModel(object modelHost, DefinitionBase model) { var modelHostWrapper = modelHost.WithAssertAndCast <ContentTypeModelHost>("modelHost", value => value.RequireNotNull()); var contentTypeFieldLinkModel = model.WithAssertAndCast <ContentTypeFieldLinkDefinition>("model", value => value.RequireNotNull()); //var site = modelHostWrapper.Site; var web = modelHostWrapper.HostWeb; var contentType = modelHostWrapper.HostContentType; var context = contentType.Context; TraceService.VerboseFormat((int)LogEventId.ModelProvisionCoreCall, "Getting content type field link by ID: [{0}]", contentTypeFieldLinkModel.FieldId); FieldLink fieldLink = FindExistingFieldLink(contentType, contentTypeFieldLinkModel); InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioning, Object = fieldLink, ObjectType = typeof(FieldLink), ObjectDefinition = model, ModelHost = modelHost }); if (fieldLink == null) { TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new content type field link"); var targetField = FindAvailableField(web, contentTypeFieldLinkModel); fieldLink = contentType.FieldLinks.Add(new FieldLinkCreationInformation { Field = targetField }); } else { TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing content type field link"); } if (contentTypeFieldLinkModel.Required.HasValue) { fieldLink.Required = contentTypeFieldLinkModel.Required.Value; } if (contentTypeFieldLinkModel.Hidden.HasValue) { fieldLink.Hidden = contentTypeFieldLinkModel.Hidden.Value; } if (!string.IsNullOrEmpty(contentTypeFieldLinkModel.DisplayName)) { // CSOM limitation - DisplayName is not available yet. // https://officespdev.uservoice.com/forums/224641-general/suggestions/7024931-enhance-fieldlink-class-with-additional-properties // fieldLink.DisplayName = contentTypeFieldLinkModel.DisplayName; // Enhance FieldLinkDefinition - DisplayName, ReadOnly, ShowInDisplayForm #892 // https://github.com/SubPointSolutions/spmeta2/issues/892 if (ReflectionUtils.HasProperty(fieldLink, "DisplayName")) { if (!string.IsNullOrEmpty(contentTypeFieldLinkModel.DisplayName)) { ClientRuntimeQueryService.SetProperty(fieldLink, "DisplayName", contentTypeFieldLinkModel.DisplayName); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have FieldLink.DisplayName. Update CSOM runtime to a new version. Provision is skipped"); } } InvokeOnModelEvent(this, new ModelEventArgs { CurrentModelNode = null, Model = null, EventType = ModelEventType.OnProvisioned, Object = fieldLink, ObjectType = typeof(FieldLink), ObjectDefinition = model, ModelHost = modelHost }); contentType.Update(true); context.ExecuteQueryWithTrace(); }
public override void DeployModel(object modelHost, DefinitionBase model) { var webModelHost = modelHost.WithAssertAndCast <WebModelHost>("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast <ListDefinition>("model", value => value.RequireNotNull()); var web = webModelHost.HostWeb; var context = web.Context; context.Load(web, w => w.ServerRelativeUrl); var lists = context.LoadQuery <List>(web.Lists.Include(l => l.DefaultViewUrl)); context.ExecuteQueryWithTrace(); #pragma warning disable 618 var spObject = FindListByUrl(lists, definition.GetListUrl()); #pragma warning restore 618 context.Load(spObject); context.Load(spObject, list => list.RootFolder.Properties); context.Load(spObject, list => list.RootFolder.ServerRelativeUrl); context.Load(spObject, list => list.RootFolder.Properties); context.Load(spObject, list => list.EnableAttachments); context.Load(spObject, list => list.EnableFolderCreation); context.Load(spObject, list => list.EnableMinorVersions); context.Load(spObject, list => list.EnableModeration); context.Load(spObject, list => list.EnableVersioning); context.Load(spObject, list => list.ForceCheckout); context.Load(spObject, list => list.Hidden); context.Load(spObject, list => list.NoCrawl); context.Load(spObject, list => list.OnQuickLaunch); context.Load(spObject, list => list.DocumentTemplateUrl); context.Load(spObject, list => list.DraftVersionVisibility); context.ExecuteQueryWithTrace(); var assert = ServiceFactory.AssertService.NewAssert(model, definition, spObject); assert .ShouldBeEqual(m => m.Title, o => o.Title) //.ShouldBeEqual(m => m.Description, o => o.Description) //.ShouldBeEqual(m => m.IrmEnabled, o => o.IrmEnabled) //.ShouldBeEqual(m => m.IrmExpire, o => o.IrmExpire) //.ShouldBeEqual(m => m.IrmReject, o => o.IrmReject) //.ShouldBeEndOf(m => m.GetServerRelativeUrl(web), m => m.Url, o => o.GetServerRelativeUrl(), o => o.GetServerRelativeUrl()) .ShouldBeEqual(m => m.ContentTypesEnabled, o => o.ContentTypesEnabled); if (!string.IsNullOrEmpty(definition.Description)) { assert.ShouldBeEqual(m => m.Description, o => o.Description); } else { assert.SkipProperty(m => m.Description, "Description is null or empty. Skipping."); } assert.SkipProperty(m => m.EnableAssignToEmail, "EnableAssignToEmail is not supported by CSOM"); assert.SkipProperty(m => m.WriteSecurity, "WriteSecurity is not supported by CSOM"); assert.SkipProperty(m => m.NavigateForFormsPages, "NavigateForFormsPages is not supported by CSOM"); if (!string.IsNullOrEmpty(definition.DraftVersionVisibility)) { var draftOption = (DraftVisibilityType)Enum.Parse(typeof(DraftVisibilityType), definition.DraftVersionVisibility); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.DraftVersionVisibility); var dstProp = d.GetExpressionValue(m => m.DraftVersionVisibility); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = draftOption == (DraftVisibilityType)dstProp.Value }); }); } else { assert.SkipProperty(m => m.DraftVersionVisibility, "Skipping from validation. DraftVersionVisibility IS NULL"); } if (definition.Hidden.HasValue) { assert.ShouldBeEqual(m => m.Hidden, m => m.Hidden); } else { assert.SkipProperty(m => m.Hidden, "Skipping from validation. Url IS NULL"); } #pragma warning disable 618 if (!string.IsNullOrEmpty(definition.Url)) { assert.ShouldBeEndOf(m => m.GetListUrl(), m => m.Url, o => o.GetServerRelativeUrl(), o => o.GetServerRelativeUrl()); } else { assert.SkipProperty(m => m.Url, "Skipping from validation. Url IS NULL"); } #pragma warning restore 618 if (!string.IsNullOrEmpty(definition.CustomUrl)) { assert.ShouldBeEndOf(m => m.CustomUrl, o => o.GetServerRelativeUrl()); } else { assert.SkipProperty(m => m.CustomUrl, "Skipping from validation. CustomUrl IS NULL"); } // common if (definition.EnableAttachments.HasValue) { assert.ShouldBeEqual(m => m.EnableAttachments, o => o.EnableAttachments); } else { assert.SkipProperty(m => m.EnableAttachments, "Skipping from validation. EnableAttachments IS NULL"); } if (definition.EnableFolderCreation.HasValue) { assert.ShouldBeEqual(m => m.EnableFolderCreation, o => o.EnableFolderCreation); } else { assert.SkipProperty(m => m.EnableFolderCreation, "Skipping from validation. EnableFolderCreation IS NULL"); } if (definition.EnableMinorVersions.HasValue) { assert.ShouldBeEqual(m => m.EnableMinorVersions, o => o.EnableMinorVersions); } else { assert.SkipProperty(m => m.EnableMinorVersions, "Skipping from validation. EnableMinorVersions IS NULL"); } if (definition.EnableModeration.HasValue) { assert.ShouldBeEqual(m => m.EnableModeration, o => o.EnableModeration); } else { assert.SkipProperty(m => m.EnableModeration, "Skipping from validation. EnableModeration IS NULL"); } if (definition.EnableVersioning.HasValue) { assert.ShouldBeEqual(m => m.EnableVersioning, o => o.EnableVersioning); } else { assert.SkipProperty(m => m.EnableVersioning, "Skipping from validation. EnableVersioning IS NULL"); } if (definition.ForceCheckout.HasValue) { assert.ShouldBeEqual(m => m.ForceCheckout, o => o.ForceCheckout); } else { assert.SkipProperty(m => m.ForceCheckout, "Skipping from validation. ForceCheckout IS NULL"); } if (definition.NoCrawl.HasValue) { assert.ShouldBeEqual(m => m.NoCrawl, o => o.NoCrawl); } else { assert.SkipProperty(m => m.NoCrawl, "Skipping from validation. NoCrawl IS NULL"); } if (definition.OnQuickLaunch.HasValue) { assert.ShouldBeEqual(m => m.OnQuickLaunch, o => o.OnQuickLaunch); } else { assert.SkipProperty(m => m.OnQuickLaunch, "Skipping from validation. OnQuickLaunch IS NULL"); } // IRM if (definition.IrmEnabled.HasValue) { assert.ShouldBeEqual(m => m.IrmEnabled, o => o.IrmEnabled); } else { assert.SkipProperty(m => m.IrmEnabled, "Skipping from validation. IrmEnabled IS NULL"); } if (definition.IrmExpire.HasValue) { assert.ShouldBeEqual(m => m.IrmExpire, o => o.IrmExpire); } else { assert.SkipProperty(m => m.IrmExpire, "Skipping from validation. IrmExpire IS NULL"); } if (definition.IrmReject.HasValue) { assert.ShouldBeEqual(m => m.IrmReject, o => o.IrmReject); } else { assert.SkipProperty(m => m.IrmReject, "Skipping from validation. IrmReject IS NULL"); } if (definition.TemplateType > 0) { assert.ShouldBeEqual(m => m.TemplateType, o => o.BaseTemplate); } else { assert.SkipProperty(m => m.TemplateType, "TemplateType == 0. Skipping."); } if (!string.IsNullOrEmpty(definition.TemplateName)) { context.Load(web, tmpWeb => tmpWeb.ListTemplates); context.ExecuteQueryWithTrace(); TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "Fetching all list templates and matching target one."); var listTemplate = ResolveListTemplate(webModelHost, definition); assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(m => m.TemplateName); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = (spObject.TemplateFeatureId == listTemplate.FeatureId) && (spObject.BaseTemplate == listTemplate.ListTemplateTypeKind) }); }); } else { assert.SkipProperty(m => m.TemplateName, "TemplateName is null or empty. Skipping."); } if (definition.MajorVersionLimit.HasValue) { if (ReflectionUtils.HasProperty(spObject, "MajorVersionLimit")) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.MajorVersionLimit); var value = (int)ReflectionUtils.GetPropertyValue(spObject, "MajorVersionLimit"); var isValid = value == definition.MajorVersionLimit.Value; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.MajorVersionLimit, "Skipping from validation. MajorVersionLimit does not exist. CSOM runtime is below required."); } } else { assert.SkipProperty(m => m.MajorVersionLimit, "Skipping from validation. MajorVersionLimit IS NULL"); } if (definition.MajorWithMinorVersionsLimit.HasValue) { if (ReflectionUtils.HasProperty(spObject, "MajorWithMinorVersionsLimit")) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.MajorWithMinorVersionsLimit); var value = (int)ReflectionUtils.GetPropertyValue(spObject, "MajorWithMinorVersionsLimit"); var isValid = value == definition.MajorWithMinorVersionsLimit.Value; return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.MajorWithMinorVersionsLimit, "Skipping from validation. MajorWithMinorVersionsLimit does not exist. CSOM runtime is below required."); } } else { assert.SkipProperty(m => m.MajorWithMinorVersionsLimit, "Skipping from validation. MajorWithMinorVersionsLimit IS NULL"); } // template url if (string.IsNullOrEmpty(definition.DocumentTemplateUrl)) { assert.SkipProperty(m => m.DocumentTemplateUrl, "Skipping DocumentTemplateUrl or library. Skipping."); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DocumentTemplateUrl); var dstProp = d.DocumentTemplateUrl; var srcUrl = srcProp.Value as string; var dstUrl = dstProp; if (!dstUrl.StartsWith("/")) { dstUrl = "/" + dstUrl; } bool isValid; if (s.DocumentTemplateUrl.Contains("~sitecollection")) { var siteCollectionUrl = webModelHost.HostSite.ServerRelativeUrl == "/" ? string.Empty : webModelHost.HostSite.ServerRelativeUrl; isValid = srcUrl.Replace("~sitecollection", siteCollectionUrl) == dstUrl; } else if (s.DocumentTemplateUrl.Contains("~site")) { var siteCollectionUrl = web.ServerRelativeUrl == "/" ? string.Empty : web.ServerRelativeUrl; isValid = srcUrl.Replace("~site", siteCollectionUrl) == dstUrl; } else { isValid = dstUrl.EndsWith(srcUrl); } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } if (definition.IndexedRootFolderPropertyKeys.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.IndexedRootFolderPropertyKeys); var isValid = false; if (d.RootFolder.Properties.FieldValues.ContainsKey("vti_indexedpropertykeys")) { // check props, TODO // check vti_indexedpropertykeys var indexedPropertyKeys = d.RootFolder.Properties["vti_indexedpropertykeys"] .ToString() .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Select(es => Encoding.Unicode.GetString(System.Convert.FromBase64String(es))); // Search if any indexPropertyKey from definition is not in WebModel var differentKeys = s.IndexedRootFolderPropertyKeys.Select(o => o.Name) .Except(indexedPropertyKeys); isValid = !differentKeys.Any(); } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.IndexedRootFolderPropertyKeys, "IndexedRootFolderPropertyKeys is NULL or empty. Skipping."); } var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "TitleResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.TitleResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.TitleResource); var isValid = true; foreach (var userResource in s.TitleResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "TitleResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.TitleResource, "TitleResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.TitleResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } }
public override void DeployModel(object modelHost, DefinitionBase model) { //var siteModelHost = modelHost.WithAssertAndCast<SiteModelHost>("modelHost", value => value.RequireNotNull()); var definition = model.WithAssertAndCast <ContentTypeDefinition>("model", value => value.RequireNotNull()); var site = ExtractSite(modelHost); var web = ExtractWeb(modelHost); var context = web.Context; var rootWeb = web; var contentTypes = rootWeb.ContentTypes; context.Load(rootWeb); context.Load(contentTypes); context.ExecuteQueryWithTrace(); var contentTypeId = definition.GetContentTypeId(); var spObject = contentTypes.FindByName(definition.Name); context.Load(spObject); context.Load(spObject, o => o.JSLink); context.ExecuteQueryWithTrace(); var assert = ServiceFactory.AssertService.NewAssert(definition, spObject); assert .ShouldNotBeNull(spObject) .ShouldBeEqual(m => m.Name, o => o.Name) .ShouldBeEqual(m => m.Group, o => o.Group) .ShouldBeEqual(m => m.Hidden, o => o.Hidden) .ShouldBeEqualIfHasValue(m => m.Sealed, o => o.Sealed) .ShouldBeEqualIfHasValue(m => m.ReadOnly, o => o.ReadOnly) .ShouldBeEqualIfNotNullOrEmpty(m => m.JSLink, o => o.JSLink) .ShouldBeEqualIfNotNullOrEmpty(m => m.Description, o => o.Description); if (definition.Id == default(Guid)) { assert.SkipProperty(m => m.IdNumberValue, string.Format("Skipping Id as it is default(Guid)")); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Id); var dstProp = d.GetExpressionValue(ct => ct.Id.ToString()); var srcCtId = s.GetContentTypeId(); var dstCtId = d.Id.ToString(); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = dstCtId.ToString().ToUpper() == dstCtId.ToString().ToUpper() }); }); } if (string.IsNullOrEmpty(definition.IdNumberValue)) { assert.SkipProperty(m => m.IdNumberValue, string.Format("Skipping IdNumberValue as it is Empty")); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.Id); var dstProp = d.GetExpressionValue(ct => ct.Id.ToString()); return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = srcProp.ToString().ToUpper() == dstProp.ToString().ToUpper() }); }); } if (string.IsNullOrEmpty(definition.DocumentTemplate)) { assert.SkipProperty(m => m.DocumentTemplate, string.Format("Skipping DocumentTemplate as it is Empty")); } else { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DocumentTemplate); var dstProp = d.GetExpressionValue(ct => ct.DocumentTemplateUrl); var srcUrl = srcProp.Value as string; var dstUrl = dstProp.Value as string; var isValid = false; if (s.DocumentTemplate.Contains("~sitecollection")) { var siteCollectionUrl = site.ServerRelativeUrl == "/" ? string.Empty : site.ServerRelativeUrl; isValid = srcUrl.Replace("~sitecollection", siteCollectionUrl) == dstUrl; } else if (s.DocumentTemplate.Contains("~site")) { var siteCollectionUrl = web.ServerRelativeUrl == "/" ? string.Empty : web.ServerRelativeUrl; isValid = srcUrl.Replace("~site", siteCollectionUrl) == dstUrl; } else { isValid = dstUrl.EndsWith(srcUrl); } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = dstProp, IsValid = isValid }); }); } var supportsLocalization = ReflectionUtils.HasProperties(spObject, new[] { "NameResource", "DescriptionResource" }); if (supportsLocalization) { if (definition.NameResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.NameResource); var isValid = true; foreach (var userResource in s.NameResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "NameResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.NameResource, "NameResource is NULL or empty. Skipping."); } if (definition.DescriptionResource.Any()) { assert.ShouldBeEqual((p, s, d) => { var srcProp = s.GetExpressionValue(def => def.DescriptionResource); var isValid = true; foreach (var userResource in s.DescriptionResource) { var culture = LocalizationService.GetUserResourceCultureInfo(userResource); var resourceObject = ReflectionUtils.GetPropertyValue(spObject, "DescriptionResource"); var value = ReflectionUtils.GetMethod(resourceObject, "GetValueForUICulture") .Invoke(resourceObject, new[] { culture.Name }) as ClientResult <string>; context.ExecuteQuery(); isValid = userResource.Value == value.Value; if (!isValid) { break; } } return(new PropertyValidationResult { Tag = p.Tag, Src = srcProp, Dst = null, IsValid = isValid }); }); } else { assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is NULL or empty. Skipping."); } } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, "CSOM runtime doesn't have Web.TitleResource and Web.DescriptionResource() methods support. Skipping validation."); assert.SkipProperty(m => m.NameResource, "TitleResource is null or empty. Skipping."); assert.SkipProperty(m => m.DescriptionResource, "DescriptionResource is null or empty. Skipping."); } }
protected virtual void ProcessGenericLocalization(ClientObject obj, Dictionary <string, List <ValueForUICulture> > localizations) { var targetProps = localizations.Keys.ToList(); var isSupportedRuntime = ReflectionUtils.HasProperties(obj, targetProps); if (!isSupportedRuntime) { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, string.Format("CSOM runtime doesn't have [{0}] methods support. Update CSOM runtime to a new version. Provision is skipped", string.Join(", ", targetProps.ToArray()))); return; } var needsUpdate = false; foreach (var key in localizations.Keys) { var propName = key; var localization = localizations[key]; if (localization.Any()) { var userResource = GetPropertyValue(obj, propName); foreach (var locValue in localization) { LocalizationService.ProcessUserResource(obj, userResource, locValue); } needsUpdate = true; } } if (needsUpdate) { var updateMethod = ReflectionUtils.GetMethod(obj, "Update"); if (updateMethod != null) { if (obj is ContentType) { updateMethod.Invoke(obj, new object[] { true }); } else if (obj is Field) { updateMethod = ReflectionUtils.GetMethod(obj, "UpdateAndPushChanges"); updateMethod.Invoke(obj, new object[] { true }); } else { updateMethod.Invoke(obj, null); } obj.Context.ExecuteQueryWithTrace(); } else { throw new SPMeta2Exception(String.Format("Can't find Update() methods on client object of type:[{0}]", obj.GetType())); } } }
private void MapListProperties(List list, ListDefinition definition) { var context = list.Context; list.Title = definition.Title; list.Description = definition.Description ?? string.Empty; list.ContentTypesEnabled = definition.ContentTypesEnabled; if (definition.Hidden.HasValue) { list.Hidden = definition.Hidden.Value; } if (!string.IsNullOrEmpty(definition.DraftVersionVisibility)) { var draftOption = (DraftVisibilityType)Enum.Parse(typeof(DraftVisibilityType), definition.DraftVersionVisibility); list.DraftVersionVisibility = draftOption; } // IRM if (definition.IrmEnabled.HasValue) { list.IrmEnabled = definition.IrmEnabled.Value; } if (definition.IrmExpire.HasValue) { list.IrmExpire = definition.IrmExpire.Value; } if (definition.IrmReject.HasValue) { list.IrmReject = definition.IrmReject.Value; } // the rest if (definition.EnableAttachments.HasValue) { list.EnableAttachments = definition.EnableAttachments.Value; } if (definition.EnableFolderCreation.HasValue) { list.EnableFolderCreation = definition.EnableFolderCreation.Value; } if (definition.EnableMinorVersions.HasValue) { list.EnableMinorVersions = definition.EnableMinorVersions.Value; } if (definition.EnableModeration.HasValue) { list.EnableModeration = definition.EnableModeration.Value; } if (definition.EnableVersioning.HasValue) { list.EnableVersioning = definition.EnableVersioning.Value; } if (definition.ForceCheckout.HasValue) { list.ForceCheckout = definition.ForceCheckout.Value; } if (definition.Hidden.HasValue) { list.Hidden = definition.Hidden.Value; } if (definition.NoCrawl.HasValue) { list.NoCrawl = definition.NoCrawl.Value; } if (definition.OnQuickLaunch.HasValue) { list.OnQuickLaunch = definition.OnQuickLaunch.Value; } if (definition.MajorVersionLimit.HasValue) { if (ReflectionUtils.HasProperty(list, "MajorVersionLimit")) { context.AddQuery(new ClientActionSetProperty(list, "MajorVersionLimit", definition.MajorVersionLimit.Value)); } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, string.Format( "CSOM runtime doesn't have [{0}] methods support. Update CSOM runtime to a new version. Provision is skipped", string.Join(", ", "MajorVersionLimit"))); } } if (definition.MajorWithMinorVersionsLimit.HasValue) { if (ReflectionUtils.HasProperty(list, "MajorWithMinorVersionsLimit")) { context.AddQuery(new ClientActionSetProperty(list, "MajorWithMinorVersionsLimit", definition.MajorWithMinorVersionsLimit.Value)); } else { TraceService.Critical((int)LogEventId.ModelProvisionCoreCall, string.Format( "CSOM runtime doesn't have [{0}] methods support. Update CSOM runtime to a new version. Provision is skipped", string.Join(", ", "MajorWithMinorVersionsLimit"))); } } if (!string.IsNullOrEmpty(definition.DocumentTemplateUrl)) { var urlValue = definition.DocumentTemplateUrl; urlValue = TokenReplacementService.ReplaceTokens(new TokenReplacementContext { Value = urlValue, Context = list.Context, }).Value; if (!urlValue.StartsWith("/") && !urlValue.StartsWith("http:") && !urlValue.StartsWith("https:")) { urlValue = "/" + urlValue; } list.DocumentTemplateUrl = urlValue; } ProcessLocalization(list, definition); }