From d075f472cfbbb183dd99b796e808a68bce2aa2bd Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Tue, 9 Jun 2020 18:53:29 +0530 Subject: [PATCH 001/130] Fix: removed usage of obsolete ListUnifiedGroups method --- Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs | 4 ++-- Commands/Graph/GetUnifiedGroup.cs | 2 +- Commands/Graph/NewUnifiedGroup.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs b/Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs index 6e9092f1b..170e574d7 100644 --- a/Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs +++ b/Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs @@ -52,10 +52,10 @@ public UnifiedGroupEntity GetGroup(string accessToken, bool includeClassificatio } else if (!string.IsNullOrEmpty(DisplayName)) { - var groups = UnifiedGroupsUtility.ListUnifiedGroups(accessToken, DisplayName, includeSite: true, includeClassification:includeClassification); + var groups = UnifiedGroupsUtility.GetUnifiedGroups(accessToken, DisplayName, includeSite: true, includeClassification:includeClassification); if (groups == null || groups.Count == 0) { - groups = UnifiedGroupsUtility.ListUnifiedGroups(accessToken, mailNickname: DisplayName, includeSite: true, includeClassification:includeClassification); + groups = UnifiedGroupsUtility.GetUnifiedGroups(accessToken, mailNickname: DisplayName, includeSite: true, includeClassification:includeClassification); } if (groups != null && groups.Any()) { diff --git a/Commands/Graph/GetUnifiedGroup.cs b/Commands/Graph/GetUnifiedGroup.cs index cba35d65d..6a384d9b5 100644 --- a/Commands/Graph/GetUnifiedGroup.cs +++ b/Commands/Graph/GetUnifiedGroup.cs @@ -65,7 +65,7 @@ protected override void ExecuteCmdlet() else { // Retrieve all the groups - groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, includeSite: !ExcludeSiteUrl.IsPresent, includeClassification:IncludeClassification.IsPresent, includeHasTeam: IncludeHasTeam.IsPresent); + groups = UnifiedGroupsUtility.GetUnifiedGroups(AccessToken, includeSite: !ExcludeSiteUrl.IsPresent, includeClassification:IncludeClassification.IsPresent, includeHasTeam: IncludeHasTeam.IsPresent); } if (group != null) diff --git a/Commands/Graph/NewUnifiedGroup.cs b/Commands/Graph/NewUnifiedGroup.cs index 38c0749f8..523a84ae6 100644 --- a/Commands/Graph/NewUnifiedGroup.cs +++ b/Commands/Graph/NewUnifiedGroup.cs @@ -70,7 +70,7 @@ protected override void ExecuteCmdlet() if (!Force) { - var candidates = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, + var candidates = UnifiedGroupsUtility.GetUnifiedGroups(AccessToken, mailNickname: MailNickname, endIndex: 1); // ListUnifiedGroups retrieves groups with starts-with, so need another check From b44aa9266ad48eb175bd439369730a2d9e529d0d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 9 Jun 2020 20:23:50 +0200 Subject: [PATCH 002/130] Added verbose log to connect to show which parameter set a connect was matched with to aid in troubleshooting, added check when connecting using thumbprint, if the thumbprint resolves to the private key certificate and throw a clear warning if it resolves only to the public key certificate --- Commands/Base/ConnectOnline.cs | 6 ++++-- Commands/Base/PnPConnectionHelper.cs | 24 +++++++++++++++++++++-- Commands/Properties/Resources.Designer.cs | 11 ++++++++++- Commands/Properties/Resources.resx | 5 ++++- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/Commands/Base/ConnectOnline.cs b/Commands/Base/ConnectOnline.cs index cd7b56781..17f83f733 100644 --- a/Commands/Base/ConnectOnline.cs +++ b/Commands/Base/ConnectOnline.cs @@ -118,7 +118,7 @@ namespace SharePointPnP.PowerShell.Commands.Base SortOrder = 17)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId '' -Tenant 'contoso.onmicrosoft.com' -Thumbprint 34CFAA860E5FB8C44335A38A097C1E41EEA206AA", - Remarks = "Connects to SharePoint using app-only tokens via an app's declared permission scopes. See https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/SharePoint.ConnectUsingAppPermissions for a sample on how to get started.", + Remarks = "Connects to SharePoint using app-only tokens via an app's declared permission scopes. See https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/SharePoint.ConnectUsingAppPermissions for a sample on how to get started. Ensure you have imported the private key certificate, typically the .pfx file, into the Windows Certificate Store for the certificate with the provided thumbprint.", SortOrder = 18)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId '' -Tenant 'contoso.onmicrosoft.com' -PEMCertificate -PEMPrivateKey -CertificatePassword ", @@ -502,7 +502,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = true, ParameterSetName = ParameterSet_APPONLYAADPEM, HelpMessage = "PEM encoded private key for the certificate")] public string PEMPrivateKey; - [Parameter(Mandatory = true, ParameterSetName = ParameterSet_APPONLYAADThumb, HelpMessage = "Certificate thumbprint")] + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_APPONLYAADThumb, HelpMessage = "The thumbprint of the certificate containing the private key registered with the application in Azure Active Directory")] public string Thumbprint; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_NATIVEAAD, HelpMessage = "Clears the token cache.")] @@ -656,6 +656,8 @@ protected void Connect() credentials = Credentials.Credential; } + WriteVerbose($"Using parameter set '{ParameterSetName}'"); + // Connect using the used set parameters switch (ParameterSetName) { diff --git a/Commands/Base/PnPConnectionHelper.cs b/Commands/Base/PnPConnectionHelper.cs index 729347674..5fc0c83f3 100644 --- a/Commands/Base/PnPConnectionHelper.cs +++ b/Commands/Base/PnPConnectionHelper.cs @@ -445,6 +445,12 @@ internal static PnPConnection InitiateAzureADAppOnlyConnection(Uri url, string c throw new PSArgumentOutOfRangeException(nameof(thumbprint), null, string.Format(Resources.CertificateWithThumbprintNotFound, thumbprint)); } + // Ensure the private key of the certificate is available + if (!certificate.HasPrivateKey) + { + throw new PSArgumentOutOfRangeException(nameof(thumbprint), null, string.Format(Resources.CertificateWithThumbprintDoesNotHavePrivateKey, thumbprint)); + } + return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate, false); } @@ -562,16 +568,30 @@ internal static PnPConnection InitiateAzureAdAppOnlyConnectionWithClientIdClient return spoConnection; } + /// + /// Tries to remove the local cached machine copy of the private key + /// + /// Certificate to try to clean up the local cached copy of the private key of internal static void CleanupCryptoMachineKey(X509Certificate2 certificate) { + if(!certificate.HasPrivateKey) + { + // If somehow a public key certificate was passed in, we can't clean it up, thus we have nothing to do here + return; + } + var privateKey = (RSACryptoServiceProvider)certificate.PrivateKey; string uniqueKeyContainerName = privateKey.CspKeyContainerInfo.UniqueKeyContainerName; certificate.Reset(); + var path = Environment.GetEnvironmentVariable("ProgramData"); - if (string.IsNullOrEmpty(path)) path = @"C:\ProgramData"; + if (string.IsNullOrEmpty(path)) + { + path = @"C:\ProgramData"; + } try { - System.IO.File.Delete(string.Format(@"{0}\Microsoft\Crypto\RSA\MachineKeys\{1}", path, uniqueKeyContainerName)); + System.IO.File.Delete($@"{path}\Microsoft\Crypto\RSA\MachineKeys\{uniqueKeyContainerName}"); } catch (Exception) { diff --git a/Commands/Properties/Resources.Designer.cs b/Commands/Properties/Resources.Designer.cs index c6164ea12..caf653b26 100644 --- a/Commands/Properties/Resources.Designer.cs +++ b/Commands/Properties/Resources.Designer.cs @@ -79,7 +79,16 @@ internal static string ApplicationName { } /// - /// Looks up a localized string similar to No certificate with the thumbprint '{0}' has been found in the Windows certificate store. + /// Looks up a localized string similar to The provided certificate with the thumbprint '{0}' does not have a private key which is required for a connection to be established. Ensure you have imported the certificate containing the private key, typically the .pfx file, into the Windows Certificate Store.. + /// + internal static string CertificateWithThumbprintDoesNotHavePrivateKey { + get { + return ResourceManager.GetString("CertificateWithThumbprintDoesNotHavePrivateKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No certificate with the thumbprint '{0}' has been found in the Windows Certificate Store. /// internal static string CertificateWithThumbprintNotFound { get { diff --git a/Commands/Properties/Resources.resx b/Commands/Properties/Resources.resx index 198ae2253..5169f6f99 100644 --- a/Commands/Properties/Resources.resx +++ b/Commands/Properties/Resources.resx @@ -328,7 +328,7 @@ No URL specified nor does the provided access token contain an audience - No certificate with the thumbprint '{0}' has been found in the Windows certificate store + No certificate with the thumbprint '{0}' has been found in the Windows Certificate Store The client certificate is invalid @@ -339,4 +339,7 @@ Parameter set {0} has not yet been implemented. Please create an issue for this on GitHub. + + The provided certificate with the thumbprint '{0}' does not have a private key which is required for a connection to be established. Ensure you have imported the certificate containing the private key, typically the .pfx file, into the Windows Certificate Store. + \ No newline at end of file From 8fc8322ed5334677e1786966f46a46abe683ff9b Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 9 Jun 2020 20:28:05 +0200 Subject: [PATCH 003/130] Fixed error in the example --- Commands/Base/InitializePowerShellAuthentication.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index 8ac256a4c..600de7248 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -23,7 +23,7 @@ namespace SharePointPnP.PowerShell.Commands.Base [CmdletAdditionalParameter(ParameterType = typeof(string[]), ParameterName = "Scopes", HelpMessage = "Specify which permissions scopes to request.", ParameterSetName = ParameterSet_EXISTINGCERT)] [CmdletExample( - Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -StoreLocation CurrentUser", + Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser", Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All", SortOrder = 1)] public class InitializePowerShellAuthentication : BasePSCmdlet, IDynamicParameters From ac4ba3010938f0155675480329de55f50c81c004 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 9 Jun 2020 22:29:57 +0200 Subject: [PATCH 004/130] Added additional examples, added some error handling providing clearer feedback around the use of already existing certificates --- .../InitializePowerShellAuthentication.cs | 41 ++++++++++++++++++- Commands/Properties/Resources.Designer.cs | 36 ++++++++++++++++ Commands/Properties/Resources.resx | 12 ++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index 600de7248..5abf1680a 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -10,7 +10,9 @@ using System.Linq; using System.Management.Automation; using System.Security; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; +using Resources = SharePointPnP.PowerShell.Commands.Properties.Resources; namespace SharePointPnP.PowerShell.Commands.Base { @@ -26,6 +28,15 @@ namespace SharePointPnP.PowerShell.Commands.Base Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser", Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All", SortOrder = 1)] + [CmdletExample( + Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -CertificatePath c:\certificate.pfx -CertificatePassword (ConvertTo-SecureString -String ""password"" -AsPlainText -Force)", + Remarks = "Creates a new Azure AD Application registration which will use the existing private key certificate at the provided path to allow access. It will upload the provided private key certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All", + SortOrder = 2)] + [CmdletExample( + Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -Scopes ""MSGraph.User.Read.All"",""SPO.Sites.Read.All""", + Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.Read.All, User.Read.All", + SortOrder = 3)] + public class InitializePowerShellAuthentication : BasePSCmdlet, IDynamicParameters { private const string ParameterSet_EXISTINGCERT = "Existing Certificate"; @@ -79,13 +90,39 @@ protected override void ProcessRecord() var cert = new X509Certificate2(); if (ParameterSetName == ParameterSet_EXISTINGCERT) { + // Ensure a file exists at the provided CertificatePath + if (!File.Exists(CertificatePath)) + { + throw new PSArgumentException(string.Format(Resources.CertificateNotFoundAtPath, CertificatePath), nameof(CertificatePath)); + } + if (ParameterSpecified(nameof(CertificatePassword))) { - cert.Import(CertificatePath, CertificatePassword, X509KeyStorageFlags.Exportable); + try + { + cert.Import(CertificatePath, CertificatePassword, X509KeyStorageFlags.Exportable); + } + catch (CryptographicException e) when (e.Message.Contains("The specified network password is not correct")) + { + throw new PSArgumentNullException(nameof(CertificatePassword), string.Format(Resources.PrivateKeyCertificateImportFailedPasswordIncorrect, nameof(CertificatePassword))); + } } else { - cert.Import(CertificatePath); + try + { + cert.Import(CertificatePath); + } + catch(CryptographicException e) when (e.Message.Contains("The specified network password is not correct")) + { + throw new PSArgumentNullException(nameof(CertificatePassword), string.Format(Resources.PrivateKeyCertificateImportFailedPasswordMissing, nameof(CertificatePassword))); + } + } + + // Ensure the certificate at the provided CertificatePath holds a private key + if (!cert.HasPrivateKey) + { + throw new PSArgumentException(string.Format(Resources.CertificateAtPathHasNoPrivateKey, CertificatePath), nameof(CertificatePath)); } } else diff --git a/Commands/Properties/Resources.Designer.cs b/Commands/Properties/Resources.Designer.cs index c6164ea12..ee6f7c37a 100644 --- a/Commands/Properties/Resources.Designer.cs +++ b/Commands/Properties/Resources.Designer.cs @@ -78,6 +78,24 @@ internal static string ApplicationName { } } + /// + /// Looks up a localized string similar to The certificate located at '{0}' holds no private key. Ensure you provide the private key certificate, typically the .pfx file.. + /// + internal static string CertificateAtPathHasNoPrivateKey { + get { + return ResourceManager.GetString("CertificateAtPathHasNoPrivateKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No private key certificate has been found at '{0}'. + /// + internal static string CertificateNotFoundAtPath { + get { + return ResourceManager.GetString("CertificateNotFoundAtPath", resourceCulture); + } + } + /// /// Looks up a localized string similar to No certificate with the thumbprint '{0}' has been found in the Windows certificate store. /// @@ -394,6 +412,24 @@ internal static string ParameterSetNotImplemented { } } + /// + /// Looks up a localized string similar to Reading of the private key certificate failed as the password with which it has been signed does not match the provided password. Use {0} to provide the proper password for the private key certificate file.. + /// + internal static string PrivateKeyCertificateImportFailedPasswordIncorrect { + get { + return ResourceManager.GetString("PrivateKeyCertificateImportFailedPasswordIncorrect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reading of the private key certificate failed as the password with which it has been signed has not been provided. Use {0} to provide the password.. + /// + internal static string PrivateKeyCertificateImportFailedPasswordMissing { + get { + return ResourceManager.GetString("PrivateKeyCertificateImportFailedPasswordMissing", resourceCulture); + } + } + /// /// Looks up a localized string similar to Remove Client-Side Page?. /// diff --git a/Commands/Properties/Resources.resx b/Commands/Properties/Resources.resx index 198ae2253..d82d42388 100644 --- a/Commands/Properties/Resources.resx +++ b/Commands/Properties/Resources.resx @@ -339,4 +339,16 @@ Parameter set {0} has not yet been implemented. Please create an issue for this on GitHub. + + The certificate located at '{0}' holds no private key. Ensure you provide the private key certificate, typically the .pfx file. + + + No private key certificate has been found at '{0}' + + + Reading of the private key certificate failed as the password with which it has been signed does not match the provided password. Use {0} to provide the proper password for the private key certificate file. + + + Reading of the private key certificate failed as the password with which it has been signed has not been provided. Use {0} to provide the password. + \ No newline at end of file From 24b94011a20802f6b842244bb593a2f6121ab35d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 9 Jun 2020 22:48:14 +0200 Subject: [PATCH 005/130] Added HideFromAddressLists and HideFromOutlookClients to Set-PnPUnifiedGroup to allow for M365 Groups to be shown or hidden --- CHANGELOG.md | 2 ++ Commands/Graph/SetUnifiedGroup.cs | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5c340e62..c96ecdb07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added +- Added `-HideFromAddressLists` and `-HideFromOutlookClients` to `Set-PnPUnifiedGroup` to allow for setting the visibility of Microsoft 365 Groups [PR #2717](https://github.com/pnp/PnP-PowerShell/pull/2717) ### Changed ### Contributors +- Koen Zomers [koenzomers] ## [3.22.2006.1] diff --git a/Commands/Graph/SetUnifiedGroup.cs b/Commands/Graph/SetUnifiedGroup.cs index 7730d2395..9374930d0 100644 --- a/Commands/Graph/SetUnifiedGroup.cs +++ b/Commands/Graph/SetUnifiedGroup.cs @@ -35,6 +35,10 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -Owners demo@contoso.com", Remarks = "Sets demo@contoso.com as owner of the group.", SortOrder = 5)] + [CmdletExample( + Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -HideFromOutlookClients:$false", + Remarks = "Ensures the provided group will be shown in Outlook clients.", + SortOrder = 6)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class SetUnifiedGroup : PnPGraphCmdlet { @@ -62,6 +66,12 @@ public class SetUnifiedGroup : PnPGraphCmdlet [Parameter(Mandatory = false, HelpMessage = "Creates a Microsoft Teams team associated with created group")] public SwitchParameter CreateTeam; + [Parameter(Mandatory = false, HelpMessage = "Hides the group from the Global Address List")] + public bool? HideFromAddressLists; + + [Parameter(Mandatory = false, HelpMessage = "Hides the group from Outlook Clients")] + public bool? HideFromOutlookClients; + protected override void ExecuteCmdlet() { UnifiedGroupEntity group = null; @@ -98,6 +108,12 @@ protected override void ExecuteCmdlet() groupLogo: groupLogoStream, isPrivate: isPrivateGroup, createTeam: CreateTeam); + + if (ParameterSpecified(nameof(HideFromAddressLists)) || ParameterSpecified(nameof(HideFromOutlookClients))) + { + // For this scenario a separate call needs to be made + UnifiedGroupsUtility.SetUnifiedGroupVisibility(group.GroupId, AccessToken, HideFromAddressLists, HideFromOutlookClients); + } } else { @@ -106,4 +122,4 @@ protected override void ExecuteCmdlet() } } } -#endif \ No newline at end of file +#endif From 5419cb55041597df59614ef3b4c9189e4e8073b6 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 9 Jun 2020 22:55:35 +0200 Subject: [PATCH 006/130] Adding credits to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e283177..e360d223d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed ### Contributors - +- Gautam Sheth [gautamdsheth] ## [3.22.2006.0] From efd14c10c6fb763a4a6813e741b849182b606b4c Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Sat, 13 Jun 2020 08:58:07 +0100 Subject: [PATCH 007/130] Updated cmdlet parameters for the new replay layout commands --- .../ConvertToClientSidePage.cs | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/Commands/ClientSidePages/ConvertToClientSidePage.cs b/Commands/ClientSidePages/ConvertToClientSidePage.cs index 92bb41777..bca548810 100644 --- a/Commands/ClientSidePages/ConvertToClientSidePage.cs +++ b/Commands/ClientSidePages/ConvertToClientSidePage.cs @@ -78,6 +78,22 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetConnection $target -UserMappingFile c:\\temp\user_mapping_file.csv", Remarks = "Converts a publishing page named 'somepage' to a client side page in the site specified by the TargetConnection connection. This allows to read a page in on-premises environment and create in another online locations including using specific user mappings between the two environments.", SortOrder = 14)] + + // Replay Function + [CmdletExample( + Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetConnection $target -ReplayLayoutCapture", + Remarks = "Converts a publishing page named 'somepage' to a client side page in the site specified by the TargetConnection connection. For Replay feature, Capture the first Transformation. " + + "Then make changes to layout in the page directly in SharePoint. Finally, run subsequent transformations with '-ReplayLayout' to apply your layout changes to all transforms with the same source " + + "page layout. Only applies to PublishingPage mode.", + SortOrder = 15)] + + [CmdletExample( + Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetConnection $target -ReplayLayout", + Remarks = "Converts a publishing page named 'somepage' to a client side page in the site specified by the TargetConnection connection. " + + "Ensure first you have captured with '-ReplayLayoutCapture' and made changes in the page in SharePoint. This cmdlet will apply your layout changes to all transforms with the same source page. " + + "Only applies to PublishingPage mode.", + SortOrder = 16)] + public class ConvertToClientSidePage : PnPWebCmdlet { private static string rootFolder = ""; @@ -214,6 +230,12 @@ public class ConvertToClientSidePage : PnPWebCmdlet [Parameter(Mandatory = false, HelpMessage = "Specifies a LDAP connection string e.g. LDAP://OU=Users,DC=Contoso,DC=local")] public string LDAPConnectionString = ""; + [Parameter(Mandatory = false, HelpMessage = "Captures the page to reference for layout changes")] + public SwitchParameter ReplayLayoutCapture = false; + + [Parameter(Mandatory = false, HelpMessage = "Applies the page layout changes from the page used to capture layout changes")] + public SwitchParameter ReplayLayout = false; + protected override void ExecuteCmdlet() { //Fix loading of modernization framework @@ -231,7 +253,17 @@ protected override void ExecuteCmdlet() { throw new Exception($"The page is either a blog page, a publishing page or a Delve blog page. Setting PublishingPage, BlogPage and DelveBlogPage to true is not valid."); } - + + if (this.PublishingPage && this.ReplayLayoutCapture && this.ReplayLayout) + { + throw new Exception($"Please specify either ReplayLayoutCapture OR ReplayLayout, running both on the same transformation is not supported."); + } + + if (!this.PublishingPage && (this.ReplayLayoutCapture || this.ReplayLayout)) + { + throw new Exception($"Running ReplayLayoutCapture OR ReplayLayout is only supported on publishing pages"); + } + ListItem page = null; if (this.PublishingPage) { @@ -454,7 +486,9 @@ protected override void ExecuteCmdlet() TargetPageFolderOverridesDefaultFolder = this.TargetPageFolderOverridesDefaultFolder, TermMappingFile = TermMappingFile, SkipTermStoreMapping = SkipTermStoreMapping, - RemoveEmptySectionsAndColumns = this.RemoveEmptySectionsAndColumns + RemoveEmptySectionsAndColumns = this.RemoveEmptySectionsAndColumns, + IsReplayCapture = this.ReplayLayoutCapture, + IsReplayLayout = this.ReplayLayout }; // Set mapping properties From 30cb6b44e6f14e8526b32a94574e08fdf57b1a0e Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Sat, 13 Jun 2020 09:41:50 +0100 Subject: [PATCH 008/130] Companion binaries support the new feature --- .../SharePointPnP.Modernization.Framework.dll | Bin 850944 -> 865280 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Binaries/SharePointPnP.Modernization.Framework.dll b/Binaries/SharePointPnP.Modernization.Framework.dll index 071348c1ba9597ca050f42320ef3f15aa3d5dee9..aaa48882400b64f1725ead3b3af96440dea79b82 100644 GIT binary patch literal 865280 zcmeFa37lL-wFi8syQkObN$&Kdd)CZkndBySCJQ9clN%rjCWLH&>?9Df0SS;BZYO|* zi9uvh52mjfO=-RgXYK?Cto*eO= zss&GuIP9d=h4yuxd!o1O)b|I$;x5`=$G9FR5+VgPjCpb+~0+nhFP0Q>x$w9(QxZm{?EBI|+`$NSs> z{)F|b&Rmc8(UvY3%c}YI(U9c$30}cl0f6wvva_I_cn1E>Ky^*;__($GCMzxV27ctg97&WQ{Y8YRAGikiBqz_{{uF|7#Q-nGw@!MUqwlTyi0Gx;f<28lU#Xs2h;JT zVmc{2Qhr}jz9Tt4T};^-^7v9px#=P_{7keix-*-FsHJ#{a}+L9ZB~xq`X(mbd4#^UM$0cCI$7d!*3N2`vd?S!#uDqhpJkr)s9%!mEITIKUrFdx2@ z=mdm|eD*;;#rX9{u=e+o7At7Ttf4;w8g?>89^&5LL0VYoQ_lB;`SWF<{8`TO_+6KC zWvQHvp@2O3GEhG3pT+p~KW91fW#x<;QkY8RI^mzlZ({%ay36uILsh~{_mL#)GHSep zJfWJ|W~6`l9fdCgl(G9Jq%jILQ6rjCsY-}7alhKpq&FIIZ+{AI8aT>CVrC?JRc`Au zkV!|@I}j1ua;}3Y3mV6EYeCNdPOgNrurJO~jnh!V=|`uII7Tc}ZCBUh$1tneZky3= z*WekGvWBH^pjj?LzbtW|ifusuX|CTHMuSWmv77jow$Tn_y$o9WklTInqhfZnjxp*Y zJBKmOjHGwe2H#YNq24!)J&eZr#*ikI{Cp!Ea*wJ4iy?PE5ZW*nz`|7_BO11@!|#~! zpRI%uDO?>u0Y&zM5qQGPK;5}BKq~Cc#BXPfE)hz>A;UJJe!s1&gf9sDw(Trj2f1~G zdakWDB1n*#RA(%OCQB&#vp_i+&25Ebn>(_-onTso;T^*I-5;?v^}Rs1E!aiL_17c5 zVe1R{?a0Qrb>w;>b|pO@+S^qmvDhb(PV~+}>Jka-0KE2sZIzjY!9JPWI#S3cwpq}( zwlxnh=1`g5{QmSR60jDKjI}V3L42EqdbPJ%P<0SuAcJK-!!_|r47Z)J<=0@bmp`h- zz)(wC2ba@^By9^~u`N`gor)CP9o{PB9kvcb*gYIS zMyA@Zhxw6K*4Zr-=tz1jhl@Wjl0y6 zf?^t^B|%JVird`uKm|5-jE2SN9#1yrgAHpLLSj5cSztSC>})c27*RF?m_gmYRgEB8 zUWa9kAQEf@(aMb=YE%~+0qvXPKeA}eXw;=7+~q6^C0ZS92~jhuT0%^>gxIcHLM)SH zOMn(KljBipr7y$AbI%*2C*qZDHUe$qmxH&Bi==l36a?Bv!mw7b!To=tJw%OK zv@%1IG#jQBwlxGlV?r)5doj<_gIciPpD-v9jPAB&;s;Z& zRLsIqWoLJWFz&+qLCTnW5|U>k_DnP4u4WKMdtnU%9nhI4lJ4Hpz&Mx(I*W)E!7q&JK*w6=fI)G~4S`+WSn+z$0-YNYB z4Hhti8ia*mWFboyG!>Wl?wR=c?-H+;?@PuayXwQr_Y;E_E+}7OQoelllW!TYl6;Bq z(d8@I{I8PlS-UM?Vp6_*_LFZJu#$X<@X_Tf+5AtC?+{}KtXni@v+xy||H){$=N8!i z(MZp&co?CEt%##dRKawFwLXY~g?XMsZ>42kIqk-QYs^n;!R2NfxfFUlvE8%rgU;Ro z-PgllHRg8SacS7RoA3%%lY#vKuSGUx!^YJ5@@IYYWsG?69(CWLG!iNI{;t19O4s)` zQs>M@eA#>^!7@SbtNBb$&vF8dVhuQwDG^;!gQ+zWhGP@+n1?*JRhWW65Y3E-0~dO) zObm(q6liucp(KIgCPg7u8pKdh9BE1=QPZkD%V7SzEZX}tGAd15df6VVPZD=Cx$MX_ zZg~LG>g7)fO--FXQbufXyPJ`94tVj$a!9E-3};eisky^hVXr);z0q{nzh~aXl<2e4-n0#*gT3IMVeQj za$4Dhhf5QVD|={2{wttXxD6^NGt?Yv4iVd^=PROfTvF?Wz1r6pLq_NJ&&V9w`?K;E zOERT~)cfiFY0Bo}Xg+P^u$@06@RKo3GgD{Qbw=4}c8oN@pR}0yA4rQCf)+Exx4yC& zxFyZ>_?Zj91PXN<{$NNNFXB&(1Uw196Y@I%fA8TX2wxj9jQbHkUg=?kXtyPe;{k_- zD)V7)Ei_8VIv)ku0u!i8W`3zq%)I~*fBI^T1ncf7{6J6ahluhicT}v+nwOHGJI2^_ zArR6EFO=)Ame~iBu&mZ9L7Q{WTVVq(96@OKTCl0OVgbu%g@DAXfiRZcaV?6&%{bU%1 zdJ*o&5B9VJbbP#v0b7ngG^gtJBOnUrkDw}V6w-t<^YG&`t_g2b+Yrbi;B4}f5bRuv zxBN2-FA2Nfxw05-;cYdezl9&~5!7%xPnmc_YZ?49gUcm&IfL6Icp-ytNU(>&of717 zm6sjDWG6DXNPISe)oC9cEZ5fYrl;1&sXF!)mmHZh3l6mW+yc(w#1 z4Bjunzd|BjsE!D4Gnkj)s|=nc!R-t_B*7;c9GW5SLku1)!Fw27FTt-e_=E&+VDJwT z`~riM>Y3~!2G5k>W(FT*&_2_P4&!s3ca%I&@~)BR@!lKqJj$D!W&FY3XXQE9dr+P; zy!Ygp_h#f6Kgl~wo|gBJJlnm$$+N*5-@y2x-U;%Id$-EdNECfJT>Q!#p~OF-0Cr%7 z?H{05_$+$US@H2RVO#KD7=MT0?=bvPN6`0@nUpZjhVU^-rjMCQ#X176>lQAIcDEqL zheA?Vd~~oQ*hFR@TssnlV>*?CBU?s;`hh4=c@RCmmF7x@I*QfNo=yiQz z-YZDc3r!y|Gs^~USkF=Bt*qyTpujxo#1*@=Xqi{$;>!Lx4lt-`_wImJIvgbEFmV5l z#joxWeFk3(%GZ_(p!{$Ce^>r<`j@=D3oPySs>J{T_oom8RQo?E@By3Am--jOH#+~N zHO95DjPVWx1jS|+ZrAhV+mx}&4us_d>PFR@Dy)$ed(l6?Mpo=UFoJhqkT7kb*DI}& zz3cZ!(A&-a=nJ=uXoX2DgujdK5DT=BA|t!67jKWc<}i zr2rBD00x}`NB{r~3<@9t0FpjH0sy3ZfCK=54XBbx0D!a)kN^OfWhe{@0D$3M0VFUc zWL=HMjTy=uKNJdEsDh|59%E7lmK;bMbuyk5_Tk;L1en2NO`s(GpZbULJ*n89FZ3aGNa0oF`Ady z;8HG;j}&A^l_O6HB6G=)$jbzoQRT>c1(CVCiO8o3GNa0orvZ|wsjIQBLk)?W#RB$u z#13(Thl;!&k=BfUiQ5@pTURR!1(~#&?wo|gmq=E{xYJ2^NZklmERPD2V%*?Fyyt-} z+j63tz6veX(Ulvs>2?HmM!$yPrEnw4-m#f67FwEZ-Gq1V_edkwW+nr@ltBdTLae+P z_3UHeR4f^t4b>s;h9sWok_Oz126~KiRkRkv&U^2IPK`awdtaW@yhJnK_wY=4j`ten zIno;;&nB-+o^?{y;VsA@RA0Cm3}NyBWzpa(3kd)Kr>W8&5&!@!D1Zb2fJ;*WBme-W zAPOJ>0N^oF00{s9#i0Na0HDnWNC1F#A0Pn$M)&{;Kvp4RECc{mYWjLiZLxqAjXBX& zl(KLOiv{hr2vuybbP!!+{P#lE76PzUsE2^ikgA1 z+gSzGH%wz^-P?iTUIead?5sj7d=;Q%C~7ScsM<4FZ9I&8veJIsJAlw2dtQ$?BbcQyvnAD$oe``r0kD#M z3%b~3i?XnuF|rvsmMIr19EqeN)DIJv9VA^a4lQINYaCCg57j~?p!(*s$P?WH?XB2; zh>pgx0$k}Hi$PX;ET3rq1}qO_FZ}I~zk_$<&t4Jo4uQOTFmgoflS1B+#h1k)Z)x#m zQOH|We3=>YPA$Gn33-L$%UEgMkf3heLbc9Ar(GA`La^@qL0O}xn?_5h@SO^>mbliw zaS`e)L*lZbaKyR>DGT55lT)wN2I5OGlxrYuZWn10KVaJ7yGV=pzG=}P70+#n{)rJs zzFCb@F5(0Tknd9Zb`_k>pthtjjtH7>J7Zvko-b_n$&mN?$VcgAj8E7SXF=yjQ+9W=ub8hukECLj z2q@-|^;uwS>u3yFpOHY5cN0;x)}?mzbtA@I~g%#Zy{RXWsRAKi6Uz* zYOB5UbLIo<#4OyY^I?ew%jav753!KXU48P2wJ;x|l=2y=n+r#m1CWf*xqNaWDgpL+ z%&!a>MP?{mXY3r7g7F)*;FpB8GJbiWy^#RMol6)a=M~^YFkm}jZbm6!Zgw%EYU)B_ zp+ip7Vbe|pS0QUFBDTPmgqiQ-oQ@=2G4C^ox2wG?@UZTo&@ccb#~Ai-q`j^@t=g=p z;;~Ega?n)RQSV`3>aZA8zMry6#)x+ESS(uMRwR_#X5WE7#(;IlzH={fmdMgrUorj7 zgQaI=DSe3bOXE3^e_hqiVdx>vu>$Nh*jBWn*zQ7NXqWRED%?k=h*)f&3J=Di&ofI# zg3-Qsx$?4wOT-k1tb6noL-NFmh_3r^;f7#-Y8+KE3P&VP7m)HpYf`5u07oc{~gd+Q_)j z&gf0Zv2Z`+Yjyb(BwsGo#>*j`Pos>*@6h4>0xc};E@YBxkwp0z)OPt`lb?WQ`__b)I}B_khUuXog;RxsAGHe# z2L&n6Z9xj>3I#uE7ZeT&Qs9meQn*|w_))u{aA=SMH<*yZEkePM8kBcL)LPn zr)M5kQB#O^P}IFl-U2g8l_)qv6;{E=YVxr>)RqognvsYFY`aGyGLvEk6rGYqTf(=> ziqqvmnepJzfbrI>beaV-D7xt`zZKjmt>8Os1rJIqV2m}ms zXV!a5p0%FY#`tLA2S^QvkgB5`Zt+i-R!oVe+z|lih z58G$NSb)6wuk}OLh;msp`yy=#h!plxSlWG@atpf;p{zKl0oxR#xO#PeDAKd*VTx2^ zg*wA1gR+lRZSL~` zN)yF4?r;y^q|GQCOW|BmhQqf2&Nzkhg)$tz1#pyp+6WUjkQd(qI0&NlHh!@Thi?HK zTj6}E42N$49G%xyWjK5b;J~P1URRgl@GXF&>A(>Z;F)g$90W-RV?zLkZvh<5^S_nh z@GXF&^SY@Fhi?HKY3relH<#h?tv}8!WjK5b;J`d1&$pK0@GXF&`T0s24&MSe&~&78 zTNw`D0yxl-#JRl;hi?HKo!3{(aQGI$(Pf8G9FQ~L0yvt^*UE7C)*lB0Pk;{J`s2V| z5WwME0B4da*PUfJd<)=celU~-=yPtN84ln2{xYOKU1?%c`V(T)rcD_zq}?a*3I^=5HzScdDxHX5yn2s| zj2+cuxHFJv8RZzGKD!n(F8h*EU59L%F&@DN;eJrGODl{aA!&r8?vtb(F5e;oYAI6N zks`)VCGQtQ8~3R)BAr9k(|rn1b-GB7Co5>$j?}9uvrz@d2UiuEM;XmaQ zCPFf{?h6josb|Jx}5zns4 zx<5x~Od{?+i|6{e$T3xR^93F9>P%9-F>W8l$G)NZ9u~@XZg6ZxN`Eax%8OCBLb-VX zhFz7zusa;Sh=}_fGIf8!pY8auuuCv1l#TIhJNtv?RFoxT%|`_Gx2X{uRS|Zd2Y$*n zWA48rP-BGR7WRw+C#FtV{bmRJAF-If!*{$cL!;5Umns9#RmqN1%Bt`Jh$KVavl#T$ z!CY_1NMl{rI+!%W){D$6*8L#(!5exBHj!EA(L5)XPN=i=;2;HTwBfj1GlFC5XW&HG zFd*a1o{61VY_%O(Y_C-(=Gkg5UX8^XX|MAPGnTyyH(11SSK*clwNJ3C#tdE^A}hA- zsPk8G0<8l(-e1NO=gyMuuNZLA?bzC}zf=ifGq%Q8W21AmF9yTr?HJ=wv_L8AvsvpP zmNO8cb{1ke7`>uK-+OYT@#z=Twr5{`D>4C%e4J?pI27=;?lq%tY{iY`c3`%kCXtc7GPxy}Em{TU=hslI%(m zgUgO{*V$;_-IQI}!mwhub-J%1cdok9%`7)kr0fnI>G+Y*wTQeC45ai$B;wA)3~^uR zG4aMq0D%2`fCK=T;R7T905+DZBoY8%mJg5s^>Ea99FwtW zbw)gQR81~z#&hnQ%qDImI*EBZG55Su<{?-QOZx_jmkBYj_ci z*tZaIlrZaJqj=QF)JDx(_iaG2znz=^!Ts0$a!Ogg87#{Xb4cfEL-CW-{IsncfFB_w zn>F0uBLk0=O0Swd1yH;UjhaJ!USLxQGxs2oy2qz$HF$fV^m+_lA1=Ml$Lmw_IuV(5 zO~>mCrPwaK{d4_w|k=m-r$Xs=TNUpp6Xg5<;ACdxEDmH3lBm_3__>|7*whJb%+ZK9RWir z#Eqs@{z3th4FO{hMzztBve${wUUk2)6D_1cb9qBG{7h~q3BhdHoz)bnvZHu9yTD>A0uPFjCJ{aB5t z$7ENIN zGgZ8FgV*O2uVINUg|)_;2ha?zL=KJCNf^Ln`cMFaEWb;ER6KM5t=M}6rG+6#ohB_i zBxhnzEjorebU>3%-BqG9a{q`#qU^-^Ta&*LOkgn&m!rXC3>D7c$QpJ%HLyn9^$b{} z7>h>cZosP=KB(-+v79(^gZqcVW~9*?L9~=vZKmAQnJ#2jTO%1wOOQ!1S2Cj=UC}Y3 z9K745=wjQNSO9AddEW&jY`p^>r5-HE5_WHCZ7gbB2C3}_f`#wOS}D9^e`1OLjGvxw z!MVBVGR*m~DtbSCp6>!mc5$PEOx+SjHWSSwLu1qD6xsu2Xf<(;HS8e@a||%UUbw@r zp|0AnH>~(ZrO1Ah$B=q5OP5e>%l!+p6$lJyGpSlFDRbOYlrbTM+@&eXNteJ8mC|`R z40?l}aH-kGy|Xs2ShLgNgla|1hnpg!EUSH@ZcSUj(nroiok>{+QW+fM)Hzh=ii(;2 z<6M+$hV%~$(;A!tcjp6N&RmPN`!`V2%0@by?7NRP^uM{M zxL+O@OZ0A+8l01+d2jYB2MEkDhj)F)*M~EcV~ZY2RPGWR&TQ~ zjliK57{oZVA~}@v40j6Y@uX(=L0}R{)Y&-vCB4lx#4+IW`vFm@V6qj7X<*ngs(=@- zm|xtjVkC5B!orErsF5i87z}$F-8&)1V-(B<@|x)F5#{Xv;!a zN86taQ)qA;3{=IG5{wetf>mH=a0O)t6p5LZ6)jPAdbSl%{}C7de{5q`AajUx5*MQ} zh0NC6N60lUJTXb0f{v}(8KNS9&DQ;Wh}$T{7=sPQW{n$1&_F2dCR8Zy;w&scLtJ~3kohDj6?7^A>M$9CP!Pr)` zrK(J}K9kF?$u!`vF_&r1W?J%hLth(aquI3Ps7xcCLm`4zv$eAYbBz|WNu|q~*{qq% znoSl=Y}oi_b7r_Xy!%TcCi3EwQF&i*}_mVIKnV7gBU^U zIGL%hSW)$E9U~hII7UXmF)~6sMzWb^g4zIT^L-`xUy?D@4Yl7UOmmW%QFWuNdIZpV zjv~J!RVJdv%#o_2*P1Pv(dOvRC5D+(e02z44Q2;tN5$$bZ$bmt<;YCtr8~(;2bk;d zne)p$M$;bSVqUg8r5*z+V|*&0I*gT)y?C{oL;8+P6DHD`vF6xm6L7HtMKTQd!;1I- z)BsT9147Aogc8!C&=(uLbNp(Ed{ZPG99L(AXb^FMN--4DL(08wQMFEyf!T zz@CT)44LoKLcye0?uvw?k4G_w7_sO^BD*IcR%SDt>n{hrkCEPkfRY}3OUSYh!5Wl^FkGsykWrP&8!xbIADhNViwX5R_Bkg zWw%Zib5KW&!_t2%+>%qy@?fSvSkCDZkMpw(*iaPMhhtBusjGA3pg>AhiyUIE(c!Hq ze_Amw6Sxen{IOagg`RuRs$gim3069?ygCtcA{i&qtbfQ>DE9dbaBRUuvoq01bR*N0 zJR+GGJl4vMov=5;%>!2eOar+1#o~wCorZrxeoLv;vFTJ8SGQnFlBDxUo5W@+wPOZ7 z4FRT(0|hf#oRzqku_Wb^M`Z4=%M>qq`GmT*BY4qEOr4irM$Tv!?}Y;JGDGo;b>^^j zmG+m2rf8wlT}H=ILKh?jx0)h@saCQx7Yinm>$uVJnTRKqMqs)XtET~-RP$+X9eS8| zJ$@_<&(H_Pj^+$zy54reIiWS7UX^nl{aEf70g^EW`s!pnKZj>Eo@}NF8cq1Q2+y1F z^z|NIVQ%5x5%kl!_-jU3_4|nE!UNcM+l?89A){>4uEE+~{*Auq} z>stZuLR=rQ1U)tX$9SjLSm+a?x&qIpQKBoWRh+ZHHAp_7w_N!9cyT5?H4XYL61dVg z|07@mezd~ERdlzP00CpCWE67RGMKT0X-m;4Oh>#+QD%1>N+{D+-UM$S7V)kxLg~_J zGZNCi64J@kWEr=4XccRZj(FcL;&UpS#AOfcjwxK-D1AiSJM>XOy>Xqcyxc?ma?7>G zDO-F+2AAL9{|L!GT9rnLNundTB?~C@7hyif{pO@O9+_^!GKbobhUE=xNPC3c-bO^n zX2w{v(C_IMi_(U+(ZaF3buVRF7v4E+F{-jIoU^)sZzKv6@Th_R0YjYaPQ(jpd_!Ht zLhV9c2G*C>pM@0eWW2k35Xki|cTa>mGdkc-!JBw6*qbOGUgrH%2+WIHr4 zz{WfY_6B$ai41x&uH!+bdm*OlQ#*#>%I0h*nwB3$IdSbYg!^U=d`fknka2?XsW;>} zhpdergZ{ICGJ=ryCO;TLY&VZk(zfdis~aIKN4wMTbaBxMx0}nTuh3)ebilwCP_ed| z?0N!h7(25Q0&FNup_$J2q90@DDam4Z$J_^N49SKGd+AWqgial5o-k5}S|>E(pQlAG=;ujEHr$ylX8B{RmtxNg%&1r2Y?wX~G`iDZPSA=X)V zjM144nls%kX(ViM_eT;?OyMP~Uo<_Av39nt#{HO}82Mi4Els>}LX8d$S4F`DvHKg; zYdZ0!@0J(ku~JbOBSqoV6pf$WobH08O%$4ke&{_C{ zb3)F*48fEC2>%NzZY-X|@e+iG&^N~cj%$>QV;}KP#NVq3%mduVr_H?&-WRejS9eAu zMQ?J{$d5%tZKNv|ap!?g8NTTvZZlv~yYm5p^$r8P&(&IRcE-DZ%|-?P`Y;I2g+o1A zScspr4_Sm4sJM zJrVW;x)sD5vEbfLc3rJB96WbL4Tn{H@&*45{44qAfegFsaK1rFV-Em0NxCPaWOXSH zr(%9}bLt4E1-UF7MIe?G(fV=gH?fZ)WQe^4v)siD4mGgqwFDu!5RDmX1(3^6(=-X? zuR9h9z&j2PcPW#>y}^FTRiz=gM-7gQ;{nFpzm`m@i`P)1Gz_oOt!rj2*P5_!8IjB4 z%oHa2%a9EEwP^J<_qX~~S;}Y6#*VRYPlUWYMiR_cmxGFO?|e}J0Tax~|0e~)N-haA zo4)`MGpmG|)75R}0upUd5`}N0^H|6NQrF^a!Zbf1%Vv9+*{o#QVwg?nS0V}cI#iGP z6@<_XA^4T5%idr%`DF(i^{B&Xr>df7ft=OdPvzUc=&gRyTl*HhHCXhJ_Xxz{Q6}2u zh3;z1{Hp4gry;x=fB%j@zn`)HLEj7ft9bf0DdF(7i~aU$01lAcKlN?EVnAX)ABAC= z_?O^kB%XKT8KmlHachEuZ7Hx*VCS<3q?i4&gPyAM;9t_1ZN zJ|v6fg_}1(qk;F@>Z&bg>%`rq!HVwlIf-(iRzUEZhkFQ$qgz{fhpl$mx^%M?zx;l1 z6=_t}Je8K+h}?5q_f_rmcg4aKr#S!o-L^*+tBJEDju->U6m6)fSTB`}`*Fl?a}Q;4 z!yMMSzmLw3;&8;Nja2Apr2-^+IYRfzdw?e53l=S~)bE0%J~ePL{Iq_hkhQ?TUE%7? zAYqPneR%ZS90-e}MqiXEWeyOQ3y=SIRiTl;7PY5ac-=%+q_y9fW8C&i7I(Umbi zn1v_6bP^Yee;?Bb7~HYih;oZza*XSSLK|U6!iC6KcYPRJcm*#k?LTm*c2VzOh^?S? z2D}pNm#Ej$E!DjwUUnr|^OgrtmWr2I2YTvZRAh(aho9-G;*i??4;EDM?Og&X6*u*C ze~vL>7h_29lM+`0$F~tG6@U(;lB)3UE{ygLUH}Uw12p|el%XRFl>(2MZNb~D8Kvt9 zwvb_CbPH=CUw{;F30IiL>=*~{X|+GaV5_)})&D$xu)o;%Mb@X_j)aY-cfHeZXBZb& zb=*-kj_sfscjevDELWFcjho9Nfi_+niMXe-J!Df+cQr~ZZpH4+z(*%p0{}jXK|ve| zo|Vc~;PP=$x%?_AbN1!lQ_4iyZ=(&C-)!q>{EU%JZ1~iY%0msE5FP~jrUE>UAoz%ET0m9%>kmU)o2&a**g{q>;lUzZ4uzXVt*LO7PEVfcPhTSXZbb%wH`!w|q4@gu*l&MzA%dGw{>)I{< z*R`ovsl@)bckNwwOVygn2QzpnEO@>7tpWJ?V=l*nfQl$iCuC@=pdxxJTMlNr_vLci zhrOm``}AIcPStnJDKjUiQjX$B`S}b;uqRwhmk0!GL+m~9fvJBKuA|h)Y5A&8=o9Y^^%>azi5jhos z{Y-UDD#E}ya<~T15poE8iUD{F8{y6)&^i}Comjtzl2luJ$#ApTOug2Itw>|EQsX-g z)4@L*DJF(zvB6yoR;c-?>3o^7LCCr(rySTu)qOs_UIXB4I0=>r5l5IKy4{l6>_!vkh#I?N8cFK{Sspiya zf5m=2yk;TRz0AEj57Qb^)oE8*o$g(%)4e}To!b12L46l^()wElC(OE&UZ6*y>fb?? z4pgISltwZemS*y1zI)qXwNKnkx2kIFEbewMXNz?5a0VEr{Y7%_pRH{+$VRHRC!q)@8{R?zQH=4Va`x>Jky+sGYIB1RmU^j+febUW@os! zvJuRxo3%5W1)GwORk3>a?O(lMUY3CN<`PiWbT+iJr2CuuV=ZWZy%vPxejdf;cFm8O zAL~<})5_{|cCkKZ|5w!K?$$dLFdE3G`!Lcm8I~3i3D5C9eEtbIdv2C-b#@ z2tS|zgFl&>J3vFC`Z&-$uzLbimXG%HN~8UJHOwzikA>#^%t7Ws{YLwP&4cR}R2uCM zF%PL*7#Qv6snLFcIZuuD3k`FDdB7l}{UUP_NB57LAIIhjHHG2(B16FsH4nvrp@&(Y zk_k2kANn_N#H9cZGY{*AJw9-6BcjWJHFNj?auixFhuF*!im4;bBfEbHn&sN?hywMc z-(3z5c9)~fqf~b}+B~|`HO#qqXHRjz0IKS>LT8~x#@J!*7bS3j9;4@~(RufVnUWGc zynipV4`b$s7uh)CUy`Mfzi$xr=8tU0n8$R(?KE)B$WXP|T-O7*g2pn6$Ste0c|C0QD~uckPT z?MhAAAsb89otb68{dQlKRvh!pWkruG+^yPsKkbii%NOW^8|f37<>vCvWmIw}qq!?T zi&A(BvI}QwHqD);isI1tuj}cE0y2o2f+GQPH|WDz5-nmaPKpNk2u9W!91a}MQgNG8%fX&PK-Fw zI?+6_d!CFk8iBJ-&x7>T^s>PW!q4{MJbHMNc~bY4f!R{u95SoT)f?b~79G6CT+{tN z)uo|`?bYOyR`YblX zSl6)zK4E^M`)_QF^_jB<=pXCnVU~39>Ku65Xm0FWZkT7uBtho3nX`P$Jb4SO`2hm0B((fkesEh??zroYJ; zuo4zMuBv>` z26a}8_>5eG_b=laZ!E!??_$7zi{~7`eLe~Q8|W?v;U&ma7Nh~=zE3Qca*r7}wXR2# zPDb&CO6_2>ZUA6CUtLTblQQW_?HGZ}p}a3bV|l&!iRb(^&>i?DCIGU59yHY&Xq7Q; zywOOWn7GPZUJoEUV#m4L)<03#sTPkrav#cDpu0~r0&=?8){RK zk>5KY_on}o`))NSEjzSUINmB9MhrHw=Kggt*gYM^?`MW8QF;d(+w~Q-8?g-y8!v8wiHOVj zhd^Tx5Y_-B;5pDSXlj^zP`7Z88}C}-ItPfrMCj2h3y=rL4{OWW~f;u z>#%pD;a|I??^C2q1M!f!zW=Fm{29AQ|NULWL#Yf(ziJopk5`Jn0_8hg+C6QdCI_X%!7dOr^n6JPtxgBJ9zRh`qwIYl|@8W1zs89@O%X)7Vf7}7ND?}byNHUI~Xj7s5+L3-FUJWO*Jew2>9D1;VKE!K{+dMv6KB232Mx z_k0`*s%Imu_eEB>?DWuia@$BVVy_X(eM#7jIx1N0lAJCr*(DNjv7ZSSNaDhPX@GI7 z+J>>@jpD6VcO_u;lW<(8FpVParY1Dg-a};OF42cNWx1e@9iwovB;++r#x%4xaOUAr z0JNoz)3!L!QY$sOX1J|M;VU;!g&0_<`diYQ&`LQTZuF@YaYr`C_wS{ zumz1D0O2SiEG7c&)M{fN5I<74>0rxa`<9lMlxb{OcFaX(7R!x^Jce`!`3uCx)I@eO zW-{pnbt6^n5k|s&8y)~UjHzJvHwxc`$U3s_wR(4lxR9&>7&XRT*sY$BI@Jliy_Elk?$K~AVXyz+7=p>_s2bfVT z+Y%)Uy&n+*=>wcU1hlc^QrC?tzJh1CxN3go6E$ zeDY3+kZ~;VvA@tXvYeVQT3@$2)xT~xnma0qO`#I?BP5hB7ec%__d@goG$dXwtiuon z=e%7%EE6+|q|b{FHD(^7>F0R zf$nFRgHII~PnS_uZLZd6wf#01k~6W#lV(V4>B1!_r5X;R?h0smUrpoK>JT*$C^)_Y z3XcLtrRW$L9(*XjV8t=#Iq1e^1JGRtx~Z7H))j_a+=!*~@GRh;cO8^_)V&m3MBUHH zFHA}O;TQ2c{1~t6_d$o{&=Znz+`11%=E>uqAdVxD`ve0#`7gSbH;BYU+xA_0Z@5bC zyv@W_8L-84C3wSauXPFQNz%YR!tS4uF^mj91)!}KV;l{VVOkh1?sBGRNx$@Z0BZ=a zXm0pe%?hhI{nCR0EM85;Yx)YL{uHRUuge(*EB8c20C+r>H+72sVu4vvznrBjCRi1_=DTZfRm&M2gm@Y2KE>k82i{#jRI;C*A}nh z_`na*NdN$xOj7^}0C1uYkN^ND`2Yz3u-XSm00698C>jy~01H|QAOQeQ@c|M50QRrK zkN^N{eSic2fGMdkBmlrVA0Pn$VA3iK2>^hFZv~J500kc)0RXW3TVY55fDJxC0sx%u z10(>z89qP)0Kn!|G$a53Y+nVC003wC00{uF(FaHXfU|vo1OVvq0TKXUlMj#p0H5>$ z5&&Sc50C%==lB2#0PravAOQf*^#Kw9;L|=p0sx%n10(>z`944b09@b$BmlsLK0pEh zTz)jmK10HC`mq7ne$S|1<*0KV)4Bmls5K0pEhT<-%U0Kg4CKmq`4 z^8pe7;6@)H0RaBZ2S@;bn|y!-0Jzx)NZ^Q~iRisXGafm?6am^VeKZLG@Ujn(006J} z00{u_D<2>M0ABS05&+=WK0pEhyygQW0Kn@$Kmq{##s^3MfH!=A1ORx`2S@;b|L_44 zD3!3#3zcpmCso4V`e+hBy5IQ#2>|ex50C%=Z~FiV0PuSsAOQgW-~%K8z#n~p1ORx) z2S@;bKluO&e7jg7g{R3ba>Av(g`Y7DnhZa~FjA{x{Mk<~0nmHb2S@;b|MUS80N^h^ zKmq`~=K~}Fz+ZiU1OWJ(50C%=fA;|r0N@`!Kmq`~?*k+Nz)l|^0RTSm0TKYf4C!7Z z0RZZJfCK=@_y7q2Q11gI0KhOGAOQffK0pEhAOQeytBIl^0RY;3fCK<&_W=?BV1y5l001L>fCK;->wG2S@+_%LhmR060Qa5(xkRuZRLj007$uNB{twOH>#V0HDhU zNC1EdK0pEhO!NT~fGv{29fT-3?@+{D=U2n}gpCvKnGC#8;iu>TJ(wUM_;YlKo;?v% zD_9k->nl3mu_oBU?z3AfSkX#X_XSB^4wm|m@_qPzT6IyMTC8a3e{*7x+Sfh|W3oVi z<9)+nuc;G*K~l~ANd*{_wEhK$Tt#t-UuiiD;u^e+3C^=nE%unuMplNZ0hcmP;bXd` z9j=^@LwRW=$&}^ogY;+#X}Ek5*ZpP*l9jIjyFV;J3eSQBojEdnMth0Nog^zb&nX-c z!fah#KzI;>h7KPZ2pnm%PfW0yeHg@50o2gXIeDq=1y2TV>v)~U$S6+z+BdH7o4tju8E zI5BJ(EB}S^47&#+qZ}qxT!oPprFoQmv1u?mQ1xMVHUQR3U_aGRgAb9iW_IAMvo#cW z^Y$Ygwo1}k3w%z!c;N&lqM%$EZyoUHKlf+U;`N?@sh_UKV#kn01aCew_&qucu9Qb2 z))1UpZ7cNr^W#WZ{8S6Cn)JWqglQ+f+LR8NY0LwUXP$vm|2Tv#4US$`e&GbR6+2VJ zXsF>_jP0r;9%u;giq8iLVYv%ullY=8+B});{RHf>=sY!vtqqOVDToI>c*$})oG5EM z5X}|7KrInS1fV<1LDlt{Xh4L01kaFCj@LxcXb#Gd@ND5A+Ev1dK>r zRmHCptio#nCS=luH9|Lnl(utZ%zM=5tFtcf;=;OQskuCYL!P)K63b6!B!FQp7cpo` z^osL3sy_hY#F9r||wR!es6^o1?49OHZMM1*j@5QL*pTqwmzKeHh!~hOw$| z-x*y0gk4w|(Yh+xIu1_78zXzrQ*g<{K2dewnT`q2f+3Bv=kV!@Y&BX;eI^o!kQUtn z{)=iUW}S#4(FW$NgEnfZ6sO4x0<3Q$1Y%v--|*!qNX7HA#qo#!nBFV<4~+wCs4!Dy zN1JsHk*5BK?aOn3!s|Qu?kWe2mtFnGOX2tL{rUAr%p!vw4Fe|sCyLwAI3Tqz?FKXc zX9-xh4UgabA(S{gPE;zXOuyK%b^%9JQ;0Oa@fB}2um8ju$J))yE_`B zfq{xNs5VP9;z1fyBpoahq~1e*VKbM}z&J)4)PE%!2~ER{2FCrcyBE?H2R&*+?%X6$ zt<#S~>ALpPkVYy!fsEFW;zhPybs8dD2Z%!r%zOLzi3l(Y*^#Py2irqHk-{ojr-2#~ zf)g`Dw@7$5lq4;jLbZ8Pw{t3l%i6FOlVW9Etx~I^eqHi3^0hEubS43#uGBai%!Uuu zIC;z80F4vvCrioFGRWZKd@&80%%;vGAzsE*G!Jm97v@1r$ZYY=1DqgcRpPubc2sDI zhBJ0ux*E3%tuSL&BMbuyP8v@uZ}zs7`nmRID}e^ z?AseuCs3ntt7_8fWoX!C+w|KMn*q-kKL*hoq556)ARI7ears>YwA`HPK_mRukJP*F zKsZ)R5;(paATcsPV%Pl#CznZrr+!OZjM5|wyUXWHnc2CZnXMWe>=)n4*1gFWhaB!* zfQhT>c&j0)jAdHPZk#y|w_BJw({kaxfvv+3yfh4j-8?Wm!_9V8Q@|WThrmsoxm*xr z<^ug&_kxnOq5zPrbg{ms{&<)xsC#>~~nWRx(g( zkY)j=Rvpw6Fw$k(0f$Uk zNSV&zj)jCyjXfM*H<-axfqKST#xW4u5sO;h{)DT|0BKlC)@s^9SPaE?v{V?2dAOYw zLjctdmzrK-6V7H*`P&(Y;v-s^k6}zLhSDZ(I>KO+%pI-QiE4?KJ4zwqYTgT*89a%M~Ad~U#Ub{^ih zkR$pRGK!A}8n^(yt(N5+IcPZ}_@p4Jb0b-h9;$i+I~!)0*!hx)gYP)_t~OSn@1sBP zj(E(jqp8LkOhTZPl5sTFDhs~kcDH&JU}5Qa))ILvV=D%%~bW6=OAfR_Nw zDvhS||G+|{&ZD_P9MU9-WkC)5QL@+|S@<6^XM4k50s|c#?M(&&e#MU- zmPS`~RDK5haBL(j!LZ@M!Tw|YrEK}yf_Aag;B)P{$wT6~s|3m~BeJVw+fU4BTLEX* zIKxJ_L7*M?z=ys2L?P_Sfq~6HZsxJ8882Qh?$JvaKZ45AI@m%IAl^vFihtRH^2I~*7;EQnLgZ=M2QSo0a1b7O@^>w(t;l)>ek=~L;WM@3~sFoKgTdu+BiZb@#xTrT97Cc;a4><>rfX~xbH*d8y&%l zVY}~(RZU_Y-peG6TfbogVwo;#L=N`;0Z@P^Z%kfqB6SbZ7~=tP#ajmSHF(kJY&8LN z@!Oa0n}$8NBaZDxxcYGitef%vUf*v)U1K0KzJk7ufwA~6hR|Jr-HX3C!lO`1>ZtP& zKBc6ipn>qUmP^4&jqR$Ba}TWw%eSfYtoE*=NX1FM4npRaU#q<@7hx!>t(?HIQ0a3_?GHg>*Sc5; zPFgNg#ngATVLzs&4Zz(oL;^Yefo=T-@Ju|4{abHC6ks=^&Nk|s>#=tqkPM?<UVLeZVEi7 ziac-nQ8{BjD>23xVT``pc#$!9{kw0L3W_VKp^7GFAI-gk;GBVyiz#g|rlbWTj`wB4qrj%hpVL()DZ5?1@L`3#2-lJ+%UN{HMI?a z*K(H{&N)a&TSmang?P&!g@gc%v!hd;Z~DCqM)+9TSkLsn5&w#M^V+^J_9)w0&?==(=blGLA}uw z_L_<>>9B_bLn;Qda_E>L#Wisw-vKINZ%_2|!``f7B*#Rwblu`HihO{U&t*_< zoKDG30%^af6(~WoW;}T2UW)r6(e5@7ArrX0j+CWP>1Mml1udLN14}V4&ab%_hsPBpNjnf?E^QCl-;I!Fv={q zuuEnxlJ%KB^qV=7&p)hl(kpK+ZAolF^Y&M*}`UEAK8d!7x)V!wl~Ocm#GWX5eOFyVPTK z&*Q2d`6#Q$>ws9F;;jLcpOUsZhlk^_;3IHvZAsFomr7UrMtff`7pdenK)I>|<#M6d z?8-OT=g+35c%H)_7cq;=+Lfk9Y%ha0H{=;?Ze-7lp8exudqZdJ#>8$n+Z%J+{q|-? zdw)|d9m%&SojwgND4yMKaR2Ix!IY`g;-HPXPeE;<8tA~)O)rG*=r_ZnyOxghHz`Os zV|lry`ji56k2=W#=rQQFB|ofpT-j^U<#Xex;v|ZPIkH#b!+iA7a>cltgJ7^pz^xtz zGyG6Hn~6CjxAk~A5%kqyN4vp7u{h@lfY1( zL{bwCob{4rkB-`Cz$)*6@o+LNc}&AFH4b!HZSU7s`)ewg=d4qfJN?ha9!=d`Wt@q8 zPUo1Z?A|zDF*!Hd@kjN|zbX2U_HYgU?CD0MOcrYF{fuTEnrh^9$Tk{uXoN9bhjK=% z4yEPmpE%XnoDf6#+mHfRhr)qR&Wh|g5RkIosfLfdY+WMGZnTlLfOz*nEb&?4}SU-e!MXE-%wU2z9tSs zIEgP)*i%%nCLGh#>v-Ex3!Vxb6ttpjGm$7hwFhe#yR4bSh&3FQ!db4j@PY*ubgQlh zpn!JNj^S|}A?sT+Xj(&&p;2WVifdHs#E%dbW38Gz;41L7sC)1^6O(%jI@zXM1ZPA2 zi3Ud04kIS+jX;NZZGNzSq+)3-04Vh?a;0JTiE{cU4NQN*uIc0Weq00r9|iVm!KQ6B zyf?u_%u6i52#fV6oQA~DSy&UPhRIMZXGxy{{4A-Lz&x<~UO;0qXGtg8e-eJ~#93R1 z7)GM~htIFuYu4SEuqE1!pT6EQ>v0S|iT1y2cr`H#%Z~^)tbH{yYdgx8XkXmot)oSNf%`JgWoJb!N zq3mVM zL7>xu6!`-Msr3`DrkoRWB=d3}Wu4$`Jo0|xMJKBKstRTH}_<2K}J2V9r)wvrl`R_>N!mf+6 zEbqQc&Z}qMSKT-#Yab+swReWA5(6UlusXf-Z199^3l_VIe*Ztmq6z> zA|0*B|7uOvc?&a8ik*2mw~(>v68ZbrH#aiRC9iF6a3UB0iS+U*osG_NO^z7O2P|(= zQcS8ntA%-9{k5gd&aX$R6a+f=lI&}TQ7E_mc5{ofObdg3*cr)MdQ2j#pMQPSEV!nC zchRJC+jXt4>Nh1y&Uw=nedn#stO7^}7lF=2%|L>_MNU6`d-HJTuet`9m-7b8w3kG_H{ski<~io+*M~dXG=*h< z*xcs4s8bNbxq&GnlH%To`3%1=5{BhDX^%{JW_Z_ zB1bIw)<~9j_#WquVBQOU{(8G}Yl|xH1%KK+!ui!i^+F8i@2t=ZC1umQn@2M5Uq1W# z2PVIR(uafli)`{r=-D?~>=QALU?LDvgM>?BqZ@|1*jF zAo9zJx~jjou4f#J{(kqlW5~uY_Bwa8^MWS2CVy^+bFY3OhI1uLwN;4x`sLRxvhi$u zljZ!!Xq6LzPL?^Hq}X`$pmEL{4Jwj(Ie(vq$oUfKEt_LA&oh4Y`Z(u5(LUJV59$cp z&H>%(g&5AIjY!cbDbAYs^aSR4?aJCN=MG&u0-YBqpFbbMqF*xP!imncT6ip~vyBvf zA(2hLKYR+yd&iuf$;^An=4U54pV9qm^oD<*Z)d5&f8Sl|Twm+DsKo-6IxxLBU6TQp!c5cnd~sc#%q{)dvb=MVPC=lPW&S4$(&pwu-oeH|p}@SHHSCo0Br?-l=w_bp zJhQCZIZjhJd&jzNXCIv>F`Vrr*B~i|yu5B2^E~g_Wz(FQIt77FJCXi$5X*e?@WM3b zSDFHg>Rir7_nbsNF`_V?CCcE_H(9b_5T;tvI8Hi zk$-&=g>mbBYv<{z{>#L|Y!>~q-3w=ujdR{yH^ZsZM5jLB&2S#oM2O)`A(0z|$jS+Y zkCBa5XW=YoGTYlZ8ndj57@6L9vXi^lG zHorOBdA?n}5W~4^GE#I&iedMzJ&<`$2!DO9^O)`+1UhFDDK1ENKe7KjCoS_mRa9pV zBY(S)MgP0|%S9~jvhS~5$h@8V*UooL#FP7DeoQj^+nA4 z&kwF$X0pqb*;}`u;nO9VaWRLA5M;pu{DP~vo+h79I)kZXO*@jiQ)V- z1A4a$y~H=(JAxdY{*2D>9NKo&O^HJ#BgrM z$d&)Dr2OIIjmI+YjrYE{#HrFL2y|{jiu@M@Y0X~_I@bA%?ljEH*+dGTkjU%befBu! zS^M4hj&*K>B$?-Zhi^H~S*r&~VmPbNVDkq^il%87E@hrK-2dKj&I+A^KxZ6!QhuZ$ zEj)6|QfH>7z*=_lq);u9kNv!HrLO8@e(>Hh7X8uhzjr*@nDV{%mO3|RqK~}y?D5Vp z-BpO;c!Ej%+apfeFYBfqyG zo%4L-iOzR4InKkKcbR9CMBek>Z|I)k$*W>yD8&5x9cl(xWKiHt#!jr#j zJejh2cmM4tk|9j8-p7Xw(6Z)yoy>+*` z`@MAw&UKbM+74|smVUnF|747{KT8!HLhEPxSs<2n|9PZiJ?lO!M%Bt{1H&`j8R~i+ zzq*U@&HQJb3H1B*NwtQ!wgw_yRii)M!=w0_&*|=sc!l!IKe;y1o#qi1j56pBQ zb-|GuGZ^(7#_XETU~Ij8*ZtPFZm0XhS0+uj8sI)ULL1iaU=n-p5+>TcrMn(vFpiDg z^?)_cy@Sx|PD{TROL^mVJ!D<(8qzQ8Qp74YT@0VUq1MCnv(cYs&9I(!3-NQ~cg?W& zxW#}rtbV+spWN~3rY9bzpU7d!E00ZgOR>~p;;x6S7hD$@RqIO@gRmH; z-tfR|#&_E6vRU-|yGP0%v3j}HUCR1-cQ?j&{PhpaqTlTwnmWr$ zb1Ozd>v=l=C$W?}w`{iciCa<9FRP4(3&ik=!4J%#pJg|lm~D+iWyWNEc3#;WYn^)s zZCGEhI1QIOS`2w$F8#c4e%V~BuWO0WdYYCxi>1)!4RfuLrgDyD+v*6Lu|{IJ_WF`l zZUI04wg(ovPd&UiIG?F-(_>|iGDL6Q^uRo8u3Nr7o%{Ga>(L_R9&K2wSrP5Ln5ppb z-_}0L5cM1Oz@t`A_YOjz_^3Bg!2b;SA1GEkx%f~JgOCNo){~7B~ zZUN_0wwA$WtXK@6sx@N0`=}3nHf$ZE{=(wns~L=)+n!uy{lP6dQ`etdW!>vKLL1g> z#_Fq!81)Swu78=qxN_I9m#tZD>KCQ4!Og=watiO` z&s`YbHnm5*O241jH|$mG2iJK*>y?JEv{Nj#I52F3^@eLmzpU$N__7$j`Ngo;=;xJ@ z@f)mro2mdlcK-Yg)(dWHM;odqaIf6)-Jp@L(a!<(M!aSn$ zb(!lN+i`0QLw%7LJ~wsZ2X15jT+0z#+_L`g%298*86fk>u-BO&(*}>+$iVgca@a=e zQ@7;)qyC7E)|dv$U)r$NFgiy%GePcdIO5L?+>_BU8?9&E7!X>0aYyV;v6S6-#3n1r zb%B0aU&8I!3Nid8Y0~TTb4B5Z*R3DH8NGLIpZL1f%Z(0gST`^~mC79h#!P&JelGoL z*c-abL1+bVN9+o*)cO3U-n8)As5r-{TH6`wR$^Fi+sMs~Z@p(ny-mNrI)D6IR_{V( z`GH$UzHN1ILrWXhbG-9JC&t&>lDC87?y4jOR~bp0Us9{s$bY~s7td~n`D zXtif0G*m2&a7MmoZG|^9WK^wJ8TCuV@ZQN2-)DUPvMu;N{l2c_`1h#bIwbn-lyOHDjoU0waRs#&>BPMk91(7eA8+C`_?nAbM(s^&CtIu zhK>I;YAgL5xjnemTI1H_GslhGYIS#=qYdj3rqE+@$1gjAAJEUdDHFF^nQp)ctp^#f zQn9pd?Whl|+g%q}wyo`~2(A%Br{%9-xdr^mjOM%Cr@r>n;C7}$hiMbHF+{UI4sNr0 zx*@u3-KcF=8`nMBux_P$0dep0PclDbh#Gzp{Lnhjy@OC{o7lk%nF{+}8TFwRa9yBZ zRz8FKwixdDEcg-q?7pJIcI$t?^7v1sZUdDI-*9~{m@1B2e_?gwMiE^oR z#_rFoXWif-G79B-d{I**c$ED z8-&&utOd%&(y;~ej#$sR$;YQ`{f$rQMlrOP?ETq&)CU8}#~Jm9{u=(C!I<*LKmEg+ z?=~Bk*WK`)g-!pG`)NZOlvsf{^3>P4KQb7z7wrAP!j>?xL}(qRPd~M1)Eh0_`=iy^ zHKbpbpXst&48Qn%|4;Pu<;V9Pw{l!dJ)YS6lU3WjpbhIFE@CU?j?%sRPtec3i}#+e zhPf3Wp|z5h?h#ARH);2??p-jdR&Ush4Hv_HQ&0Sh@m+Xe|4I5C*uVd0tDozgZ|UBX zRy)^O+OV3?*{Iw(f7#xD(eL*McK?@k4Wh`LL}=Bb^8v9`ba4N_ti7%a^vl|t4#T4* zOpI$996UuotEFY1vX&qn=)$Hi_n)%nyLZrrHJh1Zo!oJ>;lW?%=T(2*|BE%ywM1x5 zp{2QE>G0wGr>$nL;T_NI{nh#&g&;N#hC!zf*WQO<*}eTD)-*Q?9HQY|!kz-hYWN`G z1p*(`a0+1qfy*_VK$tFYy@s4zik*nj_gxweC;U?2VGXY*+$J!smlw{ygxKqi+uLb) z8R2q)-8JMKRO}IfgEWj0P7*jvLun(130$sW6WZ)8aHEEG2-^$XqhStVp}-RwrV&;b zn0190cpu@Zb_{$}!;>rze-mhF_#NR#0()zCgzzEED{zvA9}t!c zoUY+pgtrKsui>kNeFZMp@I}Io0$03_$A>$fy*`AO?ZjG7d6~L*h=7g8gfM@ zR$Jhw8vdCuDDWE%*AjkzKI0zj2HLb^F&>z;XcBDwI=MK;U|PR zD;98shFb}_voh!`*6>Zj4FX@(a6RGE0zcA_+kRqm1Y%Exn@TGQ?-F=g!zT$x2u!`& zvpJveDuInOe3-C}b&GuVFHwPvB4uf8ogIo0ha`Yxo1)`IX?4W|?C6_|F7_cSLHZV{NL;W)yV1UAy}Hp0aMTWC0x@Bx9AhSw2t zH%`#$u3;ZSZfpoTeKow4u!q3G8g?Q)U*ISWFCeTZaDs-#gdu^`G;B61fOT)v2HwiqX z;a9Nzc0Ha{Wdh4JoJ4rDzj z3OuS|Kf-K*r!>5r@H8f*gHFb^UMh7Z{7PUw4cim$6xc??R)l{R*iXX<;j;oqXjqSs z3kpGJoQAoCcMF`MVFux?0vBnRMA%Q@^BSJ23)orUM;d-l7!~-9hDQl=1tt&hqWJ}3 zHGz#Z+(r10D8t!F!w(5}3GA=oX2LfGj@Ixs!si7}({K&pV*+Ps_#ELhfzN8Vl<;vb%d7-+@|3RgzW@=t>Fs7h5}D% z_yl2wKy#26&Uu7CM;Q0E8a_mLNML^rrxJcBuuMbQCA(hWLJe)&{Jp^S8s1DeOWkknSQJEwG1%rG(cCv^Bhyu&coN8V(^m zPvCkDuO-YExKG30gh>Lc-Q@Xx3E{Vx#0@%y8g?N3Two6k&nMh0aI}U|!aoX}qhUkB zMFQ7qm``}Wz}*^FCmbvAw1z>#>jf4J^}>0k0I<8j5)F?Na>WXrd=39WSV!PE4G$5f z2%M+k=Y&6CG7Pn%h942`7r0$R?xl>qC-55$Hxd3xVA?P*oG%kD5!g(_=LsJY*j>Zl z6OI!&T*F0#Hwv7l;atL=0+(v|AmIf9H)%M9uz|pR8crZg7kEm;+X+u#@+Roy5BCB; zoRAAinAOyfA0v-#6WC9~zJ#v`EYKM?Qw1*8us`8#0yk)Q1z~@IyEW`ac#*)<8eT|PEU>{yFYs*$YYOb9VRJ&i zz>yj@Ap9rBZ9!+IhBXOy3w%+-EW)=1eyU-BaJ9gb8lKJvd|Y6iTfHFtNO+&XE*gGK zI7Z-b4ZkEDDDXiIcN1PB@Oce)5VjKdk%n6cYYRNC;hzbE0`o_CL0U`rJ;oWB2h;Em zg!=>z(QrB8y8`di@NvR50-x1z4&jpmw`uqQ;e!H?X?Qo`9Rh3I<^^dy;b4I!8jdEs zOyD35hY_|FI90=eg!Kik(C{k4G=cAF*n{vV^oxVeHyU;(JSfl{?FFeF;RgcSYIq*u zI)MW;EF@eeuw291gnY{{=q%MROgK^CW(`AxLj@kyuo~eN0yA#+g7kAuz!HJ2H2jvZ zvA}*B{*5q8;3N(A5&jEZHq2^j_zB@*fp2KIm2ii^!y3LxxItj5?FDH)A$Kzdonj6D zNH|Ae9}QO$-X(CHhEEcX5V%l7**OL{Oq(499@KCeVMJi^7%xb75{3mf({L=| z8FVp%PA?5_Av`K@tcHULKM^=z!)pjP30$vXFT&>p?$hvM!ubNLjrD?L5l#_Us9|fu zQ388t*o^QRful97PuNA^91Zgb@!faCXsw2sgnWN3=9DFAY3ZY9Pb6` zL@ppd#*VSJhW{j-AaH<&hY4>ISgzq-!d?QGYPgdyCUCQc?-Mo>cvQnT2r~tyP4I&B z3gJnVhM?0_!_|a;71%+;rwO+U9Hil5!dC^}t>L4DD+JEca0Veamj<1U8s0-#Ch(|+ zlL&7XXioIPIfk&0Kug0Bgck}NqTvmMO$AQSupeQzz^NKuPIwv*D(EcGuq)wL0#|6* zo^YqYbsDxJ{IkHV8b%1875J%!^#~soct}H@v>Cfw;0X;g2yYdbKgo-G5@A1qZ8bbq z1F*Be9vXg67!^23!=r?`0!L~11z|OT<22kw_z(Dof}r7tgu4VjsNrV9Hw7-z@HN8c z1+LL>4dG(~H){AC;WU8Qjo(qc+QhPp9TF|FBa= z-9mAm$m#S`dMGtF7Qqf*Cvv!-2%7IcI#ZRMPSo5z1m1>vjp9wIw<%pf{k76r)WOMO z-%pKWw0Q4{F!XIIJYQ4SQ+5tew^4d0br+?#Q1@1P1N9)KS5uEtdO7tZr58|7S9%8Z ze5LQEUaoX0^@~c6px&hPKv6O$!D7}a}ZHl-vi@Jr< z)2MqWJ%O70T;SIz>LH2`rkZVE`p)OH+4|Pwaw^I*N`Ymc(>2=gom0m?XPw6GpE0mr`{f5%hslQRW zjJn1>5+0kntcqn@vHlzOSs^{Ag$I!wJ@=^*uHrB7u+ zf28!c)cce^M1550UDU^w-b!8VJ_++C>I|jVQ0FVXlDbgoMbxd7o<-e3>1otGl%7D{ zPw7$ALzEs&JzD9$)RUC%PJN%!7WEvZTTm}nx)JrWO6O6pRXUCO4W)n0gx;p~57fJr zK0(^w&y%ODAO3*UG)iskxAj_%5I>Q+8%hFIM_)>eWh@Qg2jx z1ocj(2T~tWx;OQ4rMpt+KOpY6qi(Bol)9JF^{7WF9j2bHbdY+9(x=j)*DC!j^;V@1 zQSVZE7xgivw^I8b6n{5SH&A*FbqA$aQuk7N5%nOYXHidAdK&d6r6*7)KO}CBqApN+ zFm+p{`%-sOx;u3*r7h}_O1Ge%u5=^nB}(T}Z%{go`jFDUra_-n`UmRp3<<*#>Sjvs zq3)*icIy60zeUXjUOeA*)MbjVqTZ5!8p3=5Bf? zd6u}(_XC_lrMpu1RGO~>IAfLO%VEv}rRz~|R60z3Na-MT>TGfIR4Q}}rN5=_r}QD} zGNpG>FI9Rg^=73vQ6E)$4RyvGadRbgE2S4v_fvWn^(3XIQ7=|{0`(h8kD@-T^kC}L zx#DJD>ZVF}r|zb-MLksM7SvOfZbZFA={)Lu=#xtSK%F;F{5nG2R_Q&| zeU;u$Jyz+rsAnm?j{13}S5a?OdI|MWrRPxx9~JkfQx_^-M%`6un|g@SL#gjpxeQ5JE@N- zy@fjYcjEpA>PAYhrtYHja_YfKFQ6`0dIt3(rSGO*uXHK(E~Q6MA6I%Hb$EgJ)tkDN z(p{;0E8UKIw9--P8A{iqepcx)^%kXr)Q6Qm6@X5COx*vLx>)H$)P0oRMLkaGt<(#Z z-bB4o={3{`m0n4myinX+MBPm3S=7Cho<==Z=?T>Hl^#XCUg^Qq`;_iWUF~skvpaR6 z(iU|OrCU&sR=N@O9HsN9*D9Sxy<6#Dlc7&5{R4G_MdJPu>TXK!p&qI9cIuf*;~N#| zS17%X`ctJ>QJ++L33Z((#LaosU6h_qJzVKB>Iap!sh?MRDD_85_oqItbWiI1#o}fs z>JCb`p&p`iQ|kMaE}(u^=`8APO8cpgDSaXdy2g{@=GW9EN*|yer1VbesY-95UZL~` z>i3jhP5q71%c;#J;^qSCwo1>S9-#Ey)a6Q-QZH3{1odX62T~tZx;J&kQ{rY<>Q+j( zqwc44lzNiV^{5vs9j1Om=^*uCrBC^xQM)sgsw9n~SKMDLsq2m(tUy$0|L6dcM-5sMjk!n0lYmeW|N07dN|87b^`}a& zqCTng66!iD#LaosU6h_qJzVKB>Iap^H)xRml^#m{k<$ICk1O4iI`3(5vlDe2rQ1;V zP`WAgNTmy?XDFRTy+~<4^?OR=qdIV3X&!6o)LAL+;~ZzqJ1Na`Yn{U@^rkLUx+`^w z((R~wDIKLAsB}GQesU9G2vc)%7dl8iT-iBgKyxY={99_y;6fjwo}ldPqF$)DiA-mZ63I9SpI^>sj`@Om*OEB}Sc? z`YaZ|fA;}cnVc!@97SlHygwLYawAtVMt+>SZR7i3?gyK2WHr81>{zfMwjzCKDfS2* zm2law;kzjI7XG&v|4rVBBlhK+P9H;@3H$@c`In}_xxy(liHyg)w2=w;FBHJXKJh({ z`fz=z=Xy?VZUk98fOY_=^dY3?osofXLZyT~5)xmcV65%_uvb(+?jnNn9B|+^zB7o2 zrXr9l-#WM->A=IRYv9WQ{>h&t2JssP5${eTh%|{zMCka@v`{!0ZO89lQKsN~Civi0 zQ`p5R;rt*6z9gKCudyb(6fT=7_;Pv#HjuJzzIYwqmckdTaOvg@c>igl_y4T$o+je` zT(Tl}raq+cw6-6_{SH{8>8IQ7JnBkmqbm^E3 z>$SUAF$0=mUl|KoHogs}(&kE*JF$#8BOG~O!!T>`dwQX9&!Q~ws~Y$$cu@hII_^1T z*2r`7^S+h{re`0Oqu9siyv2U(MK?-u_W4~dpYtnBaMw-VY4wt}W(}{DoT-(APqK&0 z7%K0K`7l3vE-A;#BwM6?A-%IF9E&PP-)u zZ1QLDG_If@^E@b=LX!k<3^Rx6!_TFo9OZ=5<$Li?-D zB_8zbx*4(3)4{EM@O*G&|25&-hFLrD!Qi9ol^#rO{a_Yg7Q{{H+LaT!c11$d(pz2_ zB9cXXrD3FJc{}71cz;mkJ$~7}WT^z&g_CzDCe-&#s2to`IE5yWyI9@Sz;(D@^eVF+ zKPDdv*Eh`i{JLHsyMgzm;xImhUc}E7H$crxPfNdmONFqv55GoXj(tFW%?9=!3Of%D zA=A}UEz}CsMD7@ggM6zGVHryZju=0#uZ_1j4(I$!t9k|sfY6hctx`r zf|oZSG6_XGoay>B8N;^t{P`oJfUY2tohFgVj6!XOI}+pUOX*=);5Xaxk@h;kLFBmJvmIAqDV2RM7lQ_`yb1n@R)1(7C}fi_Bs((=&~4hv-`5a=L>Z*qFBP zQhPr*AI5p+c_sYN1U?AbBHqkCh9|+6qovuhXi&m!3D$n7{J?$$FoI^YGl9Rsi_*qO zw8-6TqFVTz#RzeHs$=6RM$x55U@_dvFk8uIJ<2~qW=ZgaK?%1p+k{)2t!obGR*29R z;ja_^uEO7N{9$trKV@Rfz~7Vjdl7$|@rRD5@eTf}A-~nYUo-r5z#sZy#&G<>dt(xQ zXX0-u{?_8}J^by%-!c5*(s!@!;F8I3&e;irefxr9k_dEQp#NR9Ui@lBi5Q}=@ zNE5_b;t^Y;SV0_mN};?sG*h9Pap+Ek^5f75g=)p2s}-sphZszRqD~w-PocVTh{HOD zH8qX}T^5RCKOhlkFD;I7SVxu~$F{mGBaW?eS!NvLu#Wd;#j#l~s~*S7TxP~G4(oVt zb{y;LvYa@E5-;{@#IdN$a^qN@%i@#W@3Q!G=dh0c#wYw9m&HF=bmPTd{L@(DviQfb z#AWf%gBh28)T;96&qMs$O9nKxd^@y(V$M zkMnw}l)rifs0+?F&o7aL44SRZ1isScdkV{UTf=N?W9A?fz99A$BXfa`F-0ic&M@2A z%~%bfP=&%V!;CrmSh4QMrTQLkNsOahvqXK5x4mJuceuAoKF8|>|KzI39q=Z;j*ARo z@7Xe~q8s1`>aX_U3w@?nNk%5HLAx+MCgz249~QEIVoik}Jlr>1*v%0_r#rNK!6&|! z!ipe*hV3q)_5;-CU`x=dmUyiy;wfh7%IpG|UErDFya-9EqdKX)s<0P*bsI+3#Zupf zJ7jk_lN&*ANj?ze3_4qIkWejHb9Xd5mK>4X8t=^UO7(Fh%4g8YY*AVSp&Q%J=_M+) z5E`sbHtGj7vYoxObsO0(-nHAvUgS2io#PwXE^&?QMU@)asf=T1y9Hc#=A11mUektF zcLy?nYISi(OWfhLyPXr-UAO&HA@tf{7ph?XkG04DK9+VXhH=hsZMi#oX~~w`jUj&6 zr7*jg7yZY!8@rNx&OW4}WK1=9W08rdyjT9yufL*)8bRKRczF*4RmqnZ9TT$<%tEf2 z&oS4+sknKI=3OxT!0Nv~a@5869fn_y4ZVLUe#2;k3r?4E0N02g^1{EBmPne|BT;wo{x)D;5iry$MXRCEDxdMIU7?c z@th@MGwl8$j`RC!z2FAM3i!@g8K-+Ndm>*%!za&TipaM)Bj`tXvn8BWs(@-z1oJr< zL!{w5#c5F^$oZjymPy8o@DqJ{e5bfIo@Xe@{s^w1h{85Lcd9OJ%&%fR5kKpL{z)Ls z2xefCC0bVc6EX(BpO$JSJzl<#z2|_Ld?s)LxD@kPp~zI!evx}v)8dPk2!EJgM72%v>0yKQl;}tjSJ^V8j$E-_KC_ZLAUn%+$Mh6+v2tY|IGgPo_3Giv`azW+y^6 zW}o0S95@p=d6u~0gNTe9zF}C@){C3^+M64xc#qE-DTEds=1}_%tdFy@Q_kd0z+-ZA zep0~hz)*b5WN3~^s`5??m zfwKl~91^n{zHg6SCUX#zKx&!q&mgta0!6`qo6>&F|6wAJY0S4xSoZN6jda3WBjwVd z`LCd55MNI>477_TKD>AloDKOaid|Z;bQVIC9&ipJcq#U5TsW)qDd#Yx*Wy2wr2@`3 zu%T|XQ4`_Au$T@(0@Q1<*uEjo+HtXlQC`R{U=ja!b~zvKI$0ZbGqU|>xcj`C`hKHi z<$x1@nU=)C7tUb`k6#K_QnWrkpUA=#M$3_%EaeA3aU}!h%)Z6Dkav?3@~-|aw92!G zjNmJu{1t6;k~GbBSGYWRFA8ql)YEa6!i!;0IE5yWX{=}N#ebY* z#uqgCd1U(%n5W~*iZ$c|mlydW=&<4W`~2l7PMj!b7)IeCPh}YVc6Zp9kIvUcxX=X1 zvu7Q=9)E}MhqVHO%PT$bNAqp?{jGoAJ;)gnZ(j579`}##(XZIM07wu9F}ESor;~jt z!i87RD|pR#{(J?`kLU9%c&&I|UcuwtS3c6F(b@G;hACA;qDVo!&1V13O@>yx`788U zVyE1Uw^`wDXD>W&{kwY^ckRo<-)gg}FVP#%89XMJ=Y_hFo_fKnaB7Mh;AoArI2ART z*Y%a50!(V&5IIo<0O~;nM6~w#b8;j1bH3VWj*BFHfjpaRyu;|>pD(h66W9C<>9rL2 z6zvW2n;f}be)A%?xWDKaz&tnd0NwQEMbK4}>qq1|H!|C`ceDFD#x=j){dL^mJKW!U z-CxX8!=11LPzCKC~py6m5iG>Wq6(xA>f$xUp_&4;18bl;$L#le|s?P=Ig+z#;}f ziwe+_AaW^Fi?vt3YPd`)zlJ})NE_gCJZ|VR{**4q#98?us2zQnMLMw2SdTj1vEZWp zDpbhWQO`3fMMD-!OU^HauUzE}q(oN8Qw*lq5g74BWncLKIA`onODO^kvliWptGI@< zxlv8p%jb-G@2O_eXUs7!*`>5fnI~1cA>XpzMcXO={x_wKFInQmb>NV3eNDqa3xaki z@(UuD*kVSmX1ZfxmWdl#io^{CihbzN`pyKNMwCkNbV8BKSx5WI_)ORU<)r&CXsD?{k z_6X)!qt)`HGf&sPtm+z(3WK^g;)6r!KIew@=mtfeLMleChF=c8sWqmKT872~J0`&b zVSI_ah_2oXtC9*8F(Xp0!g6O?=CbU6Oa@rCXc_%1SMf}`2lpft;TCr zZXW`G*F1Y@gXHBhAVGbU-5noDoGB@J>%kiJPeB~=+-H{u?QUmT&R~7wMt|Z8? zMV?A6^;CjkETyRlG@moEihIoPd9HgZ7F-T18jZ3*uM&Egs(4f&wq95Q!x|Nn=uOY< zipNc)vZT8sK%D#z`9{XP_E_`+(dWDMw|iFKtdDcXd^u8i=B8mE!k@hql3fl44)*am zw{3Evw?QJ$EpbdU#`s)mR-n?%OIl?)5@TuyOW5;^yWK{|E#%C99S^4wRMD6!W*fBG z)m6;i(q@)v zV*M{dCoDICG1)>W_=SHR9XVso~i%^?mCC4l)68?M<$a2?JzqUW8(#fn5b zRSk{%x3KEj$C;~ca1X#2H)L4sEb4L=cPfuNo#PA{qa-0oaQMFth?#AF1DA5o__&N( zG}th+o$et77c=f5ER#lyFz8lD&5jqDMMY`YOok{i;^{EW<30f+ov9L!m z)yn!d%$-TkcrGTiul|(m8p=}S_joMf+&t_?+TS(IHKK7fsu|TdO~w@``f(_n<8$nH5`&8I5s7~bp88eHo4Mhd@m1a` z*2~RcY7b=tSFf^}{Rd!g&XJ8#C$m$@>ndY*!ENHQ`>f7-Z@BYWaik8jU>CDX{F8Od z>P6;7MLm&xUsQ76%*nI+BAzHp^ZCrWnqAQ=A;oHS$jC#?oT=|7h6!Dd95_|;y~^0E z$>(sfd2vYx%=p8~WLnwMN_Xh}_AGc(gl3Juc0YI_4QgKaQuERx2Y2kKa>pFrp@$QG zrdJQM2PT}&9QzuE5x?sY@jSafuYAt=?e=H*3~!G~#E6QiYi6uvSJQQiHrnP@h1BUx;UyZM~@A0*y@L+toa z+}>(0vsV%4|Jg06;z*wB2oCX5w_M1OTwz{ObQeP6-1OqU^MYped^JMq zZT7~_JmtC?^d(OyC#J;|_s~ zg;Qt}xeu8$azFkH_cQykn!Lum2Iax*Co2)o?~&rN8c|e`fG~@eP?7XE`xjY>chO4t zTA%Y8oG`DIdOp5HnmOjRDvEhw3{1_dS%L?c1JHcOr4k;{gGf;Z>^k$hq7wJoO%?kl z`Y{kr4OC9~oL}hMz$(5W*-Fci?%_-P_6*m->&@$n8X;HR^kHJIQa0elP`ZAJVP1l? zEaOA-+tcyGfDSSTm3*r@0%skD-eBHP@*&On0NbIGurVeHg@ew`p)huZ-fZ4% z4}%|=)11=jT6;L8VZaX~-kNaS_#r$vzPbaL}Uw{&tY!Yf;0;A?B?#TY#1+89yJk`YZu9{In>5`2>~NK%uT{vbC`V#)70l& zxIHmruwmKcF}DLET@(~tsSVwFA*ZyIS*^R@p6O<_k>*I$NW9` zhrOPa?3vxY2mEE?13rVWyTzF%syI(aaklSdhV?n)D!IfqsTiR`UdGP0K=@YkR`mQy z&m+YdHQ`a_C{#vOx+US;P|j|%Z&hjYBHT4^t6I*Y7oO$L(YSN8nTuW4qtxA}dH3k5 zcOyNRa<`ke%g{9i_tl8BmVo7i^Zo4B1j4py7h%#aXu7jxC>NtpVj?YRm=CV5&HUU* z3%S(=GV#LLIhElCt_S4iz=UNJs^H6Y*X^k83ixMn*k~r&hth(BhRM#|&EL`&+IgbizhTq@gH-pgqHx)Y= zK7$@m!!Yvj+X&^IMq_c!PS=H4@@EC=@hxzyKg{aZG>q0R=Q<3w9pOzeu6_7(B$I`r zMxZ$u)9yc z_=zz_SyLUTxaz@7lIBBB{Znm(+rYZ~8%*%3HY1VWhCYU`3^S-nJU+ErqTwF73HuJt zVyK#Im1PpcS@E(QUK1<|V*W18z^P%WaXojCxXfmzspxk9%+xHQ{AYudEj%N zKtjYhYW$xWuyfWGc;mI?C1gKz3sUV#tc&xa4bUyc0524- zX_z(LwiYuK=t#hydEPD(Z0{CF^5ICna-^1F)=F@smgh)* zg(LZJB;T6_ILia~Ie}e?We0)C2p6C)R?uASRjHS9Uau7CQu&NwDd){qx&Zt5FF@=t z6J=K3CKK|hZ8B*_AXu?ECOzRGfE4td)LzGYqk1#7|0Rt5*5lyj{dCi7<)i2_VLSIw z4cLc@)Iu*ZE$B^(V>9+eMlgbHno(>@iR8f0Mne<|s^u`LG18KP-fR=+wp69#j6v+( zP8#+q!S8~WVdL+35*Uqhuj6-cLmZQKahqYCM-U0=!uxH# z#2T54;Dv*pJ9y0=L)H-7<}@o~rTUBq^Kq+KP0?0UT&ox`$haPRM@sz3NE`P?cCa#& zuB?|f6SMa0SrvP2zO#?cp}QVJ`e5Sj-=q(!X6Ztm{oVy|qEg!K$o71RTnbaKPl2RX zPSrd|FfRG;oytFlQ`mbGT7(PB*acwz3<)DQc0+neGXr6|ZKo(e_2L zWb+QE87ftQq5oF}hR%_`Uh)3z~koV+XH4F_Tj&YLIdIa~a-e~yMX-RoAE!CC5%wOfT1BCjr-(0J}XVfHE zM_``~^@ZV2^xW7V!5J?&VB|(5gwqpg8W{qm&iFyEF9$s|cUBZ#EUq7Wdt9GjKfT{) z#u&XN#UWC=Qc`RtEGGvsqa|xrgJDywyS-cW(3};((j9j13s*-^zdAa;?2BWjH59%k z6lsA=_QiXEU^&3V=xqx64WUwO*A1olb8pSHKY@2mg3d8G=P$hn*q(;}nj~qnKoI-B zS7NrV^j;W5?!$jZ^X5K(egv<};I)B&Vw!K_Zf2?bX?``6QD{8fmrj4t_Y ztdZd*17DzauKgmC3aUV>T3Y4T@=R;ydn&J{r<}*&o&7L^7qC|=N1PWb&`U0Qr7C*8 zDtfmn`b$;BWi{7FaXv|2B=ZIA7w8#c;q0xr>3J0Z`w#B#D*gsIvIyCa;J?UBl$5+P zK8)e&#PdAv`3c#x@n1%2IB7pdWB5P*WeOfor{6!sgEz1iYG7qWJrrE?-I90lJL9)L z7rzWBi;MlT5i_q%1H3~p2LY&`Rv)fckH3Mv6Vxi-7$j zv-ej>6e;b+wX2x@?3uwm9Q}q_#!{{gei6asf6|C$ZN=eNa9-& z<;5_upTvJ*Ob*D!5?&<7-)L4$iE`v!-MtNSwokz>LZ0l+Ldbg_+C16DQY6fc=q;X4 z%jkGYyichKKIs>WvA+=x4aep=q&nuNFwN}N z;hO>U!gVSeFoqT9BH~>ZBh|*M{efJ21-vN6ycnibP4A89MtkLrXa{E=j9F$sL;GeDEJ?;qQWX<(ayZ}&gq3g* zpD08qbjtEglxq=CLT3SNxEmtb3}dggy2pr~?^;nMdlT$cEWc%E$su2IP#>0qvm$Gd zVmxA+2PFno9L#{6g5vDPo%XX5%4EEG?S}F&se}@%H#kL6urEHnA{*&uYO0-raB^Xy zfi{z3Y-RPpO0s1KgXcK z*%R7XOl(R~aZUr7sb<(ljUIaVuV@yf6<3+H!mUiW#hnK{d=I{;n-h)Q{A-4BVnJ9o zoJfStY}gisHFX%}m^tdcM@HhHNu0&kz7WR%;AqKg*H&)0RxE^kosbL#x#8Nm;X1J` zDj6ywg7lbN;kfd)5tLERyLH>W4mRe?L+ESHuqA5 zFWK;Z3B}ngdFfIBJ8nAEL1^%zk+Q9d4$=Z|r?juH(xSk#SqnCCte~=~iX3d>MU?jY zP&;4&D=F3X;n|d;(GIcafRL)AIoqfI!uS2-Pi+lM##tZnO-c^${3C8EoI;bxEH)|V z!-T?(qF0)YZ1f9o0-k~M>5%zDNtIg=m*eM8Fjhgv#adpxjQ>2n4jMaN8mZ=FC1%AN zVM4o+H!B{P{B2^eYE%S^CULtA!D%==boryvS@Mikyh|DDxi9U5daQ9nL$dI93RQI|siG|* zzX;dZ)nqKeFD6gqANg)vV_b$NGm($P^&Q|iaLC$I8g_soS=48Z9!*Nn{?}i{Lp%*~+s%<4cmL-GlZUuoMoUl^NH@eP@9!9@>g}2oH{eh~~oxm8rbW zzy>bWaH7gcpW{)2Ys~tY$vnuTi(KTJ0iN6;CUSB|IK}Uj!bmj?n3PAuAk{Nsz%s)? zvGocgD5?GJ2Qu01By z+*>$=k)AR806Z84jb#jbY`G;mkP{B(gi~_Eskz~hFPNHbWT#{Yvs1G}5fnwFdy3b| zNH$V=7_mGZrZbo7(W_B@#udGc*xwMz>MBc^W_2EtTQnYLTyi{J z(MkmBMXrl$>7)aQb0=BXhf(yhZ0sHiMdq`Rze^U5*2oS=-lN1xY+2aorV1tC`+&t? zqDY3%O_g+=_iIDtF`}3T)Oh(cqe<+Ya%y zs$2wD9+hgE5GJpQjh32Nm_#E@mlk3AN4b;_mv}lYT*^;yDZh$K`EJvLB_`a2BWih5 zR>DnLi8sl^sur$o)-KA2uX@bEGKSQ2+dSF2&4X$i;=r{Odn;0o^&Q`z%^*P;`~VEO zg|EO>+{mYor_9Q)eI_%0R(3{0{g)R)-okAus&KS8&1NtD-Tk1w4L9TT*>2hOA|F!L zH?r$TwnIq?W5erR@1QZ?^TgsV;YYak%-m5C9Qhcu_$7p--kDtF6YsI3e?AO@6NKdg zWX*>7y%xW$U-^&x1N@x?LqSU57&sZ9fgQzP8Z`gW{%QPo6@Gi8{Ce(i&9)mDS|Qe* zD_Kyb?nG~o!@;y@O|Pq;BJs;eO>uLqduaC;3Ecv=2WmW8!)RPmF{V2Pj{28=JP$vT z;)+aycd<3FSjop^K3cAkVx2N>1b|8b2LvIEDlezF} zQ4RHLbEN0>`dRJp#4RkT2gFvK9k&yfO2^#i=ysDXVxt+~O{z$b`o`wNUV0=OA7g(Y z+7CP`HL425_#q%Ybd{t|56U>kS%(C}c@i9=dZCknL`@_V2ReD~KqqyXy%U#AKVoN} zcV9S(RcOVam16^(R^nOo?l+TM2hc|R$k_=xP%(y)A=e2YHT)^AixHT)Uteb7vX#E% z-Y8a>7;&q*vLB4>Pb7G-I8s|Yn=@tFl+Iw=4t4}5M%9@CEAChhZJV=N-%(sO92g`N zA?w51W^GL>$SSUWn&|3DZN0b{cUOvgTpZ|UMN%-(Jl&j)4Z11r(?~wxK1H4+p`Rma z3jK3yBqEZW-TP#v>6xfW-8o#ZyVum7C}27;49nO4Zf?5 zN3|BWfy$$bR0+3NsLhDJkDdN1$sMU2?wvZ^=$7hxdH%B-?iQG&k#N&yT)11RaPtLh zgu7(~qnH3+uGVhg-D!sV2Zp<~3U`Yt;SPD}-9q2T*Q=|9yG7-2Cx79U6ZDz&y?F7u z>b+@R7Q-wN4h+HJ9}*25-w}*p3=;_BUF@QA9w2mG(%noKpWsqWa@Me!=(-<%_y%@a_wr%!#sMw0rg6>#YCJOm}GJ5VQ!6f$L z(aVos=}q^3id*Ep)Eu+#vkt>!#Ni!>j;7z1DTLQ-S9#e zgH$Dj;@k^gVqQ|&F>I;pZg#KKNx#(WW?rgdpM>5ni>FFrysxa%*iF4l%^qIrU56nF z-#Sk0r1ykNJeF#5XXaG=8PyaC-1wglfj zUs0pU#6%bRcqu*`C$4qHH?u^v$A?Wt;J5%DUXdP+;B!|(>fsx0B69J;M-dtLnw5y8 z90>@VWLU7HEio({uf(Us*}`%e?DWN7^g4WcN*wKnZ_JCh93PStfl%%iflwY3flvm& zbVC^yflxLTfl#&*flzi8;f0dVYEVKLyP;G`2suQmjz8=%m!U}%zc?rY(SuKY#1*86 zEdoA0C;~n$7XhEviST^-A4-qy;^FJv#pYK>#)5GVWdsh%gV6o>KBO?gd@I`s*wc9aw<64$J+@ zLZ9U1%kr+h8ehAjb=8`22&6qzT-p}Sj<|l}q&+c6&P>Wo&J1J*)r5$FqLP_>WpQWC@g&H?z8kb(9stdkjbqB(La)NOqzWBuq_jbSRIld4nWru@l5v8wRC1^<{89xxM*ov!@x$wn z;IY>-k`=ReAvkINpnDsSh`>`oZx54fQs?wWnMT8kI8;3LP{28fTqZMI?Hj^EKt{Ie zI$N$eH1B%F3{#L$#nyLy-co~>g&03Jy839 zk6agPb4RY*=!JF(pyPDnmA-ycuGj19m*n~_eZ5SsKhoE8<$9OCzDKSPde_C{@UZm7Edl40 zz8DyAQvd1(yZDNLW9o}8Y6pZo(Bkt0P6KVyG~g8Li&_Ckr(1DGKz4G-J?MI(NMT5s z9!<(s<%RhZ`&5m`C2y5t$|n@6Umue@{())gH*Y}jx&i6A8EBkR{dohh*uy#`otb?% zY@^g5^YGt>rQ)7{6Be#J z^h1ldi0Oh8)80U@GgO+2Rf0mly_acG4cfqVxqY|@*!%H+=>hzQ-Eq`2e?ViJ;U9-n zC92t90OZ;S@jsuDRGE{HC9Xf@asA;@*eIMrlL*#jqI_2Pnp?7LnL!okR_P`DJS=9) zgXq}HJRZ(?zZeKZ?BCIgRK9}3YI*YaiGI|q@Pj7G54_Q$EdP*bIlsa(O_XJPF%Roi zY7b9tt8|RvxSIzf5(W)(@Fgt02pYb!5mG_RjQtq|)4&q6EF;y-FtbWC;P^6krX3Ed zDfcQZu~>#MA1aLgOj4TWX{RiaDJ={5Z>mIl&ggvdJt1Oe}EBJ zemE@?HKJJmsEKr_8D|Q|YpOhWM!p}2S(xJ8%G|6av5kBQM{t&c6!u(KR7rgvfmk=r z-FSQ6GZ4ScT5->y09SML6RB+$s3&5X1#wTL*euAdBTuBLp*y`*oR2rmSKa`Bn9YZ>PO;lkW-lV}?Ru#s8lCQCIQM_81tn0m4jSA32QiG;7^G{FyM zhRiys2yq%=@f&6%5G=|!#t){Q%(^hZQf~1RM(j;I54;uS<*4}Zry=~!b?7+N(*}>O z7{{&2LyGg+eL7|_+{e_8*+oyZq)sv0N@O6(ylc4Hk%12yR=gl4&ITnD(F6ATQHO}_Kb{iX zDX^_iHpU`iGK(J0I>txSd8}C*3{-N%=SSON%7lA+%r@rv`cZIJCoj$*F2wNXe0YdC zBXytN*nl~m;x&fZ28Ni3Qiggj114vRX9v{|7)-eoT?)TTqSz#-wzrf#&V@nFjF=iJ zKbOJ35;%zo6=hdDiPPqaH=)^MKb)nCr^wylUWYs6ggbI=tAm*o`2eKr2JqH>Sth>y`9>|`8gpZ*fqeFAYcaznXkx#?9JA9R_eSva0pOBEns zZqq{(RZB@<0?P`jewU^Ptx?H31QnC*g44M0ELBw?HVqte+fr4bT?#6XeoFMHc7;bY zQ66zQPeOGf(Q=&%%QR7zxh8C4mziI7jv)Z45)y1p!{Nv#rk*9Zt%9aHH%=WioP>Ur z4${wwzSOPog(k`uuIE>@Z4!5E2g7&Z@h>-w<6hEKw5vylo7GjEvD9kD)q-fbRN2nN z0iL>6^O_%QNXgF5kuokz6^IAcim!#stk1KMQ?Y^i|!=nwnJyp}3OR)|r2^9Er1XKt&2cUUbKfssZWCY2syUd~4b z%|{09a=yx+I4w=~U*i??gna10$KQdaAm4fU6UWD2fxXUhh`$H`jFA)&0dS=UL;&>h zfCzxAJRky~uLnc`pkOFRMF8~kfCzwVJRky~zXwDBT`=`V1x%m0NmmM5db4SAOhf44~PI5a;hyWPl0TBRWJs<+W@qh?`QV)m#xWfY?0LFPh1i*L?hyXw>tWsSB0D5W)hya-6 z0TBRqdO!p~nFmAwU=O8oLj(Z&bqa_8z$AtOA^=|SfCzxq9uNWWM-PYqc+mqQ0ABKd z2!J&n5CQNf4~PI*>j4n}FMB`)zoGsS>VUx!mb-5q514zXoWO$M2h5sgCg>aUyf}Y)}f~ro%1x)UZG^q%fd=Dw^ zP4?d&N6hTIZ?dzGQuW=Jps^SI4m5_?JKh-wOt}a4mGG=7S9gfh_{f~*ov1O%7wJlY zBs|RKCMEVRJi@2G{>CdAy*7opG@!EW4lQn~vy_7hy!*|eU#i^ zpdHG<&V+;U#u7knjJbwnr_tfK+a;_O=E>;wry1~!0WN+ByOc5$LW})`n0&YvKBc<> z#||s^p;eEz$gZwJiM~(38C2nqX)}Ez75)U2Kh>2#@4}zz3I2GF2R+BLqg}GImE+jm z7`BVy9y@*9?9mWiIcG(MZ^|^zw;*~rj8?Yt?qztFo#0&__cTh*s}Wm|sw=yO@+#LT zJ%(zhFlhgs&3IwHjSPw3(iC`KSkw07$IIc#aXLuNIUbx(nTOH4#2%HO>{?^z>UL~7 zba6M>mCwpIGxME8h=tt|X|MWACF&;5+1hP0Fy0;e zUy@`%Iwtln9t!`>jj#Q)hni~i6OoWUyX#P9PmXhfg`rmOPB|hdI;}h=p+4$7TefF7qX?Y!b*uPwNoHm7ro!Q&AZ&C z`o5RK|2_D_Op@MLhwiS?AJ=!{mu;W7-;Vq=t}n!I2`=I}`j5sH;LlXzh?MaG?s)`t zs%M{bkC!9jOIXLM$mfT$jWfB!5GM7xy6sFEWt7KVs1+BR<1R|^*h5^x@Qj@fOz)2> zfUk`0?f=K#n}A1JRr&vKSEVYIsx1Ac(pfs)onA=u(v=`h111f!i0r$pf~=yl2rs?` zf`o)dK|t9AQE5c55d{=caTy137k6!UXB>N+adg~u+_!1|pYOTvR!N%0(fR%U&-2Uk zq~7;EcR%;sbI(2Z+;iPQV9lbn-Uazv@&0K}Oig;BrnOlyzn#Twt`=?dhof;{E{&hV z@pB}8u85zj^bFCXCADl00l_b9zeN}b2Q9+qauNDm1V4^Yw+LTQ1b3tlvS&}OhJhAm zmX4;)MR(%VPAjp40dk9WGh$aq^srE}g%*j!XxWRmVI#O)(1n;uF9=@8%qYudQg=jO z&L@+iHcOTUxnvhAnROV+zL!s?{kbez8k8%|x|U?M|IAfVri(#Z$uuZSmg{%Y?wU`F zK4)@&Xf6+rPF9S6jZvVhgLaN{msxW;mqQjaE6nwCOMcV&{A4)4e?Gs>&!bmNR?6p` zrpb^Nz=x~%D0XNx)KbPB`7*R(Z!P1D`N~Ms%q~N*L!-}@GCrIyL$X9`8K=%yMw(`J z8Hybm?YETilYAKxNS;I)X_|SWJ-xmsp1 zbB!^+N3}Ve$(@SPr^pQN&Ft9DcR16tvma`tY|X#Ke8bJ#>G>YngJ9R@e4ZAApD^;w z#_0Jfh6sFx=$110oOR)eB*bJ*@c ze)~LrF7ivNpHZnqEvTs4830PQ-!T+3r>t%@3)^w-QnK=&_nik4f z2A8+U|AjB#x;mSrzwh!d8l8adR`CuQ;Gd#s=g}?}9X20=#E~%G!$S__->WB1U?nD& zgZJ@OYmbew61v6|OtRERh+%X+3;sv~m#>LOD05fhC;ANBbeKY89V+^#tkGzj{zvlW zddi3G5nh4xG5taJe!1RNbfI|(H(87prWDECt%R2X@Dj+YiI@wt)n7PcF-qZOdQN}H zviSwwHvM58}!AM%%(`?McsF?_Nsbjqar!-r`=`!>ip(CER2$rSMgHhO7s1W1{*jr-at}V1Jw8 zpy;A{Yb3jW587oK#GXP|*~~&^wLJND!o6ZRMG`c!?dl6sAN+ zady9=UYLGxk_r2Q_|}TH2?ThLE2r(^3al!0NU;>|r3l<_gLA+MlyP2fd$7O0)R>B0 zA|2v?AHB;2^R3q$rSqh8>FtoG{_6C9(}UDi{p?q_mRBcz8{9@W23V&wbl_i8yX2$e z*crZw{m5#0bW0_LLFSBF9(XaO40L2-0aoV@`ug&7f{6)B7tF5~JTW-C`joeroC#o3^ zQ*whFzGZ(riyj+wptGs8kJy+XaE|LxI*S^2ZQ!F07;n%)X7%Wcz->Cs)D1|2-xrWe?=G+nS~`*hKsmFYH~5T?d9 zBYAJHSl(I==5|`APEj%_7h8lK=851{>TQiuA3tpK$!4&_yOFxSxrKLZ0FoaD+#LD7 z1b>N}O*bgR--=`>){>yPhT^(9dJ6$-{_1qeYTVv2rI+wZIy`>8CVRaud%Yohy*Yb* zMfUn8UV|gxQ?{7Xnb^C4XzxuMm=986_GH__-&6K#p06PgL&>)AwR&miRvVNA!LyYf zZ~AMXmyWIFh7i=?J%E48m9_0bY6?4@!J#n-VJ{~~4F)uYf8f=f(w0Qe?qdgghJOSI z_G&gHnPOKcKBI>Ce@f#^I=A?p;h!x&)df@NP^#-c?&!9#wIA(kLbve174a9LreL ze_LZfbH=brjeUDdj$5&A2Z4J!JhD|~=cL?YE059fuGPKmTNf>+*?xPY6g&nn^oqhK zS!hs?zXv^EsbxgtxSP|pg=p`e%r~NIKb-}|bvmS;`Ki6hJMy~@jT)Dy(cTThp=(c@ z^|tk7$vVsJ(=4Dg(I>LZuB~vTSZ{LV+u5tyS<#txMy2@{D)X|nyrY`*8f%h5Y{R^>uM0jAAHJ`bCfEhl z%=21eX$~s8{ryU7Mo-H!Qix>~V7-tYxR<8lW-x(_pL&Mj97pEYgd>_R=Z@B#cgk{B zNG@jvtY#`{3s72jV563EdcvS~7Q^kc4Vz=Q+Gt0~VTjs$kn6Prshw!omDKRNc&Qf& zrDh%JBFU4)b_N(K%8|r+y_+Kmn0=Al`g0Cma%Xz{C2JBH1`U<>4aV-S#mt^VGR$)R zzX|O3{3mC91n=hmH^2(;l>{z3q(_0>D?Za)0E=c_mT?;_Puys}4lK=dx01=O8JQ@= z$RzXWfi@rC4#rg4WO;Oha_DKzVYe&?h2#j0xnEQxjVpF;6HL%lFwSIQYbH<6GEqn_ z6Uhx$tlyeqB1@r=TngOoxD>suDJHWN3dyAqORzFvoq5K)K1-pHT#9OvqOUc@?pX?j zS*fVM zf0Tg%pP!2A6Gvi7nO$`Eu>xVd)pcrU-%b*I|Fe51BV zSEg2vFDy){+2JkV!Kq?VVEiKmpbnZ6ri)gi;8ZHkkzG}soi|iI7Qy-;ix9VLjEL_h zVotToMb!i0yMTGcxV?stBGTk~YD8Jesy%!=QG!!4B+bf7?7bx`VawrJS^YxG9$Kb; zRxiV3Ccj}zp*d|qKjPwr9l}`0gp43jLsa#J98nG5OV-ipW5^Mo1Jfo{o-37#su%~G zO2-r<+^y`IK*;-(HpqRGs-ZO>S$5S+-#N@`6CEgFAdY#A^rmlHnJLJ;iGNWu;xh0) z$ST|pKTLkq;1xqSeh4wj#ZM7Z8;c2xuadEgu=rw22d1^^wGNblg(@W3iVF2np${r) z;qfcP5!(4$2V+uZlF2X$X8FA(dZL^lVlfmUx(1@xzsjw6(f8byt#}L3dq9t)yX!Ov ziZ(*b1SF3rdK@}0W$RnQ8(%Dah4gZM(w#ghSmr9-u|QV21mz~^cR z>(XMmWAOS-v=oCfESVQLgR(bH#FlQ{?N!;#9@6ZchGa*@uWSmi!?V4GZ6)u063Ii< z3mCZRD!98{Wo}3-a{|JCu&)SSm3e~P?o?$$x{lmhHzp7cl(t^#aL+QPN*YUePeGfD zu98VgEe+Y?(&+mHUBnd4zJEOWEOiZ2AWKzqsX8_A77@qs+V~^pvnXDSrywDO4=@l= zu7?lmDLVrj(E~g=W@TR0n6bGHjDue%!))p}w(6D{Lbcw*-M~Eo1`3Qg2Ghb|F|Rz> zJg&NoJi?doHU3RB5T@l5nO8YbvVyl?Vc#77s;z?b1a& z$2hcS-~C-c*l$PgwIB{V)g4e=<&}!oE5V!S(r}adwba_L(rah^);94mil?uw-%3&n zSihAEt({Hp=ex~)B;8g{x{X7;)@^P1ZYzdKuR)KJv)cVqTgmmBZ97@7Rq3^=>ov3+ zy*1ZswU%D1X1!LO-D|W!y=HC`5p3zTws<92uA{c`JL9{Pe(jAfUtnES@XqnRzSjcl z7Wr1kG*mib-!Y4#t##YNtKcVano2ofpfwO~;3s{|aBt?Tvl7pUm99oxAL{0gHRO@# zhaSxGLTPH*z-*mLDNe^sEYAp#ANv>IC+$0x#ypi*3&ApaSgWx^e$If#ETI~5y0jXu z;HT5J0xIE3-tqMp9ltnlupqA$~$j!mx^*>fNywmvdyS> z-xm|vrtCeBb?Uo>gP0c=%RBuNGfewAcU2|f$_LMXyKpA`bcDb!?b(JDp3Y6@o5 z7LDs;b^LLgXt-u(48kjYaQ@1rAA$y$;<-itOAl2|ge8X6}FdNco zn>sK~F3vh1LdKs{I;7(egEVarHL+xb`I_fRmNb;oAhm>{j8t z46`WsbwY|MwbuQKePC?(9TdIRd%fn_V%c?0-i)QOSsUV$(XXRtvejWS!f8j(p;q7@781 zNwR{j;(hrW49MQa0Scq4Zs{HlpC{BW;rOjh%S+s}ytGWn^9gBwl8VN2a}JVldOR{4 zgZG!t$LY!Ah00yd%uZuz))r@KYbhKxpP|4J&mVCU^>SGLa>w#l!17l(mcOEf7~=mA{3mm? z;1c1-_^&{^dH80&HBZAZTi`$7dz|>_pj%{sgMc%Fyq#ykwC1dRokwZsCzADq99V`pS$`ZW7vCaejXRLDsPU09Qhw$fTnB5a{!hu9<46`R@mhq^PliM z4zhif^}3x?wHE+iO91u);Ohy%UXY_Xq(d1GiBA>+wAHNO$50e?P5hi9(vt;KcOYNy zOnb&Vxg=+TXp8Ln7}Mxk^bf0A1)W2A8lro+8(SGDE6!yv`{{bcn57(`_cHylti6x) zq6ab51By*tHF_v9+8bydr1*%_h43i7A*_v|46YR745EACbJ07*?0z93;YcFMx0klf z_uzf}I=5|(SzS80wHKVx{j7U-oZS{xYDm|Q;$;G6pSL{ZR0SWB}XIjgvs4`JbYTILZMPj ze@pdr=PhjAG0h2!Hq%5Grt}&{(1Wd@5)E}>N^J`-1U~(3-ms-Zi>CY9+-ISbtzxGC znFxu_`=w}XQ=PYnD9N#?>%gV+ex>sKj`Bp&eKD}BtU&W?14#FRT>f z+%m2D7N%5W;y}~+^eNUFD+^fjT3d6m3R9|oa2|464X+K-k8$T1$F_}8I$Ourt;QG8)a4VUDM0(tV?kT6cuT5uP7B_KD`g>^2@HT1hLyz)oIQF(@V z8i6<{u0)H{Pq`G;8kRF2Mf{d`#8oNasNe!gs})Wax;Km?^D(?qKGW{ftUP7Fu!0om zB$F&lme0as0g&=us7}qoE7C$wN?Alup?x79&#G7~uoBp>fiM=YcUt4_aft9B@Fvvz- z$i_!`TIiXNm$jMA0%{$0zUSPV0)lJ10Jkv{48mM<#4OW+CrT zNc27?*EsEYVmHUorO_6EfgLm}1TWT5XESf|*J3P%=r7w!5L-;T%<84Wl<gv#`y2gy>@#~6Noz*pm&w1x-Pp{$-3K7t-6W6Rge#3e6jy&IULY)OZf2_AHbxRWejch5%C#Aw~?O z0l3skQKQ8M{Q<;!nB&7~kZ$e(Yr}Q1Fu(2!j-4XOI7z5ElOD>UW^OMv6zk^JSblwO zhx>~};ZpZ3a$0kjD+;S=8m;m>&0_lr3rvQx^AlY3cBk?mAbmEhO>d5EDm2&GSm7)K z+-EpLSyd$AyEV2i1dC3oE<2}JlMlLEHf;)1VuE9f+%x zAujPuH!lf1x|KRO4H3>Q6D{(NcZAENye{J&u@T6Wd!z0MDn<7Y8`%tTGd}KQdVO@{ zoE?CP`sEwW-gz?;qZH<8ZX6Lmh3{IUV$E|iH26Rs2H_ri@CD4uoRFG`R4z!p45Je$?@L(RczL5RsA$-J|do3KF zAsSULda z|2W({l3(l48Zt(%2i1Stk9)-WufNzl%F@f|UpwP~sQf)X3H~61-h;wr`DdbQVV;7AJTG5tEZ5 z8ZpbY8%D5>uHs8ZFJ)fTmXR~f`(oVQu8Gy1G^s1FCU?j8*Xb%POa#l(c7JBLoeo>F z!_=4xcbgI^y5%AG;hr>xowA9SFl6Ec!Heju=p{;}H_&2C^aH<@QW zCXZea+E|q0IV}h<>)W_i!3J?iR&F^NQ*K?4sDk8#unSWf7HpsGtT_r-uY=izhR9@t z*_DRe!8RmoaM6$iu$y?%bb;H~$-Brg>0H;ZMh&`N^wPAJX-DeLGI&pdJi)Ec!;=^= zmXB1BQHoTR5?^Z;(}aSk^X}kQwMesy;VvK4E#2XBmF0KN>ac7@>YV^Z={U_bLT6C> zgW)aY#q7_l3F83Uhy@y@_EjPOLPnLbflk3yPku z92o6pof+7(BV1!oW>jN2+)EU~%7{VJ*6|YVqA!O6ET>M;Jg!5S+jGWw2RF*raLwuK zX#3bu{Nfyo9z(H|oQ{Sg92 zHz*``yC-)xY3~Scxrh%m|4YiYVV8Uc7r-`RvNvigohGlexN}Nq<`+axXvR?HXvW`u zoE2uZ(Ei^3YYBfeT zBOR3hX49D6al|%xOc|m_f7j$|BVVf}!NmXzaX>U(j;P^?CNy)30<$h+rk9=S9;5|s ztWKt5b-l*w`gp8zjfEC<9GOzm!T+Pk;e{I7<3Z>JbO-;@qQ zb)*dlxL3Y}7W~{3X_o1r1%3SI*>Pe4{%Z~I6rWVCOse5dV64ttytFoM79P!y$8%%v{bmo1G@qQE;1S4vg zDc6r=NqwZ<>&-Ts7w|vM|FQfdsoJ05MfSzNj~wy8jAECRE)lZ^>-MV98{2@^uMr7(UH)rGm z+^W7kdi_qUYE~gkk8v{i#pGchq+uz22H9$erPeMM&#B7X77#k2g7*^I^HH@YzR8wz2D+#GbRCw}dwNfK#pHP^aIoxIZzYJWq*25H zJKcyzx)fqWD7B!eYM9(hvLykvvj3Eo-uPFbi@Y7O6m@Q`y{otL3my8kU-Wg-fM?(9 zs}_^%s>m1o$ofFDe^om$E)0ELZGtri$}1-}+$xlwuJTTdA-AWH17paWQpj#GDV6#1SZyG?ze-( zNEW4!+3}PCk=#xC$&Yt3wjJ7^*aYAlXs$xY+ zui)gru{(#pZV51CMaMX{6oc+BkP^^!KY}1kqZlhmxh%UKxD1NKf>``?R?vF7dxOS5 z&~EgeYN(bw@0iIE8tA*?H5kXAP#v1snnE|_<|{$?X!IZd1cARsxF3zaN$EwC${*v+ zIV!qNK_OPTRTOler1s%Cyu%Q2VKaf6oMUYpwK8lA&jr5utExEqxoYqkQQlwz|5XcI zD|QhGf^J(Od=Uxj<@qW!>@B!}9L^&`a2FMc)(KF~s%S>qxhitXSa&5=Za90dGodwa z%Q|eSlbm-aacGe_ryAbu+MKoDHPURNVrLRg58v+n=$GEQRWv~TeG*N^5|;k9I}&A{ zw32_kTbS8YFHa41{fj*}g6K|)o#H~ke?ak z_9sZ!QBaNU$fa8gq;OdmO~@I?x=eNbwDvO=a1=pXCDo9fK~U-XD>{h)E^3)^=q)ke z9bOaNx_AydCEhyzOS~sI)*SZf498<-j>Dp6835BoufcAJ^S{@;TsTg*abP`Mn;U)a zYPKp|_4s<6%DYMysUT`I^?zDHH(mz46E5&du1*WQ0qW%bVq!!f%O`Sa7I+K&Bu&vf zl6Jv9q+|X)1e+LIphv4l4-Ua0!&mcawwe}Jvpuo)@cC$QIxE=$KU%iXD^#Y{2Y5u9 z_@gS~oYI>CmnDuZ@{I_hDKKw*&yIPBN4XOl_W%!3Ur}>FpOXf#Ov`88((xV4#5_B^ z5x$(b;g$SEUsckpc+;Lx^jp3bhyO+OrCzqr;AecDfUQx*PGk7hk?mqJSf)a|V-P4% z_*11p7maS&&VXubeyQ7A^}E``7f6Fu@Vl(B97k>2(k-&_3>)#3yI_f!(i^?DO^Jy2 z8gIpWy&Iaw+X~(as?T{?c-ycI&yu%TI{-sl7nmi?pgxkl6Y)a6z0WKD%wi4HSI|hC z_MVwAEqK;2A!~#d=E0MB#I?pNx^N;N1Y_RnC?5ZJu9nH1ui$n4I?`b)!}c^=W=K;g_lg!U@gW z-zzLhYV!OitjWc$Cgr&B&baW#xsX>}+_m}Qt_C%og=K$50i#Qz`>e2~91vxFP#sAM zTeAiufB-ud#3r@5XlG%+s5VERBuQ`$g?hn#L?~=6zlTTjS|B0we$|Uc+maZ%?qN9B zg|+tncA>ngxe|hx?NZ5mcG7pQf1JNKevX8`-P7irQ==Ubl<4hDoM4y~LZD+zoy;6q+msEGQiA=?n;;KTgrjSh-kEPSQK z#X?!w)5?vBgR78jcdc#Whj5i*bT@<%-cIo9V)zDoME{n7qBBcLFh$%!I35cgVj9C# z`;Gc4$Jt@55Pn8GT9wEzFSvjUC+;NJb~kuO#!cVfl)MKLa%BWo4!=su;2q$F*`geN zIsK~f^>uy0AR1-}Rr8|V$)CxHTefkFuIS2UvoE8xDw5TM{`#> ze3+bgd{P;n%@4CqIsC8#ekujZBb8zX=O{{d9L0V0@byiFy;JpBXkMty+X{QYok5ea zQ0Hi<`A?851E5_F+6AVE+ZS9gQj3ov`3uK8d;7L7dYDy~uZ_ipf%PYyU2bj?iWDMa ziYrLQtl@WX9x47vBW?eUQ%>t1!)-DJFe zAE({HSqFAPiGh8gSPni!*@$Wy*xGlTd;}E?^}d!0I0{Kfpnu{@g79x;BrrgnM~K7O zk`!-ljnzt4za>ueqSYwPdMXzC<6!c-A?9eKgqR4U?Flp*B0r<3q28g4nDW4ss`9{A z^2*gir(*tz62mux1da)UUmX*?M_+iovO&SskZxE}b34>m$AB!pvmO1C-3+hQ584iM zh$m(}!T&z|Hx7)BrRw!1jlH4=-OFy#*WJr_RO+yx?V=sr%W!m_d+CktaW5UwL+%B1 zeu_8UV1XEr)JU>|O)zm+Q1!Q{Hz(7xfLQ({y_pW>FObo!(cM!`LD6LTF6?|q*m zEiEan+xGw&tvZE(BbI2_T2j5f`k98D6LuOs8#YJop&oF(B)(M{Jhj-?wVXI-S zKfyQh|0o@K8Xr9Z@+bId=#Y^=y&dWLJbZ@ly@7vd7JLelV8!flw{fx{v3%|zv)2(9 z*Mn(3!+3_&nX#{AvP9d=&aD)Cnke=G4Z95r3El;_skP0p!=I2h)g1DY0yT1~4ZZXx7zi?s#r{V+w!B z#&9c?Gtsr+f~5&H$KuSqgC#c~=jXsUi6icmuvl#x&Ceb~a>Z;6^QDeq;)*%PFw@C# zZx`A+IdVTLi`q$cUxlBDdjFO9sZP+%G7Phc6Vk(OOtO!|Pv^vI724@gB$46W6tyft zQP<<}lUg?Q=1~+UnT?_t?8f_2PLUeMw7yG}23ps(3J;wQd#5=3bk4$F)eXayE);9G z{4ng0x&36|u=ktU*h^@qXX1xyeUHNpW+Drnz_u_aupuU84aHQ8Pl<;Pef5cJl|kL1 zuMhO?-_3;8Hw$ez*7WlNMomO|Y8+g6#GXpQ#5ESf@Gv{GeevNhUS zSu};XXywYx`qpS?XVDbmqP2I-?A{vfoGh9`T(nBZ%pR@L&ds7JBzQ>6fsT%uXS7Cp zQ5H=hE?Tu?X3y4W=Vj3p;-b|$X7*~0c77I3AubwV7xFO|(iJ}HUb@3i zyO*BuvwD%;YkeuZlS`AcXETLU{-w|b_Si!!dN1SoHOU`dVQgI?>lJq%($05`59Z-^ zGSc8^;cYj3Y#kegG_zL7>g9CU?cq%bVW!`1&-B}!m98xd6BWCe!8;X5YP%jay^{8( zqznu{2F}peX}<;4ulA2s*MabZz^jGJ)WyL=ki*E+M#e)lg4JjT)MmEWG~Jo4q_WRi z^a_|g*XT&gWh)pC_Danaeg6>ef=cuuLT#;uyQ}7V$qt88_mbAbk3rtDKC*4$hu^>ypqEcHgggKlvxVDxb~W6_Dob&3QI>-Yg| zV@m#pa9NmABzNQ9GwH4HAE*dwqzLj*B7W$3&YEPZ` zI*s@$IpV{smkia7Lb?jUC+RrJ;~~;u)eZ)C7>(-iW!fQ7S@3M}V>DV$Wy4OubEzKN z^snU+o=RZ6i&75HW)r2}-dC@bM@ECygiP-XfAZUz`ClR$+73{_6w#3BG3vc4w_Scf zv}pGh)pgNq@F`V`&79^Kkw$O`J<_>q-3LkdoV-3({E{1$m=#e!ulwsRSK0-tVW{n@M{#;WkLJT* zXnHrj7N!I#wJ}WHnU$woyuy?vo3d2yL`xHtPfrpme!!+w!CT@jopk&_x^xy0&PKzu zSI#m+a7L+v7ZX^)y8+m@gdcZX+ITG;9*%!wdDCV+Qfr*$qKvgf!8iwJ#ce)3NE;lT|l9xTd{_C$3vt@&8QSir(JP z*+1p*R(I_lucf{U9R7N|V#&=VwTW)h#Au46kF`Vxmz>*o1E4nXU3wFNZv7L8>=V%l&?zc&!tqGxQ3W6#CoI&RpWp~R}!d`P4XCsl6g zc5~j6qmA8?GV|nP{v?b#&;@U!r{!;wC64#cIb4nv!~YbIJ7r)&;;W)R2A!3Hs4N&x zEVAU^;NrrR22y-gNI5&MVpny7pdQ%5b6J~M9QY&I5o&w7rt*^rN!0G-`;vN~A$WDl)8Q6qFN5!dGs zu?)jB;%eFv{UU6A;R5O}#$OC~WXeG>(MLHP=L7LYlYn{X*}NTF>d)cJ zip3dU>biJ*ksmW?EuMBJ8^=G)fAVo2>T{GJxB<+y+e~JpoPQ(LW2dbm4cbrbeKDJE z!;v>A_!7Tu)9BKu-#(W4HD|Se+j?XR+dOg(>}6AcAgpx?{Grz~t8k8A|Et;>pK;ej zUk*2zRnJ(h68@Y{ch%$;E7qZ+ZB6@?@TY{x!p#K2XeDKbXvuJ-3N0-Gb?LfUZr)-W z_d#d3=+IL4$>j&+;tq4g$PmBZA*qcB0BQ4btB!55;xB{@emP| z^RQV89BpW=RSQ)Q7T<^&ghKSGN*0l&0BkVpUSYXt3pwjbGC(8;_zPTU69UQ z5-{2@3r=RNvJ7#>->C`42YuWs$Of(J7B3J=v zsD>|-xNMpgF5trv(KBNrGq)jwUi790`*JMX&C$DUFn4;5C0M>4NC&kB*sRS2f?~3w zefsM9i=D=g3r|0WlooGfRPYSI5vEkmdxdv>-Rb&T<-8Lqz{zytkGGKRcfoHV=%aK@Ma41%MsfoaUwwMTLp|}@>Aj^*RdbUkJLyyw*o(3&V z@2%&QfMfN-l%QiUDnXqFi7v(NBlu^CRkk%wUd_%}YhLQ3zQZ;y3c=Tj*ES#xm9wqV zxEV)o`ZtB!fT}vi>;w)vm@6C#L}z;Q5B>?j^r0+mxE70x z0y?Jj9!^$JUWpYLeFWa-%NStpu5TA%cSZQ9D1#R6K}MJ{HjZEr;()XbS2UMujf4)O zDzC_m;9>DPMxf>zjU>F#W3cuGA6FR~URb}ywS!$PqVps| zT_n~t4qaXJD_#t%19pW&C$=ywxYnveL1DSw6kxHFZ{bw)6njYjF5ETup}=Y%w;rA& zb|EQ7{^J=MlW!z$Y%3X^Phj&Cst+x}0$OjCewkxb!bkN{Z5&CNm^tc%dwcW|k#f;P63-Q;SSk7{ZL*^XQBkQU=C-BxS{WNkpjkJYz1?Ts5@?x&<>nu2nr=;2% ze&?d26NYRL;8gZ!}MY*|cEJ2(wRWrNqe@JCD=rTW!6qiMjMwC3fJL$2p1mQ8wC)Ox>)yXH zT(1J=52ZePDAa3gkAay@j4t-vLgR?#Cd>0`xVKVq5TTN*+rSCok3eqpHY%H;B(0R3 zk0c1yA&+`5PI@M=1Vw4<*EiPt97fPE_ZgCneUEkX^^jWsIkFb#mHK!W&rf1y1#P=4 zya^-+F7$A8s*I#ucGv6qiw44{t1-B<{;?>pEu%cwHSERM+QA!2=0y3XM!1gydWW2x zA;&?S6Ie zEW1(deCNbZI&4n7FDentv4wKL?qegaL*t+}3{z!mGPakOMnK(VHYj6ja>>G-z|)1t zF?7ODYm|;)r*W#fK5h+_*o)jL(Ln<{zTWESoyk5gfOX2okUyFnSZ;?ZkDAfI8Ja z8ot0!9Q6pqf73xo;5Hxf9U*qHj^BO>2ocw8Y`2}MRT{P?MZmaU83(Ux{Pp^y1Lo*zB$ zQt!i)3l>XWf*&*Xtv5zog%-qPKi{z!Ai zk1L+{AL{S^YCi_V2Y|4V9Uw%>S2b?{hp}6jP+7A~DYM+2sm1VQt*zuJMPx3qYlk>i z|4Pr>uonir-yvysKdQSJbz+JVUE-Oen3~P)$&tKlEx%lIY$q9xZcs>YiDp`y;WW%W zNoSns*{zAL%n~WYCHhd3Nd8)yQ$*1$U70?N7!&^?-I&YFuWT(}rVLnERfDTYrKvgi zuwJw}*`%mUz;cn&O%&$a?U|{1^okqnE^{J*(|qSmj%W@-0*nFOM7NnesZQ)wlKHJX z*6CNKRFR4kSan?|XV+^S6(xh(5Shsd+;Yh1%_5`5;sqDY|nF4X#@y@?Q$TvW@1=Q_84cC^`DhmF(K%t(Gs8*(s|$ueJ{ zX6ESDF1aef=;#K8IJ~m|8T)rKb;$P_#fe$8Mq`a&wLjz2(8 z<&U)b{oH);5lCVBa7wqYkLv3P`?^d(iLh0_|1yE>9mK%pC;tI13S#{Jt>u{n84e9F z_yD2boTlJHZgRPcIdd#IshbyHH4{DAmsMdg9W=h zcLCxilBoA!;rMdV-nEZ-JFxFVoy}_)!t%p=94r`JQ(;Py6apEWHy6NE^%ZVHI+TOW z^dr0-h^^eUEp|XYo&~YtdaYOknu}`iai)R*9cV)uYZ957Le64ht=GnRYH1ErXe|YVt?qwd97Gp1gaPso> zK^Cul`e2Jk6t~}cg2D~~COTQDhGzP!;hpMUbA{)jewDq1O0tGb9u5%t=w}PUfx~wT zpRwv$T|0RzF%lJ{sw$s`)ev`hbe%G?6yX&}F*(?oPyMjr#hXv$?r?^F)X1iHBHGQZ>Uz!x6m>XDk`JN zqnE4QrZeiRSNo7(bCJRq6VvX=ns_fKJeseB=yf+e7n^i%oIYMd%I}%dGdwGgErj36 zX(f1-68LP!F?uD=?n3TQ6%$yq#R~VV=|Xx(zUc6L&^~v zz4>~gnB(LtSPh(W+lem?f`vF`cpF(oJ1F#Y$&`aF@Z%G>_JRs~BXh5@3=<`{#nChbc)`EK4EQlnWJZ0=3s z1_u%?u?F&oHU%fC9tQ(dA=}FGg1K34Bagvt=JDdWc|5sl4Q(^aXl|C;QwC4;erR$^r(x|+pW@V905>hYuOWfy(zbyQgbR;A8*s&viQ4UgB>^RR1 z8(oaX%gh~HrrALi7W;fy;aoqgjO!}LCre;Ts0HdcW*ytjqx{RkS%1K}t+LkGT(qdY z-qmryfD2%i-Mi8Sc#S^Y(Rc-sIBYl)zDzG%S+#-|2xzyKOPV(9Oi`lAcWMag0I@_Z zpmFs*CFwCu=C9;v-APn}6Qdj-bn=Bs33XPvbynAtJ&2k9nw-$k&sQoctUn4Fd*UZL z(2;bynD}UF<^Lux7Tlw_%ZfR*bBM5mEb%zIV z06Mm7oYSN~8BOX!yr;7P_b+7X0ocy~?72C>F8*YQ?pli*3elGR_{|(G+_h!D-XFaP zE#`2vRB3k!QIl6)a@E=&l?=JwUq7~-j+u8rnQUFhTjuCRXCWeqN8m+svfuPd4p!fz zul|g_`ks!yaIQItVp~0JB(_KR9Q7bRK*K9Vta!-em3wTel06%n@&6MGX;Z0?hV+L; zP>z=j#jG!Sj5s+LSK@w%Ww1}Kx5>qig+lSwYvu`Px|Hzu32y?*I;s%83;ZQx>{d+^ zzap72u=o}j*NO5o%CY3QpPnzo?CbBV?MVm1oymXDtIg}lH)LFk1{weR!#`qzQ%&&& zI{BxVP(+0F{oJ73-`~&ZG2Dm3>j(G;OtO3@Wej~a`CWt*K3qSrzkblfe=BSMK>whP zM#*@pJlKXtsCc&Os~^&PC_oL53>bV;2r-s-7|tXwiRm%EKljk&2FXL*4U*xBB2t`K zhVPV(!x8=wI%BlI(Hp?~0rI$)M`lVBvx5doisfhl4qCIbNZ&Ywa$) zoKx+a)vC`^ceVN;_C#^)=^tpG=8p7_T>mR}M!ku8j4!bW!y^0K`#A&%r(*X<`A1Fu z#89{2Y;--l_vj>cio+bbj`5F~jjp2;bUizdu4DaU9lDP5kISL!Sck4-p9o#geq40T zuC+r~+{mojd31qlHKS2K-amefn|o}@>Bh(YE#u>a*70$|Qy3q*YP}HkX}KNGk~WNv z0qgl;#9){#+F&@xaZP{KsrBdh&zZzyS_-b8=*GiIo_}I^3;kYy?gSf&p8s5D&2qBm zpKJu4`W1|CzNnw#pTfMbmO|^N_MYaSGO*G5&#~N?#7|55?9_apo$jCR`s@tDFfs$ERDz)t}eO#e)F z7tf5XXJ{@bSZoG;zW@ALU3F4RSG}OMt6q?G)f4x@lkO@>Ch#pyMdDj8^j|nBHwg($ z_o`LvXT>o>%_#M=oAhM0evacX=lbVPewqZWOy=yScu>*}XXU%$MgEIiH=O66H+G@t zpToD9O!!)Ib)RB3vpOL}gjDFF@b&i6!sX8iUnSs^;__bBg=fv}LT2(;n&!l+2{BMc(`yCsWajEeBa{uL%s2Maw z;#p83qy08ZC2O@S{VUxdyvo07axaU0W&g(dEBq@5HrB6pU2u(m%{*OjbxRk#BHsnq z`q#QHc%}bJ*9F(McEPp(TV3#qZFRvb(k{6AZ`cJ5N$XE?+H7D)HdcQX($M>In-8Xh zNu?qGRf$QE9fxjgN9=F2($25>=V_s$y<_-^qKPuP5s>lO;df!Lw)YPnd#t^FoqydJ z6M1g^<93mpG?)WF!Tyx)T)Uon^zVo@sziGK`dnK$b&pj)X2AF{n6sO7Lx26oiS@7w z{|5iYjrE&6|E5rQiSAAeQR}bvUp;nW0#C)e-R~F(*-Nd?oQQ_Z>};OH%hvJ@+KK%x z0izof5-|HUg4asYz1hFXE!_Q^!=JK*313J#6ns-|GI6e zZERAx!fb!4{u=)^(kZ;we=XML@xD}CnRKa{Y)SQ~M*eGZyHVzhzMgi99{z{{pzpxUqATV~3K`bWbiU?vp}XSWek=yMKGD zfba(Y4Okfhm4Hx3E!vO*ZFVi3rsOuyzfH{R4*!nHnrf3YCW4OKZd=;E%My?_+TQ5D zadOHQ%eP%5t661or+??9Eq}?>fOf}b{jS24?FTy@W*l;n7O;2adq}s>`FGh3mGw9I zZ&HSv{7oDcZsJ^-gVApa?~%m0QBq_5?%c?r%39R;ce@Q)ukkFJo2e6AXkWZr8{I@J z^3{t|yBkUKYvChT4Ba~iL-#ri-RIvY4BhYFKej5t(0zFfz0JSJe_QwlVasc< zr|lY^EA{aj{`REd`S@?&X2WThEuxmVMbum7T}0g@XVh|DN!TL`k|) zRJ)CC1ec9H=Lz<2bBW`&MOQ3A>3zD^o$v79p+Rw*TZMLFfSRb69DU5uEK$M;STOb< zkK1&fh&cka@cbKL={Nc}`ZvJRAO4eA`h)(1lh<2Vc3bj0{dcl_&9x`Gld54Yk~Yu) znQ1`qJ+Vi#FvutS>m~gBSwgSz_Q6m_d&Y3(BlsCSPXfqXlm2~r zsrh;LZd~S>kKQDoAM^c2VqG(m!IjUqf&YZ(qrlC;o_E<7k&X8w`UCe=;$7}o9!B0J zZ@8wr+2UjI7FX%0hT@i%f{3Bc?3-DHUd$$3YiRuAKiz z9!#a!F>##!$nXSAtzlPR1D`Gon`g|IEbKTJ_7B3f9UAB=_Xj@|w~mdebj%7V!f)#j z{u6K)wkoCU7_bby-$&B;z=4cctgTblRA&w}4C(2BQb!@HY4pDB(GBh-1%&iO=G{14 zs))7ZI@!0XtA>^#XXUSx%}%4*DZ)J<^5-i~%?WCXAM1*XNBT9nZ2Byn@AqVH;d9kw zx!C8Jjsy-_isK0S$k5>eH)xPRMg((Jy*VvmR?}vd6hQ}+% z#!m6~Q2f0-{vL?G7slWH@i&E7NjIt_xfYVS413(1HQBMZk){4O=5?=;rFP${uu6|J zd9~`ymJ~-l2VDPgnm|*ATw0w#x1>aZQ;{o)9CS%6(RriEB&)fRvK|UyP=+LxIS`^> zhorpnperjr#mBiL?MC|Tj#kn;$%SQ1Teu84t~BQ2-;Z+`ayf9cK(*B|Bjr#THfpo` zF+n`@h;v_+%V$Hl<8lI?R7 z$@V0ZY+s#8whGB4+Zyh)h0t~<)?NiZbsWO*8dsNNme;6SeO<-y8sR%>2IFe%8FYvS zy9;s&+uUX%_G+#2olb?IRx6o&N2lSDHP=z$-eAXNV7m*>sa|{m2L^}oxx}GZ7)W|F z)_CGBRPCqWr+G7NlzryOG>}7BMvmT?hOyPvg@C<(TD)e* zLa{&i32Z?}Rmr#H-9^6oOQLX2{{+RwC(Lv0IS`x`Kal`|4+Ll0vp--P$i80?Ke1Zk zyFWNTezMxOZ_IV<$%dUh@fpZ-xTzaLM(t+U=#GN3Z2);R18S#c0tTK1=LC zR-q&OSeA_B7ie}e=)Yx9 zl*>>;Ay`MMX*x}=cJyfCBDOqzvH=`t*CaIkY>L>-?CfkPn%grftEHjl!IZ#sz+Gnn zkP8)I`Z>zE<-9amD}C6hoQ~qHJ9UV{45gzG3hr(TYeeXZV;80rlhZ^=qV$~f%e?;A zCw_g}JmhZYi~oNO56tmu<2>@O!?Rhk)pc>*OV?)H*0#=G02i_@>fQ;4z{A3>66MSwsq3v9yo z1YLFlU6F79$2m0=D2`kVCanviZ+$S17C6b;E-9;b6r%1&2so4<7eIe&l=TNsw{-5y z?E1`KMtaAsU6`>rIMU^Q$(&3yC>6U7I}JG%8FG}?3|T+O7q<-#6L!;YB~_VF}q zVounX(lBhQX65)njD)o%s^^u^Kfy!V)$ZEHpW3sENx?dAvzJp z;4BV=ZqkWnK1w!kdLJ1!VAztFx<`~AG5^b((rf$?4w>uzHD@5qEu_2 z4>)XcU!QVeDo6c+6kNcYoHShrHBfTgNRZ=>uGm{r|_Lmd;;HCf35Vlvnmb+q0~N-Tu@#%cEo{vZp>J28UE}@ zKismK#OH)46FN6pEG&knf`>%t5;tJ)Yx0LQiBqLke#l4FOx>7#9mwepbefF&F_gKg zfGgO}0XzH8R~qwIR>9U%>N;?C5ja!P(YYT_IFnhm;i=5B3{O-45b1QDvRz|!xA> z7ozXXie8L+x^-QaqB=aqYTaM&>Z^D6)qDEt3*C6+a6uuu7mo}%T8nv}i%`TB^=~2M z`oaN@`)=8{&V3`}7cJrjX36_HxYbV%Fa6}K+BXLBP=7p`y5tdv>#KAK>lk9(Ju6)? zJc)`5PdZ1n){Fi~1lNA^D&agpt}Xa$t-dLf@Ygy9FVDSVdtB2*J~85iaw zJJC-x<4t~Qob-0!=^{?(!XMJhkes_2p5yLYS zdl$Avc5&V{3(;S`0FT?n>Ev=K(~U%GD%E`l&5T=okcf%pa(J+c8jweg@Ib-1Go2$@ zejnu=rEjiEw+qqH2Gtiaau?NgiTMr20=k>i1)@y$*Vh-d?Q50AbZ~4nM0Lg&TT$X- zknQtS^T~nwdh8uR1`2UJYdCz31UuG}*B#bnx1wWE$Te&8_aT@yV8k_p(LDu z0zdqvxWHIuu-V-2cD)|=fZx~TVjNcN#qj#LzPhdBo?TzXNYaOAtJWH1hs=t{ zactM4GiM}Ao6~vOTHdIojgIq=ZcvDwx^~w+U#cb-qKjtdB%~jy=Fny0{V|Oi!Nv_| z!C#hVlHTr+H6^(~E#uS^>R|s`XJ%bLn!MR>*Pye0AkvPCM66jO6751adIWQnis>LV z@(1UTP)l{J7hIL5PRxc7TUTYNCqfh}S|=|qhR>r&nKF)zu|V~E+?b+?=OX6>J1KB6 zaQE#m?hl@3Rg3|%ru+JEe;prVj<0YH4O=F%f%N@-2CiStf(<{wha=#d!Mxok9PFzY z7&&f!5nT}M$Jd2-DaHZ3rH5Odxha@nvAHRnGL2*!D%TIvWK;|}f>f5>r##7ZJBPi6 z=q==(Xa6yx$Cx&m-MQVlFoht{CWH&|V)$HnKGr9SH!>^Yp*?t}(G?dOs&6C4W)9Bo-zXwSD0s3UYE` zc#S05foY@Rq~SX=^xoY5FDYpy0IR90;CG*n0byB zJ>0fz@k}RDKLS!c0#%W>&zb!2cR#gy8qa^?3Eg|r-wFOD_9gy{=SQ@6lY@VY@6Yjl zcNc5S9Q;92{gSXdSwEv`vwU>!R;oeM{YSrJ2n736Nzq4}OJL?2{!j7_00_-5L1=sct^;A$`7NqSDnEjj0tAM0WWh?U?{ zTtfIZ7zs`;+1hCYjP3?^*HNo#&RJ$Y6K2lG$%KuPMu1kavD&SW{)aW`Mm|!5;_F!1 zO)3XvsUlyfa=s7Bj&ebEUbDOH$dT&foY({f%=eE|`y#pO1m$?jiSr)WUpKeq+c+Qy zHeFVO+sJDFr=Hc&HnN(T+oC6`)#7br^<~9~afa@IXvstkIKpW-vNl#TaQ*I1C_rSLEfhe;2hVNh zwmbb$QMEhd4y$vLS?gr&Z3)b`S9lsVjt;59GEV2s^mP^aZ$HXw#0=btbT%k$8J?Y~ zX0ec}X3Dl&Et#-Za_dgkpjDH4n84C_Hf-Am=So27Ax|2+buJpW-B^=`7{Zw_mCx$M zb15xHr8!B;)v*;zuosyPB`V1`z=fk@zm->>3FMS#?V)O|$&XDj6VFd2rbUmZT!)tE z9>B)x-O95a&#E|$)ZFOyvsShZu5SyN8}VsY@tDdyw(jvuc@|ud*`)bOrtQ%vyPtkE z`sQPa@MqIEM=@Lh?oxYqe|<6hq`KoAGQk~XXMfkkEtFX4aL#VSbAjhhFnxxmaQ+@o z3xcx_b`%*1E|Epf6^_CsXEA&c5$fgnYBkJNG~{p|5p;oR+3w@@xgx8)Is|sBw zA;eV?e+mO9bahm)usBmr-nOjc-q9rI-O0^G9>po>%}SL=LY%`EBr=Cihs$>F=fCyV zNw$!GxR=pl+v|_6TDjnY>El?87h+d&&KZSV#kD*G%WW*Q9Hov(II zypi`x_#@ttgq*YP7dG*=CMT&lMV)VheVR+a+h*wRHovsBe0Q>cCAox+1iTN6Vpky8 zy$iJXr71;s+v+P;rQ7OT*p%rA{zSc2Yp1?K^g{@Z6veNkY8piSin9_rURFZ2$`}{I z*C89s5;-M`o;^vF=&SH`yF?A#!MpTsw~woP8s7Q&3@@_({I!jNH&b`kF42FHNv4;q zwWpTwI(8Nt;dT}(96%|7`YtNo&J*{v#h{=U=(oVm>Kn+eBPat2@8FdN#z4HvvSWq! znC8oQjIwne@#GHoa`S@%6z4;8_@Ls9`fcMy{Ou2h58LNRNBCZQaazEK;yB?w?xj6^ zt9x;^34ct-_U~jD9>tKK0159)BE6A%YV$dZWDqtPtKr*{NOvjH&yz@X8YPI^A}$5L zP}~O;clw3&G}8kl8TJ9t@=Bf|kJX%!05#~%wI4gf_mEAKUC3(iS%6}87=lPG*-@TS zUg3WcW-|_{@%#5H6}3o3c@23;QKkdezn&PQ{Vv6(IJgk4-Hr=JTrSf3%ppJ*R@fpUeh%6hT-8)cXTW_x zmXzyEVDq9!1+sT>rsAaHK?55$F zZ=|BfaE;?g5!V_nzn5<&oDFavi?OTdO4DGt{okUw9F6bsXz#bnpYR~gqSwd?B_Y(& z!W0V8rmGPB3c|>_BDdia&&C}#_bjN?%dpvYc**ic!e-lZ4 zq)>1z3|<8=lK3X&B?3k<=f@-?Tw}6xQQLo=h8kdp>PsZgD)ueFY;saXxW>1lsK|LHNW)@{1(e3OL;!1G?`7-my|}AdXVO3WlUwJ zREux{`5FT4>V=}$c*)F`xL)s69>_n{V6&2Ul$#fjJMy$k8A%?0ArNF3yK}J}<>D6= zLn6EFxt=>K^z$vDXDc);QUDbKHGQC9{bqOVbcuturKF#bAG@Kg>r&e4&e2vmY$Jzy z4+Pf3JPuERggg{M9(>A!LAKZ}f0}PhEWF3~M<7oB;Mg|jv((RCFkwP{URQoRpalw0fw7 zI|J0@*fz$+Pfc9VYd&lXZ{cNzyXxE_owIn^TE16({u%;CHz*`Pnb)xUhmbu=epz=; zwj%D?2%n$kX%%-nv$b^htZ=;0*ZFi=QH`SPY6>!n{TK7 z==$SJ3m(ocEzqR|72G|$WdRo^tW}Aa39EHTjn=$wDb=k-=d`xyzN|$Gu@-TqD%TO* zDnu-7Je|7+UaMC&)&1yT)k=3fVbtqKr=(xB9|!&Ut58WMiXHz5zKj=A!G$Tg;&qSj z?%X$ud=Ty$pyiNOHj$8E%b|388U1&;z6eTQv<7j_~GG^dg%kLIJu?Vb& zED~W|@knyyRGDDpafOdE!z3PJ6=_X}y0?1gaHSep`bN=d^<$pnA`%<9+n0h}iwxccOa$*wiQheg2*oSAb;Vu$eD_`YA2 z{|JGj8x#_JMVuW^k(10nUh{pbk?sQbyQ2MtC^Qk(@S|!$MC`Jyfc=GA%kNhX)WO zM|iC-zgJoG0u2zn8#LS0fc-?L`~PQFDmAlc0btMUR)eLH4^?T~HW?&gEN;L`_C z{wsLq`96vk?;_xgiWc|=zBPY*W)}R}kQaXWz18sf9>VoUmUb@`9ppU=cs~E{6BYtL zCI?p<%^xQNJCpxJmY43}Sm0P4u;*x7n%Fg`caiQ@jQ*00GIm5)qoWh2&Xgp^r?bz6 z3%KZ#87No`^6hW|d8>>)dHzXdU<89SzzuMA4-I)@ztq*(F1JcA1}^}{=7L3RcXt2n zw(6(etUcaJUVm0zWG1DoGUEo5D%&m{@Wr<8Tup>rhT#$di@Fn~T5I2YPr8s!-)#AU$4GZ=bWdWlb&#lxnu_b1h1Y9&~p)4T>Ej!ZograsIh)KkW_+iK#brs zrTX_l8+=Vswo2A2l`X2Cb!z=#5Zh*w^`PQ@fgFtaw+YJi5Qevv-xyKf6-0(J=yTKh zJNCmtRP;jkk)eXkWR8NAxcS$74T{i zOaKwwB4BR6?O3bZZwRt!}&LkChgVR zF@jzB@H=ZcWY(rLah3&fucN#oTuME4jW@D}7p;dU5c3z6HSq~aLH9w54-eo3!11Ol#^E+WEy(N`+?RNPs^hS4!^UIlD7wGY?d6aa-ygU;n zIdbfnpXVWK><=^Rf9u1piqb^?KBdgNBO~oOB57vc{GG9zAy+gy!!;WcsFQe2w&|$^ zcPPJ|+0LD71RtUC!!1AuALXrk=8;EF-d%a4FG`gh9{>i@?F6KUf(@uIWSt zrSVcJdS$_PXA>{-M&IDhI&`Hr>TKyB_&~D=~cR%AS?GYX(cpHANO%jgj5F?!DvkuJTqL6u&>y z>wk_LGNQG$%%eHVKJ_ss7x|&JV>VNXn|=Bcpv z+?ArV=S_Wr^xjHw`gweW!-Wly=hPnjOg~o<4$amryxW9!9WOhJpNVmfZBvS24))}u zTA@kLYKPA*fk{bo$-Ak3a(?_T*usg8II*PPHptSh)A8f^2-N}{e6o2d`>0J+y~-99 zfu(Sg{gSrK@`XE;M1%TWpmuC2pPLU)Nf5aD`7tYlZ6~hMF?n|T;1CCUQ^Y|$nn}$2 zvuN-_^?Hh*>iy5gZ7{Y?DXre`Z9K2yIv#0EVfK!P zqqUBQ0LGtAPj%HwIO=HZiM+pjJ3b2O|D?}#{@t$_5N5iYYrf+3eBJa#s$X%N$Lmcg zB0V^xI!tHl@VQnUl+vmL=i5z$utvU&d&I1kYfOR?tqvv8ajM;jrXt;r#rh=l*3I^{ zJKny!QDg`G!M++8eU0({zWRQ8T?n>?*-T_O0VN`$-EqGMY!ldtFR^Rx+d23s3qw5N zx#|UzB;$BDr4WE;YNRK{fSCtUtT}Fs`OfB;BfOix7SAhv3l2Rg_BAxMVDcTYU+04D zfp4Z-w9ht%V0G$7e!KI7mkkF04xz0rg+GA+^Ha|!I>6yVb!{O@E0(xGi%_RH^+FQr zFXBhbCVSAF**Q5~c&CuWvzSkDC5|0oF8BmbuM~VzkK*8E!KduSob~*gF|y0|ysHWU zyZCBrFmYy0IA%O&g1CVqedQkVE{N81Tj1ggb{M}_i@ib=EQaZFFlT096iUIsp9l}U zeF~34?J#UGQZNd&!?6EI!6?)Y!;T~cqfk2x8&3Z-Dmt~~5lQ+O0= zhhYnxf>9_1)9w27r5PB7QZP|oYyTLwmog)%Q7$urC}VN zmuFxUO2arjugJhCl!kG5UYUVWC=KKA{Cx&Sp%hHi@2|?hD3pTfae2Ku1EWw1Cc^U% z85o69Fr3qC&Hbkgj6x}xJ_qyq42(i4n1v4JpEEEDrC_3de?taFp>~)zW?&Rb!??WO zo`F#)1+&P(+?9b*C85o69Fj2kUn}Ja%1=H{HdS3=cp%e^$ z2vnZ;XJ8ac!EpIXFdxXkD3pTXvbtbCn1N9!1vBViK9qq`C@M85o69FvG4qAIrcfl!A%+;^P?@h1y|0k%3Vt1vBFE`eX)1p>>#v z|Eiv=VRG$-i0yHNy%6!WIKp0t_<9^+FGPGJj<6RZ{ymPc7b3nHN7xGy--;vbg@|v* z5%xmFcj5?pA>zAnguM{)y*R>Ni1>aSVJ}2H5J%XHY-D{ES+V}6HnJPSD-XMmvGCD9 zqeMexbkx1#LEb60-lr5#0rh_4UPyWGTXN!dv|Wz1BJ6g+wStmRv(>}D#PEu zuM-|uhHVeh|5H!3o`#y~Y0LFXt`|));w!0lMgTqfH1+7V9r|*A`|^JK@*?HQz*7Ie zQ173&_rc&_U7XGdf={{k+m!wp_x>@xe@^eg0ghIl9KOPSd>7$csrLwx0rN2>(Krl7A+y<2Nr3AX(J=ym(%@&kpg`Y+YaCPUDAWg)yv<#-6OL-61H)QZjH zx?qHg!T%^!l0wo!0x#$Ma`+iw>tt(+ONKYrG9A@NmGFB)wwu00ayhvcX&YC-%i-g3 z9`zsV@_`7f4AUrz}zx&u;)9S@>3z4afd488bZ>zy~g#_@j7FvujYI#eax zpR6h2=D)gxUK3YkYPxGw32Qp(NwLT=tLw%W)=<(d7~ZC=thH*{gtsIK1AZ;;bm=Ee znmVuFZ_`D1jAly{-x2fr8#wE+F&M{ak??Ebi+HqjD-!tEB+)VazqG|@TF>It1nm#B zbbg)ikPhg7avi`3N;>r2oC45VpGaCu+EKT)S_=wE(OdYPq)~>m39Z%|!Po}}NG5NW z3e;1C%pbPPIMyMyq8B_ZhL0)t7eQg;KB33s5QkBb0Ws5+le*N)K^)%0 z?Ht};!8?yb!Q$+1s%%ee5u7HV@E+bAX=4^F=@S_O!%@#F*EC-hv?IP% zZB4T(EIpO+xH}myYzhRu8=?> z!1`%5vW&BYQ&IWX0|%&=t~xgN`uIq&t?CgqVMO)QW* zF#)m*2nG$vZzA!VxIv9>E zNXgRIeo?p(oX6bi3`lJ#;KtGl71@v4&}RIHVl(dyM)s-p;Dl+9b@BQBxpdV9bn>V9 zk9FbHeUB05&Xsp0YdCwc=>AIHdlB#Slk999MvsQ4QSsJPTgBvh!It8l#-ZG=p<>)( z8QR>PtAtmJ;?$0Vw>(VGyFqhf(rz?$F=ZsP=#{v0vn0AaJMq5ECAp#Gx=nO%c$IfT z=*~x^Gsoeix72uzVR~sSe6@03%PXvtZ7)Xc-4ud?rS{HIuRXhhb@s#}DOXAOARlme zTSUc_%YdD5zdeQfUQK*|L);%v;r^Q5|7zR?4+ccK_4Hdf_B7_~;6I_h!JP%C4Db}9 z4-lDx(Np*!SX18(P^KiR4#{A2xyxH@-)_VPa2F*_1kW!H_UB^$cE zpY(HgU_LyjT~$R-QFB!5e7+YwjRjJ6A76M=gYwkgH#Rn>Z@4%Zya^wS$0p|?d%432T!92}{T zL_4ZD7P?L&mpW(i4c!q5PEqK`gmn0hZT87GlP}-7l-dAR<(irnusFB)b_}ffgTb+U z5^6W-Ml_7ZU~r<)M68M!4H-#4l05&SJY911Wsc|Zf-X~QXAK-}@vJp)nNjbC(Q)2h z=xFYgaKa43=nr5pL0SYT<6}&%Kb@z{s-H)mtcC@Ymeu$hL;Q%-#MzU$s^w7OR*u6uRmXX}fzfd4MQW57PPO)2%C zP`<4%$-;cI1)~&$arCjg*)4u`xuXxD70gPVOrMS)6I0BJ6ve>sSc}V(_4qp4 z;x5_(AK0f;A0F0HruNWkp5~jyw6+u(YAfYETVz)o8?3Euaz_X6V*c9OYrA^>t{Fly zQ=?bJROHeC5&h+O&Y&Wgfff}_)cloEIM!YeS;`XWu$LqOVT$sO>-QR$Ms*GjWd4lm zBO@=>HiPrx4m4C{X>?B^jEdzrpqZZ=hZFo1q>lYlmDfVhxFGk(Am~3qI8(Nq#hJPV zjgVTl!_q*CNH|*92#J!T4W(o0IB1C!)VpU3=#%RdEY5iw< z!H((Vm=JmX?oy?#*7j(=RiQo9%hlSRbPRKUWOZOq^Q<*gKSAgw#@D9O!XL=oz{TLK zGbL4n*Qp~NeElS0!d9pHZEt_?@xwiTy}y?XBv)(u_V1h46pruY%G&12*}+UM;)-ca zcZ^eS+JmOsBWgN-ed4JcFXPTVp0QLlJio4YF3Kkx`}I#c7v&h;+!)Vk^71Wnd(H5D z2QbPu8Wn|Wn^f?XDs$80qQ7%G{wZ`(CbLe*n+Y0O=Van;CI*VfUmrZ8?K>rCL1C?P z@{QCbHB`B#uZ)|HXlwgB5)HpiWCxOrI{!H$5XWytFrvfxnNts0_Qnx=GuvpdDKk$zFFUUsMU}wX|B-n;+b9-Dn z%HesTWMXK`=7|bDGOrxY_$zW4omUQL&Oe7b8>@!4T--8ny_~)GpDU+qV?)eky7ZAn>>+u6v^DO(vZBck<@ry#+YOWLg6N7G=3z!pKyWIv@ zs@=XTc-L-9aqV_e|4FHK8;L@0GS4>N8U7hu{2IdSD7Hq~m7M9HIlcl@qE?zMDss+0 zVW|FJG+khXAt!j*

c1D@s%URSVcZ&Md`DKOaPK1zwh|!1r1eP>QR-$^9p{Dxh+m z<)0-pNXJF-hLB>PGE_Ttuy$HLxQjeR=x6(9Ps$|5)W3mN4%7YPre6eF&p*cj`R8m= zcxUk|%J&jFM&gY|{kQx~zmOCF^boRh{c|TDG5M#9(;-iBd@zErQ2lp&$9NSXp68!8 zd8>gR?4Pr<_*G?asWSMzGQbE3fA32jYp3wi)XS;7Y}CtX+$Q8}n+-m~Y;X~?!9_8{ zaUmYjFB^ZR=c!$0}&lS_qF++9*s>dq95!s7lan= zV6{Oo9c4<+58$||5^T(x7PybB+y-}B9968*quj2HdjR*3y_o2>qx2oKN^S8 z9xDiT13c=*I?GKp?lgxs?hS`M?vksbW_Qc9YxKdWX_ePQ)M&5{b1-SMpx!0X zN2YG++g3wi2Kc(yXKpTqO_Jk#(!-Ogv`13c64AMW$K zqkzv7nTB84L!RXQUcVI|OZF<%U#G{i?X3J(wB&dL-2;(~PMt5g9MU#-VDR#cH^t0( zvXkw3jT3<79JkPs2Sju?mqi+%OSK6P2zKG&(t+D+^g3R%lG$k>AJqP%j=fj2vbdDl zTZhX#weIA?(k6)dZY+l{kKEQ6bmfWnBr51U_9T>hu04sc&38|dpzORSnGNMU_9RIT zo%bZOe7J;`i2%wtay=aAZy6ujp1G>Rf}vA$k5*Zxz*_}ljNmCVmGcC*P| zGcNJi{Q7mS?Q4Q^ejWMOkjnfz@~E~p2tpAx6ldH`gCua8LrTQ-ffYqpE3(Z}v$!m0`k(^T$+!lIa zV;}BTY3D54J$=!Zc+nH@h8H^i_cQRn3t=c0#ta1_ciRp7O{7BJ)c4^@uZ#&S6Gw1fe61-E{u(7gn!u6O(&% zqRH`v+ze}Hq=O5#_ETi+HTL3+VvDkKyI_sW^k+J*h(6<#LZ2agK#3^xk*0>)(*C6> z;iTI-*CH^C3c0N_^|PIGw`7nD`~A$$S?0y8QI<8o%Jek#pc(~la{bF(qr5_mGEiGF zfF&Gj8hoRTUllctP6N(Y(=6Xv+>vb>&I8mmIt|$0^Ve9@pewQ_$iW|i%f+N?jS2x* z2(7V@esc`lltC|RuZuX1*rJlO+6!FiC}VmxCIUpvvf7hQoY}tea2Dkxmu2Mi?^>6W zOl*5BS%!Ho!>5u%hOM9M7JF4ICCYB*#yZ-Aqzlv9enhcPyz}VzdCa7yu*Ca~G`z?p z=2~aQ&mf<`?J_td@XPfcF``ab>ms@p;bgU$#!a>x@or;9ywON!*Mf@n7;TB^?L}K+ zW@nLfu5BtJSZn#V?FCe9q(7#Ui-rBmvZUX6gW;DW{(2q!^*Zs_M?3!a5Adu9K_*X` z!7rakn9YHA>vc;<4FnawfGkr@SdOCYS71*2S`o zUiEN+`%@uxR_=A+Z2q}(Xwxif#=0t9o;qu_Xdt|ridPd$6m-6}WSFK{Zk-?ANOGN1 zwQ9f`iOHtmS{~tx)LH?RMkSU~?T)d9@SB2swjfuEn*PW-6TapHY-v{z44^yIsrbQp z&lwSxhgw*;>y1|)uA^`q?@WMgwEnmZ(%_j;VioT`0(`B7_Ik} z@RSL)V;_)WSNn?HUSBDYjW#pS*3(=KXxZ$uVZh;9I(or)U(UVMf5(TC-BH=eyjF!c z;rHSuy5M6t-ASpViA<4mb%m!>+<-k0#tHrEVg&XgNBm%Q4Pvn1mx|{zziM#xUlHEy zTwP*p*5X<^P5>5XMltX?3y8+8F;U$J8%mMM&!SUbi<3pxdpWHrm(o}0>nfSzuat-T z%E8_eo!~{#$wrF7bLh;q_C+{NJ*GZKKj<>OYn0$~YP%EoF++!664@ZkPbc1|PXD~V zTGaeIr7jAFsN*$v(YR(7G*s?@WP`dbGm2-^ zAm7P$pfPPD_&qR6b8YD?wKo5u6L#@%V&{B5aTz=4#$_NJR4cCjeysOm%-$kc!Ox2N zBDhTvSmnVOY@!xL`AL+ViirCg=u|KjEA}e!4VijMdzF|$Y~mZoXCXGUf?LG4G!n!y zU}N3D8(Do`M^>W@G<3)8Ph)O1|9dk?PvyVcMVp-FUCh$h=E44elZc?@uW2)V_KF2( zF_}Hh3BJX0^?3wjrsW5a1unq0(UEFktypklWq=%xsVyQ%Ca2(fy`b6O6-?``>{W`k zg{}lY0!OfwNVhR?A6AT0oO6H895J8$HD-zDlBEcnn4B5=>+Lsmi0kisf}G^gc?&*U z4s&h66O^5|;IpBe#}+)vq4O4ewjAcM1y6G5yak^vhj~bAk{mj3!Dq{1t}S?sGJr8` z;Oil4C=)8)CMssVB&Eu{SB>XA!X?77c_a-M<6ytwY`bCU9gMMA5l8FUV{TM&-C(PA zH~)oU+uv=Y4QC;kLDA{M_})ev ziYwGs+H%Yo28o!7cEK!MqmHex#@aYTjhm&nRu-5l#+kTAo~eo?L}#H$-3fAJq`5yP zb@$Rn>NBIWq%Lh&jNL%$5u9ybqdIA!60?HDhg(i*fJFW)h)v70(;9JyYutsT%QC(b-lh zecIGB&|8$y5;keFhrBu+Fm*ong5R1`vWw%7tYkMj>?%F+NtIA{SO{kEUnmzNb8%O~ z)``2CYZ^~bc4nt$LphJBJ;|XncQsoM^O)|F96EDXv*j?4B_PhBbymP3tJwD$Gi}+) z0Zcel94rH@aI~7^s79Ga@b{79k$cf6a-PoA^7a;t~7Cq3;cP~g> z#8^mlw9)JGvD^0-ee?oNkr+*E*k--tcSmp%7~#vJ+b?fXevaLzG%!m8a4H)wayqsd z_NntZL?K=`dYcl^_4hg!32m4@wwYAN2zJi zussTH0g!M=&lI#BcPYec5?wmiF`)YR{~t&lNB{qm18J=DHf6S_a%mnfEl1B z^SC^YaQxPi{w49&!ojtoTl|*EJND3R$_SZL3SA~)J<^8-PKfrnnRT{HTiVtUv4Fzelzn2mrb_l={Uvx)1g*5ZD+)XEyz|{ zs}7pQbYFO#W`zN+PG~vS;n?n8#b2?rxPa_a$A+o1v2LA>*^$^Pb}XoLrgJi`GhvBp ztCG~#0hJETIG}Q0=~i%t^Gv?r2*=f6mIJD`T#W~fVxO21?f7}jji#`~ENL1(&6h^; zY34MFN^_`DRGLkVqGsb&qvXyEYg=NPYi&!+u&%4(W;I?lf}L>^H5S8kU{IGk3O?J7 z%HZ414^f6)RR%9_M<>B86s7(O##ZoA6{>MV zzgK55uVT10U}~t2SI|lLtvg=8yT-X#CwT-xZtz;txWjA*6!ll@`+p^-R%i?$ue@Kc zU5xFn;B~yN^@#f-FB3oFkg>3Hkc~wwqH(!YO2O?0=#l-$dE0ocJB;^s4q|N~26jGx zbKdFRs_R_S=DcC=Wp8!wx;J~Slg;WLwtV^ozk~6irT_55NZP%TyNw8*Cw~-&IbY1Q2TAzr7QQwKf5yT$CE@p4`1MKn4h!F%gkNdl zk0jyeTllkac;eb(`0XTcNiqCE5;(IMK9U5EErx$g0-K6q<>9Ep6MGj!KMCww3|A$A z(PB7}1bS1Ag4DgcB>noHMq$v**do`?d$&`xx@gH=9L>8!0vebWcP`ofndQTj{9n(@ z&f@=wdv#9clwvN~L}zly*3;O>`OHcVw}zslhqsa%enTe(FN9UpQlcZhB6{9kt&8xV z%?SHBwng5;k!W-e{^{PPo192q(6=%KP@wOvOrjynU%54?7!)Tl05q!1l(;*)8}_^0(Mo&$;DyFldhUQN z__jWi2T8WbRdXd7kCcLql!-UHF_ju7rQlXzgWLES3SOpH^AfePbNsdEBT z=Z@c-^FIumuj-Kgaxx*Q$l_k1=yz{;okIjPjY=i~t)b2}SGbi7;2{YX44ShYUxnjQl-{Nny5$g5AO~fL+t%EMXbirZzVko@Mp2HEw zk?I9_Mhp&Yr{JhwM2L{=lB2;Uju-xzLY$jIE$>m5w)D&j!~>T&J}s zI9wa;IUJs>CmL{m+(+yf_3b6ZQ;v;%Td-^P?_l`0(7fkQj)Y!k&*5^wMoHj&(llG?ypoS!|4u7Fm@dGaR9hS5!hci%9an-QqSy6l95cs| z8v!HX6_nwQ8kUoWA{-oRj)$#=dzI3u{QK=W9DdK>m*wq4ySiONFukmX4$R8N9_T!+ zyuG#xg)Xb1zbewN5fe|rq9F+%fVg2L8u@Vh{t8Umf5Gz-rwP_oW^*hmk&FOUz3@-u zjJ^6ZlYX(HQ?zBLs))nk9`+mwPtg+xpng1Lq&)|M%ZUfUXfC|@G!(~mH^mtk2>*+4 z?CRZYw(my)8=8ZLuqV;YVz#1GzP%SuOxBf>UTAUY@&>DoZZz08_mpLr|NH1rxCLd& zhJuIW#v2F6RE}*+wOE+GlXbu`b%-CO-4c8ZCLy?wpE`~SKScztEb`jz_{^B~ z>nKcp3qL5=#$1%=%o0gHHF*T25O`#z5LGQfG=Ra-_%fy3H&{c6U!>dVC)QIa-@r<&#qJ*F==V-`&} z_{bUQ2A6fS$#11AR6jE==*01Hg_^Cnr^ayyw&IeCAK!|brQ$M)M#VP+=sI!(72hy- z#rN>{=v47N{XOTb_?M|wy5jFvo(ZMNWXPn=<8g%^IxDGoQX&8BBrd7Y9!Z=uzGQNQ z3LQ+OtI$4FXrH+&w6DK!rwU<7WUdNP9i|4GXud1|t)>#4ndnQkCY(T%tz~jPiVW1- zn}5|bmiIv6-f#Ioga2coj&%GLgkMHH_bD^+Q+y=&ukcL6%h#abw=i3z<3C7vJ(C%F zhDp49YW)e*p{~{~tHP{GQ(2I+9osiW(N(NpfTqB?{<|f`J^uE@; zpRe~_?LDaT2&ae$KYlJd{oP#bIv%!VHrG1x2v~Gp;GK&dDF>y^E-IYy^cQ@IGKr%L zzO0v$H`NeE7$45WxHrOG@N$64U6tGL?j=}H$m|kEx8YH(k)g^|YONYho+q}_$2GUp zo$WEv9U4GAQlZsGj#aXXO2;EKqTiiTl9f+P9ALgj#aOswlS-U9kBgj9Cf(+zol#mY z_7fq15*H!|y-<5?&-*(6{ro@7e_G!8uY||>M;4Zem#7O#oc9)l=jfAm&ri?!6U8DwQIQx1MhyRu^_2lvz8x6lv^ z?id@v%jIJPd*}60-hEUnpweB1PJd3`;txa*eGsxDt^VwO2G7T$onI)_-zF+U&7d_F zq_UYF4d_U31KJG-m~|sicy~vj)rde*!baoG5omWzpzcKuH8TV%Q3f}NQmG){Da;WHP0e7 z){TcV)u+evc;O5tAHi7ct79Q@mJQ6Mws%_87evoH5A#^ z13{M*r(oQ-2uJW5z{4-A2(MMfi-B7_ksoN3IJ$kEP$AKx2lWls1#c&2e3+MiXTNKd|&PrdL=teOM5BrHE8PL$cgZZCZ822z%A*@VRYB#|qGO1u?;yAn?!ahD{K zO^6crCqju$5|3C0aao?)ija6vl*qm+e0uVwHY9jkzgneX?&gl8tQ7eaEZP`Q$pJ`o z<3e}2VEEdV>Q9Mr%IqMb%LNTqlysj2uUA8?X*4*DwF?sW=%ZZ{^t%NA41m9jbyA$s z8h6X|%Uoet(=nGKrF#S4kymu%;k7#GOKv>OC=|>@ZH#$l%;p(ND3V1_){{(UANo1X z8$E|a3E~6h3r@-HPw=lN+~oPq8S$^?d)ebFFb~D>IxBb$@f&Pj(tJ`43*#`WQ%4|T z>CU_3fj2_9sWXnpTgL-RvEzaIKe3Yal*%Gy7#Io516@7oHHNE(zfyMzrHIqeqBXEI z`AfD{57&}oYHHb6!Grj5lMxq%nWNkl3cgj>PTWfq7F~;L9+MkN*RSwFduWowj4taRbUMNS>y9xMC!!+Mlp}4V@|%1 z7+qOQV9rsD#28UbF=hhXi+pHjm;j0LOllEc!j~*xxIc%0-mFqs_u4eq-Ne;|y3fY2 zO>;fo)PJdKXl^(A9x%#0W3w-vhzzYY?LH119TZMJ6NaD^+$r1(fm!Hg=!K4T{!;{X zL<(vVP>USYA_w(95!5qNP(Dz;gYq2|`6VsYb^pFb;gk2CuHt zW3ctDq7{j&v?JwDih z)qQ^XvNp~diG^Y06W6;n^3x1@t$Bao8Lw?3-pBbzPT=iIARR9~n!`w&p0P$=3fzhO z-!lN=h10 zNl7Cr;k!YZufLs+GGpRSBvA=lB8hTp8^-jV*@hKTQVIMNw8RnwT5<_y^-h8bqSvu} z*-pSoCbV2voM_#g|F-Yzvyuuh*v?Nk_e?ZVj+PP@Y}RwP^Q**@zI$n#^f?Znyi*;( z0&n|0+tLwetw3xf+g70NwiW1!GICqY@GF-v*Y#3B+(NtQUy_a<771k>9bD=31qR>6 z)p4-E{$a-?g=7UUGwYU<6@7_JtB1#28W9Gz& zWu<5T7fJP7m%}-j4DJ6NQpGethEB2Szhl2nRMC^6ik>#AK$*?&PVWI8qEAH^|H*&c z&!UTO@-MnTzdjSclJK#_Uzv(0Xml}6+*bZ$x~Od^c_%87zudsIENRP)7d{q#$$CXx z%JV_Jhp1`Ru>wX8WD-7?cXQ5w^NG+E!G0?b7)+(}e^|1z%*0=e@pn0deFcZHuPZ8p z!`ufeuMGPN9dOIn!-X^qd*CPUUu-U44~*XNl~2mogZ3R*pZjZkJxIytN%?wUZp-+3 zcwfAEc`q+JizAXha4ugR+olxf44}u^P-45%<81jabiN)II$QpW*cv>nozbF{<$j+K zmlRsQ9yrULe6vwRlv1k=)&`m{B1(dd+iQz)y3oPb!{UsIen}`K4M}`Gxa8-dg`&>3i2D6?cUK=_bSD8uXF>pejp3DM1aQ_9Vo^5diY=#W@!sXDJfqM z%bc%=WsW|U({3$a50bScz8;pRCmm9ovP0@xHd3BXyDy>%F^`s9-CS;z99`YaMTtB_-#l6b-7?k0u}9IX ztt{g9A@cRG%<_SG?|eOQ?yG*|{8qjmCh!9h zNK&*<|32ycXYA`i=d&wk2m3NTs_7DkTm#x(N4_35&~zJO$<##R>w$yYw6BN#!0UWH zH1YM&biN)YJ%2Ku(`p<2jq>%dpY!!F8A;6&Ul04i95h?L9-3KS5Bnu(T}hU+9sMPrcfOOV&vof%#^>{~eURkP`A+I=Im~sDHbL3> z66$Oy=W&rX$)WSzx!H2iMV*;V1wZHxWb21B78AP@Ne-P&e9V@EZu`tPhh-fNW6YLA z(4IqEp<8!zJA1ZB`J=#T$>bptQaDC%lf>+2k%jrASjg;~_D69yQ!pz7{wNk{UY^4r z#iqm`g}!-W3!Jm~qZq8=AY+p=*>G6n(8vu%jVbu>lr@1HD6ecs;DbWb?%_xuqvTUb z32xMndBPY1UF;WP;=P;`W}QO#2i1=BkDTpFW8yMm)7B4X7pdiHjAxR|*fyo4Tt*z# z{4z42DPQe)w12dJRB$n1)9(Ok3X?>|+A;ny{?XI-5cd3Iw&=MaWxIll_zB=OKkE=O3H3E`jtdlbi~)OeUl)PEf=&j9rS;oHhL}N;*_K4lfgfwG;A* zuZC0nQ=G4c#j4?{7~Vf-`aM>|Qyq|h>K27}76;UDmw-xQ%g9&5yGa2+53RVT`KLv` z8eClLt05JtBNUB&HEi}bC%zg^-B}z|2A3*>-zx(IC5_tYL$x#f(}f$S5~wctgd$%J zXW*;h%)#1OUQ__*tHG7lbMQRw0dZ@j7_L?hR|vk`(Nk`q17t!C4fVl)C6P~R8LBoOo`e3qa4p#mo{K8 zE_%vLYSAgV^Qxecb)kP@*3-f>2WuBOPYciVFS@;UF}-}T^R#fW^R#erusie;b^0ZV zr-h4W@w9O9tezGe+PK{v_PFsc>0po$E3c^FIU|7|}DtFejn9P)V`&$PVneS{^e>*~qs0z9|R`C0fZ&ounSz&*rz^>joh zalGuytb#v4pWuHjGh0!w6=EhFIh|A@Q4K?%C~~+KM?EnU&O!2gm~a%{enBp1#C2q~ zgl#S+Jo&sc6RywymrQt)LuV#@wjAbS!V{F8nef?A&Vvb0a_G#2&z8eHnD8Wr&P@1h zIn09zPjcwYgwK}4TugY3GR1^P8jo2EIcTN*8lsepPudFa(M;i(a7^OhXr8&5n_ByD zw1mi}Dsz05h^g**Vt%^YaS5_$-^~==9Zk{L&e5R*@*PxE;HP_2c5GT}QOr;4=n8(i z4}-VP?u=R5$new1F+d`-8pcm&?S%LobcYqvTP^$PJ$j*(VMijnr4 z*K!Dfcvk##%U+vgjMdn7ocLd^5dDqpti@bJ+S-`LTg*E=37csx?qHyQAT1|~xPu6_ zrk;4MPv@3i;nVTybv+%QSTCWhDDLR99x zeOY^^?xK}+xA1PBUOw1W+``V{I|xm^lb?DQN|kj^JR995I1nr|+<;Q+E*3_2VEUuPrVJ@>wSTDHRYOAJ@ehAYVlCXJw*nRIOrV?#EvSZZb8#{%lTi;|62YV z`_d5mVq;;?;hx5N{@0E4G}eyxG*&O^X)Isb(->XW(-`y$bZgODv0D$jqZRd*MFx*{ zS>QbdL>pWA>r!H;{2K%0H9%gA$ft*V%H$K-c8Fa~{n97|A{S32Tm4TF-l+pcm|0&_ zEE|72UsEg&bK2bFb^w)h{zhBArh+TzrNq@#iE$C&B%qN9K_l%Cl=#~Cufh}aUn-OK zL{C!GMG@!Xzl3cr{ww*sGykQ}|Cjt%l0#?yYqlKb;=dA|4MS`%zw?6!(9AVj55W4MVpN*|COuMd!<8&N27!h-?d z5rbLka*P<(SU4d!Moc%BB1WwDi5am-e^-oHT7P#?YQt5>i1jtD#-#Fj3@3NTz}NAMX004~2^#?jy7_ZL$&p)3y*j=qR~O2+FpQ42@~~JA|Np88cFTw=q$( z*>#HxJK(g$cOy7)I4r@&6GOiiQ!5(XwK z$>fmB024#6X{lvoCpV2o!xg+@f!v);J9ADc;l(`P%#UK8&wU#kC5xcavY}K|ZKQvs zo##vHrT%3H&;tb~UUQ8Xv{;-;#8*?ah9X-IHTO@i}=c)F**-| zfY!l$#eAX`^g{@5<@p(&X}9=?a6u_$BSS3H}E`F>vutX$%=u~jWrQ_@NE8t z>3;qPpw;*D|8y{Xlm8d<)n@*idhzn%^I$Ebi`W=Fxv3TE%ZIN|LR{H3PHU*Qc{<Q)d`?yu}^rS?xyy1%TAC}T8xeRc);(VSI=jbHUKoqA{`1ut_n{e9$T$vA3Ws&KQ zE=Z-8LCvNo}Ld=L%EHF{)&P9GaE*!rb`C)ziAlB&_uS$l9Br^`!ZEH ziqjf4qUcs{sV7szjTUJUXl7KOKC?K|uae99%>&qg-m zH&rM%en)#7vyETb0D7A3+3nyvyn(SFY(ijAEl$>53tQB?U@A=vy0vBqJ1QzT1*7&LnH# zk<4&!zQU64&LnHx;hb(5Va>Ir@X<_~1{!H2q@7+0_X^UvYLJmOO4`#(;d3%+TJ}g= zLfWcQc(0}HMNQ4(6bZ{nD4Qp|NJ1o;Ma9Fkgtvc7X3^2qd2CG_-DjQDlvzw7d%UH|-a zEdBZvFFT90X>6`jDen4bX%IyYlxAeJv)0>$XuPRi0Td^I8n14HPJa?;OlELgSoZt2 zC}g%M{l1-OqDD9!wuOUoUAxd>^P4w;4QZ=gDedQ0Fc=mg#FZh-t)Bsn-LrLtW1Po@ zQ;MOpd$w*n$E`oJdD)xuYxPCcp52xNeH!pz`ZUl@6uqMsCjh7wwP!#YdSbIq8;bxoS9(h`W}C1$@-E%G@=3x*$xm} z3q>rq)gLp7Tf?b87bEp&uk(hX7*wgj#2|flkLHDU^Aqbb#%kWnr2(8u9~v4mcY3j; zyKBatV{a!cd^LS+hMm%*QfGj3Ct< z55rYV+yh##EZ>)T@3oBg162;|$ZB*y`?FcPnP}0CQjBhxPqCibU^2aj>Pg-$>h5jc zOsL|h5qd6!Cs8!J;2fTw6w)pOpQF!cX}j6Yawe0*R|8@-v_y3|?nNaL< zhqZK52P9r|8$YQw!9c~RuA{p0tC+INS5&7p&Pk!sC5)mPzj3(NI3U%IHQBUSpGF`% z7MKPCbXf|43|JJ^uMOl7%XzS5tlPBI%`YgPdbiVBKja_Toc*oi2Cx=LBpvH>`9l4@ zOcK1C&CctA*raitvm4K5FrAw^;f;Gm1Xe9-e(7#(&V_G{35ZP$lSX&rkX-noIL_vw z;qJzUT=?lY&UP(uZDv07OG&JDEM4AcH-{o-JYDn4hbZqsD#t*z5WJ59c9(8rSs|xI z-1Qm=-cMB3Yu*AFG=6nucFsSong8^?Tz0IU;dDKd)wVTHORcHI+j2`n^Q94fht z{<#zDZRdY8|F7b|i8WDO4(f*0LR1$W?-SNsT%LyAzP# zB4lb2{T)mj97{uDk1>&vt&SWfuOm%wtynydK=;E78|LKprvlH#QKpS znz~$91dFq!a@bs)E|H2o{6!j5OTA^2vG3#s-U`Z2zp)-0LqMUi2=m7U-c{WV4Cjv0 zGR_}>)^5a%v%&7`V8aI)6yY!Uakh6P)U&+po*lml5ll%kb>zyJCK#VzUG?i$TR0wikb*wq|%d>2Je-S>s_~je+kF%=`QE$7g)Mz+)u?XN%vn6?jvjAE7l-#d#NMhMG#=T_d&k}4b@fx28vD>k zm}d^NGTZc7e*uMqbRaYvl+7<`QctYQ&^G&ch438OINFnMfc4zk3hvCs!Zt7*_Ur{$ zbvIuu45?v~uU`y*Qvb10^zf~8{F1T3?Gu#8+2T82&YzhE%~;)bWKK`^WV`DQ>>)VK z!r8DrT|@Cuey(|=@;i*T*__(N*y>d~st@$(ip$q8EZf`4yQ!4hB&oTn?CDn7e|Ox<)hj(71(h!;Ce{689e z)5VLca$K~_qOsD&j}q^g=J2fsUk*QDPp{LJSSsO;gr;_*q*H1lo(3hfHkrVa&?R*Qh!7#fIVi6xeN1oKPqH1rf+0Mlf%f zBsoE9_!mn`6IsO(*-vOxF;TM?m?1lpAkqcyRe=!>Hr9GOmf{{S?0pV)5{$>Fn888x z0EaafGggJFR+Xu6<4g7+7|qRY+}-Hi)mX4}jg7ma_Zgb^h&kH-&7`L*^n~r-TiJfp z?3KZF??Tmuxva7Mxc0He*B8wB^}ZUj`|(59DW5>#$=Xx&u7O_Q4p_rF&m-8g`hT=O zsi`St5j2^FXqi*zY?+E$hW$WeZ3zK6M`PS+bfp^diN3VSIAUTJ zGQnhfKFIx&3krQ1lu`ioX(OB{oao_|AiIJ(8xsD zEiNn@j=#~e)7ylBo`w3W#SUx6gD_fd&Cp=~7+mCxSw0!mg-(k^>hpo^zQ#$iMhxHj zeMZX|qO9#7Z$~RFcFv`p=HW;Ly8V60`1(21MQbhlL_2~xRv#?jHtI)0G0J2%l%M=- zQ4Y_F@>A_7lh$JnZxyQ!e_p+#ehj|}K-|1;)hrn0b+a3^wqqOA*!sOJH*>7G859Mo zW80Kcr!^bFX9?Ge&1pn6XkUL$A+tGXMKdo3vDBdU(rSS1tYSAG+s)hEj zsznC~YSAIq)dC4vQVVTmDFWMvs1_Z*vRZVAXD1;RPr@-!u*Fm@7CpCfUv!9%Y9SHY z5uLxJ79GBGwLngm)ItYp=w6-SHTLg}$g0o*Ra6Cu+xecks}yJ))fV^TXChg=dv`P= zqm>({pQEm()`5 zzg&)roTR3(*^)F8uu0S!6br8{PxJZL%^?her3P)en(lN}*=bF)bFt#^E=}lE(_m**zn(X$_~=X}%^sb( z%0m%CS}XULQxxH}zFlhop&E3Cs1P}LjYSWqIG@x|^LoTutXt8v_|+QACQ z61zS2!^JxGHLKmkJAsa>9_?kxx7brImI5XOcF{2|BL{5ct2Q3C-%E%!H;OXuL!j@M zQns&9+(e2+Z78(uF)QBlp6@Mjyl&ouca%&kmT%Z8OunbFOTOUP1rvRC^~f?$YTM0D z*lk;pdF4F#C-1ln4!H4mQJS8{;q9C2srA$q&HHF4t>ceZ(n@x)7QUaa>^!1}F^yIT ziSB%iEpjBY+Q%C`&J9NFqN?q&`K)n`R+aj3J;2X<8S5RDvXJVT^~<1{y}Q=%=VN6EJG z^;go`_4{m@c2LVrBOExb921o_?~|XZ)Y@~*Rfg@!&sHsL!<}Y6!}fVvea1AJX2z^AZni_@`xw17bZf7h zmUnBPmY)nU4QVP4cH!46WxJWnY${D~x#jW=(2os<67}6N6gB#!Xt5?CV4&NTR` zdnVu3JTDnA>5;74?4#Rq;Y7H>b&?R3!yD`=369|32>c0}lll_Lq??ym+nHcb%&AXU;k}f|HSQ5TCll|51wFd z?U~aR2zMKv%*2Y*)wfgsOlD?J)=moWkLjjW&gWHJofxnl&74-bG||qgL|=BLrd6~0 z8p-Rvz*y{l@O9)&XUX@TTjXpRFJB+ey2&!`C$-jLSO2Ng z5W(Y%W3wdj#qd$eQVxzK5Rd%cX~i6$irLR%PEN%fY%$mmj=xH1_m$*%ax2fNV}KdU z2PmPV^Ir%Kw`W&?J_6ysLU6QRqD9+^hLgtNbRs$NSJ^6UWvjH6trE;ETO~-94TUnh zYREiL@E(JVQDTmHlc__k3vxZ^dAhd)s~p z6kwA0zS2;AcZldt#RP0*?BjB2sK*a=O5nwggtqo&$8sqK}U{8Q0Ug6%} z!q}U}I1vH%1$#tq3xmDdK3SCh1V58jT0ht?0z5b=ZGQx)7+DrHz?#U#3ef@_NCQ4C z0$g1GS1oebkGAgygH6%fP=HR7;%4^#8ASgLd*9t;t-+Ue)Az_#;j1~EVm_;`b+WYa z-l7x2K1>|5Y0Xka0E?+(8Kms#q(V!W&T+EMMCGBm4sIlbo5#UT zEHnz>Or+4*KGnHn4USDDgVFkgW7V@6v+O%~llzf)2corcSL%9N+%7t_V?kV`EsmC` z8~ChO=Y#)fFWRe1eyUq0o9!E0n;fjkA{&>WQZc-~Qs7i2wQ*h?c`A)dRPeg05LD(U z(T?KU4il$N;!tr6^L9ME?oxg*IF&b>ap24-i+BW-o0Bmu_2*lLYF?&IS=nGfe+X-|ZPuiBz_BU>oHDkg}NgI`|jO#Gl&!ZsI#; z=|XT2FUde{3Y&>PilLT}O0Y2%qa~yg?4OF!5>g4C+KQ?5Gfnr~p4fCdPV`>;bEndg z^M)7fdE|nHG=uSSbJFXo4~mn5UhhuP>jJx+ji@T#Q#(fLen7-3{=lBb8`U;+dD84V zqeV}S`!X3lVu4z@`5n@8Tcop*53ZpCixz~x7lxc^eIT$i!jR}dS|B}=COA^-;V43T zir{{x#NMfscpbw-_Q{Gmg&z+aGx#10&QQc+B)he)a(2%!$Pkh8iXxgi%qNRf8Zbqs6a}tSPWIMeB4{=-z1=}%Ydq9G7)O{OoZAs6(Q1Q1V;KT zoKkq#YrHthbqX@3nAc44yT+JDbLwR*o<`jk>GlvT3-(O`g}92J(Q8x3QD@WqOoI)8xPCHtr@zlZ9Wv|zmXNM33IvmUUhySkW8tzXR*X`}(y`qKOF^8U=)iUz*=xH{O~{29Sw>Gqzf6DV-6S1I=u z3SF*MAFx)XVY@0@^qy)|iCgNaMvVYkZHg4Z+O*4S92d1IekD)r(4;8Ss7a+bgNwY9 zHE9Z+Yf(;bT#GVved=Q^N@q;&Lh%`#?gQ+VSer6ruZ5TvO!V-=s9!(^IwGVCCjSF? zns9en^}+mVHOlH~lq}f5PyJ@~vslOdBe0ne5zYw|ey!&ke($+vslP_A&|oL2!M;K<>q9JpgF6eRFg)TFW}>a1WaG@2X~H<(vGA zs_dKdN)}aTdNBggeWFFdzM8%K=7#~BI++}`O!oVAHmcR>2kH29d-?s>E2`ck(Y2LM zJ=a7a>D0JYq6We6k+pgTBto_kWNy)os_x?w^OUx_>wI)ECwb{2MD?b)PX)=wr#kN4 z-#Pf46!%WWN<*8wOGReFg&dt454?yKhGpza59A`gw_v`R&ehnM+7o2eV$S+OTYJua zrnb{3V{SeFDz6?=7dQ`|gTYty4A|pyTv`m+nOB3aD~gP?W}XGvo@aPBQ7P;J<-*H` zVV!;f!9)s@&M~Gt_YAKjaq4rLH5eT^^L|(>qb{H=&gT_fZ5&DSBKel@(^B{;;Qfjz zsvED%mS_*rqES;W3bjF*`VOrCrU9TQ-ig1l>a{B+{}uhG{0R>9HeS^1$_plJS7JHN&!uMr@b~Pc`17J1bUV7FR7P;THzh1?p83gQo z({niUaM+t+su~=meUbK^@i86~7rBpf(U;}Ha`;ve&B4 z##&MprAAd5ygk^cqI6EBcu!R-6EGZvcIFXud!`X!aq0_nUT~nkf*~oV$~LrFvwAhW zJJUi*p^iWWHEv&BfT;Bk)@sfFV)DaVYwh;hz|^TAHCHOuQqwyaqyB)kzp=;gH3QcC z77|~h%QScfSiB_#`eeGwYkon~$$+C^W4*a)Gx<+M#@L2}{Zz#WcldKrXQ4%%uGheT z?NfIZ$!_B8jla2p{?Pzi7gf7yvogluk6LD}(gpii!+VVuh$~MUh~t5nIul$2DYA=a zo5eeer-5;5Zw7AtMy>YG*DAoRB+a4R@0q+MRXu+&_%g&-Th_m9=iq8)5gTmv0cK!F z#ZkqBeZeUGKtuIpl3-OO)EO|Do@j2pyV3~DQUhi~`S zv}Wb%R4jB};tsc~Mr{~f-^}{G*I4a^&t-7Owbg1I-bREwWqAq1<2p#J22;zD(#V+oW{Si7x8M~(M<;4U0GNZjyxZ3dksHR+xhl7-Q#2%wkSM18_(h))b<;EomWT! zc6qrs^-S^|3oiydxR6(GEEim$Cvx-#S{0jluR5UOmWRZ6IjG{6|4<+Xg%OJDqAAEyCZ~Y;8+D+mg z@UpXbrfB!yNf_Iv6zOm@w*Dv!bCzJfX)sEuqs~D_4&B39(6d|Ulw#=WOM&MA<=bE= z2H)Y=^vWF0 zdDHiK?Jorn@EBiASem0SmU`I8(X=Q&G}l<&%EvFp8T~$$(T-g~{UC@Y{)w$j*UmvS zRbpXb{4M2yGSx|rpZ~0PNh6lA6}&4c=rbK1o@qUkuj^?Aq1Sr)bFQZ4Ui3+#_x_yY z`zOY8!45Lt`r~YCo}<=$h=j3iO3`&33^ux!0*^$?c1H6I@?OGNa@*ht*H5yz&TZjR zN_{!F>MQu!`qM1nc>?^QWvZ0=N&()}t-;x! z4<6y6Ioc@=BldOVRVrJrbHlLw;G1c!a)tYcXVX6t_KOdfWE$~Qf%F%WUI~5W`ZUkqU(lPtxwcD?tS+JbHhX8nBx&x_Um1&494+E|B>C0`7FO^!C<+^A7iuo=e9 zbDA9nWwKLROOFD!6I+@S_b-lApiBn}8uBg?UMADW0IBZi!`J$?6tXn+pM*Y{sg+rGR~uiE{ARIpZ6zbPXc&1^K#1J!{1osmwGB6b~=YEf7l14b962gMSCz zT3zHQ200~HT;a0fXe0@F5_=;bp9L!mcAD9II#hmj@Uq}jfWXF2-77roa)XcQr67Ni zX+PjlE4}CUL~G^OyxksmI%PVyouHi$Q=hE#wt3#Ih{YCYGc(AZDOd}-?tF2u6pSe+ zuQVtlx)c9FGeci_4|$M_2$a%rB7$Amehu_VFUL$kRf0$0Y1A<*b`O3`4g$~$fXTvEq;cl8O5JI{o%&LJ=O$YrJQ>ot(`oa=K_oIY1hEh){YlJR)JzZvkJcv1NxOtS-eu zfJ}zCvde38FLQ*72n2#11`Rw6K`aJ9jrmGf@H>-p5bz7PjdNOvqx>6;n-kKk*pGDOj6~o^C_k5~JRO5sAxARh=ZN z3~nf4;}^M-?_6O=`U0$h$S~a+XfOYVxbFaus`%cXZ8ymV0!bi1kWOGpqly#@U4n=p z5)`G0(o|M=1#X*N{s4HOVTv0wr0h^VND7*SC{Q0&+nHWa`2oO91?N%ZIM|NXz` z<9W!w_nnzDGiT29xpP5aqeTb?AaLSL2nOZe&}}FUXg~Tblpl&w7ek#XUIY|x3_vte zf&qwpB^ZEctONts}t~b3HYW2d`kkpfiNZf zFiiym5KWX|00Nu&k~Ib(nkm5mL~|t=fM}rv0}w5hU;v_(5)44JR)PVD0woxL!1+T- z2Lljom0$oOqyz&H?UY~uqEHD2r1PVo%0V(dx*j@V&6YOvhHkVEIo{CC`k<#k(2epX z9_}R^kX)pa8GwKXNiG8rB}y;=QK|$35bc#<00Ql_$Y21XqY?~2bW(x=h|Wqd0MSJW z1|SYsf&u9OGYI}??Jjx%jaz63*@##0n~b@q2tAd6HznYW33zh?-jaY{Vk|PN67V|- zcvk{`Pw;~@Z`@0mY__ZBfB}djlwbg&n-UB_bXS4_h#pEX0MSzk1|W`9f&qx5lwbhj zXeAhcI7SHuAbKgm07P#k7=Y-b1OpI#m0$p(pArl}^jCrbhyhA40CB7m3_uK2f&qv! zB^ZDhqyz&H$0@-8#9$>DfH+{7U;tu-5)43;E5QI(Ph+9p_?2;4=ods5^zx4#_xu+lG@1+f4358; z^QeE1?t*V*348wlDoipD8eISqonk-(#t2s4ozC(dP} zeVjOtiPtcmu8a^2VNr_JTZt3pbR!fF7yG^5P-oDU&@^xb{Y3A?A;C(Vj__9vqf){6 zDHwhn^ZQ6o2oFC26f{-M)G68)L}s8-6o=&LJ}M_Yg!u{7nwB08!RdVRS&5krR!}l= zL2J660^OVG6sPHX3or&bPqW@MdsEKSc+C{^d`+?<;pS_bprIa}mjY*aT14W%5VM_$IBt$RNN ztqPIo#??g=C8Eh-5IL_VP<-=| zz7)?ySJBQA@4DGR)ISxpGpQ-dTS zVq+nE$qMP=NWzP#rayo>3!4?^I7N+fkall5m(NqNP%7glNR+$s>NK*cz-N$E{+d(yfcR?Y1>b)y|8x+Jmy`h6cHud>7w$P}eH ziuZ@G(-_784r`^pa2UT_De`!8xiQYYhNUNo%zhSP$jn2-NKe?t!-|@N{pDu(M2y$1 z9lhDfed3zO$9Q=)DLLy6BRwXEN^!0&R4ZwGHig0OXi&SZGz3^ENI?$s2 zac1RfJmz(%>kE%Xj&-$~nuXTct-C)*jed3=j-T&d%`M0-D8?F>P@(aZm^RsMu%hRx z2KVd2wSg=fV?3=saheSmKPJbL+cvvx@lfat+iXs5C_9A3Nbx~g!5azcpHHdQQCa*F zCM`C$%Wj9aQIcaYD74Jy+(OHf;zY3^qt{Z2`oidJ-2;||*@fM)e2Nf0{vL0r5KfVg znjrAmZP5FYq8P#b7`o4g-RU(@HkjNZZw2@J6+AwupkYIH5l`yrJv7m=oY|pA7R(O0 z#n_+nR?r|KyEyJYx7d>5VbnsEWS5k@?aM9>X~1u2jt2ddTeE zNKb-=x{a7GJts#zh5Dht%gx0-BW7>kT-ZnHbi6-6Cku1iXSb)%!bdKAAw^$B4HDVx zQtkWb2E6RLxgD}Q6rThiccz5%g-=CFsbo54cP#FR3(?_0G|qb9^ANe6yxE;N!M3@` z?j%h%4(D(?F14vwTYp{KWMC}Qjq4IhIe@l>V8 zL_RclcnZZw#d2JVzw8D`!DzV7{z`Y2zXUksOr)J<+!GQkh>=TZ0oJQSShX$+UnJ?B zo+8PcolQ3?QYFFuzLR@+_Ti}4#NrMJZjif?DRs^6>eBsPI;FI5*?D$$!|+r@jr2Z* zSh5>(o0nK9P$3oxf+40S={Ddi9=J+Q}tJO2U5}jnI)?|D*Grpi|ne_I!%vZv>fRKpK|cEr^)U~ zF&>?Lbn&1h?~%zQZYE{Sl@h*?AO1xq(KtA{*rnbJ1xBH;++Nweit#bC?C`l_39BGG z(F8P#+{RKviyMmOi|cwT&>7)A5lrLpOC>-hL7h_X?B4XEbarE3cH%Kn%riAO`ZDJs__^=mg4v zv=rgzp?E5#W3!LNVR^h3vDe*8?+*j(kNa-Ufa&1huSh8jz=YC_>5E_5A0__P3}fEG z?_Drb9Jsao(|E?|M{_AoSsu$O$UQuT*5Z8O7m%ayRAB6G*20x~w9%EGaVz%w zu?KY)_^LOk>e3`Q^fLaGG*lj)KmxB*s$mGn7t7-4LQSb^Y-oQgd=4b@Oe)fu2pJ-C z67Qx2B_t8sZ1~b^MmkRDoqeRf&9$L26rWtOSxzeWo5n2p8X6h6lYe(`c`aZt3wogl z92!FhhsgsUA<6O&Z5FKl#&N>EeR$&-z2QGa??W3$cSx0JsYH^4-&8&Ie|I~dzOY=- z@NcCJ_#a4X^taORO}Esn{l~QB|E;utrKrY#8~kAPtl2)xYUZ%N4L;|8ke4QZD-8>M zshX*tn5KUl{J4LUmu4CNP57$Q|AkC_)tzRsI8{Pc&vU5AfkGOn=c;fat!088uwDhI20owG&5-QZ@AtHq_0nEkkT=NtSkA^-@gKI|p~~ z9ZDWm_`^6lE0@enz%}H&cGcj@p6KgwRa|`=8-{=hX~!V+zexLFO1q3{&{q4B<2QRl z{OVwM9Q2WJH5;ubrQ1FXM*8%OyBV#%ILPi}`b3@`u_(3v_;_45`N%4V)tk#h~tB z^kV$Y^x4yFX_4|@W&M5=)x~pc*hta`YY}3 z9#12J!l0M-KBAb|@r$esK%B1x16of-y7XMxAcWLuH#WlSQ}+*w&m&=V9;(PJ3gA2A zMFuBcXw90=EMbvd&I0jCrF!^?cytGR2Ia&b-uu9zWjy0_C%zOKtd;aB6}-ml?s?^# z+!9&yrF-E>N7EDJ);4r{*AH{T3EYk%-y5w9`$30IACr0uF-#|S{ziQ5lq=xqn3x++ zYm?VQ&+B=4KW_%&iT+MI7ml~`Ab#;__dn>zU->8f1S${F4?dyr7yX7z0PFG|{Bi2j zHx`1^ol$gd5Tj(2fiIi|76Nd^&6Gk=h(Y1+&Yf8G0^ot)f7)GwfM7zZnZTmH$!>#_?@coBS#7lIA)8Qchx;8&pfP zjXNpLSUIw3J{obxs>M}d(_G}HxnV+@8*!R53?Exc(e=guQIeHz+PZ(SuXrx^rj?`8iR=o?f9d2Mn=rQzpp~vwDyYvaEh}n#` zN6a{h9d3e@@`1~tCe6X?8BOV#4&fe?oc=jBB&JgQDt2~SPB7ezywg?&RuqDvj^tFU z+jCGFO<`NWG1LiMt@IG>@Zv7fYhe7j{xoWNTT)QEkK$_bU2`(iqykHw!M z;Z!E%wt`%ma?%wRUGX9#UcnEy2G=Gj3L7*#D>05P6bB}B?osV8{wBU~0R$$yS=EXg zDkas)RVdR1Y(Ev$kfG7U8S2YH(t0gzQsmJkdO>dGyzC|17SFT))McWV*^^!heF1_un0Y2kM86PdjLJ1Z~1dLl0Yg|3Cpt=kvYt;@nxw-dog zxFyxxs;pc7C8^>1fst@mRdZWm-M*^kmVT**I}s>3os+HG!`0k&S~pr9N)FfjGL<ClL7;0qqcZtWWoektrvVoi% zHxP1(8wg%o_J?nwmSkcLgK5;}EK zCs-6Nq09ukZ9yWV(~%rHU7ZsQm4dGHreQbV8;Cq(bk8=sRt1r?Dj5u2hn!NCrPg2p z!sC2CWtvV|&!meU$f~nz9dc$+F5BaQc14RqJ@ALBIgQHcW}4$n^fpK;P}vv=2E#X! z^;?Rf3*VeXdC)S2ZzU=h*HdMOar!GrX)s89N8lc%@>V;(SmXJMst&L51nX5DMa5v3c`@aSM!39?1gP z2CS5Sy8AmDW_KzjeGuf*>doJYq(Y4+EO{Y4Sw_RZl@TFDB_}J<{Nw4U>B|TB62j3? z&Wi9cRK^*}lTL0>FziHc)tL+iADzNQB!6LvFPAR6ajm#ER}Qt-+F?qMnse=N+-zNo zg#?V~gC*-Rhe^CYK%_-}(8kXd7#Ty$|57_5ky2o(1CHze$jjY^RQ-QV@7P!Ok1JL1 zid7e6gK98US?rw>CG`j}&AL*T%&uv!YnmT#>QS9Z?wqYDSFbJE0od_{HQ6z0Plo$$ z)!UvE+IVYI9Zu=MZ8fZ+1GkZC2TuL>1jx9Q`|rf6Hs4k?8Vu2V!X0#A9&iN4f3q(n z57h@9HeAvmP{tfI7x*8?chUbWJ|BOr@v?uJKV&Y1%%NGKQ6Jt2YGl$Sr`r@LEY@$+^}Xuz6EdJ0mT8IMr%eLTY6) z(sI(nUFq3o~@dHV}QDgTLJOnc^OF5!i6Jd3pkvM$Effwpf1KsX}a_~_V z`s<4oj6XO?-3^jL-RVycDw8@X%Yl(MsoA5;UvSuBE;zfCBV0q zV7vemABYR%>&lm2|EnarfgnNTP*uUYm_zpn&^!=!`~ececFeEdVbauXAl#~zLEMUI zR`^d=97wd{B>SD0WWRJnG21Vl%4=oP(=aP!`=xON2C8XD%G0D+O4B+5^)SfvMZO{} zx4fbzEeHQz%fVDFXW+eAyoVQBOq#(1T6NJn%`%De7xhWUHT{35b(@*=YKGwk(u)CP zZ|gxbkCbt2L1#EQwZcaeLHGZlAZq1ib;EiO{qsl0pAGHXn#7;vj6c@G z1$eY8i3|7>-dw27rIpK9jLG$m)IVq8{b=lFW;CFi`p}fq6P9i{0$j$4IYBU+?wC)h zNKQ%-uNVCld$YAOeBp!m zbyrOKS4*Omnv~&VDZ@0O#9vG(s1HWVE&sfssi;JloSZE`2}xX}NvvUTbmc#|UG@)d zi~qsRE{W9;-!=ab?%Gthuw>;T`Kgef3+bouqU32F>ap}pBOEkD)DiG- z1Tv-FWTEnD7r9rOMh^b)CHRYBP&%6QmZ*+vsh-*qXUtW0({&fTn1orYhiJ*R(g049+Ddeo2#U{g3%Tlhob%_ zdR(%c+K^K_Jovv7lZ{dE-UevR(W1L=EwrJtM9?@@NVF65JrEl5&BA}GlXx@4eg_PX zW)lAAfWy8Ewu^w#YEwCGK_Kk;Rx8J~;1g6H^ha9K)pnmlS=5fw6&iI6b8=$0t~c3A zFSS-W*cSEi$TKeqb5W;-htP9E=MOuif01JJ^|@%FsBHPl=iH#&`JA1Bn?Z@hTW=_l zOdoCx&rG=WxmHSFfr~e@Yq<+P-K&su^lftMGcWG=Xyn!XQReGJM&b~wdsfUtS5aYz z5B2V$h1To@S3XP~*>k0<42;=Q9Yg29m~wNX-?6#ngg+BYtHZ}=IfnR+(g`FB4)0gb z_TK13&z2O=Us}(a_9V|ris!Gzb2e_c%n4nEMhpjq!ru}}{XQ2Z?DA6(ayaP|a^ea> zohDU?6U2~fhlc`Ccj;u;PY(~nLvn?%WuH_bj<*%!#AG>nkdqf4{$Gj7u8j(jg(?t8 ztp|s(4e>iU?O{)k39hNeTL%Si?VcUQczjqsvVXpNxlOS^qmM3#+`*`VS?@Ec1WZ9xy^O3-RMQUR_m|y z(^@UA9Zl@IFSq7POGxznwR5quZX`QD=N ziTINnkT{bUGBF_-4o5O`THP3jc`Os*(~!)}v`BFeTJLWU$PAfXn&2L%_ zi)2k$Mz)20bv4nq9hdJ!goCn4q);Su3S*X1T)WnYV8GzQ zy~c!Kk6D56Bi!kL%Lj+K&=^v$f$zicT=FvBQ}-XrTZIh(cNCOl`Zf_s1w4}Tg&~r= z|1r$;T%`AJ%ejslIgg2z$V%eu;NVS;Cp?ytBDkfsH!Iw_ z89*h#c8Wt)wB}T@Yz%@AIkRZlc^u@^`^L1XeF}ci-?Ya%=wHeEap#fO@$gy@BbU%9 z_za<8D1uf4@!=rP8*fIMZl*L@1-x?{q#}V>+Iwyu)W_yyI zqw%zo3%x|0luVklM3BZ?s_Ea(?m{?ljyX>A?>8K#iJyRsMHht;U(q}~^r4J|iHGMMoC;cp`7QdY}hwyTk8~+*qq@Q55_^pVf`0+k^ za{L1k|I%vl+v#oy>xxA|U$W}0Ym#W3pe>@aWpyOa7%P7d_Me zCiow6F&bOTliSe=&sfKyLTKKCV-7$f4jNI1#Q)J>8SJmJ4@zdwBk<4-M~@KVXnIE9 z#EvJ@L!tXXdFxp~KGDL!C$6|QhZj1{^YGiVzUwKU9_qReHrW?|?oYLnHO@jmKQ5zhkO~W*& zj(7IuSp4Nzt+}{=}xEDUEys zCB2i!38FhtO6+F+#r*q7Bzb&hpoI?yjKGt~>jRD+c(@a(N1)>}b1bS65j@I>mlgicNr$tG{%85H(F>T&ZD=2^Nfxm*yA9sKirGY#uHOq%XP_x zi+K;eiKS4aIr2s7CSP0_))zgQy|rq4Gb-;Qh}BMLo64~AR{ZfcV1sNBx6FE6+-~vD zgzD)N9N4Pw@i{&Xl1F2S-h*Y0v@hDMTKJC_=S_X^^p9+ZIx3unGSd@ya(fH^p8a$I~Dw(vIF{q8yZ9(S(_i%3#Gb*;^|}EKc%9j3ldylC_zVg-9@}qJxME@zJ`% zK|Vfs<*j&uvcoE~)D}y@&R!uI)NwEXu}ujEAYN61!9rjBBNE<LR#XVk|-SF z3x9&L^j5qEM`-~HANGZ3L3jLZ5pP8mh1!cy;UD3VKQY2@+qj+~pb$#*R=ge;P#XP` za=Zf!8Ovv6Eck5;l78E{zjQExo>AHO_ZRnfm&@ae$80-W!FwzAP&x>@5yPn1Vb)$a zaBXlMN}~rMAof1RKETHrjx4?3ElE;)D>zdLKwY1ZCsHT_5T7c+0K{iXFaYtn5)4q! zslE@y?_D&0!i9Bs6BZ*co{FG{?wnT(ACwb1{Z_2YU^35_c;=h*1}E3T+=T*MH3iqj zqJ=7X3qde(A(?d`6C-bunaMJJJYhi+u(&FzW-vfsa={HwwcwHOmHR@yFer^?!y)!1 zk+3Z6^aLZXf28MR3p@EDq1{-feTx(h1wDdaq%;oML~GGem1zyMqp*U$f6oe1*%8}q zSYN-yeXVd)5U23%bV*b^AXTu^Xmd*TZ-?b3LbEAp-|KYP#UI65^6}pi0Wzh53#01 zL9wPJgkptKNE7%%Fw(;M5v7zyOGuXvSTvN8=@+8xZ-d9kOq83nKS}ibn&~Aq(`#y` zpRzQ}?WwQS+>#>NYyBkAzt&9Gx~az0mex!Uv~+2-4`n}}vOm`sDJO?!=p@6KsNq9z z_`?_Li6R#IB4et1z=g$HyoG<~qnY(l8XZItwx9^nUVhK^(GpMbHdHvYOv;r;hfh@RQ6)sJ@`bM>E#QwM zmrSu$Nx58$IS$o}k(h>VvH zDb_>IcqAZtBm5V{$R#uh_`u1#2|g+28nR%e zQ5Nv|*}~0<-spM)x#tTv&ZLCaejE)WA5kUlakJ9;=uswF~@NW#NaYtQV{c{(etU``hXz2l71MM_{D8#Cb{EcBR`G7`d~(m z3w80tA9{4n25F*>85irq0cp5hI%w~#A$ShGg&cRzaeL8k|8%uP4rK>-60XDGn{ z#FMJQF-PN|0Sf0BaeKnW2^>8m`E4S8#{iFkk+2Uec53yLb=@UzHmA>9rH;NIg3Ma zD_=Os4h!H=F^~SF$fJg$H2ON_dm)^uCp!hsTVlY4halH}@K-{1N0}y!2MS?H@ag!1ZK;RWJ@xcHDW}rea0CB4l z3_#qb1OpIDlweRA{e@D!lt^gkA?PKt9|M1D?~>saa8EEK)Ps)@3~M*UAEZu~n{KPU zmBgoLZ${G0^Dg+{NvCU3d~WdnQMM@P~YpBonQUvk(Y-{Cx#Me|SAAmz@t$dI?*HkMXf86V=lV zJoR`cAwVGo*hB%;`e^Pbdfl38kHx6^??D93ZRj`B;yms3kbcSn3X4tnfn6GFZC_+K zeDOp!(MLR8@L{LAXm_D2ccAG#R6XvHZ=pAe=8^8Y&d z$M0Nurn}pV&@Y`y;;~faFQo6LW4vKj^P25Ec*FXQx5!&G9=$Hs2Qac&z<)8z4lcrJ zK)E)>TY(KExM5Kt7{5TB_G zVG}A?(vLGkLA~jf*iH&!N!>f^7JwWtPUTFc-0ZmoaiHe{iJa2Uq53%9)tEEHK_Lz6 z;6YmF4q_3Xek!r>9mFO8Q?v>m44nmGnR{F01}J+RuAcbf_;3IW+c?PmVKq9Zg|IyV zEvOFeTw_|04oaibsJ#E6@<#Q*{y{LZ4=>tD`_mF;*cju;LIQN;2(#nU(B#n~3RYX7 zAbyv8I>ucR0F5U4ax{tbnzU==J6s{*H9V}KgFo!Kq>(z@#}0H9h#hFAe7d?}eIDZI zWKPoB741vNI1t+;K^_OvKCTP_;nrvPAiNXk0g^q58C^;{ly>gWxnp-?0_JS|Jraiq zTg^7+Zu|}`@t9V_&yP%*HYrLzzQc*Ek8xnB)rjHdO3{{rjv8oiQV(x)8H3$uoS`!;3#m4xKAdC3>v^z0 zb0+)-v43(19POdt=pTp2j-kQkj#-HR^kVH<;Bjhcjku!8F*C63@F428V^&?KD0aP~ zPZt~0{1f!GW+s_B{yC=IHF$60c|zk5LeMHm5p+Dl3ff{_f3xT(8@4{sH5~6fh(pk2 zR!XH!OC4~TODMJu*i^dY5#-Z+k?%1d0>SD~kT+w`F3SwX^E%oGFfDpwpNU<&V|XB_ z#Px^!W#=jP0UA|tU5)qe1f7ahi8h*Jt4$;?xmqP(g_MeGPb_{)h?DlAbZ}N9$4th6 zX7@o#)t6RsOZX$#JQHZ{;q>L3)2!sQ7Q$tjWzZ+3KFgem+(!6|0ehGRNeoqn}mLv+7h(R*(gvk@n8^38CR(Jv^meDf%zjCz~&@;0(4PAakPbOE#EAIe2UF6Z`6~t zUxFr> zEwCo~7c^JqdQ20zHZ?KiP{NLTLXcx-yXBE(eqAN8>s3EF1$<+bFh{bK^^z`V%Gz zYGVq3JkUlPbJYuq{=&H*;v92RYpHKpW{sO8$2^EbPNeZda~ZUI>?@?x!(AOXX6-K3 z^MR>a(uFuYBqfuJ`axEgZ>GJh+^#0V6`I>oswA(_EJaBR+LGxp?W>5pdxK%r)T~6_ zL>qs>&IGk+plHwQqM>~AW=oIxk!$04TlyD6ir9Vou;`%FTmX5wh@++P*7lf{D9e`S zN#u=C(0qs5L@iCwTn)RDHfNuk=Ac>kv2a22%QQt>ktzwXKU+$$jp>A(i=NwDu4n{e z6Rs=jprEbm1eM})c1_jANMF&tXzk6s#b}3-(tNWGWllQnWQO4cS`}K+P9_&MK+xf6 zBLr=$qpq#d(p-vmqLZ2b7;Z)Ya?F!%?dfW&kjs())zyh^twl|NwMz?^wpUP&DTNNG zEpbdwTk}T4!bs0q<^k9R)sLY07_Op&huxMs%k;lgT=UIKu(iv3P>5%D;$9h?<%1Q& zIti7U7hpM(%MX@|DCMkWT=1-KlpemF(p&Zj2^-?sH zyG=r5nZYOz(n}9B9`*c0=>BMv1MPOjQy=rPfyST>$Mk~TOYd?K%J=gFAbjvcwTmX6Jpw>4vjZo4Owqlv)ZJuoz4k9o3Qwu;^-w`nag6`R#X= zvLH`WHOu;Y*rE&Flr}Zp5Id#HF}qQYl#eV^$1S%!vm7ZU*DUiTbRhobxv9!BJ7E#T zH8m4lDNW6zsF$O^pw|1h-!#MtC_%BXYta4)>b6zUOvFK4zRCGnTgS&?yP|^?k4ej# zXO^PPkrYtBCB52xcM581K6Z1SWxjDs&@t<-7s*Y{7btydF|*7DHy>GM>>rx9rjrFV zHAAg7E`&Tu!LLm&vvSeS4vzqg*b_T=Md8hNa>%#wKRQ@ zOKE-5+DiY?(iB;)FH%5#N-5_<`k7N<2hz_Re9o9hw^Kj!oJEf!Rm9!ve-=Fi{R^6Q z$oYg-gw~_(_w`e2doHFz$+&2Xa-K@{R}YdUM1k9i2F)0Y-m&PfuhicWE>~#0 zH;VoSn9b1XfsnzNp%B(8{nmAeP0(bQD>aqKue9R_;Yy{@(mVutq@jE>7##Hhoy;|; zWmTUMI*5Kj&_rlldaDM|5TT&SbaUyL6}I2{0Xd2xJzdS=XwhGSHoBTY%{?XqrPI~y z#^G5(pSuX-CZtbncVfQU-?qltSzvhnvZlFa9phU_$-$LNB# zqD_>(b{%Y&LIh1uq=3eWEzJecpV;3I(2$ER5QL+FXNxsune*M0&hyLzqJJ32x;f7= z$3rjFdiO96!cyPU)U4U5`P~T3N*^#QPqncHC2$YgI>&r;tBn2~a~1SNy#{(%SgdIL ze#B9756PQQXiT$TNs}8x(snwg0wqoUN=?VMVmXwusRi_x{?TmwVk|$r22GNUmsw^d z7}7j3UiLFJfvLlcw!-A6F8^-;eSGnT$Z2Xkm=}*;D9nEN=*@oWAs+G5&}DYQ28ihe zeV22nqim=GGoG2pEfWHBF{GUY8R|^n*{o&ep%0arVlWU#dY-b(RI{F$ zFZZdRv&>^$UUgyl)Mk|7v*%ARb9caFjzZFidD3{A*EP;&<1*KqrS#M{ZC#d%%!AUy-h%KH&1JYZjxnU5NTrW{&cBVVHHz z?Jl#;9PLSC<~P{;W2hTtU}|~Dddr}BV)mQ9o(9YWVPnD^PYmR2$Ba`#4Re|Cko?m+ zW44)Lp2i-su{+*ZW`u{frR$n*C?xVzhFgvXv7g@0Ds!f1B**p3VIKCg-(2Qd#-Un# zqka|>gA`u4QJDQ$5q^!CNk}0{-fz~rOp#?Cbs3sBh@VX^STpAu7M-glWMN)CDZv!4T)zlon>?+|7_cT1sWbP9`#8fa7Oz<;{<#clW!0Nn}%xrpA({r?U z4l@ClsWQF1^O@P{rspLy(0dCr$Jq1?_TJ4*FKY=yyqlR>ewRu<&HFwx3(#XpPS5oI zz)T&?kA<1&J;2Ni>u0L>5HrIp6ZU5KNUMctIVDuYTbG$jEpxuNJ~N{%GsBzjqY~Vc zC8744S>CqHe1uk%+nbpQZmrygdm4`A zd_D4{#{R5#IQ!}BhAJ~#T_$SfZ1bM%qZWGwVwSkx@J{eitMw6D5@B|Fr?Q-3Hq=h< zS07n^3L-uH^zL15d<+9`}pQ@ zsDT)9h@T&Qmvg@QVGc{oe)FgA4wf?+79xJq{CBXQtL{-hY5qG|PP&y-%Vpk1T!Y|N zX7c^_u%DkS)5O1?nY=yX=W|a-|MSe$+hELBw;J=3w~PNJX5QQ@%rb8e|69z2_6f7i z^!D#&CLeW<$sS`~zlgf;NO1?Ei$BH#P}VWrq3pGqcSN^%9tGn913tp-%Gu%FO#{ z)kV%If6z~T<@?VHQ)Wi_bC{u?i2Rh9(f&rv6r!&bW}Lsd-_ruO{i78nX1|%>Z_9qZ z&Qm{AT;^o7kP<5F@4|k{<|}i){}^W4TgesvAnGPh}SRCo)skR+%gO z=P|Qqf-=|p=W_}@uH^mZCjS-er!~etlAa~RAQzvY#z`)g`)_3CYt&p}RuKdJEPP%= z-Q)V{^OJ_U*MA%PsdAYz^PtOIg!(0MJ>p-%lCQl|Lv8Xu%}nJEWnKY8wW%T2<~L`M zjlJeF+hK>oyyeH4G5G0X{k-FU-5*1}I1b|<@w3PO9!6MoO>P8r<8#c9ydV1aFmvEr zVHSh=l$osWgt;Efe*eV?b>KWk(G=uVKB37y2j-V zWH9ry_2Ug>F*9T<4woImU23>7IwwGJZA2{~W*eA#?B~G*KMj~^3Ogh}FL}LzMjYye zYlV5&n;z&L@F4FmyUcywU|;|<>DP%LVvgldpW9Huz(DrX*7ft4w^rbIX8I;DLpb)m zZVH#d&j~DN&*hrtx`7ewXTv+fl;M_)a%RS$?WHsmGcG`_7OlIygq5B$Q$H|~nd=gm z$pNylFHp)~@VKsi;5=r|f`tpyFffyu%Qh-=Sm0u2x}c>MKgEGNnJL8xM3~Y5M#Yd^ zvQ(Kaf%TliW(Sn%8hC>JythP|fr0m#p*YB^j#hIm!4{~m*rOYjXJ5v0t3an;7H>ate)q#7M`Ms_( z_XO53Qwx14{VOwT0{5oKxi@g1$U&_aKlcaLGJ~TLF7rU(p_EW-1COLI4+S=)FpmTt z7s)n->jFd^1m{( zDex*YtLrH9Y+!qeoXvsP*iZWm_47jD4Q4WJ3bzE_Vg_Fub0xnRc$=Ac>@Nr2VJ64M zwKecAF4o0-88%P<%FHW)UF;{G_w9jw%zR#3{k#_Vh?&+6l&K1Q!pvWdm3ckzSxPQ; z1ioND@lxIs_?emKvozG+z^^Hx-VglFe&U+{DDamPK$_EMYAC!ul}60wHOlM{1k;jj z^~*rr6y~=;vlQm{K#Mf8=Ui(Ee+CMex!*E}0&SVOAzkANIE5*49H%&i$#;5ls2Pri zYU1=yiL04&Y)YsWP8s`&mqknGIA-Ey(aJeKB~)wYgcPROIXQ(XaZY79UTZDAo%2%s z^l_r>=ObIc`a087{Pc4!NW<{a(AqQo+i&_i7jme0c@1`%Q?1P(?^Lj#Ypop)aVk?J z4|OhPKgBloa_3TJ;x<3hxty6^)-q3au1Jw{inAz%In}vZLfH}=?OdDUXN+@w3Nzlh znQg2R?KAzu9N)PuMb1QL1vBw_I>}j?B4@I*iv7e}t#h3Fn2B56H0L4lV_V3u^9VEH zh8#I!Ki65u%x>-yeuwoo?<3m7BiiVDQUjQ*~EUH zv(_@(d4ZX=w&u=pUSy`iwh1xkWoC}DDV*zUW2SF2P4j$bdrDjjohtTol8tMzvzwVC zZCuwlds0GO>%7mU)8j3be4Vo|#m`dbXOJDo$!#9KBTFHWa6Azt6_ za=gsMTiR8QpP5^13RgQ$I<-i_?V6suopkmS?+5R7>M#@U2k&#TnYqK3@&ouxDaD@I zMCCl_)K5=t*&cQpu%EYb)z6bo3ufXueadN-5^AGUz<%O-e#U8=;%Af7E*(P|a~9?W z^l!h};&kAA73>nG%xrU+$6ivV%IVI2+Pk63%$rW16v^*6$8qfOwq>_-0yA;_yypyK zCa#}7&PmL~>(^eVJUtWo`4sCv^lzW{edm;vxb{_JzI4uDIbT_geeFzQ=1e*9?{G1JcWAc3?BW@_8^CoQd#nV7A)>1lJY z+Ih!FW5Q_vuxCCPBkO*&vL8J`xpo5;)fuC%myK5L-J=!#I9}1Xv5KDSr6Hahpxjm~ zZ(ASbTAr@{Zh>nnq`+~mZiBt~A;y%)nqz!f46ZzOGG@DicC1%!t3}UPwB#9eorrY^ z3IU17YaFFEm$ML?ykr|4;$--XbXxDK!2&*TA0JijOoB=2MoFk zqouctZCS zUf?{YSzqih03}MkYqhwR$5vQ$`Ud6R+@@%n<@Q_dV~l!8a(V0zi(0KzZt|~+nxQQc ze_K9R^qfUSR`R*7zr^%SyVaP19LF*jwJ@1blOkQA=rkXOdBsYQCzMVITzR0?ou@MY(@8DSR$@7i{(5ZyD+Hy@MDEEPN-8fOXZ!EXna?35(+H%EK-T;fvv}n0S z*PNk}huZXISk%#`Wy+cAugJ!>$HrD*LtJMipMvs`y!CcbSJNLWpkHUx-uJNc4Wshd z>|&4WZ6{jeWx7mzZfSb?g z1~*5D6Rwvtw+d)6qXlm2J?1Z<8<_jc)lgzRTChx9%VU%8SJVc2p%CSm*9MZ-fMA%z7wiO)})kR8|GS}Wsfya!1#_wcq7IJhCqj;K+2PaZA%^owwEhC%_ zvQjACwH$VxTbAhGEK+}o`7Or!I)x~YQ41m{9d%le7cG~d^ExP+U{ReJ$}Pq2mH4~7 zg`yJVSGZaCC@Mnz6>heb(gbI9gjY^PNGz~4Gpi1n=x*Yl*K_6i^NYGWEsJ{Z(fpC+iDtaC3M#432kBOIb+;Tp%bubGhBlYdm=~`#nBIm;OfrbP<`K6-zkSts!%0p0n zq)JfaV?~QBqOufM+8q?M+O3!6v8yo}5iW}HhM?=NP_)FlzTQgxt+(7ti{89fLtJcA z^(O33JK{*SK65p)C=`P&}N(SF@E*83~TPmHk`&n@~1HC|k|+t#czEJC>ZQ2K(7>8{)u*oJV+abi@^_q&uk!=_-q z)#=lJs_W0NQwibUt>`H1un5=Ea#JlTuvT)MQ+)+IJ?FIp)dTJ*vcmGZH*wP|QoMBZ&Swk}^QH^P?hN7kC|K#i9W zKiN|K%cj1}TI?c>H^kr9sBePGFai+t;kSxDu<}}>^$}MZM+hpnu1{U1T+uW|-(iFz z{`O-no{+~phxT9{x4SFK#noeIlp(G(a(kRz--hc(Mh~4NWB$apIPitImdAcV8$tfc zV{<*|CO2tl{H2qVkp$P1^>poR)s z1|3M>bJvqt%Z97ZJmdPq)~f3dYo05Nc@?h1V@=#r^_fPSjoHB=UirY7os1R$?Pk>Y zY0;1m*ARNl2h7FL!clBKb1UlpCyd6!as)lz&6pPr?)@=?4;O?v9cslF@aHiTOJwBX zL7$I3V&<;sZ_KZZTA@57A7hTylG!jq(K|rm`t&G8(=19mO}V;b6-_u9y8|q_`-#e( zjd(@MIinSQXv4lYNVz{OT8;FHmAq)t$ieDwhK;SY4N+-bKer)n2PaZy^u=ko{-li; zf$A{21?VtF_hR-b>AT(L{8gL!6&CFpCME4LzrjvL@^6-F>V{3Ut4*lqMTnz3Mm@2h z1?cw$&DpN#DAZNqXyic%Zw5d^636vOUkBz+?5*5Xi>?`9Irx*g>54we^&Fz;(PMB0 zE=xIt@}Mz4S(k?R3EGgbX&C(Qo7mL79X$NRvYivM=N&#u}SJjouDWm zu?hEoFr)^2X`LMMX%JaG#>z7j(zX%F+7>!gaG~BSw+J(WpfbjVuLSwnn(bc<)EQ ze;UX8#yf%%T}S_H%y@RCwE{sj-xri`5zYLCyW%lLGtnvwNA0tqWiCpL;~w-C6FH94 zdl(npd#j=;7R_{#$LvGR6Wfi9Q){}g3~Psw;xS`^rZZ||T?bh-06mV_-+V}!!~Up0 zqB$|@^ihgv{(Bj_o(Fqg%;*g(r6IKk%sqE9PKz^I33NZBYfx)9FuKInL9Y$_BhvQ_ zyB>F{F)uTU*O_IgZ`+w0V{6YC)JsWoyhc&aDcqi3ik1yk^hCL$JX`bPA&!B(*AYiz zDSX)uy%4za*taf9bfp!l-Rw%MR)i8=>2~lB*tL#Dm9RSD(kvIVT&Cs7n#3R3kf4sJ zd4ev6#S(&r*f#82+ee*awL2eufN0|wtBoZnOW}^T|nZ>aURd%VWhXSiq*CqpdP+;Z*4pzb3t9ObSaV%`j^*35kJIlRq<=yoS#s{3sJa;rQEH?5L4RO_{I1#|Ejc4E-7b6{) zc+7WuF+O1KBJ^8-GSbnF$DE4Nl0LrwPVG78Jc}N70O|C6oLv;98gs7TsjgT`n3H z+j^(!^joxlty#)Qlt(*84PaLi$5ZIv1T9Bh?ZmEIfR11^3+PBj|J%J}=}_F<%aTt; z=?`EO!zkl8MjxT>4`tNV)^1vZ7b}VP&Y!{R#7dUf*5?*md*W?Ly!DBXEo$3(G|bk# z4X6tvI9@N>uu+VjM5-i?wl#z}0P7sf{^DUjKs*8p3ZXv9SN96`hMTWA)W-MayG%V?9jler*lCDHe{ECEsv$gRLXSJLD9i* z+Y^6|mP@qzi;d$!tDz6qYKV3BD|*(VgBZ(;yatO^%4bN+?VPHb(tPhy++@S9kE0!z zuxU?e&aZ%Ls&;7y=0SugkI^j)gc3CrPjkHA%KJ)tx*dm%S0e`8@`5@PE{MVCeuonle5^OY-`qUd0TYG|v~ z&`+PL>-YnT8e6UeBQ1%||EIdXVoU$PMCIyFQZ!ITLr>@CV~?V#I2|Hf z_B!QuKcHxz&E*9a9kTKswEAoRxrVsH>i&?eTW!x#*RL%a^^S6VEZ4)fNc(K*uXFpY z@>uQ*8e*(1>0^5;_f(PQW52l>BvfSskCckV^V_Uw9>T8JOZ42^4zH*za zB^EVRu7yoiU#p=Wj;3m?t&K;w(-2?Sx>aaVfvsgzZ7u6HLqpv0i=xYH`|^~nQHyLF zcH%Vk_s&X1TP$i~YtK0A?_4YIjWkX3Pqsyxw_c?TwQb_%Hl;64Glnd@s^se=nZ(Fl-KT+3RR?h=5rWVO7F)|ml%j)@w zkCl7dYUA#W%3Xyqu!Q*DmU$Q3UbVA&KGL=zY4>Q@Yj0HaZdj3ThoTp)HoP;GYrap> zIX1s9+WbCl%ktI>)!#~+sv{m%uFSe#V_nzV9%A?s_1Ar=qI0aScG@^Twif%4m3)~+ zBdovumOIN@$w`l?{r(vHpFe#-&t;0kBRgbf4JeOm+sHR*ZLL?H|7Z*pZ<;+GsWRC z%fZR$di+4$57&dq3F%EioUZb<7wrn zB@`)-pso^1jH4X=!t)#l?HLLRq4Wj4f!PG17Ul!2`MwO~G0&80&UMdgSge6tQ-;Oz z+!lCPY$g1W4u-{kds5MC>st7_a-%GoyFj^z+&VKX*4gcohsDluM;RT>#9qK^g*4bQt+GZ7}dkvfDX-;*!-r+TZ&Z5u-Mf4nwF}3MGc!O>eF1& zm==m|Y^kX0BZ{tRr)Z1YpAU<@@SSo)o=`OUBSo}YA(m6$ow<6<4Kd}i<|vA<>*=m# z;;g962ATJG%s7;wtnj_^f$Um(%pc%BV*OqGE$%>KL^CB>QLjld&8=h)GA=JZ--_Ig z&q}hCgPV-`nbF@#ku}SBhbQ;3>ki~IY2r@{3$BxT%O z)nE7KI-l-wyK3X>+3FgfftOx@dn!5XIY6?0N+-7JGS~i0+*!gXeq!sN&cCFdjya6O zPB=>9O{|v-mSLY0u5xxu5S`r;L}#}I(b+9RxFZM_)`C&|+|4S?CS;BAvI&alw1lKjoO^QZMm@3bA8Jluv|CG#dFjdx$G|GhBzp1iFPpU zL2)gQ-HCRR{FTRY@P53Ytv*3$p^?&~MG8NTxbj%7)rziy6yfrg3+FK_psV5V zhx=??DIW8%)mjy}Q`mJs{EcCBChTAWBRW4hnb92ho5m;$-1&^+8efaBVnbW39dv_+ zE@FQt!Buqiy{jva*$QqBToZG2eJT~SxMJFRiB&9rdokhRyP}lEvD;jJ=yk}is zv96zE8W4^2V{C2&4SnMYB=VUL#VzV)N5X(8wqUEEpmdk0$8mg{WouFv; z5JmNmRg_`v?<4E_#VB2u@7P;MrB!7b;vAc!Ywd`;2@sv__L!f?X+PL}n4-QT71b?Q zlsR6}cho-lI>Vnxo(NqD z8f3LL-y%9GCVF0p+AZjq{)#qPZZgn|hIH_})#SHU_rIQqu_KqvM&v_ci_chgAyrSX zYgf1mT63DB%@#dw{T+#RNc`oXv;<8<*sUz(9-D$UZ3;+3lKSvTisCkzVM{fx)0f~+ zQaTkSBViX>6mO+SvS@sAFZD-zN;0my$XZEFA>#hh5rWz*y1UT+h2Sa{siccB>&sJcaN!< ztGZf^I7GYq(Wjh(66afJwmyXG?}w^G;c0d?yNS-wf$DPJd4($zoe9QG(Vvi67-fuIX@~lZkwW2UX{1Q zN?H4fy1u(a(LyWbCL7|;3)FRrb$!lqqg>=MwNdkiLTk7u82bB@H5BiE{kCn=zP77* zqBX9=8c4SGHP+H(+`hzJ0mnU!h02}0*qAi+4bs{#x!A6)(Ur1GCCV6pj8b?OA$E7ET}J1a7Vj4J9f+_^p_pjbaXR`V(%raDKcC1ti?*9QKqaH3c55drx96j_S-w zOu^YKWkk9$=P^R(Y-TYkudV3rJVl2UVAq#jPXb5CG4tH@CdV8FtGkvtMUtwUI7Dw) z+!97#)Dh&ErInh}IEtX$s2y@l{zP?cb%r8!#jPM{!=%h#7>j*VNQNC?40j)=UrAC#e*k1ea%SM9w!cT92H+!YHkQq7NG@I@DCr>#zt3@iZ)A zCx_Swi`d5~h+gC?M!zEVUw|BQUNP>EEFod9uu?cF0v=DMk z^a0huh82Q5=1tpkzKWbThd+<$I|8>jGwOvtrHIjJ>l#2$OxlomyTUck9Ft~DPe!d^ z2ZBrnPUrc`$36ce! z&2hZrg-tSg86_k7TX;V#5ghIgFH&v1c&VbvZ;3@X<^h;7*#OOCU)Q>dn%lhHb(nHdv=NezyU|7nI@m%{T<ulm%AG_g2bYD`l^h z(h+tg^4i0$1T}_T3F=j#Xd22xxSh2GNj|RNe2~>GW`u79F>=hQrJD0UQ6A)46DLw` zW7l}?ZhM!671w1fnRF#Jg>)r|bR~#%CH6wP5=6QZM7km*^6s)|4NE2qTg!-SND$eO zpmnGpf=+~OJj?zrK}`|#F6xn>dRe#`id}o4CQFF=NR^<*NR^;bNR^;FkSamnpcDk{ zLMaH^jZzSVhT28e(L6VSI=yo89_fDWZ^CHUpZbo^n6nRmq zk1*#$>mz75;@HUCX^`?VquEVy{~@DkkRse2s7Hh(&B-a1ct3)x$HZqglY2>7);tf5 z_xlr&1kwS{(8D6AzTv#=5UkoW_ehy?I?|WezJqI?q0xv~1htcbTEY?q?Se%RO4Rci z9^6Wfu#S29W~|~c`quV6aeK-78lP9<6vXE)@j1>{uwto4HI?8K&{a+4_7}&NTyFm3 zwA?a)@(lG5Qf|~k2%3g6lG36cLQo^Lj#6&7*wX5cuu^V1_CYS^YK@B5{jq49DD|Sr zEW|4<1C2a{%jLB6^r|LLw>6LIxoDT_xgfG})^kcr*bq{1!@=7ado!XoQ4qC>uIoHO z*sB&=-9aYN*GgpN_E*Ika?M7rWEK%`YP0b5$yUYbVGAp8PSdb@|f+p*iu4`bnLuLH`nWZ}a*xz2zP?RawXwB=((a%D@$82&L+Lb*3#%C6_6hCy=_CYZC z9$PD6ewmB;~sC3n{lX#6xW~%k(^14zy^9oh)9?PJ_}52luR%w^WEHzouo>;JI#Ch$I1?f(B-_hcJ04%!6+|+q8bZcg!QYAj z$)uVH8F>z0F#*Y}cFBLPirl?S;?nnqYD zAd*K7D8eL%ki6f7SA#HbTN}B z)kX9Hq&bW*NmEdjD#v7heyw6a3aMq~nM4<0@|0>T4l?flyc_)LJ1!lWSwAq}nXx6A-e4zs@A&4oZ^3 zdPW@*g6uS!XVh^aDbWj%rj$A-Bm)T9DW$Fn`3U7sn$qg7kZ~ZSDXrX>;2>R}qDD}h zpH<0)%mJY|KdaIUd8{wTrwra}WncM0$W9rRSIG8(tSPGs2{{NtnzE{-kfAME^PGBK z$T$$vJf~h3at5iO_&l#(6>oN6Lu9>{D%+AzsH_$2jX_)d`O zl7LWH<<($A#zdV)>3j)aFQ}=8#HrusaSSUc591chO4ZMk@g;p|DyV^m#7E7W#X0t( z`cTMf5Q^c8YK)L2QtK+J$wKx>t*fYJ3;8gP?YxB93WXIPH3@|5yrh;1sfC?1D#1!> zosdQ#l!{7ftB`7lGv(OJYOjztLCDU_>adVO9avLYoe(kxgfx}a1tHI*;IOJ-#=`Nb z0779^QTK&hJjHfiQQj-8xeY>gUNI|&l!{prR#nU*So4*HRaHGEq#ODKigPuUPsm^p zvQteJVPZ;7ou#!S%EQ12KLYcv}S`II%P6TUvN8>FV1CuF0q)d7&#)G8sr zf<(h|Ek*B$E43+9?zL3KszhSda@4wC;H#F(T#d*WMei$~2dS-!Cm`2A>ZqDRD(+#; z>#AJ>LYgiV%9Um+W*?sbA&z z5Ft$uRZs|hiGeh|RJ8=()3e<6A;q$S2KmsSI9^+Ky6GwNHa(s6GC4b zBh3)y)#UgPA%k*bLh`a)S@kWs3SkdDZWvLK(RPYj8VYL43b z63AFJ$q=sLRG-JHjpA!vD}0q6nsMqV`!conHIVVD_-hoy_)vYGplS*!m?(-uSH?Ss#Np2&z!9K2>C0dAqCo(Z~N8B z>V(k@2=&jC)dfT1qo`MJjj$%G>q7F4@`gzl zkg2MyA>m$qItlP^qyHZ4P`^4|9W$CSY68|O`@t79*r}sdKxBX+(L!E8DPBRq1m8{8xpI&!dQZ8-FIr7Az@$NDf;G#jSuzn->LM5 zgf*L0J442(X9{2z49lCz_qOs%E-D;c=J6_$b zW(uL+CI)u)s8vE}3>k0879myt*wyNY_4fQ8YGP`;>>Z3@Qtou6>HW zXG6rM>w8r|h)vh`s<;q}A=Q@ss+tgrA%(tQ)e};qv@#=^1FEBtE+848IiUIosZ^9T zKd8|{x`L4Ahlo@hR8vJ$WFk&RAvX@HWkSk=j5cJWkTa-t6vIR6sE`{V6vIOimVZ=d zMROKwE)!wrM=aDrirlydGQ*G*LXx1a&I38D@(9Te@}(g~gxFF(qAClqrF=xy5klkV zXr=JCz1j((@iV3UsOllamhw+(gb-WGKSiYCXEjkYKOoMO_Mg=fA-{l7+J9E-gw#2} z`SXi9B%~1tX?}^Yd`z7Z4VC)}r1Y4&FNDf{ogq<8;Tbu$ryyHCuA+tf3__NVtAauT z^b!=q6RM(+M?pw)Le&&vV|Y@v7Gh&~G9rejR9Dg1oIj<839&hUN{tg@YwxdWkq}#Z ze^sl548<6mVt88Z7cv%vVt6_t^fT(1(Tq{Kuqv_{xp79#YzC={Q<=}>uSpU_3WE5CB<^W%sY9$$13yseCD^&8cDw^AQo3^rtyAK!v8tNw zn4~$0F9d0_}}PWle?k-(*VNS93Zr`C&D_ z-RUXyr>fkE$&qhS?vG*As16BaFXVyHu24A5?SW0)L1f#shK7$on5La&$ z;w9DUeGpGqMCpkfv*sXXvSWfAC@1Y{6=CDCR3lCP0!+Luaw1d>$uFl3Cn zGzlxeAj$PHA&pR5{z!{+Fq+;Uruw`Qr99baZoJRr)lxW*36fG5=*Og6H>DPWJfbTL znT2+-6eP877sHyUJ6O8~Nux`lPLSmj zz;bR)e}R)?Sl}W~8Gz)~)r4F|dFh&1W7IKASaSm^34KUNt$kcNC3X1~WuPgkOu2WdVr8v z5GtK&`a>b9kgMxUVqB{~5t1FG9W>STWFdt{AP-@(hW<=Q8ITNyd?BRW`&{Q=)!zu| z2a+0^SM@p}b@sESrrsi?4G3v!>b*jifkcD6rhgQ25`@BfO`i~w_C9NB>GMLK1|dx? zeO<_j+pMXr?+NkH-bqtid*}y|&rz2YkALdu6hiPfM2)77&LE^1Mpn^Kzpk?jsS84O zUf21AoX5z#3v%oY{ge;PAo)PlcI*w0WT~5d=AY`Ymt}LWzN7mHSHHB0LAx%A9 zUr5^I9H08SsgRr?q^Yml3P~2Q=1tvMNG=f4ys3K&nT`G|8l-`a6S4w?G!67HAty!C zP>&Y!hiDq=NkW>Uwv2+mM}R`mT`fAf#!g z-3@SP)Gcvtu9FLS1WzJLS948&L7X(*(Em`{Tj*>;hJ%o%h0bg3w8LMfLrr*F7ZQ>N z&+v~8DJf(D$Rv=K`gtKcLFO6qvXFN`R)Dn9uL>CkvdxfsLh?Mp`O{iA5mFL_($!kG zF(fYPd1-@fbSEKIqz$&wy@bRdSEAvot?n;mG6>met3MD@P&Du8Q9@o3%{zLckdx>; zk06Ha^h_Z)L5>@;KuD^+oQLn~r9$$7P#(Uk*9d97itV)5n}qZNAv^8$ZXwT$oeuh- zkT=9m2c39Tt)o6>H1SatHIK17>a#-XfKcci^;IFCV~lhbVRh1Xge(EMWQem7Qq+WG zg*g?Sbuu9tK*&yKoleM0qUoZu3aKNSE;^5pPy4W)uDYO*xgcbxt1cm=Dnh5-fo}Ra zA+14Z{imC*B;*)I-&8Z-(=~+r0YY}(({+U$n#Y>%y0MVsAf)N8TMOCvB*wf*X%F2| z$oC-Via~k`ncWrZKY6k4pksxs1W5r+Pd!vfR2N>W?4>^zk_Cj~+)IBdq)U6&^wu+k z3hFYfmwfK4cL~{9h|~VQ{z1qw5K8;| z`WGQ%d$XpWJ|kor2xSlVfL?m0wH5l!Ynn8(4+5ItK+evp!eED~}B`(G76hU#TP z{s5_N$a*0iCG-#URw08V^bhntA(KTjOdl4qTr|VfA^x^uxke@(W7~*e&6m^5qCl??6a1LgyDk zYp@+*d895ZqyR_{LrMwBm=ARjzzXCODT`nKM1*pS>PpD zo}hmg5;a7rJBFMQGVL#{1K@z~r~0yx??93pa+^sgS10Oxn-K|=yKV0i^;1G@d!MME z5i+1KRtl42WT49l83FQDIwF;Y+>w4`vaTs43jH&sbh555q#H&c)Z(V-rb1#sNHayZ z6=M6Ask*Ze+qX>By@l8{t7$q;h+VUqriTexD*ftoJzB_m=~t&mwC)*tl4!0j#w$N8c4P7ldLsN4s0#pxkT3vSzMME~Ehn zY3AzmLhe1wn$LAMAyH*m^SRC|1bLT1BP4&=`lx|5KVAbAbxCFJgL zoQMWlr27lWcmlI*Lp~7l0eUrx&tg4F$V3ndYq6dvBwph4rJiXu5}z;i0wF20a(uqh zONHbFq4<2I*9dt9p;LU8=uJXeN_>{+-9pY~=lCqu2Zh`Pq4+G-$AoN@_~*4PVQ3Rw1u} zlrtockQ8EPg)S&0v)EaoO9*kq&Px59kW6A{rLH6-$0Ky608biSLr5VI-;laO+T7uF z(bc-KkUk)!S*=?O$$yRWaEQZiIjnE>5+T2XP*~qa#BhUNEgIU%qPn_4 zeW|x-R>tQso?89kUje7FHE|w!T1_v zukLe<$&>;Zb%N~EF{hX$#i}8#QSaC3e`S&!D{mv9IiTm9VRCvmtq0=isPiDFD2BVy zawkIbqwXQ(1N7LlKo09uLgs-VC-eX9d+6#MBTh8jtH`rGyRLiT- zoYfVDygZZBeok+(WGddnh3332fbymoRzUucuM2vSke$d4is3~)0(&vG-2Z~+H{Azo z#n>;>biy`EZR~^SB29_Js-i#e9RG$MCgd69K^|ys=!VT%)A}Oz%|U+GJ6bTgi4&49 zfZWlkTQV7R04rf2_vjM;Hu*NJKOP_rp!xFw@-E0LY);fVfUNAzeXw8j?-O6Nflmo|8vN1&|Ez?>UK|-M&+ZHD-iH>!QB%YyuJk z%Yjol0T~1m$4lB8nOUNrA6jpNQNg>5@a}SWhDJG;c2({c4PFW$Ba9gaSgD-Xg$xCuuu?gVgsjDEYe+i$r4^^8kX;}jA?L>ip(DuR7uko?Zz2~57rhc9V?6m)(Pf-P2@p3>?m=d2JXz&S>c!cLw~O?*sl z(2i}?Npm&G%DY8-i0ad6q!t9qn>jXWez(foQp#Ky2PZU({(Cq7J+1h z<{2k?Hj|Q=H<7Q>&agR5R$XDuvrfbLOpc;gCQVsqosdmeF>V2Q&e^koHDCHD8IbbM zj<1P~QQ2dZdJ3e1Q~4VvPYZd`*)QZrAr+k-%UH8Q$V<*CA-9E8at1FaO{_YEOe_Y= zFFRdVFzG&@d%qgaZ6UkIV~ro0SDhX!Su+GP)}|n}omE1nr@`7G$Qw@PHLN*_e!3e- zT_;9JM&vVT>NzRavgWTiCiR_hmUPDx4VpKd%9~iT6yu*kAPt;7TZqI*eegS;Rv-sKqsM+^rne^Js5#V7alA zT*w(|kS0zxAp<~G8j@E?Dv)nMnmUDqIt#yY%QE7LhL$Q3#W|`yUzBu(@BV3XM5Y}CB&|?wRHLmvFmIt zoezZAd3P&kln^`bZsklAV&}rGotZ-HT)4HfK!{yuYvU{xV%OQ)IBS@MX8moQ{i3<` zrBb_*hi#psLj13=n{3FhLN;{6SOVl7=QklcK~5NQOUSAfc&iqqo%5%VJs_72NwSS= z!qtK3e?Z=K9ueZk<8*)_nT0%!+3`5kpY~3)kSZYbY-;a3E`;8;=mFBfDJq2CwxIEI z2j^KKwgfvm6@=Il?C4Y#@)yRW6jmpvwvb1*b6B06hC<4tosy=r(?Uo!5QTdX*p>hHoW(+l6=Y3!XStB_AQZ#y5i#uHd@Gva3)oi=XPb~QAmpou^SzL=7$du{ zW2N0WBBT;XQbSG&$$)ZC4bscGC?pq1Mni52DY25n>h1g?FtG5$u=Nk2jZH;gCx;N5ioQ+(Av;pxDUJBN?-UX8BS>yTN(-?m?dQB8#HO@g zMCdWjE7ljD1y8_Ej8jWU6_6r^G!T;FbETq@(paatkX#_tuf|4L?(eh{O%Bvv^3~tz zDx??)`RecV6>ZdNE_*YhC5Y+ys?X0%16#? zLYje)osXP1h5RPFcq5!sVu+dheiajByt2G9_q6-Mv7@IqCNkiB-Q|v5IEUKZ7iFQlB=O(8yt#Q;|tjCaF=&oQ6UQNR3+N zv^FF>Q&{foInQCOxT(|`SYGKIx)ip24P=$G@iJ?sZ^9hp4XxHW!>%x)SyEPz^-j!n zCbx!QWdP(`=cplLR3_{O76#emw7x|ey#IwU?F%4VoKwHEuSLk`x*$88BDce&DabCT zg&||q#e6tx1hU6zeTVJje+o}~kbTa8Kbiap%kdxwoF1-&u;QcEqK~4QaM+0vvJ-^b z;9+NokOR-M=7=*=$O#bA9C0QH$@C4^mZQ#eA^Ab54IYiC;XgU^jb@Chej9ZV@%hQw z;hFfD@}gY*#hDoxV(L7t$((fV8xp7bAr-UW>y*X(O= z9OsIVUyw|)^P7`88K=EOF^=;kr=XC14!43!PGu&c_*`;2Cg=G4jGmwDTyr`;5++L# z`gLcSA#rMlb!v{`>q&X->!veN$g|5hS8q9|gv_2|$&xhe>vCSK(ZcdAr${;? zBURQySc3$)?Q}IHPNjk!iqBnVk0J5u9fVHgo>MTriJ?iwZuq+ITw$V8Jc9fKQSR+r zq={9%&A zs;ep87D6f%!kPny-KpGmLh69DsY|4r5WCa&h}&0)-RXP8jTcgGE8bJc0_*N@A=N=z z)FU!h$SsVKQ1Mh6cZv{a0>>wfJ4eU@_=<)mt-DCbdJsx`T6ejS%yHPQz)!@+eEVuvk3|-y}M7yPau@`^zIQMx!wVRuMF-_z>dGo_i`IYJ7Z$0=QCvbb0BvoB{gMvNd?-FgMW zB}g&M<`#I|5S4BK#%$1JcZWT}gwBFi0Eu>^pJZZdOD?yLA#tid`np%3$>r`SNScxA zy?Z#r2$I{qZ^)P^T2XEQlE=+l$k;LMg7P_!ThNfx+Sbgx?l>W~_U3c@Jw?7wYa4og zcUS^KcJjMth1hmcz^zo6ec5*LxcjaUTc4kBdl(Y0rhSAy95H;-{mPK=`&NbA-G;=f zq)Bmt37SIg74~IP(I4a~w_XtnE1c4&-L8g&)Ah8wK!{COF?Y8R8|UKgRUtOcCERpH zITbd}CEaL4HtJCrUC=wB&$vB=Jc9mtDB@GfZC9Fn#j3Bd@;?RSS$EHKOs0V>04eKU ze1XVFH64BUw;<2E!zvKj6w2pv?zjYm^0}Nl^+n?=^gdd7caN`$67u3?_Epv0 zBV;~SW$8&&&23kieQgl(svA{>$qJAoh+!?a&MQpzEMz-xxY?>Q>6L?@7j@lLmS8W4 zVpz`|P>nT3&`yceccZE^iAEk0dDAWXDw8cP+iBodtjXl|7=BhZbcelWNYoc!bGjP4 zGntsQpF|8ByLD=@uS3w#F4fy^S0U>>{9RROTDgmAlV+s)Y72VndRUWjZ`36ct3JEK zy?T4MYkgzKSk4Shd-s$fJl3MUiB9hAX6&mRc5Jrfz}Ur|+MG#NkRGtu#f@sgqA(59HU{&_2H|ZTX`^BPWe4nUqA-9Jw9N|^d?15kb&;FVMIo%!_6@=0U6{TG9>)8 z8seTvKxnUIhlPWoVbOT?8<0=km?=cYs4>0xoso&|L_>JRehoAe z-6m5>!z=b%KqkADKVw2Y{}GVsu3fQjlmt?Y3TC*YXPdB0=rp^T=@y@3h*FMbJNj!T%jRS64`h+Me-)E{8Mu8dc1x`$ z600g}4*5#e&DJ&xsW3nr=$%BvbQE8L2kNE2sDur|m_S8X=FR6Xp%)HkH! zR@UsjgmDYVYPZF9BC*QuxvX_p88TAYH$>LEH$<}pV<_5l`PMD6!&r`@_k26T&PKPg z5PHwIyCHRi6hY4S1NqKvC!{<`ydgb=*!O%lxg&(w_k1_GiFY11yAwrY-xl2LE)ini z7ToNv6JpOSZE+6?v1gXHxTl2Jw*|Ml_l4NE1-C|ozRiu=$!WKtZ*!xC*wDAR1%*)P z!;#YMZbcy!`e;LH3bF6v?QmNQvG3yThzNbB+f_8B3Zm7*&Q5ojke5KF8!}FaP5Ul) zkr12qUG6F&lXLP(mEG=sA)kSupw({on2;;WxHsP8-WGBXgfx3xZx`nVz3>Jj{-G)N!8`j4oLOfRP& z%j>k8dN1dOEw9sVHX*jW&bY;e*z!8#mKS2n>#SQ(h%K+PZVMr{yw16OgxK;r7m;J< z-NB-5_Xx4&b#W_q`4H4ipy?U(G)9#aVARnvRg;Ub0E77X(D8z zgnq^CA>=Cw{faw4NW6r8)txBhGYS2wJ4eV}=~u70>x871wtUUqAtY4^PQ`Wil#oIo zl#1)_6(R4g;C}Un8}&WsMmz}h2{+vILdHnHdebc^WSR7-UIUz3s+`#@3D7?l>W~ZrpZf3OR!IbrAV{$6Y1l639=6 zY!PDX#$ETA5L-9yMudLPy(k(g(^If>&-M0m{!p1-FeJ4Q>PfDH+;WF3{>^zRJe6O95MIeO@=^>;W z&RLZN3A_UWXe2Dj95qc_bk&xaXafYlCQfWDt&LiG_ zAx%K2bRO}J38^W)L~8H0kSuV#$_cSKmd>jzgn9|GlisT-gn9|ejr3l9A-0#u;58Ludx;EQ zTOrhz$xcSEvk+>_WGAE7TZnDTnY=h5wk>ChsLz?bVWKG~&$!IqXd%_*8JF3cB*Z=k zvv{+F*ymstZ=n#IibuV#h1gU)8WDO{Z>`nHcq6N~S%@8PWcBt4*@m8t(w@ybB;*hX zr9GQ>T!<};?A|#cwk)!H*M!(n_ha5&A+}5(^IZDV4Jt0mrXq)zT!>9Yj)+u5d+CiP zyuumnT|Q!Jomm+ei#itVVe<%zlGkf@iphE8#ukwL z-WDNug*@ry`IR+?g%tK;guI3sJrAqh5e~9MR%Nc@4XfCf?LuvOLDy z*n>!{s)+hSXE?`t)p{}^JB?sxoR^}n@nu>r^)2JQObN*Hm+?h*FOMOk)Z%!hTEW*u zZ@!QTDCPDble}U5$WHj%BU2+RPmQoV%^PQYasKp#of%%87!w~gp#zuu94|)5wCzmh zdWVFJM)ycP2jJ&)3wRcL$zyf$<6>0y* zJ35dx>Cq>Q16l4h9K@u=A|@-mf`geP6|&NsKZHr+J-oKO%Bwk)$(xwDkmc20!;hGp z-Nolg)_Ma*GATEMO5&S zc@u^BpJ62#y9}GX%HvpbXC`a5d-H|d?Zsq=H(~;7KKYHmBC^x-K4sDhWHM5*)0-(| zJ;;2Jz24MGta$}FPbGNPTQ-@Ama;hST@w?!~3TwVaU$-CRlGl0~lMLeP ziZ@Zn6GE_pk~TGzcoLhO01>t0DAJ$iFpz2QAC zWB>@Y!5iMohJ;(wO|K?vOgp8Wk%y7`V#kgOZhB3H*ipevudNUp!&_cwAvT7$B0~S& z>&==_=no?U5@?PgSAX}K%;sEO=iv(EzIT5PlWBjV?|lpJ!gv+uavuH#k{U$&P399B zspw6d93Z~GObG2#!A^Gnf{;ug-3_@RPSV`tw*sSULP6Ml(j`nToaED#%&C;c||%{r*@^f1Dv>)Ocu)<4i?vf0>XA zpJNQ*kOm7`^NjzdkX9h1dB$%pq{koVe~>?={C9+m0{PgGu1rEPEbX5Y z&55V@Ud<{bJdCq@ch+Rv0-mfIYuBANhzbeG8rk3;T z3bCuH<@_c>hM(jWv+{mxAyYt5omF|ilMuV&`hwq6h+T1g!S63*Ii9CI;H!c^RLB+( zvQxnyCFBW=;z;wN|EZ9&Af$QGpDAQ4#*n0`=+7522ZS^g{iQ+{Nt|EuR}0x9aem3) zBxIGW6;$$f2{|Nd1(p1RLe628hQfN;|3!$0=OBgkvVT^{@2h#up|W3ey^A~XQE$a? z30C$?3+V(xC0N<7AY^er)>QFd5waG9G*$fCLhO4JulNmw*!L!0iD+L{{T8C3Q;T%U ztE%5l2%TD_x>42dCd8h8tmgL>VoyI-^W%l|pTRM#?hhC85eUVwx<6J(a%mSe{3$}R zNV}-v&k<4&BYb{mnwsfsp2Pe~-0;F(ifchJVP~0U^yB{&68mhw-_% zy8byKnL+4WTwVW~kU|UDPCfswka8eor=IU_;B>8#e!jk+T*w~j=j;3Fg$&q$)2iqp z-}JKynF2Dyki0@l-{cZ(;1?279V7$7YT%a?V$bO{^q&`E&*?SvUl#JhGnkRU@>~9^ zLh6F7G^C!8>sMLR$ZsM9pKCRmMt&P1`*8k;>@@Z}3Hb?x>@@a!2{|j8CVqb*_e9gg z|3Jv)k{ni3f0Phc;?vZhC}ea#4y&0zQ^-;f3agpFK*+dTY^S-uRLF7=(lqzi2q|$L zV{DKX{w5(cK@JIZsTVaV#m*I{5(P$$>_bUUr6eMhAbi__FJV9sG$x?D}B`f0hu+dFrt{`U`|m z&Qp)w(f?YA{T_8Ee~l3PJ?c*WW+C)u2Yo}bv%gyiz1czEknHRq5@PqwyZFb1*nRUZ z{zWFL4@RC;%3b}k-h)uc-)eZ+m_#Kxi#aY@Q+NNakgOnA z3~@Je4L_`L@(QGfpIpdqAf)Nxrx&tFG(G)nLcSACPd~4aRsqeulz)e~S?NZdZSQj}ZHASAYLUA$F7-=N}hhN4atSc_DU`JHWpt#ExVg>(X;K5DQZajw$u$r@8P%(+T`Z~|h^Rr(dTa=Pr- z8;1GSgxIe)4D(+XG7r6RG{XAOe@n;r zgF%-1dxTua8pv3XZ~QAl+KtCwzyVo~I!*sJrL^f<86q}aA>!LOuL@~wN>_)7P3daC z;0Y7wr~&WbZ8?Os#;w)gM?fJSzyQrA^rYRY6-|%f1HpJ zAS(=+$wVDmg)cLKtn)7l`3+mH8nZ$sQW`}=8NCS*2(?hev?{k4Q$IGG>fb8~{U1CxN8uGQz zzabC=hyUY`L`YtY*~%e4Kly#`v9F?8wWIhkwm&tv< zhb3$AT?qL4!#|XaeT~b>D~f;m(aDL#st?hV+<@jUzlV^Qn&UJOh!dAF3D(1dHw+2KFe<`VRM3nqo2M0Zb5TKGLyqfOA8^e~8pH@$nq8}CXp#oY zQd69dCoPsRBzr zPs`+y2s^2R!{V!AQtS*M^wbfWG{JSz>`l&^G!dG#L4mYX6XKMclfz0IykJPUCZvn- zl`g0*z8XhiKLMeq3t9-FSzS?(^dZtDC6f$6Khb=dkx9m2sE~Z(slU+HRMNa7Y39TCImptkW9r)r?Kw1TflP0pa3XsYJI6AhZ25q5F~LqwAnb)y?J zxgs>VgReyspOrOX@*?U6`N|V)Gn#NI=Z&zFH~2y9OhwJ4_~Z?K7P1zh_W{WlB55)) z$se2+%|(PxngYQkAyGM)JRY)qL{j=ha7#3sbE8ec*OS4YLbl|=2|$p7L6Dy72F-p( zf)ol;33)ld91Y~Dh*T5~GK!`p+VT`=3P)&)1cgOI?>CdCNKo03aQ+mH@KrRZBfdUC zu6_nzMT3??rXlS_o(_>h$T1?tBJ30oI)OtC!EEFSa}k{5(VjKzcgLN4NMuNNM} zmmGtkLjD4wcjQY1qlD1;)ddKvWbmmFI={NakeNbCVAQk<wJ5!DIh~<_V*TQzsm}qkxoF4z;H5(cY;w zRf(|tO7NWc%7@lOzFvvYR1NBhCVL9jR1J;_nT7U6zN$s|svgwJ#H~9yEYp**deGL8 za7t@L_^J`SC%zV<2cWX35qv159x4x!SA&^CDoE+n43UM|So2!2QZ#+gN0F~u!9F32 zqnXqW&I$3T*Mg=_DD**6H(n2geojJvBNWzf3B7J`OYGd0(CdXlKO>>n4^n34+&Ckl zzZv8a@~nj3ASffG6#7hxPs5;=km7lmycJ4CeT)-G(HPeU4t@09!rI9cz|>ZDhsKYiS4`>G!~Kr zc}SMK2OWguMII9A5lj`*0(nTJXE0C5+?-5$1z!ufja(&7?_h(FQ)o>@`UKw#`4z2+ zNZ;V3km6`NMBWds3;70Zhe*G`&B|%Ni(v|pm{3`KiqSHaMQlWQ#RiXxuS#MkHh9{Q za4GkX@bxhAyx7@`I^PYorGHQ>k)5~*I}am`#Lfov#`%$oNX>wtyJ$AzX+>k30TGr5 z27^RH<6hE)$s5RLBJsf&qUnZwCNd~EXh=BigCi^t4z)p?(KqcYOxj}(LM?7ca8fKc zKy4w*LqqMfDQXL8J_wO>h#`?-5n+88+!Q;5ksD7TH$IHe41Wmmvr$b5r{ZCnG)5Dr z#v<)>?sRyNC6TX>A}oItSYMUVPRUoKW<-!zEDu0UD1kVS2udWfJTk)a$dF}PiY3b< zgBQe3QRFJkvOf;0C9*Rr!p^ABxc4CXL(2J4K|Qu(#(wB1)aW3dN!0JZ;zSiGHMPKOsn+o$3bGZKUV_ zG{_~S0eZjw2y0@5;_EU}IuE{P z2A1qc42jH&@by_RM|@pFou~5pEJ8CoSS6aFuuPiS!7)R^WjZIq*PP&@_*#N8C0}6@ zgkTydXsm&M{Z!gYzOZ^Mj{FQyfpmFJWhXgl0kTs%WaBlu5H7 zXeVS1>eX_Pg%Q5K2nLE~A^P5R(0mc0Srm*H&AdGLYq`)Y3Jw_(&Y#5*z7_|k#Md4v z<;B78LUJH1D)%pgl+;zD&L@ZET_9ft8HA+B%VbHAUC3Kd9)MvF1 zG8p~S8IW&6njQ$9G|PfUqM3{5JCWrPab6L07R?gaxdhFM2+hjiBhgSklV)Ww-;i)_ ztcvipDp+PT@lp09&#GXZ5POnmRj^fvJx{Va*ek@ICs`dF7BV>}pV(XzoDgF7*4G3V zgxJ0HwZU~Ec5i)ca9@aB4O?rKH^aVO@QjcNAju6WFQoTiwzDy)Y<+={osGe3Lf(pD z&38e4A$I@$yNI0M6f`rMaOrG%h^D>K#NlKT_s^RGOPXLjPd)bLP#<0p&p{$vLVfrt z^v^`LMp)h!#E9hvsC86Zwnb>R2jfK3673=ba$|dhW=F6{G#jL5?ugLr40ejgx`MdcP{@ z*@zqp^?p5&ZtDGh4E27;FuEXeIMn;)M$b>Z-;q#XH$(cmqajiQVNvh*Q)s5SPgZ4r zj)>teK`%*HPlOd!34Z}6LUSw_E}A{4Ei`637JQK??Z+d0J&ddrJFW19rIvC$IF`uH zi3mFgz9rHL&gfR-$yzZOc7$gk901WBjl^cl|nUB=YvH; z)`8H<_4$ajUkH|q=Bcl_ue%Ve7g7p@`ojysHX$|@7lVC5Y$`4WM}&;S{>9^n^KZdP zAu~V<8*))dZIF^6mx3EY-U2CaNaE4*<=_v|*w8NreqJhz_$V9t0|61*R=bO*eE}VJt1%~4yQ*9No+Yt(l9^eVc1s?;VVeeq`-suoFpQKNs_cP znmGK;A;b{r3X@(KOAv`l^1f(hAvYF)Buz3%NExiEtp-UJ(i}tnkS2MO5u*77mUn=p zhzLDJlCh%6fM&Aqp_-IQz7S0l%#vuQI84f+9ui3vVfm4VkPTvIJna04up%|7liU`~ zb+il8q>iwYCQ16oDOcmvTG*jDr@^WQ(u?y!7(uGJN8sSP+gAx)M`igo;dSEs|LEFL zllrp%FFTU!sNCxxcI~Rdy_s|PVSkCQ>y2Pt8}#$3Q#H>9?f2;d@|HBYJ@;7|k|Bk!5KZk3}Xa11?nRwL0DNIUd z^?0)H;M^BqzmG4o5VzOMN7McAwdILjn_smCk={|`$FskOyN+5vknX#od}f^!as6){ z<%HP?J?WZ4%AHIZT(i4uSz5if) z3CGXo@89M3gZ}V_*Q1m#s3+1t+Vuaw;HFNEwa&Jj|2F-}5Ak*9YsIR1(iZ|=1 zUheG0_Y=GIFN>Xjvj6|H0NZP;*?ki4ERp?l?Z}R!j^cbJJqK;L7Zx#}_CC2xIU}uJ(G;ho9exuj|Wm zzEL;QVW(W&;n8e|>$R(T@1l5ls>6NO+57kMlg^cNZ7CLOgvD(VUPSj zHG%!}xWiE&$n${1_0(Bo59_9FSeH@KH^syU^NAcBuSIgr>A{YcvGbpIc^qWZ?MQyP zs%=*a-&3t+yk*0&?lCid!st)RgX*g)v_F;a*tx8~_5{0}Z}{GY$-n=-an1h={ScMQzthR}?%(i}3dr-H$03f&DEHsZ#r_&gzFK?D^0R-=S4TZ5 z^JR_~#&vSv=Bst>^UBWOKbG;tgV(OABJ*ZMfxTv3c>Tcg z%X2ur_S)(!x9boOx{j)0#!Xnom2rw4H`sBC9S<;f%{ah8y`galJzwoO;R%zUj@tGm z$7BD_gf7M@iN=YE%f;6JPt$RIupHIbUgA-I>4W;T z?Kyts#Vsjr&P3M@q@DLLv8hp4%@NU)_u7LbL;+B>)*fqaX$W^%LhDnXk2UO zH%D$#JRLPb`aSFNd<3hTGdLa8&ytSYrK?uPk{vH(XY*jbU)($|Ts6duXFavh^gq4| zmec(}wKn}_64j~?T}P>fyUE4(P}i_KSNhM&f6%p~*siPC?mxCSFox~i?8t7LZtQaZ z>?rQnU1j@qTRwl+Z`gSk_gAh-f5LRn`;P4o#n*u-9aWzq7we|RMLrawYY%tmAI?R{ zeV+f}+?2^*N9{KLUAgat#{YJnI7iCCUY9X;alXVnUmev?uI>F#%(bMi%*v?P+IU1gy{$0M<`eXf_Fyj(eEm=VM;HmY-^-X_I`C@g6``1#^?_2jD zl?TsT!|Bap#v>Sa%;x;>Aoa8u>Mw=+<0Diujv6NGxRYgGX!Z6vWyc-E*F9M8)0lCF zqn^-Y2lMSrj=Seu>=`8~DDR_uKjOK^Z66_RIAQZ?vqUe8TwiJljj0PMf~O+@{ygtDpaw{nK-w z?9sfP`Y+n2pm{mjr}p^b2M-VDVfM*RDp}9CZpMGux4F*#?R9R6_t%Cy%Es%H;jFXq zr}R>M#>8-ZIDVeQ%MZoN>e+s{{qVTTRWzW!%=UU__*q##LM=l3FA-g`u=*do0-CJBiwUjO<2*;$2kMrz*?1%dQjson1;ljbClN?0EMa@|Ws~wYL-T zr~Kgg9M;X`d1dDVb{>%YGU@PjlD_OdI1Uew=k2&Wm5jF^)Y);pr~d9fkLNu#%ft)& z?dv!^n@*b!+aKC-0NuCac8VwWBRJ87_Da{Jx8n_JciHi`%ZS&P{n1Z5v(D~2vg?G_ z=T4dVv7=g?CY`Ik*vtBXGS9Ov*K@oHMGSum5eA>%qVC;eR(DY=2Da zF$wog63_Q@o979}LuP*m=i$w`DDimQQ^|hd^!#`4AC~^w`-bc}%I?$iHQweo?b@Ep zaOHUwp3fw{&;5ZXI$obh_8!>k98|# zocW7cH+0qKX1~i*uj9-1^t{b)+(2EE`4#nt^c)))^PvB~On+ico|7XkBt|xMRa#b=@4q7qC`;HH+8{)pH z&z|Hn&e{&6_&chXnGa*$E8`v;pMO+u3Yq7cqpHb1VdCp;7dU^cy@c(O>faCYyxncq zpYRZO6^lo}Jg%aJc^2aYFOLY-f+OFTTbbzJ`b0 zSth;q8ueDL?@Z_Tj5YNc^Shte-dfYH(VxgTWV-Z2KQ3Z@_krx@{fzae(o?)#)xfkj zPsN-{cpqP}Fgm;sx1II(jf?$A+2>4AkoCO&@2CuA=-O4oV#)PXz7NUu)f}S>)LSP1 zlBlOo5RXz_KOr}%+HH6;wZP*soI*oe8 zwC}X)ZIeIgR33AkUKKRg8B`fF&(5emxLKzfFA6u5U88MQwX%gL_qG?jg> zosv)G#a(3D1@`03eOKj|=il^r4$qFit-XJ{3Ckg}{QjLk|F`nz@8mCofjylth+k*|C*S{Tg>qq9S$9jkK z&-S{f^y~IITESBKyW8iFb+^m>Bi|IZ!{=iibTu_NK8D=C3BYZ*{ibSl9ADcXRmvD%Zw4vHP#G z|F5$1yUb^-n>fCIcWuW-_Wr*rKL5y0;_|ZBiCvqXe`N1}>;4VNck51&e!;ql)AQer z=d-dtU|nmU&VwXuN0wXN|CIaRP0v5;-}W2Uwf^k2b!~mI^*OO?^W{J5+VHGv{U^Ro z%UjJQu{w{pW|IXjv#V4`;|JwE6#rt2yZF)z_ zbJJe`v+i{>AIE!CiQI3bU$bsCv2U;KbKAPM9iEBfe#yFt<6+A=v71O1j;GxN*GuPh;!)BH*XR@D4TjbEihzg`IasuKG3TIg5((66SUUv11UT6XFbVm(8@ zVne@%gnk`2zi5H#j`?LqO#1B)IL=AU8?@25n?jAisu~TzlIm0#SCcNOCPss`^lHO# zin&rbHT|l9U$1GK^5y1NWw0MZ?5g?oD%hP6(+>HdJV(FIW^cFv*C`~|&@}P8J-xw|(*f)j8tKVku*DJ;cB{7qt zMYFl;AfA<@@N1+xfYB>0oQx0B;~W8PWsVQty2ZM!sy}jaE!b8y5~KXh__f&iaxVL* z?@jG;(~cNoU${V^zslfx^Fk48AtvB~@zn@_2|=2zbl_!_8AxP{j zLC_;XhS-%AHX(L5uYTWkSJkOgr%s*f zp6(r1J030lkEPq6#5bmgFxrbYeu>}P1Z^zLVh60+(xZ z91#l(AH#cFcUZ0MDIFU%-hRupulf~Th#t?vyRdK;^1Wj7-3+gs>8ajxKjK?tpp6d? zL%w%GRi6AZiTucVbFuz@{`q2K27+q67jSZupc!6YJY&iESXg)wK20=Kw2-T} z!Rv$ABcYA8*Nj}#HQw{s4VNFlp6@-q!k7fKQAHE+4$|+TjpOw(f!9$Jk1`r|zpvHg zx!={A@3~RZ9=_b+gIbAj;a6<@=EkguWVeAb#&2T{)xZ9ej@AbWn|V4W5+G z0WB<)GkCex?!mh$^2-nCiJ-avD{1yFYfP zdS`rU@EaF$M528Un$MYa0cnw?35EC;Jf6WNJV#4-j^-Ej%rAH1>XDW%wXuzeU0ygo zCf|1{J@n-Y{91%ik<4cDZMZF#q=(vAN1J&B{nrj}o7o4WQ~JKm&So2+t+XYJcO|_m zO~(SAC-o}(65iE3j@2xAHA`O2*iMe|wQTchGpPmNr&1(smaBUlsMFhl@$yU1B%4ph z^LoKo<;1!!kf{)mq7zkedX3k&5JmF3sbN8!tD@N2_1pTwSSN$vs9q2i527r(5(in6fqM7)P6 zEf{QDrPqwiG}j`cir0B((GBZybwg_^D#4s6zx7<}6%WGqv4Ey}Zr)vP_QiXFXP3&{ z)UpiUJ_%|Fy^H&50(De*4LBb{4WVD-x|{`Xb7(YH3b)&QOJ&Uf8tu82M+4`Q8gC`a zdk5a8kR162&_a%gg`pb|yUA+zVx=JCbYbY|dHQ`qGeU3S69Jpy?JANp*ad3f-Kxcw zBC+GcSL4XP1?i~!$>uu@5d|^a%h;-oMQ^@`6$P{!&OQyH{gF?;&$}Vi8&m~q33VTa zZwmp9`&sYGtXB_hW6?DKENn9u_-CtzGv>yk&Kul0lGV+Vh*(}IYk}pKZo3WR8`NAB z!lx59f)*Ce$1KoksnNeDR~MZ%8^7iSttr%UCw}F|l55qA_Q+*j_ad(zU7N{BY!97- z^}z{c@*`w2WA=;<`PGe$p?}~gWhK4NmU1byNp@{}Eocg_t##oK@u>kBVe3LSqs_O& zTOE1oV$AE7p2mC7;+^CT!Z?+6*c7g*+e82QH|`b4SI?5CvE*%R-z3k?8}%$@8cW$0 zdIWv&AC$5!^x+P?-x-$`UC$B8s!FcV*^J#5l5bHu5czh7T3<5e5YTM4U@luQmvt<# z-cdM?Mf5fl-C5|5_M*!#HRg{fWeHol#I`_Yfh9Kf4S1K@*pESNUK#GIN$Yj%(YIS@CK}W`-0Xoc0FUOxZbGo_Wudr zQH6X}VRt|Gioa;WH>TS1A(9Qo9k zTR^SGX;opjmLF9lXF=8iyVyhRAz7`TwVRB@lQ2)74{9~jZoxMwfoi;8VrG@KXlLQc zU+EfssBOLc0@F~g1c!#*FFXznPxjZW$cKKBmJSW?d8DpIhlYn-uUf0Q6eY{NR#o7R zyw&6}zbv&a7`RfO{bF|9%T>`QU}mza!$fuT-Zs1?0r-82LDquoI@;in$g@@m5J zOWJZoql#q3b1b}rL-GtJtCmsWQE*)jtzYp4nD3{9MzHmxLvFoMZAZxhct?ddy@Bu2 z0u8onpC>@Nx_J&XKFnv>u)7P@@L94Z{71B^0&S@Y%ddGWd56j;LeLwwUR>tp-0%}P zUeU%;8yAw%B&(ZoTnmf~$?E2H)VtisbK@FNZFmW;k553A#i!hbxg9jayo32v`e0qr zj@$9=lF(X1<14YBV(Ga*>3M4nz3`ddKZX`J&BA>ZUR`Nl*wX_kKNBX`6AY+$!%=+!5v2I?N%L;Oaps9VUi49m-2`e6y|xZBJg76gQvTNzC2utDd*N!sCq8FP7TyM1p4`FC zE&eNJR_TKo)M|@m=9k#o;$>)ow67^t(qYUW5Ic!|KP4oqG&=+HEKK29m~VcKD^FH< zO>BKr_+30D?2;A~KQR>#i+#}J-bMX%)!Z4Gh#oozT4&@4%>2IsHHYibX1UwX56hGP z6ln9qAIO+QtLBFzaz}(#&sI$%%_Pkx%_S`$EwUtIXbEW=k7y=oDZOo^+4Q~`mb+C5 zSKo_axsIZsc1snY1S&sMQ@O^Z+l4lhE=`dq5h@DaVI-a5* z0M&TEw)^dRO=nIl$*+%v3>=bupCdK)XV)X;DY zV{-pJaLp7+-wy(%xD>T1t+s-s3nRwTCWy z8uKac5*?vyF&yMRIF}_aFO)m1tUKF7)fx0D@-1L(i&$GnID$3${ivgZ_x%@(&%IpN zq8n{_N7_2v_abi$|KT0&@r}IeZVa!-d@rT!4BdhAF&(so$FU^ru9>B5-xBs!n{Ab> zhgRBF$$Ds!aqFSBuv-r;vQM*eM{KjPvNBp3cE4x1B<$`QZT6~_J6L=8GwjUDrw!Y~ zazAeqDt`TH#DUsuTjYMUlPk;BY~S+2XZ>|zN639g^xCkyJGY0fT8&Q_?u};)8*wmb zo2B8P^({Y7W_&amV=-fG|CP9igZXSi;eo|(>Y!-2TZ!rK|n_|zUs zAoeV1Yr}56vDUU;dbd6F@pXEp+e7bye{ix{1NxnPvC9!_Q1R$&#*P#F|XknXCIvN;wk87`32p&-7P94ck$gKGH0ckz#*RY%Xn==>Hm zK6=6X*gvpzb_BD9 zVWGkEew~fzz?^uwrI9G*cc6i`_0qn;GxA~@`hr~O<*6|ax(e}K_%3~7yWeWSHp8YZ*BIn|)gv7e5Y(m7%CDoA?_+ABl zI-chD)o5FaJXud;DKn|frq&R>2N7~sXGh#jIE_>p`DClXf0N_B!1j%b$X<)|Zgu1X z%ocJ!7O>YUBMba-&=5V=-wmyd)ZFMIZuuNXU5WXbZCS#$EMdJ1B5uxJV0*~!>e>kV z)N3Q`Q*Xr0^3@Spi#DL-Hrqa#<(IO&g+}%YOJcm(42%NUYQ*N4b_gxt=|=i9NK5N3@o$T39#)bE2%T)_Jl5?K2Q};^-Cr{a5c% z9@^Is8a`O>@eQGp!<4qLwr)#uU2b8??ID?S?nHSzL-Ch%M%orSYrEc^x3GQN*}g3i zwl!JTLlWf&;BmGi(AVwZnj00_i^mre;t07lPq`=M3kpg!u#O%A9 zQu4Wx!(PF)fKtwl#BaqJ1=U6l#Tk4JG&QpSpK+f7t&6t*h*=rb8Fjk>0}I?eU@+_G zjJl`5nB5VPw#24#$oU`r<%x2kW7$nk!35ZYKE z>z7VYS9DPU<{{8nwq+dK(iI(pdADE?p4E7DcSi1!+{}78X8NCu=`>K0gpUv)5P29=u!C$9Sge8C%cTR&UT^ zy^^P~-nOvY4_g>XwMJ4;8gm}?fodiZj6k;u8^F!Q6=5?abr7ZG6c?mpW}vPy{pX(BfBK#{2f5b4#xMgL-G%5hi`VGyK?R*!O{V zHfMp2kq@wrkl9-E$x&{MeAW;!=tdGosK$ohP$`wnA{nD06i|+CR?w}D(gAg7qOHrEM*J5-Slp! zcUOU1hwb7~ZfC?2dL#BTF*2KVdRaVI^uwGGqt?yd*kwujxtmAc@w3mw$a7vA=Uw;f zE&|mS%ej-gCph z$GDKQFtE_=c?_nvx#U?~J%fkgZcs8~1@3Z|uExl@9}%_Tf*JS?V`#Nu*<-8*4Q44L zSjvb(H+zpLlxIKb(-AhG(C9+mO$*)KbS#f(Vab?nIuCX8z4yUQkzR{0qa=A<5)y*tM@#fd!+AQ49Pp`Hyj~P!Y8$0 z#~;*cLfF+6Z>!lg9pg;264#ccY;&7!vy8BnY;(79d&ny})>iY_)-vCEwr^-Sl-1fc zQCrG3FJ+szu-*fsCuRvzU<3?fy%6z+6Z=}dw0iz=B&bgg+Y-b%asZ~Z~H79*A zn_A3%QbMlyKK#r?{~~wZ2C@!3M_sS6eeAo@!u}xyc6h=(o5l!F`H5XlW2Y%HIwdoVfdeHKcFK)N0cf`&Wgx-uJeLw?3lU0@ksJN4bQpZ-{0t#=Is^)_+0Yt7uYQO%A!t;=Jw^CMLr`^rdlIQGcmwPE zKSSGC;y$6VvE;h_^&Yyh@y3eXHPffqU6=jo9Y`8X8o`LsjM&9iRTsElVcS^Zb_d5YwzeUHVVX!W8z#lCYb1rxd$udazvq z$TMfX%_q;C(~8|)a+w|`Z7qHTgjKLEH*9Q#+vfoq+tzT&u#_n#Q2D^HdYpbEaJsUI>$mc=&TCeOV?Q0|C zC}ow=z<1$i7Q3~@?4Pw@3wE8qKtz*03tKI{hqHP*TlJ$Yd5_ES{4o|YI!oya=UdP| zXxmCIi+Co1h!>09tUQ->%q^C0-jGjM&MkJo4!3~ksM+3ou=#}jCV6JM>_p7jrS4NN zl@Zr}`gzP3;q5B?6i?efSdu;Se}e|{E?#fiG`&RPVA% ze2>;ivgwx0S57#%p@Un0rxP zL+H*=j9CooEc*6gW8MR`7tY!PpO`sW))D=2mDx{E*mw3;LR-$&a9j9NwCcE1uy4lN z#)lg)Bb@^+8u=CGt9FonGE>fAlf7fV4{g4E_kSa(Dbk5?)n^>`*I3GW((=MSSSud| z@1|lm+ioFkvd1P@PdATkKI_<0?ADmw?A@;DD;SfvpuFurt3y85C-0^$FZ>@ofw#cB zi{7s2%h&_>0a}Fn_jpqO6Xw2Ck*M_{X`3&Aw|~^NU|`g>eqeMOdQC<||EPP$?oaRF zsN1z4K`ma8g}6@B_!oA2t!@UA(ivQTzce+L@NddITfu~Ap=xTuu;q|GNKw^?!}kBhpJ z$3>;&w`|F>r@sND&naJlCPdv_Jib)cFU4nIR*t$|>`AuAWrulE^ynd&Y2ckg?-Y8c z&|6P$J-zkxPK&zPdz#$?kQL)hM$F`hm`xgA`~yZrYCNvI&?k7OYdmNs%bU&E+0-fv zW#m-gY@J(r7kcO-MAR0_e>^mR=5i!96t--`Xot4TenL&o?*f*$fGwD7cV^`}S`>A6 z@g*!}7eAA_DC+J<3)q&ns9OQ-^4yWHWF0G6$4W*_EtPlr<*rd#B)g$9(=?RUJ%nrg zOw1*WUCr3F)Ykq?lXH3HFEMY}ewLN=>gZ|cjf~aAE62N<^{!{^dTN`fZTT6wlDDwr zO)Pl}N9-n+(#_cIKOMLVkzpCquj+( zrt+zys^HYY+Rx`k9%#eL@+{1=C2oxOVIBQ#9kQAmNE%G)!#&#mBz+%S{!gTtbIFX- zDVO8wIR|&n(j8mz9tN(wrqUy^ralW=vpwgN#A_pD?9M2Z1=3V#BkZxsm9nr@#?Xz> zMzaMIY+uP<)zIR-5pg%XW35+?d~C_O1^)kpl(^6C*Lc~Dm^YAbT!|Z<6H4639?R$7 zRy!X^Df&s-PDFIrPngR7WQY9(qKwnoJj%JGNhNL_F+Z~Nb${*6_0W_Ow>GOUar0Gu ziJMvLOWX`sU*cxg`Vu#@)|a@MwX*QTDr1IC#G0#c%tu%^f~pG-!!ua|t*S5iQ*XT2 z3$4Dy&AT;)ec>Hv^PP>=LPW zF=%dyt9PcY_m9wK+InSHUQpudom(RH;xxf~@Lu>7zs)C~ofKM7;@YyHMA{(Vq5G%9DOV|9aYvlRRz5I8WPghNtbA;AuN1dfJXjp0*?Hw_}P| zXUn<7yWHA(Z<@7Ncr&b>=G|cJbZ?fm_`J5Y8Si#$XM1;9JIA}v+PU5$Yv*|_uyK4s z`Y~&ldF|G=c_*GH`UK$V3cE9``-bDL)mv^7FCbYuZNa%fQi$goC zjfHlsKSI?~#{p_H}#L+4wY2wiLKz|cF^4hi-DmBft*ooemK&<)m(4*jZD z^i=4Ci{$)G59v6V8Pai(3F&#C9n$kYC#2_ngP(7cpD*v{+v4Z@+|Sn?(($o1q~l|I zNXN&HkdBXCAsrtktm7jR*6~ps*6|Sw>-eY$>p1Nb*74CdtmC79SjR^qtm9)~SjWep zu#S(xVI3bs!a6=igmrw34D0w99oF%Y3d{Jw_zm}+YUhXWKGu#4?{DoH;e)K55FTvp z#PCpSCxwr&HXT0N+9~0bwU>mCx3)ffvb9%)Plt`0On8E|v%`;CJ14xu+PUFV>cl@U z{E)Q^!rxhYe|W;BqAvs}kpK0flU#)!V~6*-4&kJEY?Jp-YPZ{`5ddbxG9eG#hSkuPku7);`nscusg(7L@v2gY@f*Q z=85ead1SuW{*mo>iA_W*a0id$^GAd45j!X{7JDagdhChg%8;SiFC9`y@hV8p40TO26V80R4U`kjGOQ4+T0uRahH0yZL&b0-dk= z7RY=RH~oCQe}T?hi2|Ls1{UaiG^jx5qrn9_9}OwEXuXs_(l39sUtY>DFI{k{^$#l4 zdIlHjyf~y#%O6pw<&P}X@<$i`&gReh`Iq?lpYZc9_468@x_Yt z_$rF@`1%y-@%1gz_VzE*_(YM$4=mF8d{B|LYjBYs&j`QVk$$-;|Mgh^^+|p`+4 zcZL7DkN>*A|2pBn9$2jXGN@SlWpJ_f%aCI2ml4IoX-nHj8IA1@**C+b*PO|=9<^un9+Rrz|&v%Jm{}p~Y(|rGQ z-#^p(dzmIbezu=)j-PL?pKpQhzu)&S^8H!gzr?TS345HFXG%UnKlU>J_T!36wVz_8 z{`oD{e(F=I{n@uv`?G(k_EVx%&)>jOnGbLuDE$oOh0O7#I?ta}+GWdc_RC%1+xu<# zm`_W0z>oQ~^e1aqln(k-Uau^zwKi8e&)U_cufSp)*m#VC()CtfTe{QQ_ezI-CUNUa z$5^|e^h|3vmELV_zI2PVTS}|{DfvDxonUQu>Fw5TE!|-4_R`(4M~VAw=@HiMDm?`j z{o~hbVk@m4iS_Q1e8sUdt&PQMt*waNWNn|=)7JKlt+BR$>?>;%vA$nO+`!o3)((n| zvvzRoENh3vW?MTV_N=udW1FlU9ouPbD%R&qi60v~#M+Z$7g{?m_LQ|}#18Bh|Ag4{ z)=rGw^p(7x6dU`s*mUe8Yp2BKeIu_giLKZwwmx>#HnCU4uKiZ*v{>Ko#7>W$Ztcui z(RO*AiFH^zJNEeZ@_J6}YisAm4*Ee}&x_p!8#41_dj1#0%6=66{@6@w7sWPPn~jaw zA^MWo!`40#+heD^UK+dG+GVkd|B>r^c}&)?7$312c#ZpQY|np*eK98YH;j|m)%Nu( z{_9-qE4;=pp8NH$j*Z(Tuix-ruZca5*SH_Ye*JH;@5RdgBX)gkowXZc-~A-7H^tt- z^LxmA66?0>m3-_zyl;i;B^Jj!4j4bN8P;~k{$=gf*o|S)x5sAS{SSMHCR~3oZmQBV^B-U|db76a#sxrBrv7RgIwEB>;Gx2}l#ORQ8><Qw!zwT z**DfsDI1N?wPAdf-ED1s*%#JcQ8pZ(ugCZ*+Z{U)7++;|*3K+@+}cdp*VfK18->rg zV|AiORRo>S&Oxc%09O?TlQ~jmz4F#r%JGnE4$6w zrDdb=O+uJ=$}X|Ct?UhJSCrM_vt<}hW%pZ~D|;WdmudIwSzQ*wJ1UrW%C50?ZCT#h z_sT}%T}OF4|V$KSAeA|Au1XfO}Ohgv%*eucGzv6dev!2k;*VN8G2U(Mq55-4XyCQzKwJYP#TbqmTgHL*4-5XF6Z?$$xd32P#zNGv>YwOD|v-XPex2>I4zWY()pI+W*?acCT ztj(0)ax@uRs zuB%LiuB##yx~?j&@Yksox~{6I&~;Ux3SAfXt#V^0?Cf9E-bBKK%H{*Ac`)9G4XI~ea1-nWA z;1?5ZKI|{=rv1HWH|_82Zqnbq%tpW5uY9}Bw?lhLeIavrFRkY+|Mj`{b+Jj?*TrT^ zFFg;J^wRR{dujP|eE(eEKhO6suzt)(*5Au4^z$w9Uq9%-&iZl7{MT*%>lJ=EEB$&R zy>&bk_ttjAdTTo>dTTrS^wx3Jx3`X~{=IcvC3@?)8rWOM)u7(`96H1=Z-igoNLwD} z)!tX4zl+Th-~WW~U+UMl%&)J_uWyB4-%49w+`Q6T&ri;;ceP*dn%=taxVE?MJHFRj z_Z`>w)_unfy>;JlQ*YgO%=gxP$1S~e-|_R_y6@QCTlO7sKlR(UwfDWYz1w^L9v0U@ zpRBbf_4(N9_w1A%-L&sISwP@#_x(;i%wwGDAr}{tf?Wfijo4)*g*z{fDnM3In z>TQ}XQf+T@t4{+=t4{};=X@G&KJn>jv-iasF@|&s^Zn9P`rh;DolLsa{KEHMX)gBZ zI&+Orv&<8q6x&w~($))U>&MWWCe?y8pOEI8OmBwN1k!v$nr{}pSyBr~^9gCb#q{P# z?I6u3r1|pncG4@PUgNnlS*@m5NWE!#Yv~nIZ-(9`dWF=R zrMHD%A@%0yZKqdAy?M}W<_DZNAsuy{%qOJzFbVqJ1Sv&IlQN_%DM!ka6rr&9JzAe;zRC0oX&pjZhmh7W71Y~%>m?8S z_^!5DAT3!)V}&$UNMoBp8k+@aOBaJQR!C!oG*(DsTS0r!OSRsuS(pVvl z?Eq=Ld633#25GF2#tLbykjBbK(KI3q(g-2#zbHssm0-RB%qOHJ3u(zhT5=UgV^bil zqlQ|V+EkF=H>)HEso`TmJ~X=+og_AePP)S5vWo2AxDEk~_`TAo@LHB;o;90l#|^?DiYqgG`#xs#`; z)lf@Qn@X+Ol9bX)t%KA>N))?#Q=~L0L&}nJr1k)5@8+p>21vd5=`eR@0;JvqwG=5$ z%8;_894Sx2S62IVBuFVznluHp+0Ka>YD=i)s3ow|r{g(AN|QY7qp4R&kE4>BkZLuc z;a(EwW2&W-LCuz?$T_lfBdEjDL!d58D?w3g#|-znKvkCZSczXYvve3}s-@FF&6XNL zt(NWvtpe%Yufu99p>a6;K|e zeb8mKjnJYMQu2?WDocC4ijplI4w`D|LQu1%CeUJ#KX-z@vu8#$f9?c@z4Knwe5KwB zP%E_I-b0981@h-kkj9GU&z&HR?Enq;-ay1=kUwLBG(t3g#sq0Z7ihS*6%k=P@%b|* zNWD?ea4-IvX9mzKq~!_u^CU6 zY`v4=T}-c#)+VI232AMupy6Hy5vxFc@6y|0y>0MrrdP=CKak&lAiw`W!@WNtB8+Ec zElDAY9SHAKOUHub`|*Z*6G5$( zrhz&v%>#8=S_X>tk$e(SW$As;&DLiYd zHlUv)`EUB+-uEcE*;4uII5QwEuhnXYLR&?x!)j+k+f1#?YBxX&@8x2npyA#UXalHK zSxsi(G1O|TCUfy*YE!Kyv+^uz%~q57c`>zCtI15gidu)&WX|49t;=dMdx!UC`#{4z zna2lEtFqc!w0R7*8moN?Z8Ei~Rx4PA_EBrLS{1a#)LN}}3ba+!I;_?RZ8NnltI6?( z`?GzZ;a)TH4WL$KwN_|jsMT2Q4QP|8O|_aF?<{J~R+D~NOs&;wawlFzt;1^nkoHmQ zvf5A3qWegz_FRotfpnBqS#2n^G1O|Tb{e$F)TUbP3TU&aHCs(eUQDgkYPTWZDry~8 zlX^E(>$2Jt(8Bw=wnRa=(?J_Rt;%X&LaVV<{syi_OM^kPn6KGt$ZKl>`wRfO}_hVZ?!#$~Y0JSls$)s7N#iUiF&7^R`l{|nnhBTQpi?o=OBdsEB zCJm@`C66IZCS^#oNLkWiQjWBWlqYQ_nf+aDVN!xLfRrMQA*D%^Ng2{CQkJxew3!qh z;94+%G=@|I(r2~F)TUCKMXed6Pe6;QwNhI}t%KTTYF*UA16^C9AT4hIwJK_3sMS!L zOl>OYVDC$ezgg6pnQt+*R%)xLbx_+(t&3Xt0JaY_z^;}CP^$uIo5xVAp*ES?RBFwn z#q_pH*H*(#9VYt*W!jiFXUZ8Ei~)S5xsg2nW<(z}XU2er-A zx~PQ@Vyi%UJ_b;$0{MMKt%llUYE!ArqSj1pF|}4|?bL+y$!it04(98mCZzegKziif zAlG^!^+rM3=1O{n)LTVwHN8UWt)X`^y;G^pqSg%Z`<_}W=wNTB%)8V&K-!kg)Ve?# z8?AEQ1W4~p14vaM%{PWx4M@wIOig~VS@X@J*35j1skJiSDrz0fx0zZOwQ$n4Dhkqi z2T-d5>G6)CR>ORgsZFKUOlk#bn>(oGLD~mh)Xc$7i-HdJB5!&oL9Gg;tx8d=0cpu; zY8g_Nlp}S3#(2A-QP3DKDJ`H@1@c=!t%h2f+Ei*8YR%NL)LH_h zW3rX`a`d(bNb_|-(<9H*+ZiCu*9A@6Yz}e9<^@ReC8$*fNWCd))d5m(np$mu)SIE! z6d?6xskH=1y*X;_0a9NP`nya7^gf?8#O)SIGK9U%3}w?}DD)&@wu8EQ=dQg4=8OMujy zqt+fE_2#K{21vd5!9I6>1Ek&rwG=5$%8;_894SvS!&pav{5q&r21varYSjT!Z<<zV-dNb6T z0;Jw7wUz*>H%F~KKW;1yPV{32G@)nv@}BNjXxUWJbD@6QmR=P0En6q#P+v zGNV`?DMdYYC8gbJW@cq~1KW&H$;`9K)jwka`o;Dg&h66t(IA zsW(lnHbCmlP-_a1db8A80;Jv?we|q1H&3lIKNx7p;kW!>HDMQMVa-=-TRI@x%nv@}BNjXxU zWR7Dgq{;wk>r>RK1Ek(Gwb}rwH$$x{KYq*^UCA=R3w38~gXO-QwN zYC@`YQWH|m8^`v6RI8*Wq*^sKA=PTB38~gZO-QvCYC@{DQxj6HlbVof-l=RKNVQ68 zLaJ3$6H={~nviNu)Pz)Pp(dnSJ2fHII;jb%=AFj&fmExcCZt+5H6hh%sR^mpL`_Jw z7HUGOwNn#Pt&^INYToH=A4s)IYC@`2Qxj6HmYR@id1~eiS8{@sBIQYDJoAy{`v7$( zFipykvZNd-Pcmn^*aRs>N|Q3AEGgGR6I>~IQteqz6Vl^tq9&wT3pF9t+NlYt)=5oB zHScU!hmdNO)Pz*4rY59XEj1z4ny3k>)lZ zNb(&?dVVvcEGb9IlgxQ8B0)-#(xln|>2YMJH3dk$S!yi-Qg4o0o@CBvTSzHVnv@}B zNqLf)#8OBpQks+@Wl1?wo@6dyc_jIcE&nr0A!SK9lDW{uCP*n#nv^BwNO_W( z>`FX;OxiCFM!xH!OveBBehl(O1$ zKGh}novK=6auO(Qy^DOROFmntT3xc_Qb*H#YD^whkNtZa@vu*I$>%Optu9&iTSwRU z)R-K0Id=DL#3Mdw9inNh(oa`tzPjWU4N8s4!yEA~fQ@~^r@G|OD^f%4Y-nosH# ztucAxG!I`sJ!HMd_*9o%<5OeufUD6%)_a~$b;*}~YD^w^4f@4; zXZlo^{M4t$CRy74L>Knmo-rnQmuuW zkZSGJgjCB@>kN>3y&GL^LaJ3#6H=|3nviO>)Pz)Pq9&wT;wD!|_C7~BQl2DVuB`XG z1Sv&IlQN_%DM!ka@ROQ;c_~twlp$qFIZ~d~86Z6(?*Uh`kbjiaDg&h66t(IAsW(ln zHbCmlP-_a1db8A80;Jv?we|q1H&3lIK+pgj8#xCZt+BH6hhHsR^m(Eq3Jzsa8o%NVODb zSaL3|bD_HAzkF&;4w;Exz-5GxMx<>-9lSzy$u6H7lOwM8Of4gXG$LaoZiiQ>G5IB^ ziTQ*yU)JW^{|3ylHs4L47UmPud^wx%C3uDEk|*D&)R?>;)XoSYjmX=Gc6f#AlF5ux zWAc1ZCnJP3!Yq+~c^Y1!y5t^Bj!yKcF*yU|!K*Wakj5r#>>7B5G*(Gsg*3Jjq_IL8 zn*t3>PPqx^1EjG^5-X&!)gX-((%3X;SW@n$LV7n9(z|IbNF#(aA_F=qSuhJ{22_`v z?NeiNJL#<1I9rSr(%39$Sh5XXp}OQnH#>U7r^e(_zrz`1tdPd$Z0uZkh3b<3@d@|U zTW|&$A*2y`&{4_T;T5V&?jjvIN43V}b)=P~A4x--UB1gm&y%`Aovc?#>ot$cQ4YBk zXCI{X3NaGPf;LH;=hX+#P%EV&9^A&n4fOddNI z*C5D0(;$sVgN7wCT1E(IM8-zE1FukBa_t?CBv!P>Wa*ta(;%%) zNMp00Vaaju3e_d|ny1v5oJLv+YGJI9#^!A7zu*)0&D3&K#;3-lw7G>5LK=~?5y!S*Y=9b*!yj?fO4@(1)2;`# zvlJmMC2vdl3|^tS`lNRg*p#8A>%q?<^OlRhBr zA`M!qrD$Kt@oHZwNna^RUwQEQ*A__oDginwc_vB`s!M)Es(MJ#J>gm}q*{VnWq{P1qE;Os^`@!S21vabYE1!BZwoac)!L~Esn$tN zNHzS>ryI`!Qm=foxt^oS0I4@ctvW#JO;f84kb0Y_38~gXO-QwNYC@`YQWH|md(yR3 zNVQ68LaJ3$6H={~nviNu)Pz)Pp(dnSJ2fHII;jb%<~_ysfmExcCZt+5H6hh%sR^mp zL`_Jw7HUGOwNn#Pt&^INYTi<|52RXxT4jLLo1#`7AobQ#6H={-nviNO)Pz*afpqt+ zon9gJc2W~k%{=WQJdlo9A@wHct)y2-y(xOD=@n9Mn%-J^h18p&w~1aM^=9d9p;t(~ zIePOX^Nc%=1W1n~MM{%u1LU`bn*3Uy#tQjup_U^ho^|r0A!SK9Ql4aSijCS^!jQjU}-CE8qhDN>r0A!SK9lKG>HO^{NgG$}*Ml5(Ux$vn^U zNGVd9lqKazd6Id-m69f9NLf;jlqZ=LE;d0*kkN>3%`2`2UVzk_pjH_m^`@v*2S~kXY8g_Nlq2OyiC0})QlvB~ zL&}rPYc3)|N|Dl}3@J;>k@6&ybLC}7SyGOaCz*B^ksxJBIZ~cvUS|X;MM{%0q%0{% zO006Fq)2H}hLk1cNO_W3?Mg|IQlvB~L&}nJq&&&I!SYBcQks+@Wl1?wo@Cy1<)uj( zl6lK{6QmR=P0Fot`SPSxhttxe3@J;>gZy_q-*%J$o$uX%Cm^Bk?DygbX}%OGZS%c@ zd_tN}Nb_Y#*&cewwJJx-lgwJ@tqqV~Z%x#MRBNFoq+0D?SPICGrPf3(ORXh98j+*c z9w7DRsdWZOz2<$_0xv-7O;D>0ka|j&HKoeC!|^>H6hiisR^l8 zOHD|%CTc>ewNMjMt(}^XYMs=CR7-vA+LtC}NLf;jlqZ?Ii%pPHq%)q&z9}oy(Uc+=SJfzlV~}c)<{&+W^b*om zq<9p+P>eJasTE1SD>PnWOkbn}kwzn(gY*zmH`0HQQZcj#DTDMoq#uzA%TPa3CDMUN z42lx-&{v3?`_PUNc$rlgY+w;JCPnoT7k44X*1GyNb;?A{gLE5 z?S>-ViS#(qCrF9ijah?KxCiC^t`vwiSO;z)NPJ%`kZbnw2$ z)FNGl^g7ZOq#F~)yoofu(wKQj%aHcoAAN;%Fw$_OW01xnoryFBsowx&EBfJ&yDpQq=)CcBJV@@*PMYBkgveF{dGoKFF8{k=l@6MT!qX-y)@}jG2XW zKT;0qZKQQby_2X1X&};Yq!~!}Aw7h2;lUVtNb`^uA+;fWg7i90sXBAMa1?vU;pfxbcd2hw*)vBQno18D%#3rMdaeS#D@0>5mJ zbUD)RklsQ%@ksmF&^gYtQkU~dej3ZSb?SV8HX(`gHNUM?FMY{PIjL~C_ z8G@8Tx&-Mdq*GEjpGciZ|3TWb8h)hdNH-xJdmQp2H6sliW6Z@!y~bkvBAt)4;CN%c zM%wQLV@4vKf;16n3eqP?yO821;v6B}fYgq(7OCtcv=ym8(g37UNT(vrMS2G5C8Q3d z<7$i5J^kmUao&Oy2kX%5mdq*sytg7hiU`Qy=Eq}Z9bR*+^R-Hr4mQqeDsxfSUp zqz{ntNT*IfzaWh{3-bfg3rNLhqaTrGA-#w64bt~Wea^wKMmiShc%%!FrX$^fbRW{k zNM9g*i?qi?%vnf(&X%2b(Om_tkom(%fPggL<+Vd~5=rpX*@W_++YP@kCxheIgnKEyN+0(n$^!2Vc{k)saUf%D_KHe=R;We89-mRv}yUiTx%{7O6 zx0{jP9VX@7X^!{inbW+x%y{n}bGCP%ndse*C%NC7OT0zqx88%M!F$SF?LA|rdu`@g z?*((cx58w+7tL(%C3BDWvboP&X&%Hz$-~~OX1Vv8`Gc1;FM93fW$$&9^H!Nv-fHuv z_l8;Hy=gx1)|kI~Z<~+2cg!Ylt@*q6XY&v5bF;Gn{-YzfY z{p3}9;m~njQ3z+}Q_N-;dIt030~i~YUVGMQd)(wGT<-ba$4WgvqU$i{{mlVRyJ~Mo zOEI5nc`YpEXdwOPnODF8W3dhoISj8P?srM`Hcpv!Mm?NzA<+oUkS?cK_scnqa;y?Xw5t2{) z;2O;NH8x`UP)EZa!u4#miRc5(_tQR}nP9a_wDf#SJ@rbTYAHSSzP+F8$;gMU6sh+@ z8`}@(S4-Y^kfWY_JtgDYPh$Y0cbXxr&cO`qgy8AA5-d=-of3~H(HVvyIOZ!~uuBdsxb@cpJ+>fmH zI@Ym;W37|56+huh{^?*>@9s&b4MuI+`bVF2^cCt*?J+zxY2ROr$!pzKh9Yip(G~o=YvscQ-4^98qqyQ3qn)u=EPAtr@Rk&1tm{ zzQIc0(j%ZFEgcue=S?hCuum^w3u3rtPO;t&%ob-`>gj_8=)Xx;iyiEaT>fW7`=F?KvM1tXl$W-3y!EupH>=4}4C_O!ZO_{s&EuIlV|S-rc#osk zpj~9k+v^|3)LY7;C$*F;^Bu6a%U8#I|G^WE=KCA-{c2yAZ_GeQAbNuOanYrcQ6pJkTUi2F-iy_bIOw10f>X!;VYoNQZ8 z*uZNQbC^Fm2e{b%Np}o#-dp~Hm9LFG6QmKjcC7TQc6)=<{`ezSdsZtO<+L5Gj?Tln zY=QO80X<+T3Cddf|N9z@{sB+6w&e1w@ho9!{YzLSTPngmd4;7@Io4#Ap}pI4?H|p) zZ{l_I`Hikmdq#H8wa_zjjpg_o@tlh|8LOaIZM_Gg1*Z`*u5 zv8OJ?Dp^Z;()I3C3nAtYfv^A8`5J=y0VZu@c;Ay#p-Y4np!y_MhxQo4&{k)Rn?}HCqj~~F; zo+FCkD37;w^t46lJ;iErX3n&<2d>(QmNwt!YTJu-^z^}Bw`2Fv=KI}hEDtQ*Ozms7 z;5}%UTJOO3jcKq{bC5CDSdwRm>n%9x;`#1h6$Cmd$ zhq}4xkL=S4ob{IRDtif6fX-n(XTRq~?|L-e)ZKazJQXHpCIXc%eViV6>G1d%P z%D-N5=kltIYx64J{d(?~G8b#BdgkYc7rThx^4NZfd^%%Z(dOt*koM4Ol012-cIzFE zetDInTkmvq=v+5Hk71v#=UG_13j1)jcgN$1wBDY1{N^LE3unENZygokOsn=2R>Mj~ z%=hAfPJ87C7t#0~_TFqMC$a?_*n*yYi|g0AHusFMOF8O#`t-3syOvJa=pybR^^9UE zS$n+a=~(Wt`YhQqEC08Mo_zaZo%k2q`fYdyQ|cfs!ZYVb)_W$7H*e{`l^4N%RnJyW zy$hdr$FXdrqn;JTe;d0!_b9o$blci`TG})IezpQd|LIxXxB%}C*oaoHUN>T8`NRLG z_T#14*R|f{t=Q?jNbcPW@MKeLsb{8*>^FbN`O^;~9eU8Rpe@G+Fe!=zg*`Hxo)JDim{R>MnQ=e$5 zXVmqKjsLyJcdWqTvKxOmgHl%7?~ z>MD0^qcKXfwx30y|1Po-b3yf%dc1Pp^jUY=0iLsEdmd~-w<|tqu>MZH-sJEQt(0e8^T_28Mq36LnetmV-GvS<>0~CJNB?2yc_sX z(;Ivk{)Vt;ygPU({)Vu3yeD`#{)Vt)+z)&>{)Vt~yf^qr{0*6r*oF46ySxwhD74Wt zN8@kERHKa^_LD2YW6(y=jK$v&_MQ&_pMbw1>@pt&J_&zArUq^F%*ps0GN+)8o*9R~ zA#*C)=$X^-H-z2j!@y_YZ^(>C8$EL-{)VtSJsdm%e?#VMv@v9A(Ylbi5beTm4&iUe z+=zCCu*>}m{JjHv-k!M=e?#V3v@~R%LmNY8C0gfU*ZX+zt7x5PUc=vz$)R=lj}80{ znb*-e{0;^FhRhpi9d>r`H)P&I>pZgte?#VNw9dnh`FQYJw9Yf{;%~_O3H#@s`7{28 z%sT9$V{XFV5Z;MC7rY*SL*@hQrF-T>{0*7EnhU@i@Hd3L_g{lQ!rzeDgyZwfC-@sO zf5Y*4=I{6$GM(6i_pn3%8}MdxF?b99hRmmCD)=+}4PoE@Qt;>a8!}z^+6&KofxjW_ z^hHfu%}B7vdR(~=tXbho>EBn>2CQ3xSy0TI?1aBPQQLj3U)a2!4-A6vlj&%T8a zhX5gl5VI3Pz~Ot(IaPJ(r^GD=z{+9hkU#R!)GQ0ZiPz z*c+(0djk`9A52FTektOm;P+*ppyKWaOx$Jc6(nvSI|b;Fz{Krmx1i#l2~5}_cn$b( z0u%SF%1Q8N0~0sTE<(jU2T0psH=*JV025cQya{{(n79VJ3-nQ7;tsLHP+_m(YVc;| zZQ#!ZChkb(8t@h{af_8}!P~&Zbt>0`cYz5z6Yl`;0Tb7+yc2u?OxzMX7W8dk;*M3` z4SpP$xaG=?;Ligl?)jDXfd3XSVMpV=;J*W;^;X^o{z72lUc_!k#l0AqxD)JnRM_*l z8T=*edQ{x+0TcI9c0MZZ_koFf8M_}9_Xohly}a^4@K*ro3+#ea+^c|zdo?>D759h0 z#J#5SG4R&{6L+$5EBNbx3A-w{fxjM@u)FdJ@HYYz_a=5ruzLU#_m;|M!2cMSu>0~k z@V5dJ_x8#cz^?%&?oTRT0>2iRxa%rk2EQJdxIe9Y1^gYr#Qj<2cJOxs6L&-9tKjbf zChpHGUju(PFmZoT`3Crnz{LHp$~VE^1Eeok?f`!;FmZob`8N3bfQfs5+21}5&WE8heE0FV)&@&oW&fQ$g_{4fFl838Ik0skP75uox@@DBqM_mRraz&{F1 z*iHI5_{V?=yGnO~-wI?jsQeQAHXx%xg@5i7fW&>OG6w!>AfrKL9Q?Du#C^W93j7Pe z#C@@{2K-CF#Qj6%H1ID26LzXj2mcC?(V%h$`0YSOgUY?ZzY0v;zf{fy{~9o1H|u`j z-vB1;YCQn_o4~~VTjfFEcK{g;Dh~nwcVObaQ+XKpe*hDAXXPyL?*bF|y~^3(-v=@> zR2~WbLm(qV<sPFxdwFAYkGioXmhf1emyoCYOUh z49JX}>;OLt$c&uq0zVtbjGSBn{zxD*axx44Xdp9kvKRcZKxX7*ANb>e%*e@p@FxP9 zk(1v5e=?96Ie8ZNQ-I9K$vpUaATx4O1K$W_Mo#MB=K-0KlLq(&KxX9R5cq{aX5^#^ z{xo3XE=rDoUkps#CCMWACSc;8o^-$`fr*<+t^%J1GE*mg@U1{*>SPK0QXn&Rat!=3 zATxEc489$hxSh%K!FK@@w>$Z5@GF3c+mpNid={9vx#UIQdx4B;$qDcm0vXeimw>+* z$k>&<6#Vyrj9tmg!2bZq*p<8-{1rgPuH=>AuL3f5C9ekmLm*>U@*42h0vWrKli;rd zGIk|@1pay;{g;d5^j{$TH+d8IM}hR;z88DQc*o4f=3b3poX@=owC0O`xgyTHE$q%SA$2LCdUzMR|${uLm7 zIe8EG?ZCu+HF+=izW|xpllOst9mvd{+ywrwKxX#jX7GOlGP5Ti0RI+{zMR|w{_jBg za`Ly}{{f^gCm#g=E|9*Qd>H)uz{LG9`6&30fb`$wW8nV@r2i(jg8vtg{+rwe{@=jF z{XF>u_%DF;-{e!^zXZ~M$36pI0n&fRJ_kMqr2me60el=t{~h}h_$pxH){K1_{2oC1 z@7Pzs*8=IkW4D9f6NpwY_EqqE1JMe`z6O3KFmd-A`v&;^fr)#-*f+r+2&B)B-2wg( zAboc1+u#oa(r3rM1AZ2eK09_N_}M`E?AZ6f9|@$-j{N}q(ZIw#cI-#sj{_#|@nb&$ ze*!RZPaOLx_>+K%d-B-Nz}Ep2_mr`pgP#LT-1@P*z&8LBw{h&3;O7Dpcivbfskrlj z^wY61@C$+T)3I^zrvd4wW2?X~2GUQ*)_`vU(g(**1713II&g064Cs4-=rCjV244W8 z!;GB?eh`QbGj>1l!$5SBu?GNqV-EtpeC#36Ujd{ajXezfRY3aD*jeCz2&5m4oeln4 zApL0Uk>IZb(vQX-4gPu{I>6Xt!QTi(2N-)i_?v;~0Ao)C|6?FJz}S<)-wI6JJI9^^ zeE-;b;1|X=0`F5j5AK;jbiC>X;P(SE8dom_e*iFX52`*5{K3G)J*0Xu_(Oq-dsuZ7 z_``vTdqi~-{A?h#S)B%dB#_#yZUKKZklL(n1AiQl+N{oiKLJQ>RxbyC5|G-g?f_p0 zq&BO&z|R3vo7F48Hvk!RtFz$e0U33xd%-UNQk&I%;1>d^&FX&erva(W>TiHw3{2dn z>a)O~4rF~)od=%+vOcQTz&8UKb*pvotw3tL+5o>4$f#RA1b!KiQMcLz-wtHdtsVj2 z1!UB%E`nbHWYn#8z-NJp+grT~{7N92bF~lt3?Q0wbqV~LKs4v-G4S66qB&QW!JiF8 zbFMxg{5e20=jv~R9{|$osxJUv04DBW^+n)^fQdU?JptYXChob_mw+DuCazU|Dfl8V zaqa5Mz&k)%X7%OZJs{e0^_AcQAlh>E)!;{gXv@{tfFB2T^P-vXj7 zSKk2sJ3wZZ>YKn{2xMldz6Jcnz{LG-^=j~!02B9n)whAa6qvZ*uU-TGG9bO9dM)@X zfb@>)_291p(mSf}0RKZEy`%b0@Ye$A9o2V%zYdtV*H_;S{sv&;-dMd6{7pc5MD;!3 ze+;BYRNo8!R$$`ZR(&7%+kt4s)tkVt1)>#KZw9{}h*n(v0QftAXvNiAz~2c(E3W=6 z_`85;#nlgjzZ-~FT>UWkjX<>G>PNxf14JvXehmD*K(ylOt>Eti(jTk0f!_o~E3SS5 z{AM6parIN+9{?uqmg;A~{|1=2zpZ`_{Qm$G_rdBHz&`{`+=r`Q0{;k*b#e8};C}~X zU0nSN_{V|Fq}AKOZv!%uR=*1V2_Q3R^=sgt0-_05zXASPAnW4lH^Dy-WW=c60sciG z>*DIS!T$lsy14os@P7o-r^fFDp90dS#=i%?8OWG9{sZtCAnV8RAAw&EOx$zEe*&zH z{}jprAgy}*XW$D!TITrA!Fxbj=J;LU10XGP{FmTIfwabP)OYthAgytH4E(o%w8rsq z@ZSN_8pl_GzYv(X7mu$2KLMmQj-Lkp5+JQ{{B-b_0%?uoXMn#9n7BU}zc={Hfr)#? z_?h6Z1Y*G$zaRLkfrw9oMi!QTr^-229# z2L66v;%*wh82qn*iTl9#Ch-3aq)m=bg8vPWHaR{G{(pe9$?+}V9|F=Q$G3rh1W214 zp8@|nAZ>E|a`2A>6He~$0RMYn;%*z?1^)j66ZeVnE5JVqWTiGf3;t;!?Q?uD_-BE% z&+&cWp9j)D$M=JO5lH(S{|)ee0Mb6kp9TJpz{GuJd>;ItfQh?(yaxWyKs3GaI{3c; z(e%a};9m!_QX4-6{!Jh&wecqS9l*qWYy1fKw}FZK_whyW?*OskjCa8A1Y*M(zY6?& zKvrtweefRwS*eXLf&UnYb~k3 z+)cayygKnB@Npm--NXs-RX|o`6E6W@14N6Pcq#ZjfvmzNUIuygzXg{GmYR{fR#Ue>gC4XHC2T{1L#!ojvg;@LvNa z?vWF30e=)QagUz38vHRpbbyJsfjI_!EHW029}OKM9BqFmXNjIv_g0#5=&x z0iwlCyc7IfAani1yTC65GS^SM8~kZN=IDtVftO9Z2g>EZ#BHB=FZd21mdT0tf$sw{ z^G@6Z{!Ab<@5If(XH9$n%CmvYxf8d5KL?1$HSxFLuLq)WO?(jijX*T6i4TLn8OYo* z@loJ)6CVTqxFC?LaI86Q2P8DiAGw)u+HKK(zE#p8+2OQm3mv2R;s@ zPFH;ad=-#7UG*j4Jyv}gc-pG3Kwk^QcDL$w@H2pn9;?0zel?KMW7XHd-v(s#SoIC? zYk;)vRo?{vI*?V&syo2{704=P)wjX_4ah2H)px+Z1!NVo>Q3-~2eOJ;^*!+a0J4f% z^#kzl0$IhZ`Vsi|fwc2gKLP(CkaoW6r{F&ZlK#~{178Cq7ps2`ei{%v8C#y zICc8tftyc%B5>>JPX=Ck`cr_HoxUEp{q&9Q^2(?0wIBG|d;NynUil*U_R2qiKZ^Yy zwyWK5;y9M&&ciL>74D6=YjA&wd)>HmPoLoK3hp;?3%I|= z{WC6E#W{T3^Koy({S)rsYR-z_{s%X)hHv8rxNC6V$Mx>P>DSZvChp9&&RvGveL8g9 z@8a&n{RDTRydnT@pJBoWh?wqroyA-z@w;$KQ{p8me zL>>u_`zr1Z+(nO~+;N}AjXj2Y4Y=!ZpTPYXcfZF{7P!aY*5iJHy9;;2<0u2%ZMd5r zPgwRQ_dk(*KZ%oWxXl1TE|@%+-}@{Tn%>>?zeEik6ZH;?mM01 zTzx(1z>ROQPjUZ)o4A1X ziF*LlJ`*qxXG^(NZx)9G8dkKoRl;?zCv9NaH(U!QhdhN8@I)l0b-Gy@;E0r%^;otIOe z+iBaldE6mfANLyEU*gynbL(+iaBs%lfV&y@A>5_ApyB=m_cPqNyU7pkdfe@}M_<96 zCEPLGH*r70{Q|dZ4|j!dpT|9Gmi*xU7jEMmr~Yv_;{F!*_`Td)!o41M7jEiG_G@u} zj_d5>&K2%j+~4CqhfAKp9W&fxaZka$1osx)yK#SmtGX5m%caU zjk){h(tlGX&f#!Rd{-K7_Uy>2+pGe2FG#lAqTv1E?crp7_&3Zu|CfP7{SJlu%v~ujn@&l~PZ)=?|Ktm&KUXOKve8<> z=bPgD_)haZ@ZI8j>f6ls)jt>CC&~S%aGz$M{xi7G;y#D_Jh!;M!2bIeabI%xWpDSv z?#t|9|0C`zxPQXkj{9f!-oJ|b7u?ryUuW<68@PYPeG~U@xI1v)V#oa3xPQle2lpSi zJ8|E|eGm72_Mm@&`yo5!Kf?VO_Y?Mn|I;0IKgInQ?q|6F<}TRJ*%ST+?k?Q_xHfyW z9kSGMmC98vsVuuOZg5p`sM~pcur!QkT~D1bji#5 zilp#7g)^1cOmK_Sy$^V-@@7WynaZC5k5#^;_&0&|!72aw$XEtyxMuioh12)xPN z2t4V&tdwsmeig&t&F;5>H@UY0PrAPX-snD}^v?qCtjw)tc1i?pN+ixng`1LRp3Y3J zaM=mI?Ct<=N*;Jmv;u{lOYyxdZ(4 zu_xb0!fphfIW`Yu_n&<2PlSH6mj6wzb3dVc2zZm0`6iA3gu+`ZU%bD3<==q&72Y*A z{Q!yc)xaCw)xfc;rRPWBtgVRuCO7p!3H7)KN%;tTNOceJY=xVWS1DcKL#ltS@DmEZ z3%tDg;0H@sgD(U>kqCT9^}m2GuS)rEO1kLFCloF_!N02CJ?Zv5Ov>Tez)vZ>wel+P zTPk}VE};xQ{1K8D!Iz!DyT*+Ef1sa81TMR&v!%UBUe;9a^(bi@`+%DgfhQDRt|>X8 z@tkyDXOy_veHVDrjXhTIGk`a_-&6bz!2QWz0B@}byuA8R=B-W1=}(Zf3A|O|SF4iR zcTUK6-#Z~C_CAH1lKPWHQs92YPbj>za^_Q{WS)GE#3|gDD_nMhpLA>2OC3EBc+#Dv z_>+K}k{f|16y8_c!>tu5!*@;y+^?m2YvrRGgd*@323zU z(R~cKDcN+Pa0T945qO`~dx57_qy=tDUa53}_gQ^X;d_9a5=qYqg=?y}qNU$bnYvip zB#^QNQmVk4+#7&5yFUXm$^marz5pDn3cRHv@bc>aD7+6^`9rGffSZzCz!M5@sq9rs zLn#6`B|=$!52@4D_mH-9dG$VM^CuE%12;Q~lQ#2o$>Y6%C*5O#SG$eCjfqHZOg;&| z?4%c5UX_yBlsssw#31k{_jkaX-Isv3YCFH$kM;|!18#I(;7NB(@!wVa4T@h6Va$k#XrnBJk=p^4(2|c2>J~}F%2*4T*dug-*D3vk zj-M~nG4rH*HuRg_bAcz_O~4!7hk-Y&{d?eb3U64ugB8qm3U63@o#Fy-SbLk|0&iG* zHmjQJ6yC7*YQ+WKu=W9ag)Z=oRL{s#Ppwci9@r|^cg_t+=6z#G;+UU7jpti4cifj7DL0&jL70p6*j z%CeKz_^{LVJ%d^Jw7&zseeG9({A>1ScW*dn{W$BU%!4{(79f%-9OmrEnadU z(uBRy*puyAYq{Up-Z|9Y+Uf0SbUVF)NP4zNZqRsC@Ocg489`VV46}@|tuff%Y#-^1 zuu-Nv-R0f2LyaAcL2aQnsA)9k&TsH(mA}~!ge;shU&w)yW)_KSW^1pu*x22w)f<;~ zS__Syes8@BTvDH(-`wnXTeaosR;}OnRLPC<_cRteM;lufyMyJ~Mt#uiwEL6oh3QUf zX|b)*n3xun2H4hUH+r=}W2WCnbIo#=!Hh*qtrzqBT6cy)2Nb8#kSY_ z154Ge9y!!vD-CGk!_iTTz9`RAjEb46^&4}IMM`F%m1zvgs7hpNq4YcD#0~nHp)%i~ z)OGdxprZ-DQ2pelMTt*$I!Bs~{-w3{Ld)l?G>(w|^&177KHR7up`x~TY75h~?qI3c z*i38M+UqP%*XoBgLnb*~5}qmrt1)dkKIqlzgMEzyyKB9{?q1_y^LV2#5$&W=^}94G zYX>Sl9Gk@DnuB_Zp5TctIG#0nC8jFp#^?NC1 z>A$t*&QeMlPL_tgves(SnH#f|{GxX0_2)|Pw93st9JrjiLBkHqo@Z3@uL!x@-l!dn z`BEau4TY%w9gW_hhKx3ri5<0Wx7j|lwb`;NwHSvQs}cFk`tu|UgqdyBdiBFsEH!$| za~%Q?!T_TJ)1CI9)@=8E1Crvmki!`;YFZ>4HMlk%`B1S8l~0y@r690m9aY4KV~>%o zKfgRSqfggbt-0FqPP??*;?o|+OgJ@k!y{4%I?-uf419dYWuT~NX=XzSsa}e{fy+t<^h#1 zB(9Wtfl>K}BB3|OqE~7zy-JyGHEQik2aBzpods)JA$Vr?E2%VB4*S_?axmBFN-dh)aQqj<_!ZH#&kmM-pD^Z7pNJvW zUnptI%$akI;{zEtt)!J3I>c<9MxqsGp@!4psgh3(w{m_qqc1dDHWGXBffmT-CL>l~ z=55Wg@}$ivvX%C8Sm^4D6{i7J-o%HptHfC*tHxx%-xyf1Mz7b+Xf^wX z8BQd>jG1%GUHTD2zkJSQE^XA9s)vYaB50sGS4m5qS`K43K_?d$G|-;LK_6Mnhn0S< zySvwH*PC4%(|wAD$GIIeMji7dO4IHpTY*3pw)Hwo-Kpg;Vp=S!UF3*iVA8UfY0oZo zMKx?N_10^mFZm?W3i^$$OKsJmHZzO1n;EWr#D-4oOHx=uu^>BF`5A?u*9X6v=~T#Xrm7JR7ThqE9mN^o9$ zcdyfJ^akiEKF52zGUxelqJ0!3NcU8&e&i4Z-CkgtK3wZJL+CBX8+B%8A7(j}Twp^- z@d!R58g7a+2e%w=_O0WQ86?VER)1>Q5AA8gwCT{&zp%U0*P0^3nIT<@Zp4ZpWu;SV z8uwPzrv)ET$Xv>$0nRQRm~EnxT(Y43MEa_%G1ia%pl6FDi-;g-OAsTF`^-o?BqH8e zHj)$}NMx)93M?fRhAN{Hgw+5+G6UeqMT7swMhy_gwvmg5kRl4AkXRv+!CViJHC<5& zD5tU_@X<>_u3XF|afZNX@dWnjvedjE-spB|JD`P@-@OQ<+3N|{^e;es7O)lUu$ z%INJr7wFt+LSjo>L2s9EL$O&L+V&(eigzV#8i`TbG^||P(zHo)%&5&J-?z*RC+ggg zMMdsbdzE;l8J{P?R#sHKs7jK$qDtun&X=glH8mKyoT_M~3~6c--B9k(+Wbe*vcO12 z3@sy6$y{iHzTXdhKE#pj_r;IKZ=wtF%~D+|q)H`5rYb*4K6v4ns*m5b~m)E9S;<35-X|4emd})e(cg>k&#(U z=FwB=(0n^@T6j^AZ>`7SYOY(QF)<43ZEyuewM^V4= zOseh&GUIJKMxK$CQI0a*YN9dkI`CYz|EL+r#~?Y8sA-IcI}2V5lJc9baoZm&IWnLmdbgL%_a zwf(Gj=>K`bK{Wt)u1tX}0T5$FEPo}u7*f`|daKstPwd3A$ISX5-C=gn=w`pQ3&pZV zO0%C!Y4*j`KRx@Xi!OQU{Co=qyw#Tm!XzM5`-YY0cG!L>4T4dH$`d4_m~K^=d{8Vi z8$d_da5uQQ&fb~!V51=RH|SY~7|)pxaVmBy8kG-#Mg?}a8kLtuB?8OmMoGin$pn2- z5@eM2OF@UI1<8(q${3pUHU#O7Dm}s`M?`en(Ice>Mk1?KgjAd_5&O~aZnYt7GCrIl zxCAy(JGt>KzC?e@jHvvlIqd1c^?9xd(M5q$P7?YDz9SW1Q55^=7 zCc$J#E0_%6T_xk1%&8`qE-f>9taf@;W@CZ>ijyXh`{D>^&2MWQ9sH;(^1yMWR%@tqbvyz zdt1Y!tjXGl9!Ah?B2rp@lqEyCQFepV9kq=%gt8I>%XIw$LHIFII)wV5tT_uTCF#hc z*xe3oA*%JosFYObk4Cjwg1{>bZ4&iRZ{8qZ(bN?_w=u97RuK9X1|c7%2FsOGo-#Dn zl%$Ta#>b^deyk~xkK&9quuI1pA0dMV*vLTxo^SDcdo39`Aovpa6-R|M;L4-IM(d{= zeLvketgUPu?p+(Ry=$ZM{m8;e{~@MP9VZ)k=p@6)O@hW-!JXkKr^m5OnIKftElU{B^ z6br@a85am6pL+=Xr2`B?(xmX@K8^oZ9-@Zh5c~5}bA=#YpI5Nl2g$2vlGhNbyyWqjy0 zc6XZX!S43%bz&y#wVTh=nAYhLr(>Pok#(0}u^l4@8_rb5WwX0>Iy;{*+ga+>8=E_e z97ce%cQ=gXK9l^qnO#)IE>#xT(PCe&eJIS{G9=Hmr?235dc@GN0=qss@4*ymMn*cRwQETD-!GJ=_gi0997{2U(C&A{Z8A@ zZ%UI&9;QjrDU)sI$)&+zmT+S1!yuSKKR*^U`x@MN+I%L<^zthI^DXs-Y8q zjtZRX$QED>n^vxTq0x(sExlf+H}8k_p89sxRqI~JsM`8{-`E+cv>xT}Og~-5i=Xn# z6K48TtGU7 zZyRUN(k)Mf>p7o%JeNEFsY0$jUFH4hOrMpx)GORQjW%5+LzJirL@Y9SDG4f#)JN)3 zq3&%rv4VMe^r*brUEqj^P5nb&$fH8dAGEcwH2xvlN z>S3O5FX$xX`Z_0jTzMj81~ngN^aw}IZk`cvq08V)Ss!gum7YCBVj>sLlKqjEu&>{T zAfe;jr~^al8@-j4%2*CkKa+Io@qLCOqbKsQLBvEgo}An~*J#(;!r8{ymGL5;^&V*~ zPu4hq=!I(;oRd`+gJdL(8I~hVHK|vTJBK^AB5y?Sc6u_UPH&IYtg<&{Q}kW_)Qf^ImV0 zqzCyujXGawN$T)PWzO_9a`8?t^#|EaYab70UpZeT-DbhbK)1C4V%gZrcBp!HHjecb z312`7X8N#lobGk{eF+(r0@EJD8MxVQquyllvlN}Wbp3AP)p<1&`Qgqnuemf9==pZg zFy%8;ww4weSIY4;_5@KdxV85KvJ9k(2#({AVoP`uldieED_?!f2bJ4D87Wxx9HF= z@^RdqOtCa*I{7H_NyxEnMiBv&LhI`LYAnm!hvws$u#MS|h4yYnxu%|l=ug(=@aE=5 zTZV=pujASAfnV67R&3=&v#3dzHyYhc;4N+0q+D>e_^}m{-gC+w0hPd+$am3&dQCZu zaK%!yendB1IfYx}q)^|BN+x2O2|C|}Fx4PPmg+}cKd%{hZ5>lCVm-M8dZv_8%vmC7#?MWd0U%9u~PS z5UedIj65IGH?RIM-C~T?nZ6b|MJv-k%QZVb%pEEvrN!!pKdt!^X&occG-X*qD{Jhl z$)HJzvqm`5VBy$VI&?S?yG)-=8nbUrCMoqW)1Pj2G+5S?cD892r5qy7uEacLrf=tl z{A9CiE69PKIW?`TzoU7G<21g;W>T-74%*x9*A6yzVHOcnok;ogL_al(u5?J%BG10N znO)o4-3nPHrX~m}bFnV$Zw%t8dTQLO957O<1>M|e9c_r6B7{r@dq8su4G37hJ2} zL@Q=s(^`@=Y+J%3-8*`YnJGaTl6=vYqg3>W#;#NpJ`f!g)HhN+EJ(eCo{*bGbCnAW-X4cpQ(}}(p)-*ewT|JV z39Tn4KCiHv)Io{H(8;9*&f>`xFp0UZ3s%F^cDje^Tk7f*WGqpv=bD3-4`u5>WyviT zlW9jx4z*~Aa6`tWQ8P*w&x>0Gwb3kkXc|SPFfHI9en-!Ad&!LA>_lZPA$Q|U7OW~3 zAw$h#hh8G)IiEYVX&YCv#!a2nBli+>gw0LvQ+t7n5FdCQdi^Cw=I7;t2))sQdu}k# zj}%bp4aMN-7E6s1x_vZ6J5oTS-B^q^AG}0h^u|FkvSA}}Q6ktrOE?Qf8Y3S^nM+EN z23^L;S>aOqV=)F9WXmE*O^U@ZW>hTFb04*SUm_F@d_~@{VXr7*mb@Z8Sn`S-+BKHE zB0bZivUa(0K{dk_S+jYYTv1>;YdtHngI%o1@rJP?BX1Hb@@2x9)f=vb#xi6#Du$J5 zq^zjqitK2f8HS3nd1FwKAx$o$vK9pjT4hlrs8(g1pc$3%q_jI zVyi<+krnJm+nZ|0T0v44nIj^ZZ60bf5wam&ZxlZfx^|JH(J>-7FpigoWHGk_+ZszT zTB$sp75!SQBu$}bg;Q5@=zFxZt*SCJ`AWhw{mF%+QW8w;GQ-FoMlp?gtiPNk)AW{h zy)+osx=}1Yk9vh&%AokwRIe}cbVpMj?%)Lv0?T^XuUiAD7={U=(Ll#6{~EfeEXVsS zsmlfI@c(GO4c6shRSPPnXa~#v6|zp1loU&911;xEpUapsi(h5o6|7a|F`&7Xe0R(7 znyh__@oDQVlEps3t<4eK+}JrnM#hK{EWLVO{H9)qE{xOKbIVy)X)6dweXbN#_;a-* zoGDZ#_*BHpqhkPXw#!*FsQKj_`>4)sW9i%48!G&xx-6~2in-c%GojilyjtZu&`Xl zF`IG$siSZwx?DoKT{*{w-f~{hzRS6O{a((@cd^nklo@nHV0p-(Sm-l-9eKI_udnA6 z1!UsQEs}~NW`U9oi6YMwz_5@i;oIIQdn-kr^<`0Li#)OVF>vl_9K%*Ng6}7gmBeJ$ z9T9_7qBhF)x}Yj1A|tZl?nO3^5E((9v3&&TUZW&vqH>6=m@t1rr^w)-2qytpXqK?( zv6s@Q#GH3zXGbUcQb8$tnUmCz=_jUQbXq~_#8ed6zIk#tics4uLbH0dpeQ9D+FctQ zE^^z=;gU_uxsHs*you6iv}Mnh(k_>!+hGTj&KHNcVuZWet>wEB;btaJYGDs7hE8pT zMV`I}Qpf;3sVGV`rF84Px>CuQ&r3yZU@K+G37ZwzQktdVR6#4{OzFYZ(fmENV_YjZ zidl2CjHIeGa?^iHS()2`cAJVwG+$mqbZN+0`z7>Cz^<{$=!9KRhW_3>5o!k!4ouB7H{(dpB2C z`(Ze^8^KZRt+fNaW}R+cABZ+l{E+nBa*pWn(N;jd_shT~tj9u2|pyEeGomx@AkD+K9;i03#poyKZq1Vof(a#)eqm->A5VrzX5R!wR z^2Sza9;Jz`D3CRm$(i6{DrXzAYtvXr&vlf`?d_HX-qkHeIM?a4=9(o8t&pPpOn(Gp zC(1u}5DGx;$NHp8-zJ4(gXq~kZvg}Hhko`!b>yZ++ zZt#oUuY|X))j3dWg)P1k0abLY)0A-2eqYRkSN~TM@d=kLk&?)R1y~lXC2T)cjo|vI z(QebLpv5%G0q&(aOgCCQwOAmFidaHk`R$HEEa5d~ z|HN{EA9N6ZM5~@T8C6V@*)V)_2zpIP8q??X3g6S!tbZS-_yK=QB5mhbq%dvuMh4hd zJ9x0=jcy}_rj`bSPTMSVBZb7QcQ+zxhZ`Azy_X|rd9|PSIqRdxc}vR2R|<{1gqhw; z)9JWOf|n;S$1IQH+xT1(&<-gTi#>PlsU#ffl|yneL2-0NR`4Z4V*O^>9(nU=KRUQ5ioB6h*}TBGo88N{eZ-uYX1cureOWmUxO^2^LlBvnBjCN34qET}y*f zdYUh3c*SsHVejucSk8ewbWdA;!rT_if7ZV-+)s z8#Xs}1G78=Ce~sprIT)vhd$Y!Y14D}abu?}u%70SOB}_prZma;gUyI1KsQNj&$X^WazRM9enGUr@JGn<`Sl%*dH139G z?l`*9S1ept8$kyHx;zf-*93Z;uAW}Ra7WE%W0CjG?qD7saqH+QzXrE;JilvyC2Ctn znxBJjS?^)ZcPg4{DY~XJMyD6dc}miZmK*P&;q?Fq8>VBu#mFZiXkrkQiAwqIa8&buGQ1Zh?^Bh}-< zO+R}W`2Z%`9ATh0%5x;2DhnV7S>qtC=Ur2u@P_(Z%9Qh~qnY7EPUZ-vREuTbzU-4B z)t4ow8I!TYL$-BP3DxBX5}ZDJ>898#aH#BDp=d5{;je5P&9Oa~xl}j5yuT=@3{gZfOj@qsZp?Bf-Vnm*}Hl?-}~=25C)1tDqnTzla? zQ=UuJC;GgP(cELqe!`Yh_zXPLwcY}?*gt%rBN*S~B>gG94MN}LIn=?TO?c~$_fIvT z-{>bJ>!d5U^crh68fnv9*;u0S)eaf5zq2&Abf6LXf$OR+LyHxia#nsghZngxWEW4a z$Q|n}FN62xdD>mQeTSJREa)?Yt3SWvP~TGzh31=QN|VH~`luhF`}0+~FED+$!w;J{ zZLJ;`sm<)~LDm2a<>B<84X{}P$3%2-ojqgdWGNYgTv_Wi#qQ>&Si2mNwdPFwaD!E_ z66Fiw1fs^C^O$tsL~VeJ{P`A7(en972=keiW2EX@#y_>-G)!d4w{_6MR$*rxH3dT? znUYfhO)sm#lp@V`CP(pIz+WkntaE2pACm}0s=HHuwvy*){97OXY>L#soG=xR^?u{~ z?y0uE5}BU9)$0Suks9ZU6qp4a`HfU-DzHMbF7NyjU8TsOO;u%(r zJoU}UukW~LC|u~&_3w<%tBRUkWtRGsX+tFK_j=sU+R^4A&58x#T@s8Kid)x|Hm6=W zBD=X!m%x%bPSz`aS?y@ee(lB%v)Deqilm2XHL)45MiBP=mC3y4L&`RrN89o-enz$Ms8`v0P}=6^QHJE*2kCqAbqp<;>SS+^^0i)LKWO8% zEhWncP(0q7Hip?6+vPC=`*aML@rDbqIsk>qHKf%7XtEV$uuuE5Qsh9pycaGe9wnIW zJVdPLWn#BT(=pkflr@G~4Kulj-=67*BgZLMe`s#zpnNyOmdf+$UkFlia9L~h6vRr> zIwSW2L)2P7`x>pfKO^n*4K^8=?ChQviW~w_q%=0YIjC&YX)Hf{V=|rjl`YFlVh;5V zs${Rp32x(zjMGCwOFuj$(~Uoyq|wG8;X7ha$lP({38!$~ksq~;XbhHC?hFsk9BFE# z#{yy_NP1LU>mz%1+{qIte436lYrllX3Vcic2LZ{k=2iMh&<6+EUkrqCWwVxvVrB8T zSRNH9_xZ4r8zFoO>5tzVO4i*6jc-%Ctr%x{O><^Jo?w}mfw-p+K2V_Y{OTTkCg&*4 zZ*UlkcZMHY6P?Al2jJ2MmdWO#GYYh$4th32)UW6n2zGLM`rX@rP36xskG(g5X zVnoVF_&M7KnYm7eGl)MKtz*^JKq!JeG|bL^b7x z$&)4fnhQLuBtLqphAhJlGp-x9vtxf}Z4*+8pLc;&ys5A&At$Lb`KuLR7ZGW zUjHyjUs3R5BI=S4d^bN&DiO)iIFlBgm_bhnJjN(LUmEza`G`troSF8~&Jn9SSpez2 zhN?2r6R%Gjk5}-#A!G6=+fJehy7225f=~9-U;fZyc_lEpcVB3ato@6WDJWVuzPub>wKvhPolw^VOGzpZU*uJYaR!NzY zcZL*^hG+AHdZqDZywV|*9$sDd)&ZqSjp(CF3|?8fM47izX#W`^NeW6x#5F`+${9Q~ z3-aac7bVrhG>LzhrYXytNGxeXG)-FxO%gXmUK;XCP`?8A3TQT=!j%!sdc-ithbtG5 zswf6qG+Tz&ht0qC%E&%B{y*12iO;a)>we^xrlFj?%8}_&Y$=)m-z_2MbE1+5rC~`C z%lci*RS~{O2R4qsTcyl^?{0K3m|4Bbt$AhY3RP*@>s89i5#)1HUM4T?AoYdmb=Dq2 zG?ADUk+Zot{g$t>G_o8)zGZzQM^3v;o~(*f0ty^ce$G z=)r5-=#wZUtOFKWUTC0YscDv)O?NLwj23{Kl&z8O{4H+Y~$Q6-nMT%@* zH|x=BOBE3psnjQ5GhHC1iNr9C43z(%9Ipei3#H$gp4_orN6e{ZrapU}!&}c{BGmvE zQzeVg=#lDGk9+RZB@G5T$1n0QC<7!)p6b3@itXTG7YP4WI{mf+mTY<(a-LSz?d@)!t>+pa*>; z&X7bZ-Wt>vm-<@aHlY@^92(bHq-LTgSO^(j{b^*Ck;y?flJ~Zcv^&QvpehB?6g1aS z$*tbvFAKk%pcUd4=Nu@MLpZ>%|pd`HrEVOY=m+^ z`jA@L*-`EEl&zRprtX%V{_JWRTD}@>(OSwGUu}_tuIx_eMM`3#As zG+$9(9c2DWV=hL%y;@UPS^u;^8O{ARs|#mHR`KR zsxtL0uxTb5Yv#$MbjxL(b%=Fdh4mY4asY>CCB>eosA?pN$%p(MSnai$JF(jCvVQh_ z4oF1IRoW}Jv>E!)(DkinnU&aSV_Q%@#WPV^e?RM)-7T4txsH{nJkr)voWn)>m+>Sv zBsFzzX45sba(TlTU$7-3eO>sz_sdo=PtFT$E6Q`HZAzz$MI_vDP+gs}n5}aV!m-DQ z36tG&d%fO>B)&H=R0>FjUo8zqSP=0wMYqXwScZz6wvi~D`le|FSQ4T^DID>n#mVD) z{yc*QL=B~x`(ptme4Ue3GCrOcFW=d?rc8QGeCE`w$(>$?-PaLMC8bv@BK_II9+vg4 zqIKR#W8o&*m;CANE%E5NWF;S!XMCanTQZ7EgAI6^&JayZaFoqc_oJQ6KUu$4K-?t?g&Gqpb5i#9wAOHeh$WMK$|h|@14{i!K3KAIt%F}x zH}7KJo6bs7yuP7^?8_t@vlc!4Rsv%j({xN<#w+ES@gB?zhRX&TQV#dX5?npBPyHL# z#4&E)KGZLfXZ=$A9LFj?c4Y%XDaTtPS^S>r53|xA2V$E{3rLnh;8VdBSg9xDXprBS7&Q^K%TmI>FCL!2sTx5qFsX-OS7qEDC2ddn&&Sq`(H61sjC zRL?+C&C#}A!|giATQ(fZKPtce!ShIr_~H3HaCUc@v8Ngbg`verdkl*n!J=-U)h9}V zo@{s9;)c2G_@WN^r}$Ed`DR}V!S5!-T_#&+o4reRH+bcm{ay|uFwB?BZszv`87%Cm z*Qo@Te1v1OAxdcs!!)!1$VjO_fhMPc`|8sOID{oz@q=kh#A2q_%XLf-6lrfui$8w( zz(G4JIt*@IV$caL;*?Xw`5lDtqOx3+2o)hlMsFRH*AqdRLyvW2&hN{dE``epdYM>x zOS}iNr-7cu-)U};Fp|ocyQi@PA#2L;Gg8_R{cej@vz)rKNzQZ~9Wdk=)rwS6fHXYy zM}JVSlx)UpXqFkO)=<_3e)y@89^U>mxD#hi%MXmgmFGSy+BPwu5SfG5|cJ( z9eqSv#*8Oun<#5CvRG@?F@HrunP{3;aFBdViBLQBa!zAD2Gr`mk)Q32m^ z^0$YnN3~4DdnYm# zlp?WY=*K1h8Sk|H>WZ>-rC{Zid(FhUcAliWHv5OsI!5a#XK3ilk=92)G`BzPGfqR54-r1OnF!7-z{zXTl$=}zy8S2-04dQ{fkPa zL_21VS!cV#{tr4_ZqGQ}q+F*N#IFT!eff7-7No zM$Chl9|FwZZX7dYXU8K9CTVd_*{{80L0zbMbh7Oc27(x8=*vbBjX6&_D#k3o1e@!D z&h-00IXoEb>}Xv67(pauD59tB=P<@(k1kB09c)7dySw($Nv;P$PwllU{d}gLFXIVy z0@&db?Np-G$%|?lpO~xEqpcx$SWz^^qA9}?)#7mql|8$eHox0oOkKMnq&Hf29hAfC zTBexHZ0}DHQ)1<#=u#A1b76=4a)>+wu8)c9Z-x4I#7U;!GnwM(NsEIP{2E>DkS5w} z7~&h?r1JfSuyOby6gi+r$z$6w_N$2cQHnw1>T<<>~Qjukz}kc$x7m2yP@Lhws{mc19KA1G(AJc%}`5Y09=2jl4&ITe-hEv1aQ{s34A6e=Z?Sh{2A zp;;=?XT2ey48S3>G+>q*vX`Z4waVfx6MDWsM34++`AZp(Fyc(-$MKL1vMx) z!DFF=ja2%f3yV{{jhg-#q-QkP`Sz&%>4u4icIeGco+~Y)>}5-B@TCkXyppFdnQ-^Z z&%*e4V+jO;H+Sz~jn`lu>XWZ~xsz-ms$UYLE73sUTUr)T0)osnQ_HitBfMlQD-wz_ z(hfI{`%kESQ;)BB!WOxK;BibseM^aqPBd0M)`2NNhpN7=e<^lsv{Lx7&D$P;4!Ud} zE-TZ{{>W$?4b#$3^nkoH+s48!j%msP%2JV(MbbJ%Vps53bTI(B%n=;fljd8ZZ1|(* zGzv62wcE;Qsq0>c$QG6oI%e7?T#bFj!%o7fGMFVwHSB6X)ok|Ha02a2~<1D~8p)mSnVo{IG3#o^l?ZA+sR3*Cdamj@q@758+Fh2?C znH{5ult0Ol61F$mhlpVt1Bzkjg#3i1SWo#GV%ci-o-OSK{b630{;r2UUm%TNo1byD zAxrzDG&vD)92-Wz-fWtpfW}mOeb@Acau&;S*E#Uqyn<=k!&dHJ9N^xjoHUR^W&bOZ zV*4&q7y$Zd2!7wr$Krd`7Ww7USbu7`cCs!RBFWS%8D~xv+cx)C)hMAqnrak1J4DZh z>D79ZlGLDa(ttVc9l|fKeZMANE>nv*7H2##>WlX9! zyGZYBEDd`6m3||-ar}1rl(QE3DBfhRvE`~IA^?#ES@h`e%<9Dm_B-*B8LeIYNU}A% z_p|CVh9pZLg4RSBW=ZvrN&CbFp9~qP6l=>7?@C)U8qJn-JFVi5^SWpyUPptAyK?Jf znbeZ;rJz6>r%N^G^hzU#Bh;~z#5GroyEA?H&E9x?M`A9M>)yS@h>+GzcIss#OI%s} zagROhi}%-ARaq7yJ80cn68S{=oGVA(0o&7{u(-tEVT5Uk>Yy7Xj>S7(zv~*4A_Jke z&Mk|ANl!3rmY*sLuj|C4JSxfN@9-1h8m^2kjj8ZjxJnnPBFnF;sP-X$tpLqtM{|%< zRcZbEJ!+9NEfC{`ydon68E064%Fh7m6+1V(SOYz^wfX{*@c=gu5t1B$q|K&Xs~z+| zh8M^CNwV6QIY^IEg6f5eS?a}n9XCVGV4|ZSH+m&}s!P}x>Ks6=p;=ICHF-SUY9>6T zZnYDAjB@=(5Soz(QiF%>gVe)JCF7y+q;@mjV|kAJqGE_a=BwbBC&>d{OpF?hBJ@Z- zI}$wMuO7SQ_wGd)8E&* zDtiipXzHC7kFx*{2w)8M38txs=YU8)Vww$YK`g7Z(&VocA-N8ufa)6Adsqk{Mdqf9GGr z6`%jtDk~vlIFHeHLt$tE$kIa6anSz_g&XoH#VR-j6i^YdgEc`Y$|idv`1vKNRI92jYS6)xr6?%WkwcivhOOK;odaY5vpV?)1NF!`oU2Q z34uW7HylEb&yvVqKKgu|fhUc_J|FmbihRskgeE@-4Ur_%VGBFN>{paBwFrsyNF$jN zyQ*9A8E4gx5lnbI>)1Tl=*z)4YjMVr%1eb{>S;Ppk&4$TmKPghL}ETC9#0U9g-0=O zwWql2(+dRKpbc?Z1PtV)M=~v^6SQ0vA%(JlTTqX%tpK7>#w)o*htXYUwS=jVEX8N- z*W2A*p5$jNX)K6nj8WQsBuHns*~miIj(6IfMLja%njvLou)`)|x`h+#$z+Qia#rJ7 zsGOqhEn~v9v-3=PdW%SmT0C@7Yc9IF!a1J(k~&~9$Ucg!pzNqXt+kk)u$jc&L5|7k zeeiiZtPu|G2k-ExNtSKkWa+DFxc%z%R(@i^MhC5IDI6_pD@OHd9b|s@!|EbSXy!a} z#3B=%>}WJ-GxC>o#8|Dlt5;f3#ygO7Y{n2Lra&%S$O$w>^&}iOSCo7z%hq+VAi{bc zTUAQaJ{HcwIW$T+F~HsbNJ7Qc(+OExcF!P{3{>9{Qif@ze5qNVoZXH6O3vN3+nw~D zk7G6Nb~F~6@`rsLepZ_;PyKoAoJMZ4ufvflc0ug=a;@chJdnVr<_;3+8Vc=6Vk{% zI)%l6pFwh$&2f|6grpnCMYEA97S^bCK*lI$%Z;akjCgs&wxVZQ2Tqr6}WP2(-BqgS84rn}CX@KIsH@d(Yn4k*rsvyzijX|n~>?mP=Ct-cv2EitsiU2V?{HrdPnyX2__%^6aL&&h>F zSYk*wj1(*`v2C|(Ue?j!B8r%*jV0GqGzv_0ON&;g9%a)UtqrEb1(Mx2nZ{_vgLFMF zXB*TR0?S#d8}%eZqdxmQ>qr)2I81_irZPj?D++JMZyIoh5LC|H=st2Xh-9L*>V*u| z__=?%)Rns$sH=W4W5ZxgF40Q|wu`T#GO~Thx#<>D_5$BTx$V!it&(C;QOIo}7&H*#zC}je+&#lHBW*g@2^BLV|62B&3`?(KUsd-+V?TUiaz-MwT|MzzLYD&4RkwUoa-2R1m|7fWGnA2-&hHm#@4Oxno88!u+pDTRaU+e;>*TyfVFISR{XEYah{IX zk5(4RPoc$92~p(@^DD@emTib7w-C_s&Sq#{ax^;X`9aXr3L&NFWm{or|1=x9l=$6< ztW*|mr2^2c-h9HfwU7KUKJDqFxhyTXw2tOBI?iIZ%*I*5MUQ5+&v@X+lA)-#wENuf z<47R~LaZY!WN;~8HUJou_1zSn>TEGYYk!#u_v^DnX>)$_#s(pO3@8i(qVgl(@o`Aq z43UO+b2j^X3|g-Fv`3aklWQZ9wGe{Okp1*lgdYcGQCMRzq<}=D&hY1SWy&uo@4;yF5>DVf-;A9v&?xfL$cEb^|j8LqK_+}|Dt%c^B zk+TVh<&(}5SQc!Al}4VC%G~A3P%&!6C2WQqbPLTV(Jp0U8h8^@DN`EqaDZ7corc5g z{)l$wV`$V|f(>i;;lLV_ipU0FZI4Y5JA-r+^boz>n-(XAIPHwFy7cf-CW0B+m|>$Y zLkh}Eh9q{KtT#0O3{9TWN>h?y`02ltryE^)*|<~*4NR7-84=qAv~@s+Y%{o(UxqBH zV*ci)i}Z~QLo%81ia|Bw#VV2U;6}?*&pDNZ}>e^ z9ew;BU`mv6r$9W!E_FBaOQ#xCBFoYwWPvs$Lmp`=`a>O9+uMe8y7P<++O%B0ejOWf zX^qMWx6E~~*dAj{8BrO43Qa@yBF2;#iao$&{V(H0F`BPAZ}wmo2uGq&vT^GVB#XgkfCH0?M;1oVK)aJre8|66;OjVoH@i_Sgh2lXc>!h zN{puGlq9t>nf*Z}O?94PmUG=O(ceR4iNuU5TDY@?zoM+{`ArT*<9R*XEs@jiYB*FT zc1itf*_~k1Es&^BShM#y|~*K^A8VJxJ8^k7LutlO2aRQ<~p(j)bINraMnZw ze8+Nna^JO@U0HDIk$DnX=YgNjT&L^8`Fhirb+Nj%$TekdfC^hqDQ7mdd;p>Q9X(c)pYEBFj6~(aGuKm@v6kq1C zT$XWm9b@P#V@L&ZBr0Y3AGFr5MqG_{e(o|+IegUU&GP7Bm+sPLl@fk~naVuAGnG#zlyGO6-OYi%A9jr$0^U~SA1xkGl5+_8J45kOncJHMpLz(o+^;v zWs?RVekmp@F;&oosK#{OMnT!Zn6Af)<^BExuy*a6#InYzEpW|m^y$MP)E__3+;jX; zV4SPj+>wPGZy*b2-{Bfhfp@w~tnT#dRyB(5)L#bI0`{mR&)T)OJ!VA8=$aj!gNpJt zH|6PUbk!S{4pTk#;~A8)Y1T7-nR~J{+NB(OYAkpeNr0?OGeI(5Q(wbxA$S?P$(WH6 zI(0VmjK7zrVc9^I381B9o6Y&(FW1}%+lPjpLsWZgkWwKrY?Pqot z3dbVZAmKP?^z<89itc~}!bO)1=I0NvA1v9B0tp< zgp^pS38sQ&^lkoVr`*u%*(py4Z6{6F0(Rs?i=R#9mV`Wu${RSS4yoA=fr5z-nk*1< z<~?ZAX=GHftpZ)cL#4Aslbg*}(y%e*M-TIIGy23{6F6#U^^Y9|8X3@^B#yst6Byy^ zQWC*xCv#&@?V5Rtyuu-zrvICnN#w2-oPE4yC4c>Dd|K1k*Q>Qq>5j75!g7$)I_*Iq zds~(~P{Rf{kF?1X9*AEissN(DS0v=wr4UPv(bgv^C0e)9 z`zZS0jvgyVe^kRn2q{}RX^?u1QA*9;Es}E;_KT<5*IA&aJWrQYmeJ#23KN|qM(Kl5 zbzYC*2LOBeD>ak|y-C)F%Qp!P_$uUW*jZ_v3<_q}^2J=Y8nQEY4kkZI_ZFNKVc;Cb> zGg)*RLL#t%F-DN_5|j&)#~KHul)Nob<>p%)%J5m0AHY;1Z&*^tl5bfydQ=aZc%0%B z?vemTj)SyFe=;g|*tE;|WBa}MjvkTN`oqceGT^jkNaF{eN z4x{O-WHKA>ZgxjAXB&%LnBwi&G`Kb6)NeDdzKKO6VeIl~=2{2p36J4y+)mlHt)wE$1SDclO>R6*yROX4SNc0i`QZ;=Gm^;`MgI;QMwjM^c1O} zJjKk28mX7LYKh~1AqKy^^WKB@k!dLF(~+pUP==m`SlhQG-Ia zpJ_|7wMg3fRNt%`e)KxUNSR%{2ShXBQlFRB3!$OQ?>ays%h!lier6&1XIObhk60D> z4exd&>}edL<{G_72olVH@vLBEcEU%bj>VSC_hcO@f5qk(-uqxA${XPIGM2n!w!7Ap zAi5^C=h_?tEh@7OvZ_7%Q`|ak8X*o`lXjk+*scET1!n19rg&>CJ8IAM@ljFP*U`PE zmZ$mhlHNym=Ms%!(uHiiHouH+S$|#SDO(-qyz;_jIhQqxV(A}^Sm(>Qp1Mb68T?>)1#lZOsbFzQQV zK@YEqT`pFD^2w%XZFKAOSg10{X*r`+D$XWmtHygR{^vLIACU}7+2pBZo8Y8BO>r@Z z?`BiWHiqdf@_eMaIg=+z|CEU&PtDu_?H9R>z(sv0tgj1V94))Zi!r^?M=n7Gg@bJXwPTdUkqJ8_EM3-)mGgD!uhCZEjhQ zrG!nr_Mym=aHDuO5f#Iv@oiWkz9P@!E7I-zg{WrQF_oz;F_KV#0v_h&;Kw@F&CIot zY~PPw(>S76)XY}nc=TJU)CjDRMTV$ee#VY8HCixoV%3UAjvY_3vgEd!)omti&gFBzZENwufQBZN;!AtG9y?18| zQNW^Sc!ZI?1?d24vefZisuLk921XCysajfwEaoN z>IeFv?`>|@*i+*qNxiQHfw|ej$aHRD46|Oq7D3=C?UcBs#P=#cFqd!JezyeXvbsB6)GwfH12oD1P3wk3D2!}BUx!WMl$o7d3z zUCzE2^eOOZLsjIUeM4`DMzh0k##G1fzf-;7!)JtNch7Pf2Gw1EB)qTMX<7wZVce+U zgXn!?#xseSfDWtJ0SBGsc4JnEs<4S?d{$GveEs+1(m8wVGc>c6;*t9cK7AY*HH?N~h#bS>x83b37tQu?$%v)QboDbGR9XL|w`V zA*8BH9J!$Pl)1L|!H=2D}V4 zgvTB?6Q1;yaz#2Uw#E36331g@vwlRLnduKPo|~7;C@{PYnyUPnsA#cE=zbx-3`dT7 zX1r}ipZKfJ89J%V_`+T@(PpTA49e{JWSD-c4)1r(buQ&xB~RNN#%$tw8EH|q!bix{ zin1|gRY&heIGurf)6INT*Wo2(Q`c-`yvR;Vwa7c>Z}F#HBb}ZxL}m+5l$K0dn9#G{ zZW=>eovCi!=QUH7Pc~tonuF=j0ZZ4gk61qs#Fya!qA|f`H{0eJCZf70&|8x{=^5T8^kM}&KHcB#cUkO5o+NVl}tEPyL2Iw z&Ql~pU*)MtjzCg#{<*_V9>8iGq1$ofjuX-SAwxlGQVTdA`v2*Ernw*N&`@_K|qd%zUi%52uEVqWy-J1`|hY5?v;ik7jx!gPW%sI%OGO=-r9onYp7SgjVk7k-)?Qy4$|R{q0UIZ<9$%4X$_lK3TAXO*lh|6wIoyz#EGvAvG` z*D8vvI8wf!^W5j2bMNo|?)^bCyS?KTDt`B#_w$_RJn!e+!dziPuSQW86)dX=CN1!B zL5B>)&|_c4hOwOTg*n6K$^@3al7NA%%oS3{a7peVj4E2(QW$>9cWgf8i*Od2SH7bb z(R!S?e^I^6jZ%z92}RFRWv|D+IDz8*>9TdC01rEFda`SR!Q_e3O*4|CCH=a zugn521G4ICU9A}VD^15`djMX8TOp!Qo$FRNUPPN#>V8MXKCZBV3p;)EMaDF3roxFw@6M_AnIeBy1%@f%R+_R{=^CudSiKo_g*}B z(wDAG+XE!dDz$T8VoBw&VFU zTm`<6gzsy40Y=hVpuXL_Vm&=}?U_zCtPo_l0BMXp^im9ty<`)%rwBZG(ui~`;3moG z0WW3p8Pdl$XU?p%}=?MnBRj4O!%E=|&OzVs?IWS1RgF`}Ckuo>ce}GP5PN zl#UBz(S#8|7V{<|qFaY$mQ?t}ik8aT29?@N^!Zm^Qi`|ebFBy-RyLQ%o7ICF<1mV& z#(BTBBvE<1L0;l|F$Z^03eFljFpOmUlr>Y#@5STBRN`HjIle2 z&RJHJbegjwYDc)5cSRy>RuP#kdo^LOl+LmojA8ub!xU78Vd>?hi&W?Vi6geXR~+w9IyM; zFN#Fi(Q@1GZTZxnxp9MS_DHcq@?U0^7w$Y>c(QWh!P3HQR@9=BvV387W4gQHqFJl4 zM9B*j)O5?PdCEI3vx^?`yn;nzZ%fIpyu=<;vMgO%O~RHhrNlt1sO#0^Lpa-&BFv)Jj5X z+swG|RKjboX3vf>mo^r_ zlrZ%;~!ISS^%|3-v8@(JD(Mkice3< z{*st;n~SMDeXpCN1%pQp5SQ?{qos^g6SI+~p9;oUxAe-gTf~jclSk=_}i~CndJWq7)Y(&Pq6r*B4+*iaM8g zUsQUdI>IwAbdNl-aqbGrY<)Au4THouE1pi`lu&aehOs}85i?7Y6*7BMJ6={Z z6gRSZERLuaG7O>(Q5ms4hS`)}E>crwkybWB<1kTa6vgrQLe8nBQBI@Py<7?fs8?Xe zyEQz61A9CrpMR2`%ag+CAQTRBS*9XL5wsg~&dB*$-a4Jtz_i|!9+j~Rx+)>+J@S*@ zzaGzU&*4NZ(xN>sN1;S7+>KcXiMCJ57vNvM03RLPE6+PP1ay^)C|y44CtU8)Ztp1EF`B=VBSuJ5Og8XbnZjW%(%URHWS%zx_G+)idQB ztp!OsmRgPvz=RPR+$==N&VClpkpx}^O^Q*;Bp zIl9R99;<68-Izh=q7K%8#WXCMpIJ9#=?eD6|6-sn<9| zg?dfLZ~2+yKfRJm%y+U#nM`CBpaX^B=5?8_R{U0XAzgf>>e;0yD{}hWl^!>}8qTbS zbF0M>iP$ejw}sW%XYnXTBNkA+$Xd!Eb?fW3Rn)i`OULhbjAexni{EH+0IKDC@eRu2 zU7W>T4MhrrL**@AS=Q_|2BSqDh{@IlnA2Jj3|&wjX#ndiYuEfBB{I^RH0dM z$+$>EKFNeBa--kZ4pbAqUo2Se)I($IvFH%Bt5}#_q#4dE34&%D(HCQ4$i6hPy9;xA zA&4*jMr@5nQV^^#ky15(bgvs}k(0*?C!Tnj0^zi~A3`W-*eAt=4RcIxE3#PzkH9ji zBf__qvxl@3I%o zDZP{&^P)a77WHCl5N0!pj*K-?S@v|f&?JNVn+`e3w6Sn+&3urM{% z_A@3hhL&PObOJuLw2*g{7d`g&fvaw9ZyKPM@4DII<&L{^{r=r38;JVED2-VK_KBSd zG8nKHbq2Xu?nH@;1dqxqI8##$T|=E1Z`W4khTKlxCAjU+p9sJGIo|9fs*l&qT=<@Y z9_Gr9rvV(&{N2&j->;jp$zXNg7l+YxGs>M)3s3Bs>N1Jg`SFYRisBZkB}E&h<;KMj zkzSQ3t0D7XLy&7Yy~Zf*f(TgZgZsMQ&P#Kjf{uvB9|mj(%k^zluJkeqR(@eS`ytU7 zQ%LdRzO-a`D>97How)y5@y?)%l_&))1S-Gw*zp5gYV(wnGQ zq^0PckugkLD12VCtIR@28}x(!EN?S^FIGK%I#PYzy5|LBiuqS9zQQw#8r8&T_w^Er zFuLM0Rhqe$v023voVP^MTo zf76V#V@vx4Xzy92FcK9h?Vjk^_uR+kYSU**B9CS7i%<&F;(J`I>^++Pvv+4gF)7MF z7{XVvNi6d_uP?2LnZ>7qV`~5fU@gP;Qy`#A>5@)u*Id-(ID@7$#XJe51aQhyt(QVk zs6@k9nn!@hDol8Pk?3J6F-EY6P${ySnyQv~5MvHyZCsK1$$u=B+(+^2J@G}LETYJQ zkW>OPhp#lvEM2@^I&5QB)rB5Dsd&_5`_kbrN~=|i-p$#Ivuvf98y`TH_>lWJW5O(_ zKH`%^q4HVagzd+3HZfBPL{6oI*%*lu^9&U%ls%=c@)?kruhZN<822)8$(px|l?JVl z-?Cr~XY~^CS8&ERf;3Q;5?cAI_|-MZh4Fd{LE;WQn$agI!>-(klN4Xah(;d+q6Fgj za7xs3;fAiI(ff7d0P&e+jT%Cv@&%;%+=@=a5lfauPCAyQoF?vN)U_*bZ52S!nQPu}8m==<5krDS^ z@my?JS(tU*TalKuogzUfR6H>%v9LIiB8ef@lJ3O&58|4{+v5xFs?Qo#y&7eNoRwPE zncw&UT6?|4caUNuxL+mNKY z)cD90(Hmt=#gHtmT)0s-nZMH)6fH*o#FIp2v4&(y$CAX=S4%e}QyLQ0kj2afWKpZ? z4u4YZX<(*P|6pb}2~Tk@eg?3FNBnAK`6h^!Q}$=ZV1hxGSxNBwABy~lT-TR!VG2W% z7M7-_7awtMZ_y5Ukjnh~Qz;v9TP053x&P2)UcK-Q0ksZ!&|CF`BE{!UE=gh&b?`Dq zi_G|TMz_$&+<|W4*;iL;3B~s?Jl|~KUdw{+JTGgmnj!P8$qZidR_*<&*|a>{=MlvO zPlTEnUVBPm#4nnz6!r$IiPtNy5}x>a zVO6up%GdxznaBh?qw4MSr)t5xPb|8#_cXyPaugIptEUwQO^PEjIzOv3ow~@7qwjLe zD3Db*HGLKb0FAdd@Hu-!#G1Lc7=u89Q1-z>ygN}eSWzMJaXwm5tCt??#7`w9MlD!M zl!8$Kw3Z5;;UsYEG95@S66v`wajp!S@5=)6hDrvg*fNduC8kFDvfjIINsz%f(gH8C zfy!5qjWE3}+gvP9isRhF8_aFRew-$hIubG7v-hsu|11i75;1i*78gbp0x?hXpU6u8 zBtj=fis+g7_%nt&-TNKlJ#j@jyW%?*^GERjWzOGUTzI16pz-t1#xVne0jF)^r)^Xs zJzvXGJ(o4K=edhA5+6LL3t6r|3GwBP;^o##@nB{JWwR`ahS@Fxer1{kc(VH6s#XY+rx!6cgPAo)y0A+~MXO>p^xvjs#>kz#&GKucB`yX#U zSXlnVI>Xd{_u3sBLHVKjNV?;b-SJZ0_`pnH zCh;ZWs=uVbi9Tbh&Inlic!*o{!j0*B!Wxk}rpB`niLeZ=k+ZPX$fp&R5mPkm%DW&? zd5@HG{=t)UeA=%0jbJZzya@FVEcU<9W8(U>7SK|BUxe4o7jQ2a+}^qTBNcniw&_$5@ulM@#ub)`%ug6HaaLUJYL7In&80lqJ7H7eefMwTlr#*d{?4Gde&+ln6@ z@}9GCy4ljRz_Icx^z}?|ZeS*?(k#&TqeA5^MtSLs!mo5IM8t|H{>0_CC%YQYo?-I# z#6T|U#zxUbODLi|i#pLUV$bFzv1j&D@f0lu68>gooL(u?;PCfE;OzBNE~=0=FCAaM zK*)o4GVjDp89iPG;94}O5i6N?O3A`WLzy5PjkihcosMzTWqPbyEJ8}mCwK{O$B@VC zOF<@n_ba`D8tDyq&M6cirLdaS6xkWPV@@lVwnG)rHb3YKzv-g%heJBRL zDiHd4lf4ZgRUX1@pPhlS+e!Z?K>>>Xh`GU^!Ee*g{9+Z2f^K9@ig;~QV@VF?#Uf_` zbnj12EfxNKNL^7S{Ebp8Qx}fjoDf z%zAK>zA;+1>I^ToRKAGkOA_$Q5}wFWf+wiVzQ&0F6FIev18)B*H2Sh!LC6u2D`))c z<#33Xl|WltyfO*AttDm4Tgy399`BD#JU1Sf4KDjk!l8G=d^jJ@g{$GSuuuOE=zl18u?!nmi=F71V}6KZc!V+rFYR7T$oDEkUiCzV27`kB+y zqMoNU>gAYzU2Uu?^}h0FX?tYnGVcGupdDUk;H{zHy z*Yz{;U6B%6pU?|itK(Zz?x_eLjeU1D&t~pzpHnGOM~zBrIr>(3D}<46>F+1BHrJI7 zbiyd>5Jr|m`1Aj4efWtm(edwC_#h7SvC7Q}UG8f-OW}B!6u_4v`sf-hm0SY06KYp_bLWqD80X(lgey+S5Xp#pkGLwNDBHAn}6ctPhhsXFJwb+D^do zhM@AE+GRTe-*!Zt3{zjJ?+?@yn`KG8Isu_qIXH!`t8pzC3gkVezEb(&*O*!QKiYUP zusf!0wxkVj@P`bo3Ll{`t4+H+6i|GGQJLSbd|HVL!(LB!%qTciD zTk1V4r7(!WZXOFSdO!D1h9OEneuVBtZMQ!fGR1oQ;gKj%=BvT$j}XB(Peqvu((SUq zislnW^e3562B1jR?@H#I4HxvkvzGV7%vSY=%m7oI5$Q)pT2`t_W8vri!M~ZC=fzOV zVff2@Smy&0P;i#cB6wW84T|C>>FG zDXI|nM1oLm9w;3_{=Q1x)Ef%So=BeV==WjS-c&Fc_eLIvFgy9ush7U>(#%WWdFjYY z6XDgDCSN-E(l=jv?WNOt+MyKkXJXpkm!@L5(?#lDmDsPk-_gI*FZJF(qdtBRH|2s9 zu?hVxXu~p|+xnY`BV3S5gnGEDl1Qh_!AjqXDfeQzA1LRx$ilz1W_rz=YtF1Ws{bd# z+j={&=FpnsdOon`JNkWBf8@Ng=Iu2n)_hxe`}KZ8zi;WcH#4t(k-P2-PV}D$2NER; z(TaY7%tMU=i1BW+CGbRc4x1ML{XhNDKmUbSA0EE;r$74hkN)5HE?@Zd_j;R2``HVx zJ{*1ef4)chx37)eRQlmLX&JZF%6-+n75jY@;qZOEqn>`EJm6uy-BSv13Ma)#dbdQ_ zK2fjKzpWCCduy*cqJJ67FzTOCdD@1gN|o*Pj!)|sh>{DbL<0ab463&^0?INk%3Raa z!vb@pww;+(Dk?8Ji`BWNUzBxI9INA?1=_Y&m<2Tjuj4aO&q8NH3o%G1$X8pTZCin& z_Mx-k|Bf)3h&mkkwD2hWo}O4Apv8JIx9{tZ8TF>m>WMJ`VQTUwk8yl^sG2~W+Dl3W zw!f#*t?J+Jsg2*$Z|@^;g;pnu9`DA{1CI&STTmXl52G=hf%({oYzz+bZ+xD*0P6 z|L^JjKO6bGG3W1$^bY-RqyKR9ACLa_=tTIv(SJVrzv}lNkN)qYzd!mf;{X3B=KL?C z|7i4|s@(7Bmz3W0x5nNcJ2G~DY-(&GjE#L$zh}obk8K*;r?j6^-o~*%rJPMlod{d? z|BkU^F?S-oIkso)+he^m=LLK4n|ZO~z<}RJ;rAo%@%FE^IxFFQ?VcMdcPHZUiXd<= z{I1^qKqY$T=aj>GET}#^5_)wrwq;fWu+Q*`o^I+NYe(rN)la*La^ao%2xIVKLa?^h z4F7Ky?XU*4WM#k(-;XkP?1ZBH(|!MX-+!e)Xv)2PAMJax@5a7+`#iOGWyhMcqH`zK z{8jxz_x7zhvgURD|CauauQ@4-cs4$NJElS@_bX>w<@x`t%A8&E*NfC|tK``=e_4OM zouB>2)Bk27{3n0wKl+Vd_RUL3{LpdhcLkVMhUN zsP*X{(1XHGgkJAK*x38N-oRI&#!e%zr&K6x?@YD+LXW-tL~tUP78iO(6`_BY26e+6 zNIUnnQ>~rnUo~tAw8%P#nQ4vFsLM6APCrH;n9q$^s=m(90;6|E?L;--zoJ?{h~n#Y z{SO{3tL`6&O8-D_55pHdC=K-Iv3i9@{ehk)l#AwfFKp?7E8yjmNZETQonH9PN7!Zl z##4-1J`@(iL7M49?`(G)PQT#8P$#Iq_vly|Y0XvIg2s(#F9AVpKMN5HFw7ctGJ$;S zpVBJES?8@YcE*aiwN9aKiFU)~53K>KjtaNmUUN)uaQNf;H4Z0%CIJIYIcG_!eRIS6?_``2VVUzMVX9Kye&L`6naNK5WHytd;}Zd(mzmHD9k;L zfjkVwKn=Ocut${QOw;P34uK;;nRR5ZxKz`OCE>8`0AH~rCHWl4VJvW8=q-Ck+;(d7 z%WuBidwI>vTV8%ezu$g&^5t1Q|CyJM==bEyKcW98UOu3_Eidm;e($YQVSn$cu;;c$ z#Ga$g{k`k@;~AVVm%y#?&*C$jj2$MbF}+i3_CbjqAH>x)95}9Y@Z*Cu)fGM=ItYfG zQO-q_3+n!68`&JKM7=^=l@0Tx8pNA@c&X?p0*hNReWd1{|h}??)~sP zT9@9_U%`$|aX^e1MDvIM00;tqClZ5uS`4~oDexn(lmK_J*gl{Jo(dYblC}*I?lD$_ zQv5!jFvXYvFk)y}dsHfsbnUHI<(Wwu_&MdmhN4Gf%mf-)=10WPHqI%J(WcU2x^dPnEur2D2iqnoe7_+}`uVI3No~TuUfysJbk|I4$R<$)FOsiPK6{QuZ9v+#U#u;N1y9Ezp{8G^~ZbEDEpiu!c?UYfY_Eb57-9t@@U^<{viN z4y=^f)}O{sDfa5NV{sf%fQxYzZH}v&t#DqdK-lqiH17NUtd|nR1Vj9VP`yutA;9pM z_5nLJzA4`r7Stf7yq2d-2&Zo7p9x>Kwzw3`(A3*_Ok*WaU%}CC@)pyY;ob_H!Odz~ z+*8};G%xcQ?-iE7e7rSLFTw9(hP`1+UOM5fO71+V)k)Od+o+V;oY(de^ip+R^+qGs z&K?YJinSn0y%`SbX^;LtBoohqp7!hiH7Zqql>aE#{)vm2yNmd-VRM-cIR>a;NotB<37a+UvsBlcBeES*s{aUHg4u z6u&sIZs_-}-e1@5;up787=!xbGX|^SX_zk9HBhJCj}9rh3jL)x9aqQJo$5 zrosE$#hSr+Xx%wb*lhUsef0tbEz`HK#&?v45W^_S-gbJK(`t!aiztA9mwxE2)!K8K z8RNijA2!d#b%%3R>TF||nV^KgZ^i|WHy}0u+6-MG#-Iv|dTzD%u**lB_Xn2(`izTS z!!9@zoDPX0hecj1OtB{z9kt9_en}%j)@bS_9DzTg5EuuYDCh)Y(}H?mF4J%5iS?c+ zcthA?6a{e>>PDXioiO7$U2ROL9#Bux&<%~o%q8Ki`pB$x#O|(k!xo^2WJY5Xmv`X(u3U%?LY{ zvd*7We!~Uj&cwf%H(q^LiS-|<4sDzbdXvm@0ZB-5jA-%5aXr1Q@BrTR|Hx52?Ums= z%phZdGwdcH#4qpA4rDrZ6mP~&OfJJTU^rpQL)ZrYGHwB7HFaK>*2R?!8?VMa;(I&# zm_+AMTY)8#bU2f@P=_BJ6&mC%GQvfTUP@)z?@_&pH;zNKR<$cuWSo!E^#)IIY5Q{A zv(-Iil1`Y+^L!uK>}{u`WNN2B{Y$Ci{w>lxT=X`8#wP5qleQHl&~0GdEW}FOaQb#_ ze0!|_uQg0P+@FrM*g6nZ7LzcoqynMRV9SOyVVQ%i&=)pTv`T<#3&x_;8#NfSFD#31 zs)<;}$ez%fnyZY>9ifgSb0Qwh)_Rp-e|Sc1!L$kD@^-7WW;KRO%Kud5jF76{45a&> z{+U9Ca%U=>5j0yMvm8Noji}a0?cnwV{a|8`RSG?L zubxZ}NB4F@5UQQa5`lj5 z;0}IV;eZHgT=2pU6&r;e}872t6hW+nqR*2H9A~>`pD4So- zFb=`yoem4MK>0`pQyR8yi3ED4(++5sIwv&9M*8|^ z(GttbqU{a6!_T%LKB};8r|N@jI|b&4Asjia9!y4owAdV22qy|=B4f^GxGRaxR&;LQ zjjRb0V(4S@VH5F@^3Ld4RBg7ciLk)KTpy2Cl|Az+`&pbn^5>Jxy5Qx`Ypv1!a07Ig z4!eL}bBjp_3L9)gd{OAiVFzPe&Ndb@9GhcN+$-|4*XkvFmhfs|!up$B8#be*yd`K? zd+8~rQ!5}V(@Ehg@L!a@$=6i()k)GoLPhftJfrmmtiySX!#a$4ySowhY}9(EBhVv+>DEJtrZLsY9_qT)38RGWt)53(_)t z+Y-I|&oYGawa39Elaf3FvgFXfI{kWaFGd=_{wmazF z-8Lk!K)Ep&i!pQn@dqMc<;HpXZ+oH-267E6H|oifgDkF5;Bcs;1>~F^4%tqF1CK!s zLl)?TQIj0;%pTQy`sE+iAP`6stZfA_iQ(5^t0w3|m@WR>!L|#*z2xO&|G^++mpTRzY??*RcSp9g^NIO5uP_9MzK% z&s=ynY-6Q)3hT{ShQU{F8*($Vh=jt=88z|>J8)6PFXqH^7&##2__RjFoKbW0Fnr3E zf$Eq0^RV_Kx%h6+3E&`^4Jd-g1|5;C`6&3pnUd&@(2Gb354^6Su>r7|K&~J^;GG3J zFY4F$4kB|J0QObe3QOX_%av(?42WU6q7SrcbkH{O? zAkod3V7P5F%SQzX1z0Q-5{k(Ppp^+rY|q@kVY|@CWfg@dq$~Q)m9DrUM*!(sQ*G@5 zYg8BWnxL(P8AC(U!)$jR6-t7PQ{qC8;+(Gvjy#!6^FYt633AAF%~*W>(5|pc2*dig zKf`qO6(JV37)mpHX34B6Z#HDu1j18>HoJ5b;;%sggih?1t zi>_=ZH95YWw@8OoYz{r@wM#xu!BlS9?%VGG~y#AtHsI2ewHR|EzH$jBbgC+K?gQf>MymyR~_plVKa< zU`Mbo!tQUWHTEH6TnQhm?)OB3^0k4*yrONbzjvC-LNKth(C(~YV$i*;w>zpwZDQ6S zOkr1ZZ+ThuGCD0+M;PJnp8jN+7=vIMp-Jl%);@`24x_N+u!mXMUU#QGM4Pbzdsvsv z5*a^iz=aR%h4f1<*=e;+rZsxeS7#$CJe13csoELCR)t+GtaEm&R2|!cfEp8zOkxuE zfeQ(blncox%7cCp7$C~3`BoYutR6{-Ss2?ki<`3$Mu}E~g$9-s-pT9IE^}jDliG~% zl5Bfc--Y2YzE85?J}HCt_on7iO*x_{scOnT;hbVZqPyyVoL;z~rsbA;Lr$gx`a2yl za-ULhYn_e6k&lJH z+TBN9iQ>ewiXYkwzi{SrZKC~gBk|;NnIXiy78gqi+l<`Y=(`eAKi2=g{qs%zJ&_SM zW3|1s5xZN1j3O_-B7$LUtqM)qdP}kA!7aFA`D)Fpbpb3jCQZ{y5~G_WHAZrBgd>(7Q4{I=LJ?C%lVxvbqX) zWLHK4S%Da|kEPD8U5QHTxEzTRts%Y*Gcur!LRhTcjivF2kfknt%UWxi45JCfHBBg|BBJKbUu#S4LaE@3&%Z^F_e7zV+-hUcZQ~#`u zQ@+6?$xB(!rjOq)usw~rf2a446LyO*NKQV|gK-v6k*1N>cYhn?>Sc3E(LWx9Kw_|<3a^d)m0LA*Y*H5Lq9!4_6RTJ)JgmJ7B zZ6T66XcIN#OAA zBQ}QE$`*q@Bg1HyFe7ZM=HNv_*2TQ2`E0G{CJiZUuI80+tJU#zT4m1AFgGhQ*8Clp zYgms_n~|aq*i0&JFnrP3T`N0CXPvM`fSG9JXeNFVE^I|tN&eExep0J>o+tbcdDc-Z=F8rNb2YYG)JN)onV=fawi0LBDPv3ge#V)H$U%RSdf+V*x6xH~i5~ubA(j-C1ygLro=_ zIT#3a0z%Xx3czdx!q<(dRym68c}Z&8&V?TVzp%an>utEd%spq&gnO1dYn|mrsBeLH zz~4RM;fY2TdEI_;u#njv22X4+vyR5eT&gHI)@yAwaCl`={5u#oAwD*1r(pD0@MT5g zKaMhll?ywJqMKvSW>w`xVG||%oGx@Nx;xj=!>aLt@>%<_eAZ4ZpS1_eXYIc7S^KVh z){ZNmwb#mL?XvP&`>S}yMwXsazc{Q?dg>QfS4vO)?w1QKrKf(QL#^y9^@~f*%O8*} zH9e<(56JSF(o?_K8B==d7Z+PfPxCz>N1LY~%=+b|TS`y;a{4W$r+zs@m(o+e2eW=T zHsh}zAX7W)ccbBzxz@qt6>%x}qsv&v z8^{mqNjLhlAf9b+RUQ+zl1hYeKlcffTf0wd7QN{X_-?$VH@e_623B34#N1L zFu>2?TXF!kNUB*xmLm;@+J;Sa*hJ}g6KB)G3YXQGM_6ZvR7}>-H55W8e6(R4>TXgC zqh-{VVieQlAcwbdxAx~6T$Q)M^740mt3~m21>|?bg}}ioRFF5Jq(-aZGvTn61a|Op zB)DoF<51+^REywhtT$7yXKTrd!NsfC3@>2a`Xr7``P{)C&YXrVq=IYKrb~00_ZT^F zvalYGMGy#lJ8aG0XoXoA4ux%bUf+({oYuUuT52)3H{*?Qt{En)d5p)_nbiZ6idE3; z@-~W8%`Q(({;Qz!#v!ZN3lz{5zc zv<=VC&&z`K(9H*tBF0uWK^wpr(}fK71Or*B&FiuH_my)ADC`(q#w575R(y|!ZLCJF z$1sk?xIe@xw%e*P3M?o$T>K6Sn3b?8q0VZmlow-I_0s-kLAzqBUO} zxHVr~xg|eJVy*e@@QV^#YyEckMaizUemnf41lU@?9ez<#Y^^W&?P|imK6}a#r3A|% zN(m!}C?&WKQA*f3L@B{|h*HATAxa6}LzEKM4pB<5j{%9$zkKi4>Hzv{OWihD5suqdw+&VY(1Tn0ZG+VTbmf-1ZLo^=gMoFUMWH3P z4OY?W&{DSzR?#xiQnw9O(R$HRw+&VYTk$H|JO;KLtspJAZLoSB3r$PiHdsY#N=w}~ zSVfCVOWihD5f0u&|IrE2bntUT8M=W-RLeB;&}tb$ud^M&u(OOH*;%HUhgQcUsCKr~ z%tNc~2*RE1bi+AvhmLk4kLWDZ4QFoC>Kb$88l8Q0!#Q%0&UU)t9JxtnJKb=OoTa0k zX#MRh(+%fnE$(cm8=s?fxwD;ae2&)W&UU)-Ia;qf+KF7LvrISLI0!fIY^NKaiCFG# zryHLS!sR>1(~Zy3D&N^oH$F#>*3nMnYn^4f;T(BfXFJ_+j{L5(oo+Zs-q+bqH$D%; z2ZbqhI3F59-gsjOIKMFjoZlD% z&TkCC2RWqIHTO4$fb$ze(2X~Sfb$z@3LR^~{g_>44i5om4heR*(~ZxEhk*0pA>e#? z2sm@BvU|+k_ICEUGt1pgdc9-df^P5B9GdHVt_tlNhZw>)x4pDda)eYx2hk)~& zL%{jS5OC&rZP%DN0NY)r8_q|Dz~>`F!1>4!aOTF_?lE`M4Q|NAXM?{AADKn@nAg_g zOrk$^E50LQRq^2ClSNa+C-a&7x#W@KKDOwwmJPj{iYLpWZDPLqtmfmF@=NB-=S`FV z5it1KR&Xt;O!v_HTQ$zlgnb1Udu~&L?BI4mb+1sACTCk6anbIUoVH35x*bT zQsG<8J@IkuyYQehMm$saAuUD-`zd{3yH>p3COm}rU5V(jHPAfANTrX4`<1V5u)UU003ENnQ6|8z$uSO4WT#t2l zMcF^d424-9o(m7jk)QgLD{&#P_jHqZ0lQ|(x9 z)3mUUT})IBRA*lOa4&KHxq^B1M;u7lWj7=(6}R0RjXW3W3;Vo?Q_>BL7C+&!vGiF# zNpM+st{Lw?8E2Qy2wX1q<3;7CGXg$p?fNa$Fe=OcC)J9@=W-)?p0lFw9k55CDVztW z=FX`slqAMRZm#B)^R0XtWHFx44eL)8v$Gig^rl^#uDNSUpbAgFHK|YOVddE(lp+_G>y71O=Is%(+v93G>=V; z*>?}v88KPkU_mnJkKQNUcqacZ#yjn+(fg;g@^C5JE7MwOcnXm|^)I{l`h}gRv|r|Q zZ3^7d_KZdNT#9=n-tE7oTBh1+sy(k71y|M_Xb=3V#_L=9tVYj>D05bGsmAMD`dsWE z{*>bNJ*OJ4Z>dBU83Y?@j#H)@p5-s!D*QrpL99;Iappqi=t=xI_ks|cxv_g~- z72Gf*{LHRk)K?VxBlN+6NN2Z`TaCc4;N#Z*{1PX(o>nVJwpNB!g5&BIfxtP==^np-+gnp{!6gq6rOHRi+(;9CXp}*}+#7^WK z;}US5a=)yz+z96_&~GaTo&H3-!?^}ItC7AFi;sMsV)Bi1z^^Q3E^0Tgwbhu@JoA|R zcQsceGxL>Q)HtmrQX=ek%&NRep1xKmRVF(fwr*B)E+Q$)XYH->S-Yxy)_y9VwUf$c z?V<8nyQh5CzA2xzW6EdkmEzf=?QIOvzf`8DextvrOi%rCk3?!G^~<+eQhMq)`uvM_ zEZW}swP<^PPW@W6y{D&sE!y7GQ@<8%@9C*ui?+9Pi?;XY1n1~yD8^>d_Fg9SYti%6ZadCt2Qh>C>G6_s>N{svqNFYB&&6@@rMFX>QF=4|E2eJn)Ph#T zucet5R_xxLP>E1AB%y8`xvb%>Tf2`Bh&LZdeYHy7xl+)mCm2n*e#C! zgy6|Jg_2II#S}+>QE-OJh|_GU!-gAT!lw5m@vz>DDg$-0IQsXL0vxn*TP{eOyb=3b z(#=FE);Q=ZD8$h_L{)a1r5KenxgpEl+MjE1RZV?ig|_l{zTkCLDe)V6yD!8qdexzF zS|heNdT=?$!ymSi^UC>5Yr7aVmntOTJ>(NdU)IyNSm-g;v$gc->nfhkM(ErXK7V7335UYAJg;vr=!;Ok=9Sgb717{~ z%YE;vH|KO=vYI!q7HpltY@~)_6*RlNjUshRHT8togNFKu~=a>QB^kLDoPX2|EUtL2G_2`|jWpfM_4ZgFC;NDqAQ12`wn0J;D#5>Cf-koIx?anfS zb!Qnty0eVnysaP3aPUHdYsnRCTXF@}mR!NJC0CGa$rTJ+as|DXT*0j+R}gE-ZG)A? z!ViL^#ljEHZG%;$qXS1}vG9XiZiAJ@!Vj+71}lq&A6&N$Ru&6CsBYAq2hP`G;Rn}k z!z+u0A6&N$Ru&6CxNaM)EEaxn-8NWREc~Fl77IT(w+*i>7JhKuwmoRE@Pq5N?Lmu$ zA6&O>4_Ykzpt{i_F%WYs7JhKuHdt9K{NTE6u(DYA!FAhUWwG#s>$btlVgUQ=&WW;D zW8u5XH1p7EJAz&Vuc?-4=AqRx%{;VPrkRIU%QW-QYMEvpS}oJeL#t)9e>>)GvGDD1 zwpjSCGTm^tSop4Xy5St<@6LI3!#T>~o$YkPIm+W5?N}^)``j%SzN<_(oGliSop3o-E_lZ;k(-D#%GI#?`o$T zpDh-?tDSCqwpjSCcDnJ|V&U7{u~_)7GTr!WvG85(bmOzd!gsaPjn9W;>~L2*-S}*= z@a^qbEPPj)ZhW>__^x)k@%hadqutd`H$Gb|d{;Z&_-wK8UF~$^v&F)lKirH1iYul_BZ-l7AX`z@@Mhx_5o>+cPFyb`oMe09mMzr ziE=f+J+V2hAguw%CBSvYK<*c6Vvb{TWIN2G3Ahuy}^jg2^F=iI00I*le^~ zw-uF`BG)}FMKXl#A4LqgCCnpw$fI#fd{qR4?E&uI$HQ(nLGt-(zB-L}o;@8-E*ItI zg<+IiiBTgSuW59sqm4cNb-@W$`?!)Kf@d7SHi16V{;0`tRo*wI+5fDwoIRN|Q zCp07f4EO`(5{FM~l&H7jaT4LW(FXfqEHF8$@6X#Oi6>Q$xcv0-&54-DXWPj$NU(xF zw*L9kdv8a*j|s)gLhP&t223ZUT4RpJj#w*|@40e#;X$qB zw>0Eod!g(Hniv7KhIGe8@ZL}#`^rDcKvwvsDM2Jl`gSd$Tm;gB26yy%FTmeYl=4)nw*`K%c8Hl#E31XXgBozQq- zCXP0shJ}~Gywj)BS3>XU&l|VRu`e}R-%FDbEBi43F6sN0y{Q$MM{v`kGL0 z+zo5^g6v3ytlt(3@{?D`w0^v@4b~G+HGbm6s7}|?Y!kH(N1E}upF;Ox^B#DWe`UqD zf4v?W1V|JXO!~I1J}FXVs9~G}85iCFzccB0q9B)v6F}pguceKWNJQ@)>%m7-hekre ze50jLlZP?yJG^sQtMBbh##M2tlTlPjRR4DC?Pld%he|le+-J1zAa-$M|As1m4O4l~ zVB(@UHX~`m@yXB|WjwtNc`c>x>>g!Lr}gZF8oNMs&QfR4s?=fGu@VO@dKm0(9=Y$j z3=iL#SLv#ZlvQeEPQtu-q*^Hp%Xz_!fQro zAH>*8i$P=k8f%U6<4K%PNOVR^8)!#j5UVHevtA;k)6R`g=!zU+9m2t6?gB zEp{>-3vY*=lI4D=&vO4v_=dg%+gtx#i7%f^xcCOPJTyRGtFGvliP;jD{w&V;cSuseZSPWyov za=cSBKK%}zyB2%Kk`i{zYNXtVjfDJxS|Q)4q>VE?{rBqKu`N(e5VcuExGQSSXL@2$ z;Lm&GKT~HWW8;aLKyr*L=R6gpafSr~AYLOe8uKHU0q+RCL-~=_)FYdak@;q>DNmo* zXW`|LeQeUG7ksG2$;n;KE*Gj!>m3>6lKv3@?B^ zwj|)&`4A$+eQf;{mXR4yp_3q$sKV2~?G;#;I#F(#%qcmwR= z3cus!Hi2Ys6?xU3%7q_mHeXM(+L zX*Li&?FI6FK&J_MzJCl2`d7w?5eTtIRDtEBBX+Y515+!{x$x9AEf^0h%uOQ@v?lNv z<=87)(L~Y!4}gIEG&1kw97?G?FgNc$(o(StTl!!*k|EUUFwz* ze3q6iX(}Dd1DZ?-+xQ>(ibe0=lXb+4u@UPOfEJs)*}rO1bnRR z2n#`SOJ{Y{CP%J-#XG&g%L6vBc3oT4lymUTYbOkHY1RaWyhNH=8bwdulv%-KMjT^W zwtIdr%ZPJMsdGB>Jgd`tXC%#X?rlyo*%`6k3o3C@X(uEnU()X>)%rk`?3Wy1bUF+V z$+w3u5U30_t14U$5T`G_UR@o;4mx6+zaIrqs5rX*nAh=lzn++uVhyc)tsFiA)wL=J$M zg|yCh3{Z$&NcPr0zW@_C);J&Z0=o#97jy>DxmFrYA){`XQaRd0+MUvg%&DkXl<%9S zO1yOlNwQGtoN6&zZ(FHz^AXpZ5G7v|p8*yTc35I}4P#$-Ni$&=X>99{X*Txub_mzs z(=&bLY%uK;#A;xfzOH4~71*G|&6r@-E{^tT=Vd;_R5>fq!hz@*p=wV#@#bkdh9`7@ zaHE{jDUxWNt)P-38-u3KFbqT{e8|wfZm)7oPY5GIn1h$INhD%nCQg>qK$=e_JpKFM z5!RXrz($6O8K%1ql!ojpU8iRF4`>0J3Xa12Ow5NbF$FYAmxJJ@Xl1rPjBX;K<-8Kj zm=c4q9YMjd)71te2x0fhh;6VDUr)!y3DK@pFI;xKO!KO%1l4|M4`}3=1(Xb5i=7kw zDnJ2`2>a}DTxhJ5wkxqp+v0#x;C59FsrFf=TgEJ5l?f>(^w!&*>&5x5s&k}pE5WA@ z-+n^w2;+3Z5YSP}bZe7Lh%Ydy#-Z8Ug?*%&HlejKc?om`9wB;*?dxrn^|ca*xuVyU zkxvTr;4&!(DJqj$p%d^xvm}*z$tptiPdM+zCd&f!PcA(DYmPlt=G5PSZ&&Bh%?%nA zs!j|(y%%xj!nw)XxGCH=zLx-U#5%#-_>j;aI`|k`lfRhE^ z0e^?>zTO@7*mPqKQ{e75QYSQ!zsd@r&T|nR#zG@!?HIsL@j#X2JYay}`m|btU_Vi7 zj!{MiZ9UA*&;Bu`Fu^h3oOnBbcTUI!70d}4H#-@cf$H9fd)DEqxiu1Q0G9*#Abe~W z25G2Vr5ve5eYh;DlTY8uRiPRk$ZjP`9)<3a_MZN==ZAmY(d8(`I=rYg2%GbrJRg^W zT_4`5??d0WRgk8&WyjjJY@l9P%6C$ez}ZwY2@IyhLVZ}wrn2p4ZYZb< zFWz=gs9aJQFBT{mHqGnFJ=SIFLX$OS81uZhFs(i5CNfZ*XCet)Knzd6oEA=^rC@#c zYAk%JXu$_wrOA7i>uZo}Z_my1EZOqPC4N{~lIB*5MO!cE-+8AcHt)SlH z=?Fs*o}N*s(1)2L5J1X8ZcP#+BY-xpDi6Amq`bTzMomd)YIT(F$z6-$nFk#C9JC${ zxehJmPUqX3^+>W*U6c1V*;cF?n!UokpUi3eY=a3!VcC4}eA%UnW|B%u-mAg`BMiIa zyphTV_hTduNya62Zz*oiFR!Go4-{P^xIWf11N6e!pPIU@>y-I^&1pxK(z1|k1`h`l ziW|$ABU#m&Zj<+^c|FA7x{Bb2lQg4hiT*KFTLXQt_!;{I=*X2wq7iRCc84d9sp!C6;onl2F%Z$`iwZDXae{Fv+6hVFpt zFKupYuA(v>3lmxnbbQlQ%X}N?9NfKI?=_6fW|iD;@P89*q32LHP{3vh{j`OJ{@P-I zpw+pF4r;f;$Z~NZljzo0jG0e=&8?J8vM*RvTux)j3k;bD>JkZxYIe1LGUm~g$VSvYehN`3)hHVLq=afSb`n39jjB6pb zq}(eSo1rKoQFx2UU(gsGBdnjzBDccY zZz{&@n}R2l55$L1VEA&sRq}dQ4LM;%e#$9YMP+5Rj*5s_5LNw`lmBsaqbKlcj(y@Q zzAK-1Ld`vDE#X`hI(ezy7PdODWyP0bR9>;gwpVjzG=ILu0JeaIVP`cT+^Mt3u+i8f z>kghE0fq6tmNvMa%t$yLo6pH58Fm-GiwDAnH$zWn4;%Wcv~*yImW~KNh(s*r{94|# zaYt6aX$-xMq%z`@<;cQ-`Yw#*bLj2J`)cf=QlhbqZ74O>d%v^MY_IpgXjwfdkaotn z&tR@d3yn3{W#BY>37!uIX#J;X$dp(dVHU#B{lkqktFdk_QU|DbSbsi_^_H+otVj12Gje;osC-y^*zln!%{jrtj8$Qr z_e#p6LGvtdH$HEg>ip673ZP;bq6pm60^~SZ3#Yzy5K&m&zwblx1?Nz3bW4E zbG&7^jG~q|raGPzHutAR*k~2#2`{^N)7W$r9v0#^6-d7=10HLk)!x9nsqtW082tnq zr2j=f^#8&5zs?itS?2`xzwR6ug%*WTj5*ZDRtMDLzF21z5^fjP=R7uyQjY(r%N@f( zI}j%~oC4~rlue}E6tv){8SN0Rtp|hM(Zfi^-^SoCP~NcC zl&&xiXF%8m>huxTn+Fafl-|~w(jPW3qAXBNywm#)>ym{(Y;nrIN44pb*1)FTZukmT ze&g0)0Q}TvwMX+dp3vK1l+lH)FrpRMKueD`(n8RaE5O}oQ9P%Y z2BVE7H#J7{-@Fhd$a<7pQ(0su*1LN8fumr2tu42#d`ITR3yS;7)S6AqrfyOUymp!#j$VK-bAoUnOc)CiyuS5yOPY4Qv5YM8th_Y9U2sA%$LUx+)) z@JRH2yY>7yp55rjw6HyI2i4JH^591B?63p%lRhr$fB3HNq4H$@YrfZ#MDDdeP%BR1 zqD(zCxa_-XAG+{^*c)=RXw_!lrz`PmSMzF*T^)9k4j#44Twm-nIL{U{2$PsFQK=0R z2f}RJ=UhrBJAnYM%$BwL=&R!#@{aA3#T?6imNVQBg^Nbhp`w^?SSyqJi9~Wkm{C+D z|Ehu1Xdv=H)imbx-Y9&N)y{57PCbE@=JCj(ALcMFAZI0KLA`D0sns;j!HkgW8Ic*b zt_j8-$RHl_^gn<_=SOf12rv&HFpM2^N#>t=ga%W#>C+aBC0Wg=RYh!i@U7~KF<`5P z!H217)dVO{N|5H;zCJaA6A_<4T)@IMvW2KJyZYGEVah?k3{QXaWQ3vP1qVs;j&jSG zS+R`ILgAPw2E}^ge>6btJ^jz0bt)FbV-o=N{&2TOPwFr@bwi>IIOrbWu>NW^&Vbqy z8+JN4%`^fLw2=5DX!X{bwJ(evld^G8cA~HjD^T&gDLo$(gTO$d5(?*>N^iFjJi$rF ztel*%v9VM$S{T2dQ9*Dr<7*l{Wf>thK!muw&BEOC^cRQejLIIc?j0o>0G9x04xGGO zr)H$t0P6$cE|sH&{Pjg4r`T685-%5@TxW+cqP#6B-lm0CP{<(CYLN3Hm!6%HXZ4YC zZt2&)hBy^R_?Z9(YTeal&u!0aUEGaqX`~lEJ!5(Af>U*d+UavzC&jneKIopxxnNNSIzH92(_F@YXazxV~UEo9F zqx0IUVeNwUGNyug?Oop9AWy&hN!2GDXJjm%R-oTG0qzT3x$(NN*>np0+|*z=xRcBQcn-!!%YhKDX`WL}Cf=Hs_AN#QKV`}D7z)^J>Z^~qq(VE5!_ zvQmczNYDp60SlF%*&^DOVIa_=vZ2*rpJ2&-Nd1dSX~Y(@NbVKSs45lcn)Fro^yj?= zeZlZlEZQdqB zxz+Off5)}p`$SJDeO+Tu@4J;2p8n-wx=bHyqnYaPz%|5#;~JtFNtd&srv2%QG!fm0 zfIJ<_qBRS8HPo}cRaxY-GpYeZ{B#0n2&G}n97~*29(D$H>Vyy?p(E~XtH+_w_d@ty z-WK}@Q3ox{+ag90lRNalj&fDon^*Y>@oLl|BHi-b@IHno6Av-O(I%Ilc3<>yMP&(m zpI6U_O&4P;GNFCByh2mwshg30b3wm-_6+JolMvT?+7N`TeyAn1a-^bAvFy>?vAtTaFJE^$)=wz}#Rr=$ zCoNq;q{qFqFKrl^)^#5#TEHWk(50(qAHsMlby?$+rFEQm2#}q71_?^yo>Dd_`gd6W zu2#78->sk4Y}qEPa}YE@Shov@?bw0A2)lEZbkx;yl(G|kHB?SxFOgZHF%G4$>w`FM zz6sg_fz5d&1$K3qr^u0R9!gu@=3?GVqFL~4+KQU@5}W5&n@bvNIhVso>2O2@m*n+E zt4Xs&g*C0oN=ir4ZMY7DvaL-gH9iO&B2;OyA9-CG6=tRbY9$n=C7v_Wl9Y;5QMI@v zOqiFpc0unSDTNd8VHBkzj9!TUgU4YlzFzqo#>$8wed!${%3gqYR;?ftfuL%1x3HD^ z@MFf0oPep-4&a8(E^L@cMB8YhVXf5;*PA2`BmCB%$rOoK5Ayc7Xl23~cv z5`Bv&`DKeI`D2SGDPHR@Xr`EVW30(6Uzg%*AbcJ4hWxjCw4z)bd0kI@E#ii9i6`MY z$v5?MP$`S5b3?h;Rp$+*Eb9NBj@S&sG1eJr2EPsX(iGesHdJXTHZrgEBtkrFJQ;BW z5n)c_XYb}|z!+m7_cN!xQEOHASr5v4PdmrI)Eu_X$JR^+tG6*YuhPcmY0=tKk)j|d zz<rM2WED zium6Zt*X~D{^+LvrO?|}tpVPlLfw_{B~?o^!S9JTo7O+pUi%*HZkY%_5yteCLz@y| zJG-cQ5CFP$GvWuZN#aS-;&>j*m$zXNa3=Cp+Sp3Jm;(ukG@PSUtb28jX50U-4KryC z%s|37!L7f(r}PH2@A+T#x3}p^9EJO?3K*^3Bbe#{+3}tFAH@=F2EJCsfc}{v0ODAJ zj_8oqDK*ZvqA?T#q`NArrks3f^B8TfnQxLj-xzt`4og*Bg#PqD9t@#WbqLorntmJgtrvJdvx3A$~s zKeeg|qsNf~MmsKHDu7C%Mmrz7C*0sV7n2U*HP=;!ae-f^lIZB`QZxUf9V}2#hR?+> zeyCdlU)9qgJ#pyebMXz&JzVC#S>_&zxr~MJhP8%T;owfyosAQ9O^vjVVI)gu*YwU8umrx_lh*XT^juKqE=^HCR<)fSvhr5X-)d8y>mMZbY8 zsQk|UR;^cuyvm$Re0tC&Dqs&55u;RYgGv4L4p+%blWb9!)#7?7s?FMrZ;HWUH2APnPd@IZHOp~hF5-quTf(T_7#4FMUZPLcvf-VtMz4ChNz;jH*mz7z zyvw0rh9u)zpG*JRnj_Dx1bk{3T; z`f77eGjD6BH|ZmCx@CJb(I2Be;hpAkMy0F_b)ZlDLY+RBtjqsUr7#-f*hh4~>Pf?% zDmMlOw#$7Ftwwkcpx)o>hjta~6K?vr+g9VeAP(oSy{$_d+Cb(A^`kG-JK}>Mv^ano z=1>QHc*lS|BOp4fc_si)KX1>Bgk=x!+Xx_N7Ek7DMmCr5+DQ>!vn1LP05ia0-7{f`v#e&U2uGZ3KeNzUxhAPD z?&fn1y5d4 z+v$w%dIaocm{r`F7@&3;M2T zu7>c>(@PiLy`tVthOu74pZ`Cer<)%>2a*{O(t_vgC{21o^y%3V*xF7g<{+fC=b2v} zjL$QsSA=5F%!QgE-^TWe6gvxmdiL4AqK%P@htRxNQL5|^F}51$9` z460yAS}8MGL7pA^P6!$javnchqHRoGOeO63-w!Ml>H!)Nn82X_* zI#xP*Ok>0E3K9sW5z^JxY?vS4ZU zsfO=LPV7(NgAVqY24u?JI(j>aJh^+aFpHWQ2RV}6%qYRS2gRt=x6De=L@S3B8qF^| zy6X2nZgO+5w+VAF12~6O=*_|!NXO}e97%jjQYUkl5|lISsvpxv-GsurxDcIuPk){h zcJOUTVsenT>0$Lyb|k1o;ur`+H_3{-M!8^}A-j|RV4Mt2bkdnDU!Q0ig^TX>9@|D2 zu2!w+#GW8`0Zb2q87cMpK zJ^gDv(6|4pr>MVc4b0A`bKKKT^G(_g+MNV9>S z^#<0i0bmE4)&Q8;SH6pN7UmBoDyIJ zK-gQN>fizS0g~{VuUJmS&#Rv#v6N-+r>}1s6-!$p?=(*DXsi&V6oBkBm0244(K?qw_3xQ!?GR`#@joWY)~!@!{L+~-YQ?y|-Y@3bG{SdTh?gk_Dh)%iv{J~?g?_h!9Iz$5FU;%t>cQRVZEx;Of zjwResYBGkIaS$JbwF6gnydC5s1P!F-kj1f5*fJyGN=!pTG@1F5ehC(TPm@L0qF2`+ zuS#1>3AfWCk+19jY5jjd`6u=MhH^GZK4lNy;N6i zxOV2_u3`03&(MkHnWr3`I~}JXrunm$PHsmD~@VG9^QvegI&oxaz$1IXJG)gh4jm{sS z=ZsSV$PaCna3B|!`e)fZwCb9!zo(S2 zZl~I|`F#~waKhXK5Y#CkXm{eK`8TgNx71qAuw~$UZkyS~%?Ku%AW)+8Bi#1mn9sku z23`Z$CjLcB#`(1(w}!z7!h(%j8&|Glzlm`D_>tB{Jw5%UVY;fKUXuB$pD)P~Z4jUl zW9m}1$)!!82p5JK9hwXVW(PxV7d3khi;A@>oH?oAWQ_JvR;A=_sWVKSR&RhmkxP93 zw%r^>fEt8L4h2Tc04D$GjNHpA0jeJ@t9g-7N|!^#K69&0mxBx^ubRWg$y zRMli)e0jFJ{FuhF2Hj-B@kOtWqA=5hsu`8h+MGpO1(U?32jLrO*9<@M+Gs03T(|d-scrZ9j*T^IF`x6`bhe zw!Tt%9An{ZwGC9ibVuDYwl!OCE1f-i#+LM{t9)iKm~?J!P+Mtc)$(zkU!EEEP~+Z4 z@cGe7*N~7K@R;wd9gR2_iS2D^Ygl7hU~I8$`mfeMEmRNT9G3?5MvTrNLW4ibK*m`@ z0KZiul?~K?`U!yisG0f41>*p zRlw&fj=7^b2mKf$zofaX9N%Lhxt`4^26E`DAmZ4&8V5Jqgl&F+FCA-4OB-~>BQl&= z$DWirr!)_tx};~Q3TzK*R5*vuR8h)O2cgoXxVpFyxp0WNLUJP_ZJkz6v~5zxi4q2y zpDr53u0me!#0WbR%#%yjG07zIu)z-?0V_fCIBiwa2937bQXJ(@q8x~dF_~sjww2t@ z!l=UzVmgtNkT4rdYzMCQC6|KjT(b$3lSUQv>0R>A>whF*99R9}d114aGF&r5Fjtv| zJvofP2fN(c++UD5i#N5<>aeE?hG}i8TRxNrf^DB#nDK&E$YEvau5pCzm*T2@qS={9 zS1lJddkdak$mGS%Uv@mx^Q`Ujg2=M)`ceVAu;p0fgeHA|D%`@gh$Ri3Vro#HF5hFxGSC)D}BF>P(trPA+{$VM{u~T5l=kR9YH?^&mBbwU6v~H_jK$0hPGEd zn>8*>rZ&@|-FHz_5b81s)C+I&8u%NmoG@-;d(lXlAo_eD8j%1>}qGywHc~oF51gZwC7v9Hj{DK#I>A^Y^j#;*~o4l z&+lhZB|86Vs-bN$mOGSZ@zZulX$c8aT0+OKekwe*<*c4VPA*cDaLhCfbS=5_kZYQ414!-Y z@$_NHYtlvdaxDg?6dlyB?7OaJqQ7gV79(C&Ve;Yn0gk$#(1(|o&8OzN9sA3M2(>WB zz1Kx>LD52J0k2$8!Xt^mVT^D()&kIJUjR}>9!|D-PcUl)&<##lq0+Y!xF#3<#r-H3JJ=)U6fQbHnf7uK2IQ;#u6s4N=(Avha(KjT=Qi|WT#2@FW-+*fJv zSXLh^l^miu_(lmXrIG=^(3S}U|IxI}C6_;%mS6vowS4GD)-np+j|Lite`GDcnYVo2 zLx>SO!C+Ix!2X2G{WzaT&}9(Va9KO*w*KtYP#DoSbS|`8XYkTTqHT z3W8f9yn_sTTw%?2+~JXE6@k#n`JQB=x0Ulqm%!(sTN9K+- z*h5#tm)nQ8f>gobtOkpV4TUS^ZGZ@QL^f1w0P10TqwLqhy0W=GCkq@24&qU!))+#4y7Wcu$2@=%C9sSETzKkC?uJf8E zS=yJNX?I=JfROhv-`H1I(s1V@JvE8c2KD?4^|e`&J%)%#*GaEQaiufbFU~KtP~#`H z947Y`q;Qwp2TllbXiz3~b0bzVDF>CR%JHe4d9?`d6+ixRvT1MSrWWk`CdBi`Q$ItzUL~*8NoNc(}!A>f>tzdVvxQza$EQebD5rs<0Ba;VNM-Ad8{rBVU>e zKv=#z_wCQB97|`k$mCLN0@3NPwy@-Fo7Qr%sH}&%QqYx)9r)$87qL(%3ifRaGg8^d z<$eqnOjquhSH(zr#Puy^BH?Njh@Q6S$jy$Eu;+m*X#DG14G^43^^hi-1Vo z6jp^xn8b^PR}sV8P3be&^?Ogh?(-^0)piJ?p#tZfA#L2+%#jj|ahyo5=fkm9v=h0q zqbRkbzmx^plqFt_>Pj?+-(E5kWf#Nc>g3@)!-Dv0!>2Z~cg*|cGvlr_76gtoZ~-^X z$lBm%x=Nn)<O}Q-8^HMkBnagh6V?52%c@I}!^isK?zGwJlK?7&I!*G3(e8rQ=$gTVJ2mre;>-l>7+HkP_ zmqq5#gsSs~`Ygu7YmbEFHw7W&N=R%_fRx!~s#>S1yZHOOMZD41)VgjMMk}}{w<4h- zW{AMy!-W*}9mJ)xI4&sLf0p-XN%vVY%D`$FYBe}xMJge&h|3xR3*5VjWCg26SZ;Gy z;&mt77(Rk&#Uj=E={^qD2l%=!MVgAFFzCFlir?;twYIh5-vq;2}tQL8C?(dmzHd3~p;) z@<~1YO9VlrXpuUG`gH5=c0kB|P7o^0B*-!S7)cr>n=ZO_to9zz!#PYFc37Z@eQLwP zKe*_c8!GM6)Nsp6^nZ|&P#u@eaI6`Qb5`}8xEnzzsKFh%^{nM|zY>l&KUGSueN5qu z_Ts$AitT70tH{a^jpB1RsGV@iqbJk6tzI5l;bAZyHiD}a$ub|i%Z_`MKBG|qWuRzd zR+!f2>Uc^Ec?>p!#t~Md<=xyIU}2Z&L%%%ef-kCqE__APzMWdWjazUO8r)-TVdd+T zmW4EBX*>8Z%AeIZF*DEWFLy;x>CBpqrAkVo?PWtXEy$YVv5BR1bIc@cnbs7{2FnEF zz&;tQwHjtt~EfptjC1=bx zdzfpNB0dugh*&qmx;KvDW`vx7rV_!9;3Jec{2}_Z%v$hP&aaQEZNE6u5yt4j9P#!f z$NAI0&+_?D(-$bA$_(e|02&BlR-=#(#N+KC5~u)ofBrTsus+qVA_~R_pTN`z+CTUgdE{Quc|A0WA^JKyh4&uF?elA7r&2?UHp3kzF#C0Q5&5({1p zNIc{PBZI`kTUbjVVX!4EBVk)!$m`qPQ?;bvJv)H}5=fv5y;@hTUmyi9OUkaSQ+CCq zOafJ=YF~mAsKASz!WCSF6E?+G<@@>l?&))HPtRy1hPA9+sptMV_x$;t-}(JN=bqb7 zFf%`AnMQFy`gzpfgiRX#d6I>JcayKpx8)TVuMN_7^1@GlOKNu8V-|bpUz{8}xgCg^ zaw1ZtSjy!{^5@4htHbtwWr@a;Sym|ogJt?E!$G7#n(s!2gOL3B{1c*2WAwv1-3Uvv ze|2I+Ih{v8tIoSNL!`rpAD4D=WB-s)hppxj=c0+<|Ad|uCnr89e?K@E`^=>8fBtc} z0)sF%3nR21`uGqy6L$^*QD)9rYjS-ZUuWS{>Hbx_uzy^#{5lN=uYlpFhgHzY5?0yx zD>aHpoqfHygqQR2-b?xP)e;O%NT!sYzo?^~0`n^wBKegJxBP08VA*9#<3=67DV1=w z>L-MXFEc~UtBZLC!mc+UVl5@87R5S~bHf+!v13>fzN0_uH`aiZ3DssVmR3^+<>h{X>J}8)*#f14aYHL%G`-u`6b1DSd%ku(|Yyr zlBTexR|><*tBJ{<%)IF~F9@?R8CdSn)xB~)XvtTZ`jRQ$3n7BcPOQMn zCrS>f=A`w15K{K6gIk9>bq(lAwh&$&3i9;Cw`X^Htw#ylWF!*pJ7 zg|X3u6m9x~U|>%i83)<_5I3=lV(9o=R-G?EvDbOa()Y7vUjjCSKmJBk=gV#N z;37KHHzf+wH*+f=a>uaHT+5-w5-|rDu zLHKM#kSy9^`H)_G8JLj<9z9vg^mPo2n*X!9XqNj2yo>MP9#*MsYO618N$jI?wEkB> z09e;e2wS)Ut_o4rpvU6iho~tz(Sjk~di;I9iC)AP8pCXlt38IHxSST=-6eRu4UexB zqrRvB%7mRzKs_roao_fd^ONCk2&HlF$7K1`;x# z;YszBsB(-RgWkxJE{n(mtNL>2dnE;M6d-_LzVH-fiJW49ciOe@m`3D3E-6kH{JCQE z$){Y<@0Hqxg?YuLI2#t84o!Qh+2d8o%6>v9^=oziQ;6*zQylp_7}LrZ_jF*Ha+%DE zPkSN3JLitQ{`$6SWSByQ{` zAhwmhyjuvxqse`{iLlKF-d@m}H>fOxNhyB|G=AgVXJGNE*tCRBL#S*(GI%9cqNUEr zn*MLZCx1j8ZdY(T;d(C&H5T8Yh7nzG9MBbO7d7S7`Y%s$>2Lz{2-RU}l#$1r3Ih@b zZ4fp-c zGDcCL*_|rwZ!+U&F>NkQu?UgD*y_5loySe88$E?Bq9?1NyIs29tGt8uAWzP9nnNtJ zRKT@mUa#Ji#DEK}CM&6JW*Xn2HloAjWu=Fg-mKQ?|GwU`xupGH&E*R@(KI{${=)2` zI+r^6a?TZ{Jxk|W%1ah^KRuC>UfTC_J<)Pr7P>}H?K5rGzxQ#F>%Q~s$+h4E<@+W? zyZKWhI43)B>{bY~qcQi~F;7ptH=mJl$L`1{0x7MY4E`w>?T)#%={LaM2pU2T|33-hyy8^QXAMNnjOnA;uajbnne*tmK+0Q*ikp^mHcflme~EJFY-VK^|D_vuMAn?bUF#Ya%=-flvc*cMwh|_%?!TE>yV{B~=UeJ#COT`|0 zzrYjAfbTFkcwKUXY&3kW_|5j@4Cd{zX~3Np5a^z3NZ0Q5Q8RjxG~9ZNf+?B2$)1G% z4WbnvrEjY~%m*|zY|6I7cjL4yxJ|He6yxf6uO08Qqgt%`mgULtEtYb>QVvNth`mn! ziyp`fe}}0l=ah951O(w$OcFPDCj|&f^`n2$12o^M&>tI0UZ#OsufIzb)+402NokwZ z&U)>?eyRRQ+pOGMblj_a7poi$z%G76tG{ISn6HUpGSQ8rYXl{bi|BUjQ*C#srcElp z(dy+MLZhvXs%4X|w&=+vs&l>SXIJ>m`eU#!*416Q-j@um9NZQTzfiw}O;4!zQsv&L zGaDQ2Q_3CI&KA`|J9ntYJCtL+TD#Lq+$jvu&wa{4TSFJm)(&57geW1!du1f$A-^4) zR3~*%7k}$j_dcD$Eju3GX;*ud>r%tPex+Wl9AJ^15UMx zxMAq*FInuBh=orL^lXJ4)DC~|S1r&!Z4kzHj=5NE1df5**DD`zGd|>ojyEgEW#Y_9 zJ->NYjFkc{f*WdsYqn@)$O#>QMVA0bgF6KmJT_#M z38d7+Rz<+QPuC9jCAxFEr!-fW>5QE5-AJJxXy>!Z&>s$-B!-SqE??@&-^04zEzUn+ zi?^X;)DF7_enW7 zMFEhApdf5dH#d*8pX856+N==#ILLa3!5$_;=a;xY8fJcn@qtVJOo6fWwot~8f1o=y z%-W}ove+(*b?r>CZ_@mMr>>E1*co+$-sZ;*!l}kh;X`OpiL{2j&5s^BB=-4+>>5o# zofkXE~DFI^uT1S^UXa>p_D@g8e2JP4C_#hA8_j zYma@hiO?|bO?$~|VEKxke?xGC5#lqz!cqq8%EU&_ZG&Xxc0G4Y(}I6&HNcoGiFK*m za>5rr%Df`vjwy=?+|NtS!fxAVA=e-%&7Qnq&3bbW{rm*by48BP6egx#u&P?5O+bU(xaF=#*Dw=0=qXeoUZ^LawTBHiN9WTK{hn z?O&}BjqU5bfY45|i0|4n-jZ;7hv>^{1#0j`jJ~~cvgAv`7qSQGmNa4s$5x`4hp+W# z0?(AMmZx7NFTdywCMWs?{+^R!GtxweTygrf) zRqD&C3+k2S>Ft$9`{Cv3Ue&X#QmIu(Dvka6RTGsQZ|ol)ZR{UaV!cvdQXQ?NoyGOa z%DPUYiO%)y6ItGscI8sArYHzhB4Uv7!1x0IRG@RwX)A6Lq`Mxm_hECenk} zy~l>DLzRW}ILj*aiE4fpiYiN!bE;!$>-n_xV%mC0ze?JADQ$hfqVxBy@bl_(=N>iM zdPix`Pt+2f9!d|^&l?|7&ssk*SnRYi=3FI2j}58Tn&9c&-{>4IRrBJ+B309QFzp;n z+u0b`8P^9JR;k)smFRw@T3R#~+I~@Ot1>bIS$3t>F_kJ?=inL1aN2o@I@%fcvDoty z%T%c<901<)^rrKe5M^~eLHT0Y7b~l#^|IK>%3_TNV`2SYkW}jRiP-Y7`ttEgWtC+J zDAX_wjgAS0$LgcWu*O!TC_H^%XdfLPN>;8)#_4d#t|t@AHqHe8_ZKE3D*RZjRzJJC zNZ791ApVfiD~#e$edVx-nCAjfFfK?$^e=s~DoPMZwti&rr>&P6e<<88U(O$fOyIop zy(PWjIHtRr^+Xr3(=S(S;9p)O%!q{yF{5L935MuV>v zTW!6Tx2g-#v=tlmQ_S{S0M0Ii&+pUzWOZrU+2&NMTQ%$Ly_U9K180TXfD& za913fW5uzaF#J4koj-=`pvBkn9=|53P^sIq*Gg5qR;c2&i8LU$^L*aEdM*O(-N69a z%0}nK$UfOh8gBnx?E5j@4k2;(DXkvx4g@B<5)=?d+=5RkriGurX#0=yGXdk8Y{d zYgLdVW?KT%f0N_G#nHrsjs0)xW7Rx8-A3Kp#;e0#$d0vio3mUk zzqCeEl+W?Js_+p<#_J2Cqb>%(Y82j<7v5%tw;2-GHP&eWB!>Q-pp+``Q?`16AZ)cp zt3y&4&-&?MKXvWVcXVvD{=$YwK@-z)M+0tx%nq36RrP<_! z&SPVZ&Rgo;gzl}Y?{IAWmSeVhNp;x8QTDSm`RK-d>GhfpHTbb!ll7+_$`Be> zIsIfsEv$GIkk=V9!sx#tNq91h9!sl>)q>h+zrj(euP*$n>Gp4zSI2_frukNGup!YK59)JXPdeY`p@o zT0xI67j#-A&d#m07p(^`{z-LhrQZGJ0K|i)btjWri$xD4oV+O zvoEe(uyVoJ7#LT&DDZk6>%)G%ULBS6MGjJeYl|6p*%pa8T5UaLoS99I znVo6Pm-UBAL;dz7YNajSJ)LOpO4E_qmC`a}#^N~>{1zjLj$FSuS)i-$i9f%`uuI}B zSkm+kk4blBlM;w@vNAfns43)bY22y~Pu82mp6<8R=5TH0f?7=!lXecIopqIkK6LFj zOiQ-kFtu|?PedO4T8}Kv)lNa)S47sLyH8Zpv~xrk;xy+e4TiIx>mQX?Z)Cy`pQTD% zK!&3TMw-j*das(JE6B%iTUHK_i%LwtGJvw+>!a0SL0?fX)csm*iBx2Edp&)CA%9?T zwPs`u$x0*Ya9&l2M^fz9P~FqW4lZwGU+30-_q%H#p^)v*v7n6DD%pNyLk=&)p`y-# z%8BWvTBN2zZ8n1U8yU1$UsYY6ryotTqtYeTqFtxig96GS(pCQGK})VF9X938JQlz@ zYQP-Ln?4#EJSr||bpF1V?ZE*3gAVU-x@)yiny27|v$c44b(MhyhSO|H zU`Zm_1%`w!^aE@%KVrWrq4T?W%42Evm~J1#u6blyCQl%bo&rY&g3DW4WT<>dzSz>C zg}r7iRW0YKISd*|49g5jXn-IIvZtll`=e5$ncn1jk}A_JI}}Gx`sA7&z~tTwj=u2kQm(y&Fa=vPtM4`&(5p1GE*>} zjT&fW#9hi=rrhu8Y)m_?GVSq|Ex;f_P(=$nBv7iXyiID#pG00Mh%F4=# zYBGYNz>csH5wcejg%ShZI>K0>lCtMTnU5?;#M;jj9BKbMUC7i-6y37a-7@vZh7a%G?9rcrM}hV%lg3@ zA{yBfk1VT>IkB`qBd@FS#-Byos7g zGhHw{l?b(;Mo2RO~V>#F^g(L_e{ z*S!xvQHV%EIz5(AGP(e0iJPfz6M8pcG{Of!wASnDBO zOAFy#wtgNi-Ut_Ohl_XDs5qs5(P+J)f+8CDm4INHndv4_n}C}A!mX#b@{{Z=ul@Zm zRR2JEkX@2={Am9}|3N4ova})hMs(S$Kju^_qOe&u=vpsMoQ-9oijOsJEgGfJC3Nq-QBhxg zrM$02Y3E@WjzV%I>cJ9t0tMCRZdXQ)p~hih+WAi7+B|2aaqV(B3OTagYqZ`=O*2#$ zDF`b($c1>LvaDJay73RhBv_aN>XBM?0Zvt=vaOmr;4hdQYlTxzdT*uKTQJrOx#7@y zLD%%iC^Ot?oFxOZw{(Vt-!ehR^5Q*wu6&bZIpJsbvX{vH%Tkf$q3e+mHk-WsY?og5%|K-n?3NM{U9r7onYEZkS z7}P@{2KCSd)$z3Rc*sik!Di=4s8WNA>nFi8E@@95bEuHTFnH_bT2ZC6UXCh7*DI=dr%9-uhnk>a?W}Bdy*MI>3?!qO**ce(zF3<luxGdvlfe!7Mu z+<7{{_H+*0)2487W*)5Nd4)OSp?4%5HLl2G!=9JO-a&Z@g#;xkl?(HzNvo^qQCId* zt6NJuf6cWUQ$)|_4BQHfgI;gkn%5vYmd_!|_j;k`{gqzt_8TU${TgZJmGm<+C{8iaggm3ggbYx} zx2M_PktSU1&(HU?{+DX2D}pq z0#LZP$83-CtXGx{HjrNVXB6j5R$Kl{_277@O2H*QT+^+&Sm5Sn*xZ5D&s3V zDM|Bh+21$ztDZ-CHrcBh8QAsJkwoUsm{bxyI##bh0FCa~O*!1}H%G%{!jf^qv?fWG z_%Tr6G8=DW3ekR@=rQ3Q)tPOSaj=*XUF_7j7xa$`<+Y`W+@kC?Yg!J#6+{2|~#$qyikN7(i1hPhHwmok%-BMlmWLqb7eMKe1T*DKr2D*%F^CJwN+0mK%VAAM4xfjC^_2Gu z5R57qEKN!=a+q)J1!;RBlLorTCN;U4b|0yy-R~|=WI5ZzwCld=Q{&QT&Py1Bia%if zc8{HD6kYh2A@fhraXnJqd-J0ULNqW77^y&+&6APtUe^yB#YNG;#r2e6X*ksvt4p(cUK6>2;sO@vREPVL4< zCN!K-;#r!8L4dm$E3s``bNM0*{bNMij|56t=^VE5p6Vw=a1!-iB9>JNPoivSG*3}L z+hn8>64@*-8C`AVb)iW7Qp8q~#OgI;uzc6(eRbZm)uCsr7pZb_t@S|Hy-GyNN?m;x zED$;#da87bG!975YpQ&u`i0m#O)AF_Ye!EC zO-Z?nUS#v-16J~u(TfYD69cI-jEYVwzDjYrD66|&r7q%Yd(Tb zjoG7V_NWzg1_94-3=t(5*r z=1BupMz!)q%TtWZJ6Ik2N7laVQ$T}-$ulz?KdqVi#l(=?QHq>MOD#5n(Ym( zV~m9B2W4&Mo!OsuG(+$W7?Ue zqgZ(0zqet|>?oFrPIhBaY_+;l9;<oVC{ky$CE^?H=m$u)7k%+R|Vy%!b zApO0Yt4obYEEb!#*Qf1^()J~3TeD#Jx8A`k)Ap5;S23fie~7>>4M|RVVIr;~W4qDJ za=0|3XT73>CVVyTE0VY*U+I8t7lMyUwODKS*U=tR3ij9~rEG;6xwg;9wYP|mJDMYC zU+Ji6UpW>*)MbEi2YycgOx!3kfk}|&bLwL(Tn-C$e{Fzve{FUWL~p~PlfnNk0Zvak zx4KA*anjqI)Rq5?#&DL}lUkIZ(=Y0aG1-t)%JK_!%P#ZoO`2WBgVw*Su8B}FX1^(f z_y|6x?d_7FqJ+tOK0JF)=%mYfG?`}4rR^Pl?WTQuQo!U~_M9Fcf8euMA_NR__wVfZ z_X1X^$euG`)y6M^5ise}hKQKCJkPcM!)i0uF>^287od5i$Lm6<`h;g^d2ev2_PR9iW`OtEHbKj&QYJXTegqSL+I_6Mv;Fw@qL1n}r<`vaCPQWsO2 z@)2IIUnG^%`4F|QanUGiae*v)TT{X{>5vB?<<~hL^$_yXiUY_?VJ{c!*DJFGCKiUM zL6Igcl;gVn#k9R!)3s^a9ABO?MJt%T$aqZ+8H3s+c>8v<`=^-YN~acTN_J?XrsW%H zdvDq{e-jU>F}1|jLACcQozR>bZoO3fqK%OJSw>%R75~?BaP#1iVZ*K|Mh}G*$<<&< zg|lgDqYZUP0Z9Gxp+{ur=}I$`lZU3ob3v;kepmrtp_x z`U1ppfFqm@o&pF8oK{0~1W{Ki2K*bA;!6;JGrYR0AyXsStAghq{^XS0Bb^;) zsTA2yNM<=l_AH?Ytw55HOf)XG*llXHjnM^mywHy8?de5lDtMRU!B0ynDvzqirdT2; zeMySjy*!<|L}>EU5=|cTms+M=22e5ID$SR)Ue`|w1j+t&n>~01GrotI{fM{ElLpS)28SEYNcL8RpT(vNj;`R=OnAib`*5Jzb)s#3VOrXzI$o zhI|2-l9wjuifCKEG32-3hrMED`FvFSeNFJn2#OCXHrW^2Z2h;@Pxi{=H-!iBN+jgW zE&23*T>%WC2Me)~1Im-O(X3PlWL<3o%=~^7$Y^Q0j3x zH&i5A4FKhf|Ms8JYsH7sR*6wF(I5Kh*JhH}>nu^wf;#;R^#}*OY+geI>x45QfAc2$ z>k8WBeb*-M%MlPHni*{Uzq0wd8r5RoMUM}bFjamyKX=nfBX&JrX}Ur~J%En-A$I0L zw7s8)`pN?s>yThnCdtDRAuBYfwVAz!8v9K_u!Qv-%?qgB?1z14ZXJIlBVKl;T%YQV5yg zNv9G9OI$5EYbyPNCO?fd+Ei$i`m$m+*>W$u$SHZOX z8#KWKGUE)AfKRihg$S*GOoa3gZTiOw15Eypp5##LtXU8{%GTHQ7KqF< z%$9#BZC{&qcQM3i`wErR0BRKIOppWZO=3He*X8Fm#!`C%Hur?M(4Mp^T;h}DAgY!+ zLiu*x|B!CjOkUc(NYl`gSK_yq1g@@NFI_1I0!ptyi8FeRz24{P32I$qc4S*Ftx7=y z)Mie>fI5=4k9hC3AWcBSK-M5EpO6mdp^UNm|@ zjOEpC^-M}2O|6C64tQ+`tn|(tLtAqU9mwnUr`r^R&-KtF(!*-z7%5un*LsAd&%?xT zS+y@QGU<{`f-IGMvl}J7#Dn%SR&#Y*#^T+s1GYzZl9wh3jaAxvOyS>}`$4zM56Xes zlLNKqkFQE7VOpha;={> z`f0P}+U7S~?dCc=?zH1A{$Q7G()Mk3yw;9a_=8P;TIZ)VR%V|a?^f?%n?w2ez)*)M&z@1Dglk0i^l}E&t8)h1z*CmlYYN=gvOlff7a){S)bgwL!)f~|r$E^l>P<%$7H~n6VgjXf zpX=R0yqol6O>29jtiX-R>86aE(z*?K@~)|Q^{GF*bsafu?QG7ANu_MYW|BG5Gm#A# zLy~H89?fCm^s2Y_Oxk@oCzL6$)|s^?pwjkQ5#m~qqt2{R-`5D$#i4L2=su^jAx~$+g=xQyfr&TS%98e`u+&6m zl4U@}P>eIhHrrYXX(g?tut|?6B<6gA`>Dp%{&GOL{gg+ppMo5w?opq6+OYjh)P}mY z3(B07&u24gx1>F%p}{_bpVP#Bnlm78BD(`l^z)^MA-x!)G3>mCq?z z(4I`&$HcshB-g+4Wf8~h{ug>yzeMIN(GeSp)zWlQf)d8R^#G%oNcKV6{vJ9%%bOBI z*l@DECY?H3-zIdmpDOUda~SvESINwN(vn$3#dB^UtFB_2&7Ze2)1l7*WMeAp`MB+8 z+{fiyq_L@kk;Zh*=uRD!HV{sCXhqbmG9$V8R`rt_uQ+&N(cr`;cj|A3AF zHiM&XXjs}Z_q-oj@fqMVucBsRiN6Va?t>i&?Kvm3=WN|_kSP;d$Z1XWX65o*24RK8 z2%Iw&?tq{O1Xn7n^)`eqd$w8*QmEsCiY*k@C|*{*fQ<$E|3?cyJh4GtsaG0sFf>)F zfP`PR{`2aVwEJTxP@!GK-Rf!qWZop#S~iFW6^wEI)Te=v7dpZCF^hg{4@wdFd9dtOSrKST0cdEKgGmW(FmpAney z{m>~BF(zbpYQ_zEvmfF5klpy|`}RvDwO_o-ZOXjfOyQNe8TB@pUh3P`_3(zuX1|Sm z(cYf6e}tzN;O}To}fV&@UJnrZMgqSt|0L>&pw)8{ zn5j!9{(`y?-2MIPGnani=F(4ARadA1+AymZk}LjeRF@#9d7l6Kvl67j{{4DbBF{!{ zKf9{v+9Z(VL9WbZV3>~2jNDO~6CgD-1&?S$U3%Z2=u z_DdK+L~D6J6LE^f$&!)`C#-&t@T66sQ6Vk`d5X;-YFMVqzcUHPD~&%-6@ZOfW4Pu; zU!wkEy=QZ@Ud-d_I_FL;MSI@8D$1_3_aL~i9fb1A*?9w73q7V$yr_C64|J>62^hFK zeCG>?S*hx8v z*$RJ>W-Ia}%|5G>)v5?cNVXAo>d*!tGJwFGhaR;ctTm+pY{%(=;t_L;SN84n;oIF zBT)SgR|h*3_fs&>vi;)R@f;n#JyYo&7z@X#E>;?e5ZV;%wVjKb_6|X(5QRZtub|W9 zuR@c*@+N=93rNrau`OR~`|FV9*CtKczpig&3Aoqq?M*swPKxvM1T`c1XKe{fz2+uE zkCZj<(bTbg!>Q>#B9m4K2nF)Qe&eVl?X3Q^ywNq|!)%(6QK5>IDzqYcNuhGqnDP{B z%L{8pvDBp;m6H-MtZo&lWtR-8gSz0gPhI$n0TMxpZWq))sjxm%1CN>Isr6dZ_qO0Y z(=!m{wtSX(iMpm1M&!;Q{f9X*DZ)KFv5m{pXPVE*(N$_bO|C?32vM(T>yOH4?TqRo zEgdH6&E&7lj3A6qN-$1N#@567grrM-;=$^**72BNDI>| zVvI0L65n}|Mhow|oW(-A_|^rI)QT)(BIu&ZN(uAzBU)6mz~uTxyy&HAhxNwSQ|m;W z8XY^2jHaE&@aWQniv=U2jm~lwm~<}S@`9?~&>I?;JRlBk`C-=15|-iD)ktT7*SImS z(a(*}dSpnV{UUUw{UYSi+J#p`CL`$1*?Oqyvy}_?cFLbT6jdjykV%YEA~_Jv@j9% z#-{2x7NhF0z=pDA@1V0qiVnT}7%!yv-YlQ)Z8I7#B3$`}wW3RljoDdS&I!f!(0ukz z5G~m|m@{c-i~cSm*w?uTy*z4`#`C!d(^Kq^&K4ts9sdmdC+IqwsiF4##>`zyb|BfI z;3BGax$SdXQ=3Jwoh$XXvErK!#0nJPD^!=u-`=E_3Kg{ z7W?eTp1?kG(wSuiQ@R?5&Q)P=HH#s@5)8L?RoQB*T`1z2H96nAkOI?8J%1QmFLTv< z*1Kqc=~8(X*cIy&NVKKmH&oBcyAYB->|LlKIVrwsreN5SfaDfdds%xI)7t*9uk8gV=FXkZ%C9l65g~-{z}hVRiw9lWjXrVF6?EcYx7sG+{|K9VVwx@yTY6X z#4cl^XvA{%pT#N?hXYYDEz-_*;hXPV?P}<|oIaCIy;cr(v^41>71Gl5j!D)Q+o;GfZ5=bkeuXxOl!%aB#yVu;AleQD zw1hQkNJ~Y4mL}5bJu6f%9@HA0)n=nCWl~w0WUgrcm8FT^i;>0R)(X~*<`6oov2Iq6 zZLCzVZpK&XCEiLbZ!yQ#BWG7f^)9bWmkWg*l~k1*Rb^f~m$na?tQcWZ&()?~qfsfu zw6hmB1BhBkz#oY&R5>q z^ZFY)^KmuydFOMad;)}B<3FRF)cO4BXS6f5f8Xmfb|&4w88CPsaNjqZ&yR+dT93~k z6k7xj-#`P3={xkFC}eduS7+03wkf|WSr%^jc;9__;+Y}wI_2SGO`dmbm-6_I;~V&F z0-NNsZF|^y-#0cV{Z5q%+lezMo37Ok-F%SmOWL2C57U8Pz9r{?84{>R;yKi`eX~?@$khv-u@qd8c8TY+=yjC+yDg zkMY+vtR&^@fp>irWj zKK2(SBYe%J#<%MCX^VHkQKZpg6RTz)?wuQrHux?cfBe5pLw}7Zf4ii7}^Q(2w*U(7iYh;wUT6IjTaEk!F$g=YxyGwL8sbZH}HJen3&xLJN>K5g? z#z=I#Qm)o>KGvlV1NzqlK)~ESuDy}3MUs_IfgH8ZL-_ZL`KZL8?;5xNw}1NV5Fc6i zcs@HcJN#CuBlz=J3EnWo>}$B4TB{vRiO^I4&N zCo$H1SnG<9INHUJa~aNO7IbBy;YKc7zb&pLw{d`Z8@edSZ$*~Ym-yg@Db$IXyi0b9Wv0Ka@@ z6Wn5}UVn_6}V$ zX$g(`r;blMJl_2A(Bm%Q@LRIt?$zHxX&8^M;dFw}Fk>0*n$r%iTR$GWPRc(1hH&ft z-9FP^LGLj8_bu~;K1$oCyS^z(O2^p8sdY|QIr)!{pBE3}sS}T$9F%66o2(mD_bJ1h zXU+#UPQw_|yx_%GgX~q@h$zUx(}7+tpF6$GEw*-}G~Z2{kNUFy-zR&*ZQYL+H9AG3 zY!h?GU0JdeqikUnS2+sc`47pSAP|jonQL38j3hc|t`G-r9<0#YB6h-ch-MQNDdY0@ z5;rHrbUA2!G+IyiMMz zLFOOU+#pnS8enZ+d`s5398gpmO$d&@Ec_ff9k4Smz9rZ>s8w0Wqths&vvUx?m92#x zvXSl*ryzS+sa@9J8+yJ^^edgC+~z9F?i0h@iNJBnNU(XLww;peP#jjQ&$pcha_R(d z(?9dL!4|F(M=dYAJUXNOIY`e@OL<1~l%bn>i8%+GV4L{$&eOvpST{&Q4IbOM#hk-> zPR9}N6o#nHiC9dhXq5TO zrhHj?kkux<)Lh2wX+Tx;?i*ia>u_AJ5km-bW!UPxTRndm{GHF-4_t5eQRLT5xbyei z;L?vW>v4+8wSnt!J`OByGug+xz^wj1jp*=%WnD;PD@fv%@M-=oaqwxc_OOoj*5sn{Tcb@}06|m=j^|nfrvP(^|L8 zyJQS|_Z%(ZZLYjqj(V`p@xDANx1m&D|18ZZV_y$^TjQhX>aefQiBsY4JuYvYZ{7|O zf{J#GTfv%d+-ELoHCCuX-*kQ zIq%#Z-vuOU!`r4ra84YDCr^{VbMBsZoQBBQKVpe_LT|Iq#nuBT-XP1ZrWy$bUbC`;k;socdQPY1UwBe(;UPDgT^wfsX=P>ua6Ei z!^WR%8*_JQ-^9K0i+LaI?h~3(J7s8RUgpmNhHjMw2mU7Y2S)BO4~)LfbsSC^yeyk5 z#IsQjE5&{P9QJoP4fyGbxnpH+F%zGa{)+HKw646G`Q-6+ibmr9nJym^;y#4iuainv1<^LYAchqHN?Zj**Bc7`KjdD`J?-eYFhYi)DcO2cYBboya# z;B41y(Ez8N5WR`3RDJyyA1x^EB{4TjE4SCblI(hM`Mvt%TLoct*(u`>42+MJ`%|8C znjL>}{T!uu9~TUlH^n^daXN5DVg7I$Xg91=JnixM>G}3AZjcBHnTQOF^`UI@txxSe)+Ze{WP8mFn55m)l&Mt2ke!y6myEz$~ z?v%mEyv!z}JN*-%e8J_7p^;IuOaY1UkhNa;e3N+ z5Of}sr&ssNMho9ko(q)a-I!w8n+!V??oF&k5fzkC$z(xDiJ4#1PdQY_wQ@X1v0Qby#(}C z_J{D8n0>j!yaBxQ-SPsiQ@)6gJ8iV*(&`S;Ig}CdhC09p9Kd=(>|)+=zwbC$3A@Af zmkD*=sd475vhZ>8*+&W+pqx9@1H~MYr4Zkb9f6&0#?2kdr%`elLVxt^YtHE8_c`@ zCc%E&NfBP-3$8A0p*qTaQ}_FXA!OO*`hfVR9Fk)D5vsBT_V&S8kbE;kQq1Ko`#w2e z%_%ra?CG379ZtSszHtDg7h5l;>k5aopZjOSTz}r8q?itmf3)4lu!y-$Cj?JZJLe(6 zX2xPs77v2LvEpzdy=n<-u6q^Y*W5K-@fDUk>iw)xk5SK%fCyM z?q3+%uKK|XYX;HXLGsN8)7)wZ?afB%v$Zl?x&FH6CjUZ>F?XmZS`D*76m!LLM2*7! zcr)vf*=wC!9ih!&H#s%TR&zOLfB7Qc&!v`P{!mvjZMHg!`9j(0ls#Jw({qPg*K9T%kvev1XH^Tcr$K5Q=*Jv6XQ)Y0+ z@~b4}f*bIKv4QX}_sKTGf94Cy9&2q{rR?73yBV$9B~bRN$YI;ilg$(fJGcSgl$pi? zzL5FM;*1hCk#&EvW_lewyx(dLb#0CiOwV3y($@@93@h$%GVUTVEFV0Y)XO=x&R*RO zB0jKKY@*z&ox$#I%6i4(Z|eIE(+h=XMc?wUVV3II4He{JrQSBZ!khFMeBd@02P0HE zTZ7lD49=eqV0wkTz^@7KO7yjdAn-%X%+x-%scv;$~g1*e*S7b^tcKBH*|8c zRbBBXs=$fbhwVh*XigtOdI#ZQkseN#LGd1R026oV?m%*AP-4@(O?=Hbn%|rT8U(-3 za$IEN%_@g`ll5w%A0LcuK<&+wD#B)TEFWPUgTnDp2t(hrXZ?`QJ_?_kD`&vjfzBd1 ziyd&`;aiphHOa-iE);UJ67hkZQ=O?lJ!le-kFbLRKH?ZdC+9@SpcEpbft}Y}tNf5V zSO}tp2~iO1ZuggyPfw~8C6KhUXPt1SF7n1MBTWjP>9a%q>l|v=2?m0-8<0x}b@L5t zWxK8qsa+vMlGpd$@QQ)vaPn#TdPt80kHj9(BgoDXwl`U~L$}o3v>s4DT;kH<<`IeT zllN1CsHtm&F5M;W$m)netVo)#iU2}bfH^Xv7?eGltWH}0V}xfmf!fUZ6PTudbtyv1 zKscP~FNea9P@pHdyI7a~-%(+FeYI%%KE(GGlck7(yE)fuQ23Pd;4ipTp9g;6*M z3JP4=-;W4mh}R<%orhe|-zRR#K6!&lO(-2b5$NqxlAQFGUdAt~k@i)k9F}&D22JR9 zh#Y=Ot++h!XfQk&FbsV;zmWp3eKY4vbgyd|SELbsV2WjsL5viV{%S?)=zIxj}NIumks*`!9m@*oQS4fpc#}%z#g^udy(FEB;|B?X77v3 zw!^t~!~O$4l6Pu6Vr|f25qhK_sEfZ8`C zmzJFxlp!PzQ80)!0XP^oO?%=-Y3twKq#Q0JP#mykRMeo@O(H~0Ah5t#p?4Ac9=ky85Celns-cC|z$C>moAKhNSg3VOx!u3Os`ho9Tn)0)in~ zFMKfBgCs-RO$aPs+TMwI4MjfIGyagvRs6VTf4L>7BGxZwx9*~mD!1^vzLFVSgeY&s)& zR08s6`BQm}g3*KP-5vDv7&_MWLFj#a)eKxyqW=L>hkI0N{{naj`RJYi0GJysyMXQLm z=~MtzLD-dJ$B}t4SRFU}lh5e7XqInKtv6cxxIwsd^rk4w5Qwzl7>xti`tNxO1*IM^ z1f;Q5hu)n;`a!Q)K!SbelFjYCVj0(5GmQ_h?otggQVrh0OQ>mQsc$jtNv|SJ+$E_( zZ{$EX|5&i_q74=RYzfChu6HVBr|yaDIgUf15EbHm^Krv+^$!m+eMt$2$LXa^HBlAC zkk)jEf)1-l|saS1zQ{l7Z_2Svf*yfYo^;crwVC?Lv#IbC-5ZGqu|PP!K@>9!3dD z6Fe9U9|T_XFthhP#t9fk`s)1+!&puQ8~rk^JUz13<}uK2Xwbnj@IvEKphOm7S$)RF z2cC`Q3o-NoaO*g9%pS38OFhtT2Np817U_}Gw+AzZuN4pqP zD91S{?6w_p7P#(6!sd@x^j9?ZqIx@OmvDsj8|UZ)Jkf;;J-vL;bbQDjIPdc0Dl}V= z{Ws+phi+m^&MP6%6=*89b7NrMVj6^Ac4LxU9)iVv0!xWhD|aug-zAVXYq zwOZXB)~DkmHsGj;TBy)XK*S4edUUg_f>4&Q1m;|bV;6l>4SCM4$y&f(09tu(NFvvL}!2@>bk(QQE#|-i%NFqE)^WC zzRJ=qbSxljQsp2@5C24n?%1j7+&8~gkj1FXO}cX_h6I5T!8P{SjXE>-1X0Tq>akIT zMyP9>R~1#A8Ube&Xy$-}fEN(J?TX(3F*~cCB`V$S5&%%dZY)EcC*~-d3eV~9) z@kv+9z=d@YSLupg#!&yYlOhd-`_bgvJ*w-EQMv^4Wd?Dii_$}p%QuNDpu3B4ta~(E z&IQFfpl^&6v~Mv=85cF6quoA5+PD}fOU0O@A6lrce~vNO7H~bh2cHoQ*k^FKsdqd` zcb)9OqS9EI!BBehVNf?DSM;-R5O(F>My$i^{*u|{$u&h592B+~R19;*b-u5q*q?m9 zSWR(Mr)Oof+=?k1siC1(YqEgT&`lPg_-aF6+`*<2!OC(Q3-nNjqo)`hL)JknZr{0i zjEw2GZ~_F^7CSRH1>ha($I9B76+*e%%jcRA)1>UVZJsXiq0F!>aAq3U%%@M9gOII-cK?L3R;*61X4TcoSzLG+gI@^Cd;1?l2{VPkn_4>IaSUt~w#+L=D&Roe zt@};k1AbU)5wXzvs}pN4F3&sJwu2cG>5*4mq8Cx7e8vc8(v{7IoBFy4)@R1$Z8zyL zQA%HNJ&3cI@yCt3N72t>-^$7@ENWbD^7e@8yE|$9XU7A^@lNbA4l&Zx*9|)tqUIt& zkrOUGsMMl_x<}e0+EOU!{)YYi6&RgV|Be45F8h5auTcX8Uj7zA{+0a0MxIa3z{-o>ereMxq6?A~Yd?qP_2bB+bX^o4TXb4-fRA|ZZv;R1?-F%fc1hpAi} zy+ceD7Z~;X2?aVro_kZlev8$CjMgtB;xAU!fv$+uve7=;5GlwND2Cb`#F_j7TI(kn zIIK9}5g~(e!-7ET!9^dkBDz`5TwcI88`1)z&!5h3PAfZA9d6O($=xvo(jP%NqTZLC zF)tjk>0}Xx(QQCqrWgF&NQk>an?VCZ6S#z7ki4?~NueVB(NLg7hyU}jQhyNQP!4H~ zdBUc|e~M8*FdkR5ZHrY+H(g_JBkFflhKnG$#5@1(uq-8XDwv&EnB^5eKE~V4!UoSL zwxTHZEPySO02ji^2=C&fH+?9llA?PMn)?=928AHmqputqC7auk=(mUssP?P&EC|j) zm6JwJW?=hiP;^wBQucxFpGyi(e^Dlu)g$f)>7bJAG)3YyO!51eLfbb6HcKw~Tn%lUsCq)M(LL(Be=!5{#L_ zFYvhM!LShaKu|5dUYA(-+-#nX^m2SV401nFr`K4A4v4E4pq^ALiE80F@|1_O+jjR^b_~xB{#aC$#Jn^a$IchHWq6HzaKoBxSV)7GXuWn zDP%?+FcXGF;98KkSa}UFh>F9B-jN32AJ7#tNWlKbat+9CfQb})=BfunfMICa8k_{WfArk_$Im&#I6q) zExIw`fU@m|M@r5Y@Oa?;lt(OuG4r?q6y>z&%otu$L?A@H9c<;Y7>M+UeCZDmHIubU z_1ANN1aXX+7uL1G%!8?WaBW3iK`kDZ$K3kyE*aNw1ZFu#_~0H>Bd-?YLSkkVxr}Fn zS3e@E5cfEh0ju%N*O_@6yg}xKC?e+iSt-JB1TvUD;nB|(L5oHLcaaplUC_X^w@(6v zz-NCgAOSYLZc-R2uVRF!9QEs;AfPqr074}}Bc^%FSFv%HWHcxVzs_ujdT+)Ojs@W=7{ zg+K%)n4#zFRyTr!8ic)DcAqRhiXI3(FIpRGt`Suf6#?@ZMLob6{d27F@ZLxeyEF$B z;1tOR&oH<}Nej32SI=OFanc4m?2jO(nR z$2puUJm3gaF46EN!ETfbpI0RF1`$7l<_Npxqc=kkHJ~Y0eBWGX!n=N>;Pv&b_ev!) z3=kJ4Ah_izxT9ZS1VfM>O~>*bb8m8+8ezyn>}0#Hdxw0|-;Nq}!`Hk$*%Z5vCplg)jWoYS=GKn7K4{ z(-T2gbO7Vp*0sSA({#Hk2`@7t7mKlo`;zO5<@=WX z@f3v6AfqQD6`S%aRia?PBn%= z4Faw>E#wG7|H7$XDB`joYrz35M{%5$%7elnK?T>$Pj&Z3AIqt2CP+f)Vdi;42A7SH zZjcu^QwVHrhFuWfynUU z@Y04a)$s)p*(fS4hW4gA#eqSBC*WZuM04QOfQcfsfvo$*On|PKwbZ-EUbdUshg^E7A}BhTPX(`ir$l4tf> z4_#Zz8kcK@(Jxb2@N%5eiWSoos-N9%p z_F_7(mFq84Ft}m7T`=Hmu~>tEfs3`Kb`f{{#Zg`18$LUm2I~goZ3_?j+kpDY;y+MB z7>yW9*c|NDU>eM|(krf4Pl~!Ra&6$LFf5o=ND4QM8F59>u9MGE?i1z}s0kHC)#3!= z_f&RyKhP8nOHBHqD&s;Q^(klA)him>jf6aN2for@P0>FK^bB>QD#BXIz~N;&pBeUC zwLLnQwhpRWzKDm`JvbJn^mKzWwi=fYgmTnX99j0UW`9zY=>xe+7gfT2NQ*Lf6Y;?= zJ%-xj>piyo&`b38RO0t^n+Zh6pONJ?-b*8??#s;)5@ftSq%c`>70-7Zy!_k*K=r(Asc z!1dM^3Xg$vv4XlMWjc1lL?TL*T;5z5amFb44Vz{*ys*8}tW+<*Nhy z9SScCy1g!l(&yU4q=XYI7HYsFFcN$M_fT0FwCVi+0DBX04P1Xn-(h(uPx?sN>2MLSQ2 z%&BJ+OdTq4bVlFVtfgVg#rC)yLI`(R854A8sCDIXuXuL?{!-M&Et)Nd9XafiDzCnf*4X~GIEk4!lt z!L%Al*BZZq@xd{cRc^O;_l=IZxNMJ-fCtIx#Z3GHvD+)s()C zgl)s4E9)bpX{)tBcdcjb_^=(jB!6dQw9)#D%4o%s9<}4+c6^d2Pb*KhnyVjh_-l$h zrK{{&9_&^t4{)J}Y4%qf-sEuWLP4EfGL&XNQ;yvvZBftCEUVP(T(sWN#bUomv%P7y zvCiYyhPinl&DPP_&ncIvDlns43JMijjfZb=P-BhO+Z=w$;av{zad^L1>h0duyS=OT zMy;lakdTdstJWLdh$;*hZ|2RmKI~XZ_6&!xc;hs=@CwB)p+|6Mhhub*p;joMLzQxroTpi(Xh(njd zUvPMs!vh>z9KJ*5>vU*`UbWxO+iJfTE~brY>OrF|+%(#^SfUV-w!usLS`JrO;wC$;v*Q}_3VV(A-JzF9!o{I*alolU z%+hEJZ)paxx8Koi_V;HP!NhJZ>fP62uJ+&cdX-I8Mi+`wKuy|Nr-z-3bZGsQtF;_9 zizSYd^cXzcdSb}f^BKVS;!xT;#v=|L^)+q1%+*e~Lp&o+cuS091)!M@o$l4AK}dh`S&bh}7`hX-_MZ{q4(99kTDbKG&;dt+o0nPaxGU z!`^+m_jpt6@uuD|wl`PGuO_c(k2 zx<1s^RFZdgib2nw7o!{`d2tV*SAchFP49k3B`A^hjv&ORNdK9S(@jDh#R-2?RWY0r!{UJO(f*5uP;c3>gn!f ziJBB0wI8;cJIm7D=>wz5P-B0(yP8N+EKYaV#)m4al5}^ymQ;rHJlnc38TO01Dy!(p z!bGz6epPsMEE!H)-s8Z9WbcJ9`H>NApRZfj-C)9hc(rt_V!isOpQyc53Vk?EN zNVkrt#mZ=t>lJD}y~6UYps8zVrE#snd#(3yBuUb3^k`efjx`}w*R?7qHM~S1=IdM;p^i7Yf=OjlU3ZD2)M zSf>%vSp8PUmOiaCqqx=N=;p@*JX`a)!D1Ey;OysJ*KgdZLSM1xdpCv zvs-v$9I(JG5uF3-m1vhs$f>K`91jot_6(~gn&;zQSxjJvGSQ+)D|=QqGTa@4gx=%^ zypckF-4i@DgJ!QfUUO*j%TVg=LaDc7W$zY}-;K%d6_Vep0`=aZ35~qbog`acYc?M9 zW#hf%)*CUo^+pbue1QO%E_;b@#>6*67g`^N#FWd>h4%}!z7KL*9~g349~h=a98)8P z!)1=cWp*>}H{*7**l+A4af_42NMxjQB6@vG<>fmCZhF5ip#<*KW22IAy`m`#?nBitPp4k@fz8I{ge?(k z`_R6pM+R!^=Q^pew{)V3vzw#F2V#x~MD~G8$?V7fU_1q$rJ81&GS>>nvLe zP?qXk4lyriR%*3c!-lx1V3l64SHM#1b-=Nc7;(1{f>t%fA)Nij5P5}V$*vgVnenP* zk+baspvlvuvaKsyO;(7}(IXFtpOiD(DppzATp*D_W<4Bd7+O#H)5$dZJ8$Dvi~D#L>0$npNl8o~1ip8`rh{RZJF<+n%njqm$D1YOhGu z%fe}BU>Q8&NOaKosZvCZ*dn!>t^?&}J9}f0?KF%WaPSV;&E0-;x83aXn|*e3o8R1K zH+%eMkKOF@n_aq*o63z&_T(0Sa*I7V;!lp)%^|-zWH(*EL5Inm^_#!28)-Red)RIm z6Wu&uH`0#Wv_PtGA82d|MD#d#NV7*>;TRc7MN0^`UR74<9amC|n>B>%t-@H{MY5b^ z;jaCreoLFe+S^u9`)%o#JdbMMtAVR=LX3r$mi4MH0JGHbpJvZ^wqv@o1~4Si3XNO& zUuj@73QV&xbx?Pbk(eS6`bttC6MI9yY4=yN-b)*52X@(G2cgi!Kn5d5) zI!sn?w2w+I8MS+OqAKhPEtO@~so!8~#3CXR(Si~MK>K}V(UF^&qrOBC#alEoXjg@* z*pOy2PD&j!M3ImJVwQjyTs6^Fx4Bq0`;?04GTm*Ki?G<}Kcx&)&PnMv`4=Vk}8L{jTmVwbZTGD4J?@krJ7F*1Om} zd{lK&Q!iDrRIO3Vn#jyZGE~WoR7Pg8D2fAim*m|af*-)b7~2DQ7w{NZz=mhwg<)fD zEMUXH{ul#mV+Zh$wJ`(i0Bc~4T^MU%7x2LT&N=r++#8R~h$O4Ks>M<(nHh1P=bn4s z_gwiwL>4P7Kk$cYZKzsAGGWl7clg6UuE`H*HF$Gbe&7$)T2!?b<>!?8IVC^eRzKh7 z{uU*f-4NB|}zBmN5#DBSQbX-&8U zp%23N>I z4Si4mFgnrie~2E{^suNW9p{bc7tyT5zvqNKJSTD@5BlWEFAF^+3Slljb|=X~zXr~L z2!bH-SLmKZXTAZlPH$ir1P1~M`t`|Igf`-dyu$NSAO9n=bI@P5*ev7wYrk^jJLZdZ zTZWDf-n=Yx`*`_PyyxBWS6ElglGof>9i$2`fDnSKfF#R zWODgJ$m`nqt}2`DD>K+ zFTMQg3G7Mz;3N!9Upn>ZD=1CRo)^0lzCAOB2UFbiYtl40H6DQgVgipQ2*pUd{Bzzr z2Y-$qJnDl#Cw7bHnlb-53D3l#QIf#~wL6;FUjaeT(y2#t(3&Cd3y#m?2N(%9(&u55 zrf&o`52`;!ykzT8QyYh!AR_XR7qt4_^{&WKrsKCsj8hC&5-=h*n(s z6g_dVO8=6!yJo_e(?28#9Q?!R{lAXh>qn2qqDKs;kN<+IeEb(A(L7Jao>Pz3vCFX8 zJ_lJ2PoD>v0G02bAgV!1)L(**5*t1R_CciRpYWfLJo&TFe;$GD;N8LBlZXEy59<%{ z17rL{{_#ihgZ`i#$;kNgxA@OTv5N%#pvNw{BSCI_;&p8ZE5BA=9({pv;qTxFa0_BSQ2?06rBC|C#eVrG zCow=Opzdb{!0w&>(5g2Fi%B~VTp?B{S(y~ znVh8DYX^U!JAiR1D)_HxJO}?84Zgr5`vN{;f#J_r`ST@ue(>k?32O&^Ue*mk*Qeht z{@miv27i9YpTEza8~7yEol1Vd-+TPo;ZIr^sOS9oYySKNe;&}<{t#cubBwPZKmEtA zKF5^KNi!jVnyb=~Npz;qYy5dx zUM$L=Df#m@*P$6h8s=hur6B`>08b$a2=L?az7#)zZB2fhqd34Rjsz(Y_C z85zFO?~neJ5P$o*6JyUI&Sh-uw_#5n+xXmT*sq=sHHRTkV$L_QuAZ;qJb6V(iPSL1(w?Z*KLR|KaaCH~e}x2!m#CY;5wx*xU2< z^RtT!XX?`ni?iA_;6xyf*a^e)sbGUT?Y8s`hL2B7C>; zlb>J?D<|Lz-#Gc=nitl)KCjgqcf4M|+YTMK?ReXr-mVk&x_*0e;6i;;)o?o9;DO)p z8jc$}e!J7}#pC%#m5ZtYotBEK-swpo5KWQC_e$cWJ;X0cJJP(W|DI8M!0g_X&eNm( z=(Y4z5B}rZU9ags^g@Sb%Cm8L-ou`=FMCVHM;t;Mypy7v^?w^#{a}*4*rIk4Ha@G zPWQTf58%>Jp(XO$4ZrU8fD-090+2vPns4q}=1es)cwXY(ZeWaj07_r`0c~O@Xy&b` zf&}2tXiGR1ZBn(W42SG3Q0+G#=N1UL`9p638Kt=e~ky$h~sv5(kC=ye}JoauTkh<*>i2Dga~_q#3PLaq}F7S1}q z5#G#=S7N#4t&MicREofxSJPgOAd4crRlP?fMoJwX!Sv zwjMuM&l&!?V#9w`4L=&m!QV^|eI-5gy35*83KOsOwp$8ObrD9(7#}Cp=vSo$bND zI}zM~UURFmA&m$7lY7RfPVSk7_w9+^S#}KZ+)r+Q2Uz85Rgu&o*KZTW#Iww8*KvDW zP@p5lZ~#QUu}sE=ZMWA0X-my^D-EHk>p^fobow1qPP!24r8=~5wo-K5kaQM#*ND;N zw>N_2eh=FtG%lNXH9KDS4;*Bc2KeVN#r-*6^iQ<)S*rE;deHDI0#<~)BI zVzjkZP;(k=8K@C3i9}O_r$amigj?Z9&!?x~y&ZJ=AmGq2ou2zJXb0Q7N)f5KJo66P zjx+@jwQUUgbXakI81$Vwv?r`z)8FiOLFob~;BDu&TDwjF=CIR+^#Z!54~+;z62=k( zad*vYx_yv2)$vu*-k60=?BN;zoZp{1?VdezX5pN7e%f{C&rL7Z7ToEY+c-PjoNb<+ zYo1@MU1*;B#n}sI<`*x_FHE~<+}Y{H#m3xp?TlBSKG!@~Kiin~>T_pjPfv*=H~GG? zKCe<=GI8!Pu})v7bxME+GwpX8fZD;|H5&TTX$79pficMMIkjEq7YV&`_c~xfs~tg- zz!rMFDQ6py@L{k~U}E61=%*Fu$QY0q4K&4Q5gOE-TPI6i+#vN89{d-^Pz%XHzbGvR zHDo#ZRx}m^edWT(g3%JU3l#}%$N;X7GAn7KwR`cgM5zfU6F#s zwD+AQhbX)}0yfjLNt3GomOQiR<`=0P4cF+{Bqc9feb{whV~(N++e1Ttke=OwIXfmB zMo&YhIKB5hP@3FnUJbhRUeES>#tLT6b~0nOOmzKrz11f}C}9hY@&lu(*HVM9;V_kg zLw1|MzLxjnG>E=g^<8cSG-X%dLCYf))(oA+5RqcmpLT zCeK>KP8PO@{Q}cH?&2ruK{@$@VmqBNs<-k-b(Ktd6O*Rw^;)X5J**dHSlr3Mzmp!= zg^jM;4vA-KUAP`>6RjtnjpZY1l;Z02&KU8zy(+W)J4%zdjn^?K)9=7>sl?>G0p8z| zXZGM#StQPY_7 zxAv~07+K-tnd&EcesEbtB2VW0UeWV&+iq+3=ic{?3NOSR*mIhqZX6yU6HO2b@jAdi z6Kpe)j7OX?*Eb;KklB-zo6wn8dm}XFwy?JvkmsT232~+w8kHvY09w|i3$z&nTd!<9cwfA8 zP6%IC+zTWXpttYB55wGZqAqPa4}9054!AF96wQ9SP9D-prJ1o;>kCxE?q>O(@{a`l z9(-l7LqR#w;z{nnp9Y5$$x1Y)F2oWB#=m9Y_HR`gQg#6ms^ogJVF5F5MVjI}=45(b2os4Mi(}eb7xAK93F4CYRm8e_%j!7=!%j?Z~mG974qX;1Ys6xbAIaVeRBK5?d1skO}6WrI&SPb<3+m zA{3I`(qv55XX_kmkwA9SqEy}ftM4dtPt_@vjXCt4^pMWW1g`H~tuuLMzmI*sR^ zu_7-T{n$u8M`9QGMkCpsR+I-U4)ZC81sR83wmW|4WhekM%fd{dm^ko^_Tb@dSi&Gb zB<0xY?RHFg@Ga8qG{vFs*Zo@8?e0$O(GM5^CNCP(cuqgH=kUh+eHaB4$KkF3gMR3l zlFRdZKY*3ygY8y=-+dGMG%P7Za&!wJ6F|~lP{TBSKC1?2_x{@(*pb{Tpy)b{px!53 z#3P=GIsPxur0m*X%dH*uOf}}2^)O6E9DK#93(22~@KDUH{M?2c-cNV@W}%VRd0S+Q6VlCR;Hq>Lp zxghi4DMI1CF5Q!!&9Tmy;wHt$KpiDR3uFsoceMN=Y2C7r4TG4T)<_3BN?=^2 z$`oS4yFNzLE5>wl5OtjEW^~+)IzISidhFjZ#}4z95m&DQlcD!1wGUUzaEDz2 zcyrG*sJ?8CEYb9e3J0;-IKfIy(FwPLKEg}D$7SvZ|6dxv5B_)!iccNvTSJ*iFIjqf zTP_4vzz*a*5`O?xhAE_>ZN&U&%WVYfhubhML{uHTz-ktD*!3nPLg}L!fNI1AP>-yu zQU9PST{dcXCP}!&NJI+^4y87fOyMquNzWtXn@X(B{MzY3O&Luvyj)t@ZCu z{?LHtn|Y;d(7cnRR6GpR`oPW?)7<^?o(u-NI^~o2W(;Yfzz&J88Y8J?bG=`YcJ8+Q zpY^>|ORwwaCe%LqQpR%qS0h`H2=!?_S@i&Nw*skR35*gGUUeLusJaWd0kSS zNU|gHEVlec#aV8{`2kl6ycwZ$-}5?zYg9eZ$^sj;jg?)^TPN%!;dBv;)pVYWHWPXg z+V}S@XT*!f3wx>GiWC+e18Wd8H1Vz>fcCy=GB1cfb2n)}x!p|whrvg(1FU&GX$3O? znayVmv&zB8={0;yse)Wf#^Z{|w&!jVgiU}k_AT>ka6DCWVo#pHB*gED7s5J}vr#sT zjq;qXX+vu+f|fCorq_cu0p&{@y27B}tt$|kR?!#YQP|C%ikg*aVs0i8D+u+M3F=V; z2Y+YybpBuiD~-+^w@KC+`qmZon;8IOxImn6I>Oed5Abes(4mo#ER*=6!b+u*j?bh$ zqA*;O-hN#DkGQfkgf9K)UJzAz%^mJFr5T zJUddmT@Eq0YP9-#G%jhCJqR|cy+O}Rw(CeU`)OQSh-@7~3CW;g%0OM%&$nR!Aor(| zPK`Y~wJP>9UUY5us4_|2Ktm98qVKkF^OE_-9{jx2;ejZ5i)23ZFI=7+DVrRmg6IMv z3?>17mg&J};xq&6_8y@oO@wShWYb^^2eno=;Co7V&Q-SC-RhEXW)JY}28d{?tqz@x zfyi%oyPDhtg}M-~e)MV@`Uk&O0Cc>D42x?Qo~^30Da(g{h$vstGi2~95@!h zG8xDT0s=r(DVB!Vf23MW;RQ4e-XaW0t#eF~pemLyHZhPIf^H$PRw~B2>QeyLx~idG zM@OK)0z&$MqXPOTeI0I|YrKXIlyp#4Sc1o&z` zVCOHCX$}WA8b2sFQpsC&les5^+Co`>eBR&E!=|Mj7ZX1ArU9WxL9>kmy zv|F?i+65s_7!o%S=|T^|+1;@7knv83>G5P=#No2#>g^BG4c7`aOd6HhxC4!!C&w6G z7tF!dfQn5&VDEKe`}D!TYs~G7#z<}kf{*r8-O)xwU?6Z?gQ0P!2efUB=bLIgc?)ch zZ2`qpFKS2W&8+AL$j?>)waplbGH~-cJi98OvRl258N+}Ot!>!x>OLZKV4(n*)r5F~ zBdVtsUCk{tpsoCR+}$gxyKF#jgnT@a)^uJiv_Agd&Ho)^9Tmo?vTu@2F;{5(j1j>R=uNbWIN2sk%H>>y1sI^-6sN1 z?8B|Kya(yge*1dh;<%ZDFB>?Ny@U;X;^;PpxnR>sG8Ul$HLR;ps)+jA++p&Tf$oFI z{OP16gLE9gi*Q*u8E_Q69sJ+vc^v#_H{6aG+%V;Ctf2Uh`kRcA69MeHk^CY!q! zR>O_JsHSQe>ds`}fZ<6}B;uF$nqQA!U{xb$fL7?$a0`z1q0#H>RnP4rIskZtfG59A z{4lipUe79`;DvRB(&w`H1?o&|Ism?=#r7G(_C!w?`PoQKt9TZsPcN~hLFCOu56kAO zkvjTF3GF6vIQU~mQ;jsR_=XJC2tOQFLZ2KgJ@`l=)Nf=CT?sy^0)8TDwGe{}&1gb`th#7?>LxG!|HjofHnb|(IVx!=gdAgZ2 zOY(-LdQQ~&uF=D*$uT9$+M~Hcijg_mMCp&!4zh6IKTYBQtf$@GCl&=h`g;)ye4hq7 z3^| zTcAFm&$nQdccC*yZ`1*N4p)rJ>tgW}ZV*A`s=@g}4aVhlgYgq?a3N~Y97p_ASEDCY zgukrpMqk!^XxZem#gq5DLBGTA)Hn0xde7UwPC;KNsCq#tSbw_>MT>U^FpK<0;r`^e z44i&$PpwG;JHKs|d4bo6muqOL42#2A`#-}8inKFvMri$woo=XAgDPP9`K#q52O z*u;slHt>n_Mf*EZGRuvBDYEQkL^1i|H)9u{GRPY?Cqv+$wu!&C@rgq?N!=%J8bHXU zD3d9FFl#9)7;tsv`w=TlH|BJxI5(6IH4WUPnAYAQlZzD)d&SA$p{Bcm%y`VEFHW1%~UgV7(&h;_Mjyl{MYH#_oL9+P!_+%3mz$} z9BU~$QzD9!5Qg8zk)s8}XlHW6XzzB+HPL~Z2mdTR?t@>l@R~j7$D_OajP`>Ko)~Sf zm;*O4G}bku2;q2fZ3TLNQXRKpo$#xBx#eu^`A%HUAx%e{U@1<7Phw8!qmWhxoq^i> zTs-V7?L7k&2mfovBE_Ty2%BkqKeD}6fV9k-R{xl`M6ulY%BpcK!9-Sl^pR2`NvY{IUGW3{lFDrbt=Uw@ijjPJ(LbhLHV z36ck#tB3theX>`H4<^Rzw=nJQ6*@H=#t?&=42}27Ho{Z(t?>4j_sm!J@V~fRuOlc- zPMl%@)SVg1`r>*UgYg^GpcGK36}jPqU!{Taests- zr_y;=aYP2SKpqN-T_u~Ggscg#ROdO>dFB{kutQR4mB2v^kcdpU9zdaFnPF1-K6$-Q zvC?6^x2Jxar-4JX3^~x@mc)|bq_*QG(uDX6GDsSh-RrBSB+~~N%;Rk@8cS?fdx-`MWb_CzO#8?4QswUL zn|6g)@I-rushf$l0^h(N9=aF1pS>EQi1``(~5fU7QIg(`?a ziE{E)k&`dnZPzIq-~8{-jg1|qF-q{K8(XBtp5x?)NVoXK6Jwu$7&cy5temSX%$`RQ z!?CgFPmFzmP9cwtRXJ(n$>#}M_(;^sRo&OB+}9v*9ckxZIWhJ-Ks-tY`ZAxwyP;AM zjOD&LaY~Yhnv47r5{4=rm9h9_9HvEb^VryzPmH}5KZ99{Lbt}o-jH>Bj&xkYi)Ud0 z_cp!mH|6+MlCN)?^mep*^Y$St{6o_-01SU#Pp=t<3SlzMw4RFpi{P z@XEIPkW3KTvhHM*dC7-p;bE}}-6t{%yzYm~jRzDQ&=4aU<$TSAI2}C+zn;;=b4ZAa z6OHSQ@r;)zNngOqvaevhk=b&OU=Gt#YKC70W#0&B=#VaPi1rQ=NPxDxHLsO97liBU zNWpsueY`>$Q8Rmle7N4o#2%XEdgE&ugL#&M%VG4+L>)#)0$nBy+{T3fiZdl$V7VPSgcb0;h_7 znRXE)vsE+`EZkxnErKMZ8v0z&$y^*3n=^sLZ|3t~g)nxfx_Ql2_$`hN04{Sgk!%N< z<~jwJQ*?AjOE0N11i+p*`%ptYNGQH)tH?fy8mrLBS*{^s9W)e!8S0+^1 zZksd8Wk~7}Ml!j~ira2`UAR|*Zsx|V@q6|XW9Mfs`8p^tpa@kF8$1)AF`w-)bF=#4 z4Sy5r92!N@i{Z;%`=|%+_|?X0zp4 zn~HQid*uY;D?d+XRynNaQN3Dc5iZilYBV`e79@?_E&zmd7{ zl0b{GJ`$FK{{Q({Fs=Fl_>4a#?h|Hy*LXVmpL5eTjGN=9f9JHVt-qD2+m*5w(@ z(&|)?kzOPQ$%R!{D5ilFQhF|rHa?%3SQ=k(>-RSiIMHrEuE)`2Kh%RKn8E;rGs1Ex zo(8`(j)xN2sEaA!L(-<05|Z&)o?IG7bgnn<%tWBzHOeUF_2Knv6)0K7B^E`B;eLSj zW?YaVVN8Sv#1CU&7!ZQl2M~H_fJo6AJz<(hd~{l{?M|>WPUhjI@va9?1CB@P(gGf< zC&3GOVT_Bhg8>W;KCVussZ01D*Cn$XauX;J&&9LkVuS}qi!tcwMQRKTgJ>qIaMtW1 z%uxF#17{MGSIf>l7y#uyG%6a;6)q}3N8K4i3ISFU1>-4UMtUd78t7$GgN%LxaJTC9 zeiyU`R2ka6{?%{S2=B305ta&C*nMR|MDsfdA&Le(3_jYcr8_JMpKGkBGZ)nOku^Bt z8=Az?x^w=nBzneEMv({!)Ivx{n)xQHT5FKPDvhrO9>$oRBptf2m!=C6L~5O3g*2)m zM-}NG%|D~^M$qx=GK+#WkT053P9xnM2_HpkNfukXG_R^L{TN<{+lE(FLaZ=vaSNbV z{^q-ZG`D0!`~=WT3^v@+;c>MzR0L^~C{LpIdYg=53hklBE5wh%+5_KY3au_b(d(YE zkMjYoEVoRBSiK#zmx&GKEqBCf2JYq0Hfs_Be1sHgRNkwYG;GI7CcQ{lBGk%p2rcB_ z2^u~W<}=DsQ* zKcx4iV&@qz4kuHLKC#iJWPrq;lKCQcN`{ch15bc5O9G*G*^FtBF2bX1DKVQMa~lxN zBAPpb9CJ+jK9Q|Hg!UcNJV!Q8axwU6B#1DNV6lP3M1#J8O6N-xS8=yqLs6)b)FGDd zWsjLn#qSKd07`H)>eI1QgRE02yF0rJ{d6d5SdCEb7n}S32HGC z8PPQZo)HCB&_BFRYSOoiwJakB{eYrf^Q53yGZkPlRElyAYhb-ylX*PR5Gk$jj{=pH z6(k|`stuvM5MqFgaLX35~Vl+#EOU9$!MW1&4MCu;g@ z5W&Oi=f^_3*kOc&8=zI30q`kmt}R7ilvUc`KLtpOkR!FNOgDh@IB1HnuOoA3B}EgB z&KY+5s|b0%=QnVOo#I?#89NeD-eH=TKp)s1TA{*&!$4AV9Bk&#q`93`ha*?@Oy7s3zT^TGz zpJ#dy9>1<_+SoWCT-YsX5SI8p#WljDb-yU+S?j7dxuOaMuV$v7=;kP=s(x{cF_L zG^^9_j(?BZqC&bT#v%TF$QET&C~z96jh;qr*~G4Bz=?-N+Gfm35Sc8q@Zoj+T=CgINy4pzc$Y{i;fgIUrP_Sd;Ol+3@6u)~6!^-)iIJ zKjnt91%9=i(xFNlJAsr35||o7feL&rAxcif>-{|+Ti9BBZW3XCvzsk+>5 zTn&PhE|5R}Eu1?m2{NM!O}gBeGb@)JHFAara<_{OW!}DzLFHjNu;JOUhQ_9if{+r5 zkY2{DT}xX`gYMH%@RLEo1GGyOm2Sg27o}ElM_{mR7e4&LjL7rLN-Z(r)5~i<$z>sh z0$58;0e6AjilW!E@aOO>$n=dQIZv^OHgFy!kZA2{SPg5XJOs+FpMXut7V5_*xM~B> zI+Qas^57#`M*qs4%Mf8R#^R_+>ygo}Esz`S^6C{3jzA{q@J$|4Bqfkcq>#Qis{_D> zL;Yj_$5%%^-!tMNo`I<*#*O$vqMS;!&pE@BC|u?+&yZ1MwftBQ^MGqbS&I0OiC$(x zr^Fir;S*^wrtv z3qRgFzdtc;{$AXl+*{bU9?i|~PkgvP`QCW6K3T{r%+U5l=i5zV%u%)#YXuVYNn}79 zR}_SjYZ^V47lptyV6$ea3Axmz#6cis13{uMTxDQuA-T=3;BYW9@f0krdf>Y)3RYP& z?-eUpr;Ov3%f9d8ri3npag9s_{oFZIa#odKpkNK$_7`6D%tLwuJD}osJkN?<8!#R! zUT`3{16%{RvVO7#|68zdoX50a zg*7ZHpU){Y%^Nx&B1!l~L0|2-^`uumcRvc*)+D$S7y!F zdseiId&pFQyrKmc;fFzgqhBk!#y55~9W6Q<*;^FLQi5=;QohW!V5g|jnKG^^U4V}& z7DFhvd%r{1QhJmKYpzY7__`)Kkq8 zD=9y*YKcy>YCRGCeTpKg5t6GWYpk3Bl7yK*6qiu;42I$Yv9(1qfFen^vJ zDjXFYoVvYWe)4fgL3W9f_f_UD%$`FIKi<2S4VR_f%x@tV-94`b{^F5EE7W=DKtSWt z4v7>?<7T;WCo^nnX?&dTnwE$`9sIO3ZbqC?yArvvG_I_eYBcCnUN{>p=q3+QLU*+(E9;Zd>3|mFF_6-T+^OkSu?Sm17yH_1aU)Pq z%~_}x>=|61kx|BLrDG(cCs;polAJ4j+({%!A`~$OFkninxV=Rzbt5+sL#2vTls!3a zaRjYhdD!tKN#Kz+sesNmyBq>&@r+f2q7EFvoK<_bkwvlJ1=1ctlk4GCaxfb13Fz(=73FzxM?slf=O8RPaOtiBb zbdX7QSCJjA$w}XYuxZ)V*azA4BpR%}7n!al`bgz{8`c#nkQ!`m{4(9O>mVjrHm211 z6I$kSBX+Xtath|*y{Lj_Hw<(2JPEzaGfbz9HM0npjVy%sAVV5M3!@7GHyc~#2V;vE zCv3oKOChiP;L)46p``{L8R9E3wpZf$Rxmr7FU*%=#b`)PddeA6e=3qb=FUR;!2hP4 zRoo&1g0a+={HRk7cUS*i54Q;4_u5P6=DZ8Fx;Hn6zl-x1>ZNy=G0rOP0w!8wA*Bhs z^xo85%Bo^)OytDu?N&Lgd?Lxxi!a3d@k$t(Yzd1W>q=anQ5YLWdt9>!K0XmW#VAxs zdhXB%=lkLmtNaUsJj5{}^z=ZXCl)j&{+7F`K!YT`rdnJ$Op6>dKd4EJH{J&kcxXZz zM3?zuD3RP1d^lCLl2wPQ2WGh^Rz2u-k%YuteN$kK>EP3;9mER^w9cNG65^hIgd@DTGV`Hv^}slJh!Y$E$M={V8YLLwG1Bey@u#r0?O2 zcMOS+N>Xx~bWxDAjJxtQ7LWM(wvJEM&#JFR2jBzecCpzV_dJ`B6{rSTcQaBv3qoRag-Z5elW z^2EZK4p`DOPBuL7T5O>2_WAygu=3N+=6iP#(8qTNt*h@k zmFF<{W2W9=GL*8Fnu?@iSf%||CT%*_O!GZpqiCj&nW<-}iN{QxM2MK;95Z#gE)CaG zDJRyk&u6#~fcv3c`_=++bqr4lVzV+v-5FO%4f##ym}m!qVIt(9?BET zC<+gbqf*j$yDIbfV>A>eLPoNTu$H7g%)G?-4#TX<&YGK-N zC%n$f#w&6rXS$JRpon9eq>HQFU>m0*#p^vt)JPRRmNkweU{i63pf9GmM8_8K#T5KP zBB_rfV97x&ut7))gR68v<+#19Ttb)gk;Fu8{GXfX@ zkB>rttCgeNG4ne<3egttd}KvV9IYY&Jkvo1nJb~!9{akF%-3y1*gef*kI-S`Xl*0> zH;p^SgdclIp{)WZj4cUO!WdVG**vuYsK!bpJ&TE5Y|Qx6U5Uu35F5Bm^H%&6OE%n& z0eg^fjNnkFrInzERN-U`GFmi@EY@NALW7eQ*>aQJq-6|>08_-;a;4i1y2I@(MzLeT z`dF|&7Oam2>)r^Kvm+O*^K1rJ=;pvq*GHZd#Ox0;8rUU|iQ6%8J0@<&#O>1{ZVA<5 z`GMDka(xH6|JyjEJ91tJX@Jvz9-~jXdRY7A0EPaKrmJy58$YM%58? zoMTQ&NqMZiEmllX!k`*itF*x`rP7%Xs1SblYb`(Af?Py=(@q=uF6SHk&;R=qWB=ms z{{zaD@$w7IT(j;{a@P3fm6{h`q${VU9b~_WkGn^SW9f{&+lx-l<6e=5Q`>bsTodVa z`OIWk=S1dCAU`|A%@ZAZ?M)<=<6dqdr3p%IBPouv?RGktN9Z&W@`S^U{chchhkzrF zbzG*}?l~dS`l~CyoE}mb@rnG2aME$xjTtnyqYmlg(M39{Iqh8G4rSCm_r4tNYJN=&1RB)~b?WVukmy~ZhcR`QCdYlOyPpvq66im4< z{cHqIJK(81ZUir9A`F}c@`5>j5A)*HR4vddPO4EkxG)xZ!_;b_9ju1*a9O3zmLQ##Np zw`r~~zp#Ge_N_Y`%QrWG3_1@m9hhYpJ9Pw0_uIJr!;y=J91n+X0aF(U={|7%mRrLr z`qY~b%=Ga?CL4Ngx4y;jPo>RPdtTpwLn1n-+g}=Aa2Mv!H)q}H3m58((~GtF^V1j3 zxV7n~H+z2ZT=VRibMC_UWQB&^basIaJ1#I@jh2TH4_M=rK%9Y~*}Lda&d>1T%*-aXY`<1Pb2D+ChncW5jq}RW&4<%yoibg7Gd)}&JG1SE zup-TbE-nl9!kMmz{EgEBv1tXdPOBec+!_&OljU#!cv4>8B2*l`9~yzczqX4-oOY^S zk2FD^Y#SHWU~(EAJ36nOtP--bRn(#@=M5CJAC2RD*s5OmYQ5`sdRKVa$A9cBIfAB> zm#C+^VWOXK$M0d;fe^@v;qd(&)h(~pLg8r;WRPScu{Ir+l&b}^s1CUgFp)cTZeHh3 z1^<2v`BB!}pa|P?Ngk7G5LLQ^n!t_ggQCqIYT9CQsU{q|jn}X66iw1tuyB7aEpRFS<>Ohni^Op5N$gCE0G#{;zp*wR0ZR2E!EuGhv|V zo&^7+J$ymb3&Odvb@&PA_*V&e|qBZpLyNY-qv;fxwg)E%rEikGWLmuJ%W z#OO*_tMEl{a?vayDp7j^zY;Y-PkJuFjBg!|$3$X7h+8@9M6Gp7ATv9#WSNe~L<@qG z)gIkv%S=|ctb`XAt+ep!XMMNDS%n~1^tPy*pQ3A~H4SW_HZl!Yu+8{Ei*JaN_1vM` z>pDonsYhz^@D3^KYYH2kS5sZvUb>#*aZ@2CL zocDU=Y8T_$3A*Cq&B|zp)i3DSC9!59W zNM^?KXd?+-j^-A3s3e9M;=?j74ZA5o30o2R$8_4HTs&u{RA8`uTy+>Un+}3Y>)uw- z0(wCl1|Ac#f@9)}qPllYJ@05f3%B_?aT@>ZDK+s1A-80 zwkoAJ@X#nsPAVFj{F9}T?USnY zWS&a3lFG7aFopD}8HK1>ecguB2teJC6TW_*A=dTkp8tR(wBB}$an^4_20x85IJ8Wc znBkpBze>>VynA`3^X?=G>Rkpm5lc@ls&vNHwPaJcv>1G5oVp%&z<#7C+A?ztwZX=yL#y^0tCE&a-o5j!Gv_avg$d-6!8S~nK%-|aP3cxi>mr>D)W~lWz7472 zZ$lohvN2&u$rfENkkdU4HX203?YT-0H;ePMaixJgQv+6X5=7T5YQV|u_kwF!OXD?> zNL3x2ZF8$sC>AqEgSKdHsxb)na(cG|+&-Mm+&FfYFb<)R-5?CE)T9&idt~1sYYiA^&q(4??hb1b=HtgAEK1o-MuV1)TiXnyCQqJpia1zmdg9fr-PO+rnNR18|b)KIL|GccJcqhj(}&t-58PMN=F zFGRf1S_+BqT;l?*)x@4|dVlhgu_zOH%}rj~OE;~bn5`wrMPf#SqtZ>452PkpcUZQ4 zo`~dK0nqM9mc5BRd9pth&v`0$n%3|$HF1nfOEVE|H3!#jNwq%2*NI||kxdMS$vB9V0 z>z=;eK)*4#C_^ZhF>}*K5#0a@4*V_;OLRe_ryR!4&ComGqplS&0X9zep)mm#{R@dq2ICn;W}?fc zgJ{D~3CD&apkyX~ee^ODUq*i9GE;)K%O*{z*$H+)v~tCR5rmv2kZ&UUyx$~AzzOA6 zYSLKAFv8Xt$Tjt#3+=ZDvzynhgTb>43yHEHk@glp*Joz;z1FN3t-J z%BfT=222HZ43<=x89~LQTexAOAsi*?=T@`nL)%?Ad&c3W$>St^$@t_qp|cfenKw31 zK@hHWU5a+&!E~T)Le9eS#g?5L@C&(`wZRt043hjoArCtANOU7#vKGO$#anBz2{ahM zGR>KPMmVP?VFnvBm_&v$X)35W43CSHU}7aTS=I;X26{dAn3*Jw}rTNczldb4gI+XqX>nuSYs0H+knOqE7Kb3lP3FYwU;OVxJfuN$gn0< zN?+j}EW|%HoZ2dl=qpC+P+6QkqMP)FYGH5I0sl7sKe2ZWq-1}}Nyu(yKSOjGyLY>y zqldu|6-73wGg&n(LJsnhU;+0)ojlmEEZT4047ex!rD0AtgY87G2{fvT+-XSg$*7>` zp$Zw*7=GE6_?6AoM&nJkPL$A?EUjt)Mb=Z`rFe=+GGdnkF&7y0M15s_LD8+A-)mVk zMRbycRBh4PLz8dr0-_aAQkx4hHJAK7Vv*jRpyT(mG#`bcj8J=eAwkpjXMO_t12&Uz zX70?)Jyd6Ts^W&7hwp`KVQmEUC7SfYrKn;otP8<~ck&W~M_^J~f+Y}f{rLXCg8=cs z_jWYUOKMwl*2FrIhh8^Fj7W$+!w@D{+zd!~ZWfRg)bo|S$7VUJaTuQ=+k&m6s#?Y1 z28Q!|Gu?q*>S5h$sbH2cq4=rxc~lDNNSjM_t0_uEWvm|ZR4+ZvEbR-1Huirnr}cTO z?ao%v3$ifK!V{=vT`sBc#Q(XsRDDOVpdR$wy*AciNzX!&JgXlDE}Ywb)2t@El-B!(+*4P~N)TY^wTNd-`Kj?^!a5H`g3>NPmZnqsca@F`PO9gV3+u24dW z@kG>6QKnAN(BnIH1712(H(<6vVbMW}c2X#^-Y|FZk04Q#6Gr3D{*M(gi$Yjs-HeU@ zqaS}#n^}lX?mku<)UDUO4m>kv%=hS(*t_hc?H6ZJSmvjm5L`?l}Z5*XF&s=|%7S?DYAw=iKRYwZ*fI`EwWQb7zs!<0weOMN?i& zMF;4&EKzE<&GFb-kpWqy)53UGDZ`Fpy_TJ$I!=*+i?YjxMFQv+ndvw9^aaPgN^RAM zFgO+DN4T=)Z3i}0h_KJ9xF>o$Rk6+F646i3?eZ}?s`5uk9xN{ZLD=e%-1!3t{1H_! zW0DdKI`i&IWn-avgcY+z^VK z<)pd(BpD`+G1Ni~j?KOg&=}T!-41LcR5DtjRSL3;dw~IlUIRxA4Vp%(257%X)k}@v zsG52g*G@{xiA7)Y$pr$1II%zpP$y~;s$6Zkn@L&GgvyYPbrYrfWyc7eme94>C1M4H zr&sSPrnpWqxo(TIjEi)ea;Bs!VrT1qBB9@UA6RH2vZo=E4~B)gx1V8i;Y zZUs9V{+u(Wv_%X;nLmx}yI*OTm(Fm4ip)?lm5J^u4bFg^|ji!KRoDY$x zJj4u|r!wlIZG_InX++r@s)TVQM7yYsktnH8nN4ISs`5OJD?PChRHg=#)=A7bX|p7l z%%>2k?1$Q7sqjn`2p%Md*+iO{m?CHuvci7kxviD7P?k}|Xj8r_%#j}%J!Bc6nUbai zGP}o}SO%m4RRQ= z1iXrK0toH^2QbR+8C+oB(&>_NMTP+v0-27SBv;7NxLSFGOk|&}SmmSoRSast&ZL8c z$2+raES7v7W;rm)0$UFT?M%Z5Al%7o$OcSxt92-Oq44*3Vk(7r#t2r(CbfLGH zKHZFluuFy)^21y0s^`Jh5gSTVa*ixe#=0O1WSf-gj&vW-z=aKmVlcZIm3aSI6(FHx zl-mPCjr_5C>d-^8idtdY7VkH;8Zh}Hte;hvk;w~T#?wJuOhNn5q=OrKeEV(?<3AS3 zd%qDPIb~{--Bpz~>Smk;tb>EUKFqtB z*jEmzBCZy`8=Y>5QtU;BEe<>)M(JF|xfBQ7RS-Tu_8`+Ac{}L#+*SqEmA^c!P@~i) zo>6#rwnwre6`yp+qOgZiKfk#YtlVOETmnZP9 z^Ev-*1kH_B^*ZIsD^)dy2?Rdaxpn1~2O`gGtV}EM!F+an+6EUGgDFd)v9CCSD?(qf zg)$P~^mdT$fk?R=gYJ0UCcFna0o4>zDB-YGn+{vy!0I5XkFymBJe2%uA#IH&Z4J^G zY@0NXH_y~V!!bAPZ-}XK1ZVnhKI(9jd$C z0KvLZJhIZAlBqfnJRQ(EG~=}?Y3kS24p7D@b4Jf8uo89{{kPno?_LjFvl6|vglC!q z;T0u)CUi79pmI^}5frNib$FYX*|Bbh${9UUYZ7p5w3B$B&=pf7%2fj2M?5YKRhm|_ zN0@ulL;gTcL2q=bt;LA&rkn}Jn;)6;lGo(yHA?8XWw_Y@Ek-{>m6r#qdoE(Nu7Ut{ zxL_Lt#*CF`m?93026aaS_yLM6wPE#24~Q3%kZLsdBi$)z5~;+9sSm3y(vE+Sn2CnY z&Znvn8{$M1&Xk=xomycQUHSXo_9nw#P@krAG3yq9C=Eq$Q%!jB;{K_kmMuO8PMyM9%|V{=;HQR9jlE z$cj*q}h7x zq=7{l)btoKlBmVClY_HbuwG_2V-`{CkOLC48_&Yu6+@nm$bOOs+dY3i$x?r?q zXVQd9)zRfSv$ZopakY~dq4T>9$!x6Zat_W!Rcb+3=UmJx_mkuRzQ|qoC>&ryk`bXP zoKvF+2Tt~^2B81wmiQzGo%%PM@#r2t>nkHZ)>ER%PA!z-3h>@>9=M{w0UI*n^> z3jD^lCs#5~F7#~qNHQ1dx6RiTR@ zo{C_Mr^#O`+gfwxI6sX^qqG7crIh6)JJ=*EHnEEXS`UzktkHl4)#%AIl7$`8>KVr$ z_UOijWH~W<$!9WBy9k|B+vgaO1+a2gOV-&yv6PAF@Uwu(!m#Zq)h8QwBfcNILGqk* z!jq5CswU9->=@M&)&}$Z(w@SMA(kTBB$a2P(2grZ{WL+T)z67hHOT^WtDJVpF$*{Y z4l$z4MNG&1w|BHz4np3-2Dg*18ad_H)5&tR@GaD2sHjL*zAM&6YEU6?g$#0ApN9Ju z`Da4pL)?aj0go;m9}<*6*&K1Si1m)THqmHh#gm)MEK59yu}e31lPXH!Gn>m-AaSmlPlq*6Kt8;pE&BT6&@~ z+|xZDIT)8){$`t^#>!Q{h6}TQPP*Nw4Xn8J`#7KF@)Tv#H_?mKdwtTwhQo_kXL=8a_K}eX0D7fj4 z4yKz>gruQ(1CF%Vv^2ppQs7JG^)RV++^oKLBUPOOR+4PT3?-mrO!3f&6JL1<0jo}F zKsvyM_#It!MOO?P=N75)grj&gMk41Y3x@NhhLLYbOb;0wd@!%sOF$$kAY@pWic5@0 z^D@0oDfzI;CYFJFwB4-qE+g)@r(&;R^4LstLCq7h-L87L#U1HaqR3rNo-=rlVM{dn zyg^2(HlWTYuy=_1t>KPAxL4?2mc}kTHGUoUb`limiXwVi=Y1Y4HWPf^9%UsVB1g9@ z!GKFkXg>7kN&R9LA=X6bzB? z5a$6ZoFB5C_Yb>)B`iaSQE)IZC(4fDQ&RDZZ>6^);lYqI*uz#QwBN@rz9SeSCb zM9Fcojh4}CBSE@^^X3G9>GTzB>l{Kcw5p~v*;|@m2M#l3X#BG z8@G_~eHuvjT&B%*i@LU6q`{P&;wW*=oVo$ATwNT(qDb%Z8Gxz?tmZ%@WpLHq76GCL zlB!=e`H-$I(AOOogB3>G^f$pJC?b+wXz}H;>7kFt%1YT2h?Vj7j0rI~OK-PBCKnvz z=&O4f!CvHU7u@O|&}|ERjZW5WEmNrzeyjzc)rPtuA~SH17zF6HNOkBHfoFaTm<_8B z&i;YZ5}r8LH8XO{3%A}B353`x5JPUirFaUuu9_Zh%dJ5=wy)L=c3=_+qeEN5p7?Ve zr{QtXs@=PYgiD?PN0vIi{~41B+JFv}9B45Jk0ge_qeqX(Rl1ZZM0rj*FSl7z;kPsc zH2O36o;=NE*qXR7-VSEi%4)%e5wU$h-ue`-N#y~27H&K+SeWhl%)8^jG%b~|8j6?K;@Vt;#Fw^A7|jh-Yo2sn z=7!(CBPyygnkNLO!7}DOzugFSS_s%TMMajF23M50I7$o)Bau?5OZAL1l%>kU9@T>E zM9FrML32RWa>5EWC(khlAH}K+o_r4~dE3*jyvM6a8KqhZv=g0)rrvx!n6%-^WQojFBWek}b`-!JMo? z7&?gXpiIv*&Ylg~{mBZQVKM7LDyw(zUOt+ zO@j3ntkp2zbPzDdmqwC}#%j1O2Olbr!3grc*JFDSUkQVuMMC6ZXohMOx6*YXs6W+Y zV+A>}ICK672Y}~hy9m2&K#psPP_VC&3x#+1b7C+(n&PN62 z3pE&**A2!`xWR>}L314OQ(cXoRAB*F*^RzL>GSdAeT0H^_?`M@zN8c8*ZplDH&E`W zUJx|W-)@KW0De9l)|l}3rO`z|tH+dD{32*0a89C4k(wreM(R3+1EY*$Zaoy~jVGd8 zNL$JBfTz;QtZwlyl`1~l98BinDG*^7222z`J zl=06W?TSYeDYxQLwKD4_BxaOJ>lI%Zr82MhNHxtBAE|+bBv~G1{0oO%aoV9HjXpsf zqBe@4N_7{vm2Z<&%BvnGCO()z(6JozCJ=>WgDX*A1{;pO--T);UIO=`1Z}rvFzj-p zHh9;F^Ul6FVeqtt4Kt8wp-aJ;SaG$t+bUN}{Ha>_Db=BMUk1g+ma4r9?eyw8^ZHK~jc{^ad20Y&tfiB9AeP8V#u@_a5Eq`cS*vR%tmnQb)=Ghgej3 z;0SM7*-@JLmO^o2P@bI7vDhR!2ILn_;PpFrWSDo>_EFH+fylH=0=n9)Fi9UnQ6kq=qNA9x6qU{n9k*!Tx4 zCC`K{-IV1C_G~s^A}Uc5bdr5A*-i4dEepkoE4VpqSPuG8LEJmuX+%CY*&amUjqp57 zc$LkHGdFiZ^6dKeeI5wR_BU`=QjIfJ4*iGRM_p`P6un}OMFuka zaCQ#=JI^H%+5#A2L}c@iQaMpQPE3W!+OSS{UEsQkp{v7@-p14^G8aq3P7E0I`ys(& zK^1^M1I~v2Ha(;G6nSgOZqv?CC1}2A9T17T4Fxn~o1x90B7p7x#)LZ)@oNnw# zcWNlAf5hLoFcFn0hjVx*7f~i)YMgo=jTCsLtX7J3xp?hU6_TA1aRzu(P!ytF4t`l} zuk1#IUp2NI)&W4E%+Rs19FR3QCBz(VbgGfjhevFf&6gLQb|2{wamid0-ZNy)BpTO{ zSUokyxidp&YjZlYO;AuWibm08*u)__11Xvs%7yM@co&9EmFTKMbMbhB;8I+c5mZf! zgiA9>8OB95pp$WA&}K*CapWHfSd@9c%S+68y9HhpGp z-kV-rSe%=#Ei~t*&z`?9w>Y;j+c;B$9U9S!-5#lU~J;$H27cec6U zdedjlF3e9a*5($bYiAeEPG4xux%0Kg*>iLAv-?vjfOWYRZfs$#+OFTCxuBCyAG`a~ z-kHUPT7ACWoSthg;Odt1=W%sQbNV-RA7H>z!$ytJfA6&(+S3 z6s0#`S(JJTkR8NG&>>~d1Y`09l*9lgorD>YMsR1?As9CU`x0;?9HT_8G$RP(Q@n+v zyhppX3vI#e;-DZzR*4QaHh8W}`&P4wAeV~Bu=qnQWP7yb9T1aFkwK>M>)jv>n!QR^ z6GswdW%#a(9%x+I?Lcn4y@IX@k2gsb_PPwNdCl(` zj{4X`Pe&*97z)|U1hX_M-+sfss?!cRN*5-ET-n-*T0adyy_MC1C)Wdnns62LzR9 zB*s8psnEJz4>p%!*4ssTi;xT~d_S9Rp}@p%xDUxx7cMsug|RA%y{=vid6ydxT$t(_ z0&{8%D*|~rLgPa7paod*!rlsweCz%T4F4vp7`K{)c~QM$wm z>V^6iGc@(SP{kp$9o#2wfWA-@IAkV?O=-1b8WWa=BF~2IxIjn;4z!RIso_`<7P10- zKSqg~QY*aeb!nUEip9`%`2n;uT5+;Lj5cM}z3#WjR5|5|;*pX&ZG^5_a9V}h>UC-T zuhZEtlg|}eeDV!pcrbsb`@on~`}+C0p4Qk~A!qE!i^V8qeOU^u}I8c|sS1 z#P~QgE{o7lQ_T@@Z_RJu2-^+MEyJ4Gt`moA7 z6y}Y@VhC$CkjfaQR7yjtJ1>Mc1Z*wRl&5<#W0ICj3Z=-rY#~LdF<(LSAA9;>un-!h zs~3PbWKq!Ok!T{3mSHd&=9e)P6GIElbgwkjrD0YTRLV^&BDVQsQ;TUMkW-q+rk4Cf zT94P%QrsFLv_z*tJX%YHv@IO^2{%LJ(kGLJe+m`|ViXy|aUmwd&NpVU5`U?b?gIsz?~<~^DfUw1yb5tjNM-7bmBqpQe=G)yI}FB)YO zNj8PTr@^ixh(Fjcc&tK;>pNum(GD-r&UCu;M(#V|n1JJGh2AB(!uny1gff~o^MZVM zdDDI1ZMfn6+ip8{*c7O&dWXp#8HoJ{xMEWi<^q*rFNJRh2SMQI+3vU8EAWbzsZTj8 z-&cuAIRvak-}jKM4MRi(p08_Vuo4*fyRd5O%MHxTTv5_XyNKL>V6;BUMa*VD$P7R+ zX=E^nuU*hjjyPFmGGs`3AoW=+hA|@l1_A67N_H8i)x3rbDme)g_|@c)NihargXJFS z{}3gn=T-oHP4ru%tR1bAUK;M2^ftr8S)^Zzv%c*=2zpgy@P+PCkM@0;(Nilo+;-n> zk!%GQLe~q+IBYh8pjC6bSx1eAYpXnbKKn%n4ayGtj)#nqbx;iQ500TcV_KZ0azFrP@e&B~boWrCu>nUd#HAa&>i9{`pYj4ev ztCQcNWT0*b$?GjvO|jqlcmQ88T5&dRt=+olP_k-5byWeUQE1nM&NdD|;ERgl#zjM$ zI2pi6=BAuVrDCOO9}=Rg&m|n^ygYNMNZhWKYLba(j#M66OcV^nEXQ*D06r^a)p+tU zVCo#pO!4>hLPB=ipZST%!{N-_nVEY*$G=Lc+4ySP_rjpxMMP3iUsB#NUGZ+)$LS`@ z@F;h&xZ9meB;N$>C5pljS;xakf(MB4(UYNzT`Z6^Kvq=(I$b8ZqjRqEL}cIGGw6Yx zYZQKI-b|^HTkGM`?yai5Nbc{!#hVahQYG}-Md^*K9_R#Eh6)p{F|m*1RGfVA=bYLk zA?0E#uz1I*IIW0+NWC*86c8{G9-&^`*(crnHEY4h`}U>alaJnv(oSNN{ND0o1*J( zx)1!#vT`I&n{kMp*PHeTL>_3&k%n1(zd#{xuOr0{xIvkIg{(xz zh}^25fPR)2T&G3kV@k}Q4XSTDkj&8$r0;Cr{T74!n7O#46gma6ZFs$9n% zw!JplgEX6h7=nZ8wvNd<3gX4LQ#zpqa!Op1r2|FlNE*yD4h|30i!6~q%cpfEq}$M?3yD7j zH91_r?Y1I;t6bIVbd;=AukqBxLai$o&~a4ghUrHct~IDiv3D%XBWJWcipHS(i1T!t z4Gt5%lRGNmSCiBSWIofN%2=X2nU4(VI+qplkKkHJBs<})fsKcwG>%v~duV-WaSBDr zp?Ni+D79Ni_l=txyjGaF%TZ?qz{Oas;s)KNaW!9-`}EUz;BZ8;F_k8fn>>q*154v- zY({E<fenHMzQ5-|`xaKu_rmu#a#Oy$UC)caLCfECTICHBSg;9X^F&yjE*yV22=6lEP)k z3~Eo4MokVoaSDM#5hcQ%E94tM-lqoVD${rAp)6l9gIi}h0n~3wEvG$xe&WJzw69V- zI6`RBq|Tr@DxHbgaBWL2lb?(Uln{FSI$zJ*@@rl95I1Bf2}cP&(&%+*v)V!)0iuVh z%o8RB5m!P~4;FLBAzwrYPPENtR=Le^GeG(~%6@|Mfe^18pD!}zt9x7r7edAXOgffCa1eDZe9*FC#7kw>}#AXJT=1*p>7OMa*Q&d`q@vJ~RrE zWq(e z5tZ^1XiOO#k?OIoFLmWRQ7Ppd0u?KjS|4`@5!N5Ajn{@8q2Ka$ zH;SB7!)qY_q4AhGvwGEXf4+M?a82Wd(J=0;cPYrisBF9qcYG@zfnJHQq8i`CP1f4Y zVl-h+Ot1%*E#v*Xs?P5~GCBUpc&}l{@0TfVsdtAsUq%tWIH?vqG+y!StzjA%oQSZ9 zMuKczNVXdy1#q$@J=Sow(U!AX6l_bxKBpw^_*>fri}mXWkMmR&qpShoZTI0ivqV0| zV3e7g)!p)Ib(kzi*NbsK$$}0gq+RQ6^W}Zp<^1)riOIH0@j);Tz}>vq&VAaP9(BYLK7)phDjZU^+k^CU%}-nL04N}a9w4H zRASrPeI$h2HA@V!z~ogk)FayFseI;nK0&!UYuuq(!m+y!v*?1mFn_)|>rP*|P+vr1 z+4=L+7tXk~>83Y(e(_xM?3r`!!f&cDVNv(NL4qZ%Dllgt7p{YROG8#7-b=V;#mC^iRj{3Sp#?iqO2H{SqWILx~}M43f6mSUMAj$D7aA$S}-9@gRZ}g~*g+K`L9Q zuB@ZR)bA$5!*)bUI!po3ACYiAmT%v)mq#0f68amdVqz$0DDjOA<*-#u!OVmUdJ!S-xOCrS z8-g2jb|_YY{m|aYUP^i9;2V&%jlI;tcIk;j5g`nd5SY&Pd;M*FgYJ_u^hHs$# zVCC{~Xossk$VE^*#ciI@gNBZ!oy{aYOISvpIxpM@H?C)R;7of-+LnVl3F&A^`RWLL zRLk{2fUiPe0%sa9wqa73WysMKC2_i?fb9o#n606WfGymixR601{IKG%!Hulqb=+4H zY{MY#QnuEREILqd9WwNS(7|f~?-!<1ac;NZ5?g_(2Znqy4BtZKPuLk~{8D zOqjG`hfIVKO}yw-Z#(m|v*%{!agPhG=H8{-Db%GDv`nPF%E}mE%uNuUM?I-y>i4N8 zp)`p&>0y?gnGa~>nwa_RB%(~IAwWW(wZ$dCH}dKcGDqEUiy z>-7QBC+LS|NskV$V2+T%=x!#+4c^2apGLwB&+skaYGxHH&d~?zl&t+m&6w;G@*X6E z@-t4vSt838nXnJy;6+OZP5~^pKfYW5jZ7MCzOEHTzZdcrP%Tz4+MJd?#<@bZNj*74goTKUh@JOi50Uoc7$hK;-^|bn0ANy=Lbr{+*ZEjwlY5cBdx&;=MO+gQpHgz5_@R`L|G|kWoBbRI|{u$bdoC(Wq9j{&cl4s#mBt1|rUE#DFZ;9pfEe z*U?lK^p-#f2}vvZ%E6NS#C3&mWC5gMR-TCDPE(J^iK>X za(cJs(6|jsSwns-WkjcVn9)K2;)}c~)I@EMu)-bOYU<_((y>b1#?wI3;yqP>IB6O< zU{^rip&*oXoPMEXUF=d+*WKxZQMklVf=@!|Sxz4p#an&`w2+{Q%k4T&*y~&K26vvQ zs*WP7mE)UH)v%Jy@nMUk`8B&WTy)y-+C-@%KTm<98fqv~87Ney?sX5lIi%D|L39y8 zF&fA<=gOxt<$CiY)>|lFk7iaDq924w@8w|LiX(sB9^rtxgYPEzp2nsE3rP8FY28+$ zOwNV4S6mIj#CBG#s6NQDrg21}lN*4VVBn0NwyfYz9Or}oNb>@Wd10fpkKBC?>+wMMYY4pf`%`-{!0|&I(vzuE z1B8WorwW!a8iLx8s0%fJ8^Sl8jwR&eFg3)oDHO$BqC{&V~`;sYRJ?kwj)Xz`5&4qI~e|oMqeW5WwKYi9abN0ew%9b$EBAClHjOr>pecREB2jTk;hulr*Lv^Bl7iY8EGky0MWrv{Ifc7CB?dbp9rwJ` zT}X5Yw`H3Eh_60Tfh^}pJP?DZuCnYP(E-tth=6pW1TVv61_h);@WyPS9NC$LqX~_M z7255$dYL@vCZ@aPL5fudpD8&kPf*|k^O$1w_ASI>>yYYBfI!Zk&v_Uq)=$_Jb0JAr z5n+^q2Ewg%UGJeJ2s5xX!eID*otY5tz1B>KTzWg585^4@>Znquuy6(asC}^%(V{@6 z6OQ@aXi-A+kgyRH;ENkrR=ayb=BQDM&?XQy`)y8j4CHXzyW1E%_+OTU~TvU^7is5I~d%zOWAhfflY)+w}Hdc(UVDI@};fs)!VuUwauTB?W|-9ol;{N zp_)+Kb}1&AwnSpv4YAx*p}|s=eQfU1l6_(+6TOmAy-1IF3aOTY?VV1PDs_gB)zl{P zx%7d7ob4joz&2hcw?ZV%4JI5BPcg<4JlTvY2(w~(>XQ{g8$+1}Ab-C)C++a|ZqeAB$I`7zq@v=+DcoeJo|J%Ek z-ZqjWJWdSkA#spPf*gW?F!ERg7FTv`?<4Rg)N9RMQDQ`Son*Dy@G+8RJ>(EGy8f|AAcd2LkLb$SIdxatreKs=9mL-CbQ>U0u)D1VinT zwE|@}I8~&Ii4j3CaiStByebM$&~}S5xA{m_K~l9(5=; z5M@S#Y=w|!Sa(7l2di39i*D$!^Gi@uM_o*|k)Vqd9wyyVx=dCt&Z$ zds2Xi5tJ95jnh+?PM04U|ePFkY-x@WJ|r^%0PzlwVOI6@g|#WHRC@*3hOk znAK7&kovaDFoIZ!hlYmkZvCDZgqnD$&QW8dIRmB&2Ar88PR=~m?1OkaC!V@ZJoK4B zVjLB66w`4wqDVgdq`jBKI2iNH^*O+I$)^W4DK&;r=fnn@7!G14p|Rkeb@eMUgrA<`Dvdgv&@p z)7+|kmSI*%hZFNr;(Vxes^7`AH=#ciOd&dn&tOpwo;jp6tM<(2ajJmJiY^`m6Ci_^ z@#Yb?OGRykh!gii@zGxB3zc(Zm-@bbnzwh6Bvmdu; zDJ@A+D$id`k@1-oCnPSU6q)lC`mOFc`?qY^xXIg8m+%<5hZG2PRf@yNYs@1p+j2aU|eR@bHNJs%bJ6^tfp~$=pa?tg==H32#A9{Q#IFdd1ZDXJ(mTF z%tw$!wr{*;4-k7CIg&=I(j3CcPG2;JMJJk=2jtQzL@c;(!oG5Dm5 zMMFMsV%Zzs`JGt!R32}sL~$1r+H{$+7~p{&fd7-7@X3K$PCL52F=OutC+Xd8&vxm< zIoQvxH~En_Mgs;!je#)LUW49KEz1v~ed>3~s}ARs`6#lD%MWDVFFA;0!}0@wb4tk( zq*|670!p3Om!_x=K{4SU+@R!$LBYF7*)YW(5?LEeI#w-%@|}wOgH@D18;ODH;yKU zq%@(p!*Ja-mhN&wG8lGrZ&owa=ry%#0*#>KEWtKWA_1P9U|GX)NIzO=PIb>RvKqbK zHf0)QqZtYH(f&6U&kdP6-rn|o&u@Xbg3TI1Af%-T&xBf}+IS0Ay#XqwQUqso zJ=4QH*u#zo?~Q$q;H4T&Y62Q-F9e*R?CCB5t}8}RVzVCl7tIkaw0&_c zF_?4Wh0U@W!Rn_yF}&91o6-TN@}se$ON9)k;2eN!u-g~b^un)M$+&(EptYc zH%PjxB{b^fzZ+W8pGK8Jj4*=K*;pNykGOZW2 zE#T^aiv;9?4XPC!yTj#RGyp``cHkYn>%hpOC{0g}+4H0*Yo00v zLH)*)Q<=BaAhj@Jnms_&)ZF(Sc#w8oxMNb{Q_>?ox~;MOw$I^!Js@-%G@^_|^M$x9 znJ8S$+pgJGoP;bKnntoDzTsi=YBpLZr$!xAWmS#zh>2!I%nx=Zt`v1`l}rXeHwor4^B1@>9U^?m zkeSe0B(z5we1qg$wrFM+FIuwf%0r+Mx##D!GFfPl#K&+A5W!|=GU1DHX4;(4C<$05 zw^`;TZ~I8y0+#}r7&|NZ6xhg&g&3k13MX=@G@ZUI*G4Fv8xm%?)gx*tSa;?L>S6CE+3?s=|E^Dzh8!y|F`5MwGo)Pt0Ihdalz> z!K#G|Cby8Jm&g?|bI(lNQnAD|gk|1;E%-J$&|k}hh=l0yN}#ngGH}<}{F>@msws@9 zA_d~HWBcS$c0r~)BS54*FF}=3{!I--^{jCU5icTX0_++I9HVnjqiHc|XLph6jx^TO zfF^A))`pAHngM~J>>)+r+S$%iSQ7MBuu{6alY}O^J4~TwyQuy&4M8^sLud5jcXN)I zSdJfs6L}Y^?Q1-bt!{AIqgoT!cn*yo0-B%9k7KJca6R;Yt&Eyl7m;pxDHej*!2Z)l zrBW5(HAl!?MImcTDN$j7!h1rhJPtfBRNQJE;M?a=ZNR&0$8+J7Ucixa_&P$Ufgj^` zbaO6fq|5%xF+(6u)yi8fu2fkl&v=!h41N;VcX6RUM#d3%wybt8FYn8=xTG&wt*qR& z*<4JE-?nrXtAdV|9>@x)mc&tAC}(9-lN!JDyL-XYh|cf09-8PV%^k>iEZld44i^ho zcSS9s;@q&11(>w9nOs*aAQEhhMhKMab3kOJHoG|BLzrT@014Ghz#EC7~Azpv7zD=<4NfBG=3FIl|(*#%pio0)Ez-sZ>|FW zl>}fd9#G5hvRXPWy>9iaqrkAL17U~fVTno&)Srv(!#kn~t-aK~tPLj~37_pa(O%J;5t~7sWq4SrleI)sMpweUCx=0roI6i#`xzzOM!X@Vj;QqL zIYhEXg5Mk|=*!GN*eiY4=|MGbR%Hs4;^H=U3gdm+}y=ml-uIUn-_e_#AQQTl&hhQPFq>1my$TdwLm!Hn|d{qNLQ|jNaw~gc+-6P#6Be>TnWYhbSR3Hx9WGN9o*@b{ zNqBPW6e~qD*NyaT;|eYtkqBBw=WrD|1j&C5{XXId7qaPGK7J);zKFFHX$MNMHh6p3 z4cGQ3Ejxa}&-g7Q=wE0nLzkLtb@$67d&@>tr#oMyQrNzh1U}(R&gzDfrxQt_{7R9H z`ZeUZPJvC!Ox`aeQ)zI0Cp|h}km4vpdvrctLXf#UZy*Q4jj2OM?ipfBg=GTfd0UWT zQJe~up7L;KMlohM#VqQ?smw&u7>`jEi*-7AB%VwWC!QlEHN^l|D{)pfBWwnH=CWMF z`H=EL+6Br@YY~U980kWNPCD(5>+~u0<9VJ}@HM1_&X~l?%?EE2NQ@ zgIHk`CsB0uBp%CY?ZSKJr7V^VN>cQ4VR}yPzJl;kZkc0iK{KJQEE~g(J8Z2FeLEd- zXJsRM6YS$1kpvXyus^W}Pf`8}eSo7;7nB}qDOYBu=UHN1blC$Dw90~23+yNzgPxTn zDN_MoN^4LD(5B2spMyr(PW3F3#!;@0h4E=8K-xpj!>&}pSD;#(i!M%ahQyQ75(pc^ z3UT@MQBriK5XZMBB$D~^p^bL&)6?$cM?tOaji+uG#q3Os(iysJAUD$mE+;|#z#gMc zEH3eN>L8HdXQNm|PEpKu1mj7w+HIYqL?jF#rM784naspP{>8uwr^!!MJGn?6EV43U ztRqndgYzni%vzy~XvT6F0ak)0j~myQ2UlqlRq3dmFiGEWCF9`1jw?@2}wh zcW+qM^POAP^H*B`_JQl@BU$Z{NP)^c>X7RZEe1F^o}z*>XZK6=^X{* zwSoP~+7MZcedkk#yms%1-KURYy1*8FKavl`zG#oy^~87e9f}J$!zvzmy^oK!?B4W5 z@A>+8(4&dGfY-m?xfS;EjmLOj3;#^Mq3^=iN1L9%<+_xL*ct|8ys_&8*X8g3_XEKA zX87pp%}b7f8@$-xv8>-GCwjx8J+_|nIX(9n|9|=0Th`|{=`Zp6{N{bUdEe?-AK~Y= zb%1wGYv0<#-%b47!FziB<>o*CYcX`{;fq(q`!8Pk8Gmb81d@0_{I!KYZUAc6@&U)O zT+0T`k#%f&{Mh%o)giv^;?n@%cdZGY^YE8=J-_*nuM&(7KKJp>$U4b^^jCgn9rG6d z?pr;=f%UodCfaTS-Vpz6w4R_B3(!t^Ot#g=cLa5U?K8yt0iN>lw_|-88%qr%rZEzX zGd$&6&+t6W!pHA?X#0TTGHjctavLL2V;KY1$hrV_1xztl3#0fUo>7?ELT`c9M<0$g z#&;23@_K9oV%w@)t(mi^19Ey6mi5s3TCC6adHzAHue*S`j{o-c&{ds<`-PVSe96pS$Sq1ekMqWyioHVdw;FI>9rv+R4vq)}OITEj&ZG z^ngjxwns}SrHh{H&ao7WfE`WR8_6pal-#Hlg`7P_~__+2) M&UdSiUV04tADUJybN~PV delta 274859 zcmb?^2b>f|_J3E;?4*soz07Qm?9%MaN`_sKq#`JS1W}>{K}D3t9uaj}X3Y@{t(0Iw zOvjmB6?4uJP|Tv9p5e^#^z`umeO28vJqup?|M+~^u6p(A)vKykRj*#Xs_Fc6VCT;R zE;wudXU4vFsN(#4U#YLnWqlRpyF5h+Nno*-uPC($*W#-vMIx*!il1Wm7my!CnRnr~ zJqjKv%2y5~2(Ul(Us$K-jmlR*OgXDCU#aBB_Rde(Ggzu^o zhdg^TtBxR(f-;nU1>tA_wJgc zE>c4~{YoHe{O-3O^jCy_p@{hpzx}?yD)D9oSa62<;GG&3|epadG# zj%3%&@ZWQb79$o3_&Pdr6o0_qv8ro+k6&2POJLs^j{FAND6*x)zNK_Vci<`jy2oHQ9i!Lz*mq#VM#mV@s@Q)yW9#3@k;)5Bw>o z;taRE(?xm9Gv%Gp_3_ZpS;bi{!kGf$1VVU3FmzVe7kf^K6#pp)eW8WT>+n??wTO8` z*Z8r`taOzFZ+GG7o`7P0U{4;~WOt3*S$dy?u-QepS0H>y2wh+AcX5DCw@;gNX6+G# z=Q9^bG{3o!0!9M_M9Pc`E0Y7~5fwk@6H$t-YJ+;pd_|tI? zDzfS#*%mA9?US2WhyB~+-ud~kyD>En-XE8mbg%Yib&zOa{9#-2YGsSQI z9dwLY_Q6wyR#7>S!E-@eF{%;E4VumPpnp>Kl`~5xP>LA`L{XX*rJ`>@ zS%49RF4U5pPUiC{bNAdQBQaUZP#^|FJTKG|3bdbR`(`z<^X%qX3)v}M=g)eUvDNmB zITdB667rA4-6$X%qwz-%_yg^$?bUO3fY+lB{YI@gAH@h6TZ6#Pz!{V$jshAx&+l3> z|2bB1K{mpfgfL1VTwu>W?6!&vv(wMYq+i(8YhiCzaZxtH*%^e3x|S?zVI^;&HO&J+ zGC2W%@|7I(tsMKN!%tJ+$m!~T#CV3UojS5yeJiKyvLk;C#@+#bV~%+Wb>f={L(qce z+d1|P%O(KF{%KhaePYL6)bBi$6~QcU30P2a62St0bSI0mXkI8$rUcaXndrYjJEfWn zeM+F?68o)VCltMtJt8l$hgg%?CH7g?yj_#N-Bw}i$-1zhaV9vjf8QFlrzWSCP`9h? z(?~+T0ldKPH~V(ompsu|M=3ex64cc^9)Eo1ArMpZXo|0(KYQB;tvGVDo!xBbP_vzc z8$ zj86R7G7VYzqX((g_P*y7+soT0{x|rMLM^|Y2%0nOnw3kKZJ)c+D4&Gp)T^|r;xeNX z+%#cgOyL_dCfP5pJm}yHQDbz4UZJ+nLJMhSTGTul=~}r~YK})}NWDcL03EG&O2}xawCoKJrjCX8)SXcQX`p zrt=QzOx2x8LZow8^zS2six*y zNQR6aV_$vdo^DM>&Q)vdqt2L^j-yBQ`*zdhpPrHCNjr1A!^oU0MrL~%nXAo}jLg&K zNk-;oGcwoQl@awUFC)7&xvs<;71cVe1s&)LiG9OaX<2yXtg9<7&K~mTW`_L5_W5V` zh^?U^zDQf7EtEr?17FdC{N{;jxxM}De)T)DhdHJH!7#54P@*}_KKh)BY7v|P;+D0C zvdox|4r(dY7PU*becd??F7`|3j7}}0A+SU&YdPjoG-#KYqlmMkwWDct9-|$T7@#EA zA*E3}+B}MSa6R>)zEsY7E@c|i+EVibN>k$dVcw@X(VJQ#6IJU1@TDzYelV0jd(F8a zhaG<5;cBUU=eZqy1y4yYPf5wsaoTaj({gQjqQT|qIP)lb{&{<35xM!iW86B{uCA(= zjRXE14lviWPJ(19E_a96b659rbDX!jpBsF9^#nHKE&|6Wh}ti#$#u%=dUwsVKru%jH7W5zMQxvh`PFA~d!I|D zLEWU8)mfFK-h$rARof4yWy(=x9=xQCU0}a{NrQedq5CAdft3s+(av96uV3oGDVKz= zxA$7xpxcBZ6Mg0-6j|SO!rHG`x#%9~sI=Zna%%fLDsoX*=cRF#9cJIOzLt%%UtFIU zN4OEulRhC`0nw4UL3CqYsO@I-fmDiQYEa78Ug)a)F!i)w^Cu2g!e&?3=*w(1{{&Ej za7C0*)I7od;EH3}3VZ66qpMB=ywPu-M#<18SBkINzL1z&W#4{ftfEtZpk|0~f!{ns z26D_b_J>zC{(A~xm%@4Wn5!E8JwEHSulNt~e!OZ*@8gM`xDoW3%SEUfq2olT1fiq| zMJQx1+i(aw(SBybzJo~f2$)UyYxKt;#|oSqOccuYl<>TG6gwq!Y@kW>0igEYS2qM@ z&Yt!$SKDC`)E& z{Dlm^LgBAOuI!av>!%7{t)=>1dbQ!*mK0s8H z&w*OU9wPWEsCV?^RkyOnu0w8`&6)}96FQ_>iL~5ewlf;VL}>P-h4fLuQ@cRox8BXl zQjcdK)yew^=hh4)n!J}F4`(3B?I3F2MF4C?z-CC<8#CQuU{gs>!9Kgu`jsim%<%{+ zPWV7ic!DQ98R5N@h$`5zDh43iy_u4BSX%SXO6aWZ|lR3vWMN)tMX{z>R~PHj%Pih zMG|``8aAhW>{Ykbvsw1lw+$+vO=tyL0nLzwT45sQkT>tNzqzePJvDt}$kW34K65Ox z2&yeHMC@L-*Ni?=FowxgjTtf=&T4u!Xk9{mj-eJY1ZRGLZqI=1GjC6T@jGwt*&>ny zn5d~Eu~*ju#sZKxF&ZOEm^Sb85l#Muy6gu#=ZVoRvvq1@ zuO;=2(czo`vV4H zi7|&}In=`*aaZ}?S5sAGrQ~0810d!#8L;Lzf2Hw#T?S-LC`W_1!_dC$uG-l*P^!-y z3MNVLuxXTnH;k(06d;qch=`_X9wH$xk-j2dLj1*01V7E)XkgqCjbg3Xp<$2O zTp}gZXZ8njdQ|F~o;V3jPCyIO&@!_(>eDjVfs~QV3P?`}a(6EmQtUtu?dw3u5LKd; zB(P9BQv^{pH&Lfz9HbnuEJi{d5ZX#iZ;tR>i5#Nwj3X&y53NUH5ZaSEz&M0R?tZMv z+;Zx?Q534Q7GPF%3Q2k9{fvy2YNh{`jFo9+e%4hz2ac|HXh(?pvF)_>$iJtcn>1v*;i-DQz&z>M?@gIkx!~~I<4x&9BkY_#s z#IAUtjP%iGgV8`?9|=N0D5b^>@UR>3bbyT|$dcds8&)@;`Ii0u!*%=ruau4vl-5d0C_6W1 z-~LF6J@=8&|I8egY%tf?VeY0!{&(hZ3E)JCOQ$FM$5nIv-19<3~6& zt3-v@JQ^DKztFRvd-Rb!4Shly25BAk%Qw~8n;$z7`b@vaci?Z)6SdGv`aKb6jdMt> zLimFP?5QD;^@t3=M&SYxP6q6gpR5W0g4!yLqb$0zT{Tqd@54(2(37{BhQ1&yLzn<@#WPWL%_)M>g_1Tmz%1~Nw-~Y^@l%S+) zMP?pI8B4*hGo}ef9|TVa+SSk>!C#-W)r>&IeOXu*jg7^2W*|RRfpBl+xk{f zPA#xJSwt_S z`XBJ>6lA^X)#?L8&%%l$yRIPM>7qu}ZyZ70Drf8P^o?v^}KW+aDwmomYHWz=}UgzlHt*<{moju8K zUaTIFf^6qCSsgbj%aUPmeo_Y(0l%6fpx0%f0|=`6g;5L@SwfO`9N6v{LJ2U_iEQnJ zR^V5S{gIv=3G-eD7D~Tb;O}S?cpZc3qZ-Fj)>ef1J3p~f^|k_jN-w|Wo?n1x>`I_qlbVqen+}l_iG#Q!hd(}mHN~nxIiTk` zZT|=&TJFxk#X}tACg#y7T2Xc!tXC>prCa8a zgHb?xn6DnpMzTTt#lft$;?``+cM#N?hhos)dAIPRs;t#Mc zFTgM%ZdTo%UD};gT7@W$QjAqJnP4Xy(T&zwK}gSaKp@o?T5T1;9oGX((F!2v1zPWR zikX)KB}E!=v)0^p4o#3r?1FKe;z>8Z5F#R^&6o*uuUP{WMUTrNs5xJA2<9=De_0#a zT}RB39=NQR3G-w`E1cC1Q zEJa<^3K^^SaPNFoG?4m{-@s;Edy<;lc>NF3-U z#;0Q5L2GSFx0XBY>`ldXZ)bg2@vxmy!`1ezsk`F`P1QovMyMjb?lWOPFZQbw7)iHqe-c+nCUeMB1U>i?j&RB2JoW1^GUE zu?tdjq4V4VI{EN2m5!!pOvLv99CmD_cQ<$d>*rGZKMqQ&7ataNWfSsT;DPIXeaZyT zSP3?pzGUnHaU3mS?Z>%wc+KLG?GQ_N1we_9=%H5Vj7stzDihjpamavP73sK> ziuIX4U{Gn{l@v3eheS-&5GT5=44P?fqG>l6E;e+V^nKaEY$ShY zUsl%ZP2>%k7tnlkYZ(PEBr-HV$;J*?9|FV2e?ML=54)hx`N*-XClvgJ_=H5K1gtQ> zU@WT|D7(lng~1=ME%plm(9wv+Iik<;@pLBA+xQ1#*$CF3*N$W5sZnT%Rd+x@Jj(iA z)Y;HIB8{DtVw{Q@);JA+BBag19RT)Cb8n>Q#dDM%d2uDwyqD*=dMJibGo2FqlqDFc zC)42anfm}gHy8$hhXV!6@R0GC%&WGE?o-#jN{JF?TH`J`Y9j(*7Adw+soPQeFNsIGqm1@gAOP zxLp|+E*BVm(pf_U;QN3~d%p==tXq~_AU|A>c7 ziGRdG%*H;mV-7rN)SQkP_Q|)0xc@M%vD$}z({f&m^Aj|?@we0 zjJgK&t*`ONF@RW@MVICIqNeC~e1#k+@mg@J-Q(bvM5D%m)OVJ~k3Nvqmu%cMWh38u zv#)<8nbs-q8@pn>!M{0>#exUji)q=ofEP?+J(r$@h+rpE1c9UpP7N8OP^vIO{SiMX zCXGCdkjeFeke}F<@)LZ+Bvv-#!uxh9lR%P;64djwyu=91r{|;X67a#Gui1e=@L3nf z^hExk`*$I75HFt08urb7V3!mEIb8aTHfl)KddWpIrVv0e_D3(lUTXOtMEp#_z0*pV2gn^p=QD1Xo5Uzw*xMA{~6WfA}xzwgE z!}%+gmw>LpmTz1H`L){kq=VQVfsv1a+Byzr=W&&HA#6zF<}}E>*^2rZ-=W617{Wh2 zh_%!`xjPK8Ga-XUQsl@roi$$7AyCJ(JOgO5F;3p6M4{in0GlB1B>TIXR7HQ=?2SqZ;! zI%^JGDU$iy)6wf2_}{0qx)J7+**TOrT$rphR2v#|<_VY?VFIP?R^lLFtP}b8`*-?E z>W6E?6a5tHYk*`kib@C#4Vx)#1p52D8LYbhYP7J^&eY2wOyi?OwH7^<%>U z7TD7W4<6H(3fW9^5`$S{e{KInHE1k*E}L<;EG2%phxbzC7_W^_OhJxski$tjSRD=t zB)OB@e@_Ew@P-ft9t<9w;31jdbOg;Ayx(kA%1-3_&t~<7?uA8k#u(L#^7h$ma8Clp zaEpzi3O4GTJP{Q2 zeSPMc4#C;l)YuCkXd=0bA2Odcq>?7J@mQaEw$sLowZ)0vNdJ4c zJQ71IQQJukG!F-5eJt=sZ^@>ujddIAp6teYDAQP!A_X-6Oh~ACJoS`nE#bihY-n}2 z*%-G>N^q;>2w9aI_}m4Uc~|q53s_m`ND2I&Ux64qn{Qsgu4RjP-6OsVzTz;ZmBFbu zV&!jDmZ=!!VEZV_pe-|(@T(7F^VtOMTgVQK2ezTD-MePTYsV*g(hyvNDbPwME$@Wg z!!mfsLRJ$XsC6jcxR4!Gag5~QasqkgC6YX@EnF4tfr)an`i>HmR-?=D9a8LZ|molo-AZFlykVEJGZ|A7vOn_6Vlu z9E@lcKl=z)Ipqp;OeC%ZU;rSse@jSFU^&o|52G(hu-3l89|Qm2uS-jdzCu5E+$-*-JKUrB-;QFH{~Bi|zkCTR zDa7Sxn8O0?^o^Oz`NKEbql zvlto)JKjn^VcB!nMI%lQ^F+oUS;AsGbu>Gy_9B$v?XGZ8l!T2&o|fmZDGosCn;`%^NlUMe_=rBYI*g ziRiI-9o+jc|3~yvMJt6Qp;65f5J${Bk^f?{I*C~Z%rc2tu4v_1nB~A6v5XA}{3h$Y zVi}vv#`0&Ev5R$Q?YaYNmuy4paK7wV_C(%kuS3{r>)-SUdmV7^d^vl59v;V!?^*Aht4{Si>(lkv+3{=5m%)v+({aBAY=Zf@|XZ z!iRl2?>dRCki)8+@A(ib;8WY#QzaLHb!+?^-mTt6yk#Y;D4hnNNO6X_U+hUN9KNq) zLsHnTMk2{o_?zpC9u+lT#o%oUTAv`3FPQ?^?8KiYe>yD?gtg!rjMC)ENFYN|L}_kT zePssBb}+?!g<-w)O=X#%*6xS_T_a+>CE_p`MAG(w^0x#Ek9M$SrPvQeN=nF<6Dct; zOGJ{e<3u|4=T~;XM1KxY<^BW*hLIxXv${jncFe-?L+_7ag_$i-88vUFc|;9Vq(kND zP+7T~T3Y6YVx?}#T7%-uvr&G)ypf2c)PQwu26l@iY~8Xe=`3 z-Y*QhYQX$63Y&!4DqwBP&-$_tN~=MlfRmTO&l1u zRPK`Y75_QK#-%O*@~X!$kcDmgQ3Q4dwvkS8ArcxpDaBYr+QdbON8$$uX#X3@#bqHZ z2y}}al^KO|112CKHXhGrl;UBd zwGb<8niH#{KZ#8KcL_PvOC8UE;gM2abP zImL3^oP71kEEXa(O!`;wn@(n>DG|#tuLKYT<43x5uA-bFho~SEcF7>6Nej9D*}}F} zf@el3785bC%Z&;HT0m*VJxIlG zz328O9X45?Pz=*dBr65SOXjrzmbynpW$%ciB5MeJ&FctX^8-l;gnzmmHY6f?z?uvk zJs3700UPO-qT4jnaj%Jh)@opsnFAox;?_*A;^a}{10578@OSaMPetu+MHA?>v)AZC zi(pm@h~stZWl%D&7wq7!l*5koHbDh9A!G?juSo!UKLDU~?dP$;6}q;qqHwrs?8t zh7ecldw{gCrqcuy5&rOE7MD_#DdMFRh|x}wE{mWTncI_2Wl0&A1_%{8JJijvgPRhNQ0tPcTW`UCni43%s4B8RFF_-a=+xX3EsRA z1OywqLvmZD0<1bMQ3ZBz2}WYeae~%>!E|V?Y>f&RvmBV^T5p_7W(F8gacgAgyE}jX zJrKg_wD}lVNn!JqGK=B z)4UBKfA`tef#Y*Kk|k$|+(D5p{Bgr~BHW~a9*>>LN~b)T&BXQ$6O`g%qA?zam!Dt) z*_%9sn?#8&i1U-rMCI;6F?z4o#~=yCy^OmlW{|@JF_&39$&hQ{%r`Dv^)4p4fkTdg zqu;o>nexQrM-<0t0*~kkH@k^38A(JPVj?E~K=#S{)}pl}`tjPcSl|HB5`-<%cQUeE zkUt$9V-sQ_!$-CUxQrY30kh=-9L&deM!}SOFfVFwKex_e5AN|h4Np==B0eklt`p7; z1dWTpGA+e4J?FRn6ZHt2HlK4gi%rMO99i{Lc00dD?ff7T8apY)u#w$B{p0TSJUR`@ z#p@L2LqHX|cdm*n_`tHY;CJ2QF}?oj$DZgE$WBwH!LEA0i@UT7XXH zMT$6`*F!#QF>x=ZDL6-9?h_Lb);y9GDupIuo%TdRc;K;NKFlYd!^Y2i1PHm#LX_9~ zl!_PE#6pyh8b69OIVB%M4BQtM*Z=my zq<2)l+pJNoNX+;Jn2K>-0TUGFr#SeCf+x{X5`==?$v2+Vu*t&oO_VNcRt7meR0dLX zMGvIPvPhNfLaNMM%O5(AMN^sb3bTsJK&g3Voe3<FG6 zna_ZG8a;FyFrOfh%x6W7NbEfsV~|z!(tUjDYPRR(=csLK;$ws}$E7FCZkO zisn)`{vst~!c1U~Nx+v7chfk+P3Zg@<7NK-YIbg~D@eG+D8!N`6ry;ks||$&>HKiW zypvzFh7C_$17yEPEVA+mx5aK*bEu+_T3GIU9xVvEPDm=*qG`hvm7K+w0g;Ny@f0IO zC!hr;c{7ECASHUpuTVW*&4;EgI)lZ|84rJ;#vUAJaSCg2|Ka?~^Vwc?RO?9Vjj$o5 z6=G5Gyr59XteZKzfK^nHau#!xv+zc93!J2)8bVk_|qY9%eC zwAT}w;FkbNrL3hIieYd^I$DTmuXL0y+S1)#XytPFj7O5WRd4{rxeg*cOm;`-*ep79 z0l3oP+pUguGEf{H6Z4dHT{=h0u8h!)U(7*3yFZO4#%yJ(JK5*6$$p*2Z)rjHZnbx7 zfl5%JnZ}^nLxY36Tnw|b+vLB3m_eHu9g-n?p1*k^Yh-Kq?-#<+>keLZ5mt;|??L0M zl;)&TH?v!BOy;s5wNh7h#IP*uRuQe#Z5+4sVf?&{SXFgahX=a}#S#4Ji&$@V1poFT zR*fU%BHQJsr{t$@7k)x6KXqw-=#uL${M2>l=WL#`QP$aflZ`Dc)|r4F*Wzg+aE-^N z$hwglBQ6U!b}5{MnzM^ptR|~kM)$Iw=NN zSD!RXbUeIEz4~-7>(}@AHy5)?EsLXEVzlZKR(b%`jDS8^8=UAs$I$X;kqN>XQf&^1 zb`cJ!$pMjt!vX0I=x%=UB{72T?} zw&6gF>ihp$y2DVR0&jwt@J=oyqP*u?+;+K}k6p{+skDUvZn?w7#3QF4V=b-2Vu$D# z4Iq_~5o%COvIZ2$fIiaY8E?74O+hS*&YFlv-L#Q%RnJp19~Vd;PFYWabX)Z zHXS?{xR7;#G&zIJ=nLGI{Ge6wK4!aZ>U?UOsJ@T3kH8mDi4PuHg%`ee4IYE@9^z@2 zHcAsj;rnX)dWi9@93mi=n{nD0ZJeyHA4@sS;IdV5A}yQMX|QqHer|)!)C$D0vZHc1 ztveo+#_x{O0onmsl*VfZ5L$0E09_p)6ZEP!u#JdyeS$Ut=b9l(<$TSh?DUpiXq~)x zLa`1Jfd<7|Edu3=^{fbJip4%4oRBq{k6OpZj2a-Kdn?vR5g4ji6GQ+$3FIb{7dI5^ zFafDitfUA;73*{n$XBc@_>=3{K~pw~_%y}3R|F1FtVcxvbYB($(EUUNK=+>_0J`D7 zPywJ@B?6$^O9Vi-jW1cx#x#u;aiA`8QByAJIv4fkzwoElv8hv@6oB3GAejLVvS=?4 zuegNMJiO}?ZsYBjv8ohJEb!0{CKd8wn_n^Bc%&7FYZMNVum5FW2aDf z{)rqp1^$AZf>e|KYTMZL?R8=V7+V!Pp5TM;k93d~=_xPt*u$uY5r@`Nm zqG9EH=%V2J~tgN7V$;txJvPqwImIIml5jKk&gdG#O-u^n}}bXjz1>i zx2EHFi1@wf_(lBx}*>)Ui>R>1l_9hn%gf*(1Z z(K1>dA&3ra85po)>6Bgpt05gJ4_N7zYsn9Y!w|~D{To;V+s=&*tR??7$O={+h+N2g zjV}Ob#(IDf3w=WIHeW|Xs4y+19*ETkr8xS;5DB;T1IT_2HjxU;}3U zC*(=p|8L2U-@!ja#rUOHv!WEtBY{ZrSy)Q&#NeCY!+aEBB{yKcg$VAO<8SgE{K=Ey z)!#tJ$@eWE0y~NMF5ppf2maDDC1!wCPiNa;UMCyOg}`X+q!feBJH&;FJUpMZTH(Dm z;yF0lXW=TzK7I^9Y3IEbtlKS~lqJxuvDH^abSf}!t*DynUF~Co|hK;Eu6U?gTve|ws!}fFhvujwQ zQZQF0E@a~LS1?zOwLXaL$tK?KT2?iD6X+!JaC9uXY^R^5eHdh0-jrxsxu}Kl9?-OM zA#tdQ44@|GUdt->B@$^6!fu61QK3?;+*6?n#Li4tuTra!)f=W&pn6|i3xAPQdBJt8 zt%69BA*7eqD^Uzi8nng|hY`NuI<_D1Zn_Tcl+?n;d;Fd2pctOYL)WwZE@;&CY-#FA zYT01Oe44&deL#FB{tk=}fj%fq(F3%B!jMfx!FLpIDPV0A$vVm=<=U);csZ^?{FtfNA>p3fGpw==@^JU{XBR6Sq3CsQGSyN%a3L)b zI4`xz{_4pd=S%N^SJFrPj5}D%Fi~1jyiakFEDdrNu%>44HIu6Cp%)0orspa^|A>Ee z2dkeT2o%Rh7Z*zcu=49>Z{(rTPKL62j4CxS<*3u#b`CcX}Dm-iMfQo zr=7Fl3iD1>G>#xjJXB~EZTCWw1sl|C#^@CB0fYLkEL85E1v0FkKo70SM$ux)T##r? z{sN8~y>!fn5ufL&NLgTv7L7~PQJO#xK;S)GED&O5 zi9mSTgHR+9@*RXiUy4XPOBg;^da&!xr5m2AwIAx|lkQme!?(h@Oym<6XY<3>?Nohw z36=&W9Y(-YTU5@IbR2w9nZcp9lFJ&5IXA+xAt_6driWno2120s>W=-Z1L# zkf*b|fCn{$nJG~AiEG*MmmqTj1(0@=%x_MtU~Vc7DDPtb|G_jS4cXKw-73WuuUQIS!JX? z@D@U==6_H~I?rwk5#uSV5baY>7t>?7nKDMBkGIU*T}{%Nx)(y&rWmXwNxk`__rbQ* zn~I>plaUgVC-QPm%hOXro_2#NOAw<UMJluhHOD`pgPNRAVib;bQo$FF0 zzMvY)$1OZ?>r8J+bpDlYCRok_TVMllB{xmW&C{$zx;GP{n__127H+Lu`v5E1Un~Yh z)m#2Lw|o!#g*3I{AH2+Pq1k#6C~zTy!6)rycIX4FjeW{5eSr01chN)S6Ywc`ko8P` z2D!@>uRkOvz;I5BwOssLkpKX#Z&`paW}z$qEp1+a9%x+&g#$IqEDb&rt``wKC_!4V zbafLPIU1u|_;||~Wq*^Nz>iqIYW~ZExaIJ98qicn>r3{_(GHupHlUt(CY>Mi5UZN( z;TOQafqOkfPdP-fHp(T>!JrB_EA6XjTzMrWXi+sBFbp>U^S2*jRwZ>pz_=T2nHv=E z2FNSOU|+eKmpy|Pgn}<04`AY#=_;U_pz3hP@QYgoO}IGJL9u4KU*K1YV6vcH9&jjU z+8bBIWIMw223HPPugJOYY}91cR(F@P1%aJ`4>P-*tyA4?QeH`Z3Et$EzAk!BE0zZO zkub68!3HoO_gmYtDSecoL@8pwWn9V&pJmZ~(w>GmHpzI;;j~*)dL^6EUo(^_#ig|P zS?Hm{i3OGs#|#_nZvJ)P#J=z+!GSPskm*hLagaeWV#)&(KX!pkOc*%W$v6Sz{}Dx$ zi7O>Ef5SP-;rrEWzCX_JO(_oFWOK@Mb8OGf@ku5JrFe4WyE$IV$`K2En#n>*ZsV+b zj@8Q}qT--6u(w-F9j`r}OWpo@7MZ|j87h?GDY!(_t=MN64kax?Aw%&zT&E+5Fef=K zmO37-%Xl@)ck_Gjq0h6XfptK&`Vjv0C>T2rYdAsXry-DcxFhP)jt<{ZxE%6}pJzQ6 zr!D!eKQ(FoiHWdlq*FXLe!W}{4Oj6ZwH;Snti>ourdUY?wQ_lBm+mX*l{*&FfZ}y8 zu!W$M*GMd5~iX&)PYL%Qv$reC|?6HFi>xr+=XF(TYNcDsY5t#a00vI#k}urt*bL zrLmJzJVb(Sj<>UOe3{8XDaIOjyv7Y2X2kK+eoi6ybvfx%E+>$$GFd3aQwR+hA$z!? z=gskTCI_W>a*#*1$g#uCk&=aclgUC!o-Da;7To>w7V>Q-2c>v&#weamIwLbD^|jk;*eIZLj`IHiJK87^D;rgV1ao#RTuDsy`b?JpS6|M>hgY2J1)E6S=R|DvEy;RW-FZdv17oE zxeh!NyA=mk*NLI}6%AEbq`t;CH@+fheuDt6+$K-Neb2^_c^2t1-vZ|R#9D~1%SPm{ zn;G=$b+BA62ddbTwJ4#m=aMO5a%OaWwAljr?^ZC6Ldse06^b}WFi3*8s67|Cn<)(xHS1<<3N7S ztKBG9^r7ZU7mfBK|1fF-x)uPVc2v*VVL_|TVuu%OXSsX82oxE5EDY9C*n`0r+@PP>h3v_1QXT<#PULz;dsqkIM)4hCZpfnSLDG^1TGHIooNu$C_Udsn<-WKE1K#?$|Ej5 zMpPpVZb;3$9>dRoku_q%f*UdO@F%Yo#sh4Ru-(Sb@rJEK%3YKKKy-iDx+jv(Rlpy8 zi#3hH&N^Z}K~U_}#pr><6xy2LdU(fpC63oj{UU0;kwznfmPF&d-e&vldlPY(l%rS8 zyv>*!v_7Id-+^>q@=pAPfpL$|p@ZLpa8uY?=?QQBg5Ui%8=%hqihuq#s~frME8xMj z2`TqmXHi6RA`egmCK5_9b$qRt0I@zIFbo|6+=D;Z=$ld>MU>2Wn3`ePLQ2>y#TUoC zGGLbRhu>kPJ^q27&~fhOLV;t1`4{i7=F}%pAVeSQ`BA+fSxyvjrjuu#`nB7<=^oIv z*3noh;3`jjpcgC288i}goV=Zx#)kO|e*c<|t&GsZN{mWC%!7f69f-9$jYwoyrT&WY zg=+H=0y_gggVQ98TW}tr6ys{h7t|SD>tWgHoK%DT%MJ{t zX(%xHBt%JSQAkKb-1)Q8ohGVwH%%bNA)q1LnCHQa;de*~O$-;orch#yqSeTGv=;M4 zt(-6FFkkFlCnt=$tO=twGhx(XzQ`<@q7FC)hzzZk&v2ISjBesreS`;yo_miyw(rgV z2ZQMGulct3*_8i%5FPdHE`#X6e?N#&Df3J80~R7W=)&~S247Pp`P&~4tIr^0axmfL z-`x+Uf>v_D!XhRHQ=v1Mir_}lZ7^wCk*3MPqOv#}lX~>~cCWnd`oMLIM#89b}Lj`xwi>u^FsmdBDm6?%J*?pu$4ev;aVx(jS z65sR@+cp|@W9dU60&pt8ftLh`007Uq01?1)nxl~4^DQ*aRHL3h@K@H9YJlwapxsSO zY^|XA=eItL`9@LcuGtUJwd6ytIq@ZUwsjyWbGT>}5D&OI`-sFO#UfKJpo5TZbs;R; zJ|-TIB$ZS(Ckmwy2TM5Q4yg_S%UAIoR<1Dqm~_uYyv$ZarK7AizVc)E+BNVEAG3k% zR=EYmxfyLiU*HFR!ZysqF{K|~r0_qJk0E#9_LARu^Nxb%AR2(QGb%@or3y|I%prhx z;8KoX!Nc3C^<%TLOh(ll54D&1fuFKk@dF_~yg?#1y5lM5Hp+=#idq3!$5wv+rw~el zwcvFSDpzfP8Goe{p4d0yI*Knhj-Q5A+Xc@aEVZ5ZFy=sZbKyTk9=LvGKg=GtQ9t=3 z1^!%rjwFSZ1wXVw1tqXKr7w9;$XVy$DBOl8qT3`Kt_{$5;`Ml37nTet?ew}8?u?^9 z@wpx!<4}|ck6d8js6W!O9g44iXA}xr`u?TbzLlT#89Tf|qN=!9KaYl32+kTZ6ehAE z#17@!-&o%|2Qf#a7Wwe=Eiy!{h20R)7W|DJou*eHsT8Q#=LyRAl zikd|aKNkbEy*`JIa=U0MYitC9*MNOtA`eb5bHS>+Z%-s>f(kSVMMjEcE`DT~gc9!; z6ezy@pf5*CA4Uice&f)s=w~*4N)4n@dI1}=&}{e(GT9l>S#ifGFYb@#@y|bJ`3Brs z;VPWO_2CGdBw?+Ap@aI9T!{-oBqYXN`*vRY1*?d@f!+gm@?9e8@>~=w?JN^;98W@y z!wbKUruBf&I2n?bHmTC_GG3x|UTC2tSYQqy!Nh4iL>j$PB7^jNQ_+{KqAzyQfesvd zxTzwjf_jvw)1#6dIJAe^#!ON84U*|t%CGzYvuGC>PbxuC_l_?xpX2wO=p*<+Gvqt* zyw+!ctr`nt!$Tf3DYsCHrD32udFPM_9)z~C+5nWN@TxJN#0yrDw(rpzcyYu!i9i420oMU4v82WNi)RQH=u*WNhu?fM?TS&EQnP?+Aru#9P77|RFPY_ zNC}h!Ff74l$Cs$AEP&n}_hpxW#oj4Fr5nO+r-Kfx7{;|I)x;ZNuuIX;!XCjN_zF)Y z5HEO=L_DidhZfm{`XRMjYsiP{6?Zg7`$d^epm{WaFs|8XrgOq90G>X!C zrr;@HTnjnOX6neVS@r%dQ*^HSZ<)ezmte}%j~T}Jmakd#NRp&PNHq>eZ<0Pl=d9#? zj-3Btf9k43{umO7lBnK82)j7~LM~H^qh>Ro_zf!`d=#O;K}m?C(7Z9F$Dnh_1U#0M z9yqjmqfr4lf?xR!tD8b%EQd3_IFO*aJ&d;W)NR-Hj1$(E*;tzHb`96Q#l<~ZY9tY8 z_ahO3Na%U-J^mB=?r5S-Fik+i&~Vs0(we=1cYe!y>`BydRbdE(LHx>m1TW+qN#kiD znnG@#=^6(vaVvLGMl1?6r6hXb%eQ{Z%4bm2gc%~T92em6YwBj4MvUX_g&DC2ETsYj zi+4meQ2vho0JadG023g@RUpvi8E*CH+&`W9r%58;B0ktrWr265_m7{s(_pDm|<_Es# z_YC(-f8U>b$;SvM+NRA;&EXK=Rf_x_N#6Mc^|osVR@oQ=S&G0N=(3!Y|f9Y zrZ?;oXu+s23C~lY8N=~`bd10!Z$}-Gtoys{=j(oC1Ny-o4@+LeSF_T9nLm!TpbXY* z*IRAn6=pRSV*`d;x?58-+qjO0e`3cEhd(mZwhlPOVVM)Z2-oqR2;+C}@fAN6r?v|$ z0dO854bxowK7ZgRJe~LsfAc4tJJ;tc3QY2JMJIx_ye2X|If^*1iHL7*EH8#_HvR6z zXn=KT@Y;)lFm_e6;0ae^5fN-(p%j5* zoB>2K z3QU~X1*{Z$Qy4GAkvk4!3*^J9TLBj?oiO#Z9*?Qp$zaT;TyIk@3h`rqh8co33D(Y^ zkz+9GpBU~E5ujlJi6Pz6xC>m~d!rYe&A(wTlFFL!gssKMe;=Z-YnDb72E&pk8CK&= z>7*`cyX0~K(O(=Uv(N;T_|%Hkb`nJKF2DSFjs_|Y`&O$7S>;5C3+K8uF&&Nbvwp$j zY@!j;l+bL@X`Nz?Wi*_z^g^$79cpp*&=!thR&pg(ZHMbET^=Rh5b@xjm45RCi&|;s z)f4#9meKJ!$pjA9#WOBZp7;kVOo=`fy)z%}Nq0T)^WARc(>)~K9xuy+3%%If7lJRk zI#U_yQPQ297a|<-pn8H;;co-o$|ZHMbihXV3;#^o8|fc8W0;!LOKg9t&M=VI#?5f9?@$cA4^ zaJWc2#K@H+EirwxKDd?dP12j8u@-(tc^b8z;+YzA9AEVtUQXNKZHy~YXbj=M?>5g< z)G}@kbddE1021YEQYu`$zj^TX1D@WmxF4OyW-xy8V2n>=q`WBpf1t45>D^bFcrn47 zyTPe~51>Y?zRR8#!!#{Eh=j&YO7XnggO>|vTEq{BVNpZZ*Mn?Ii;MSrjCtrQM@%&X za-1`dF7qVjDQ^Go1#GwfMWf07*Lt-;-HtO?4n!QfY+4>DJs8Jt&hJJpBKZ9ZtruM> zYLgOLnz_hISCOo>ROmIRjN6@50eYBVvJ2=gN4Rh_BmqOLBN!w}+8{T^5yLHTTqlsp z+MpCd5{hjs#2q?K2xmYDVPz1`Dd>Gjmw48Qo+W@QIt{KiF}P^98tP93@k?gXaUTx| zI5qhX#~R)iak}~cY_QR(hO7yG2up9nw18R*xu<%V2SDPe6-Q_z5>pj^)9);l+DOgp zit?_5;29*Nop6%xGK=4P7BJB?f}|@uj!=G|EtHXrP*RFVC~=poBn5WpZWa!Zh6!mb z9%Y26t01Ibp&Uf7P7gNfJ0bU&dc7(`Zl(xI@f3mUVN_u}#~|fijMY6wLDCztSyVku z7}J)Qa9)P+k2#mTqgJKFQ1%j#`Q4FH@M~tIh?aFmN?W&)LUHd%q4*z<6s=7>=`aqz z$LAd-c(!5pqXh3X;9(nA(DxxZ=MOQpHZ}7X@q29z_`S9U$FD<*2we~9zCcv|pDz%H zXJ&%R%nIQOt(aP|!z|6X%%z>_=urtwT%IJaHyz#+ta2Zqu@?Nwx2meXkI-euwuYgX z6_1sg9U5?4ca;v0Pqcj`mdJ74v^s13uiWsddzK5Gqgva4y;M6UDB1*vMZU_XMpNg| z;2_^G$&+y`=7tPT8ZPef>j#1bp*hg%s~za56AFIIZ~}T|g3~M5Cg2^bapnY!*e2o* zRUnOf=;zYUVys8$4lD0K*~W$biM-OUR_-B`38Bu493?*p&y0Le4&|MIJ_*LVNmv{C zLciKGbu+Yy+o0B9ry%~(OxGVzvmB1^rTBW`e}b-DiB^3AaOi8|AK@#|JwAX6^FcTK zQs91%Jh>p^;_H2L6zr^(`=OdZl|1Se8aF~QF7jI3sbnB*8-32$8obC|np0L>H2xNPAm| zeU3Q^07bEDqh)+tK&`BJkP0e^_}q6efQ+i-Vxw{~PX*L+@tBVFDb;j7rp1<-0l5f% zm4=LSAU~ubgB^(So13er0|}%d#SSFTh2W?IHK7N3{CEf@Ak;E=AMnzk+Bda7DrB5R zQr?Ucl=pqkk%|Za@PP{u0RaBu0z?3S4_$x=0Pv9u5CH)G>Hm?( zlhH$Hi7I$g)B-CIvd{aBJc`IFD?JqGjkzG;<`kZUJ#Y5MqPsD?axlCq`i7J^1^`Zr z;QWBIH@GeZk|&|<8pT7`=4sT7jaD;g`-GY|1tH-KVXmYk6NmG-I%eXR^&;jpUUa`N z#t!C%VU<3k?)O#ir_!Mt>?OM+yA;GAfjD%J7#Dz?bp`UaDCurUikwVi_IYy?f52GOOu zUwmOeaHtY7=ki-3YHa^`Zh{M+4}fJ6xdq*m4g-Kpf^q^d7g4&hBM-*65|qjdbJe;O zW-4-cq>|xyFCMXJ?TJnm8`F{K?%awb%(#)fpmhfdQQN5&QY#8tj{%a7yoyMUc_B^@ z@{4^Q%_eAlDpJUevU|#JDUn3S55}eF2;EOdP)EXsCsi1sfdsA6okW^`@yacElz_m) z^IzthEwI*k@|^~Vy7C{WgY*>b?%%kCZH8EPemv~RVtpub z31|6gpMa2#qxs-`wTV5!=j3CMlOZ^08vMe1HKzW<$N!vSy8K8Q|jR; z6AKoOsvrThOr0PAWj?cA0LraZ0#JdoDFLVyzo8_5@3bc0*a#rGQp&R4#`hT<9g#`! zWTapwycF5v_@yX{ic3=%YQzUtAXqH-Rn$tCm3#gzE6+(*0#509PU-O_nd07|;!XTUm*bCOogh&V^a)F_({D)24Mv0J@r1d8e^3PdkGjOVv8S`T0y`?H zmidw=5ZZ}EP!T60Gl!8stjIteD0@#_@~A0v`)EB3$Zw$ZKfo)Hc+Hrhd>vu*P)Z)b z_Cf8QquTkzByW|0A>l7j#0<>ok%-@bsF34ql0E?$YhJqQC+vB41`27bgM}cHgbgXu zNmAN;3OM;naIy+8A!%aF;FsuyJc$ROX6=cBNpSJgmw5i5qX0QogNz#;g(7$vdIghJ zPDd_93;Z2<0!&IoM?UXYjB!ASsE$#Nu_y>om6$?K4sy^$fM7ze#%urhi5lw67N=Cq z%S0EgUZ=ou0QbuL<~h{q#`X9MBfX~!n$Oq`N({eTk-^z5N>)ei7NgW#j_exZ1cE0d zZ#=%wQ{M>x#z?XgHOUnWuKF3RpAxQne;55wO#OgC2pbM18Ji$EdH5wz^JY}1DIn&) z{J0V(7l?o|8K#OC1YshH=kIB$#*sQ+WrUF7?m$2l#e_`JgJ*+=aV!4NDvnNZJpEJK zvRwTG=IKbqz{hNiH{_^Sb$=@^Z$Y$vf;gCGAh`*@x+6Z;K$Zqso6}*G0Syr|Yik!) zN_eWEZ1Recj|Idh7HnH=-fGAUW%;7pUJix zL2PY0mW$YWirq+QbW)3_sMn|rFZtu$LmXyA`@;7*+Bax@3?LMg-|)dZMvs)Ju~a8A zBL6v*e+K@Dn{TH{;CX2vU2Y>xV#AVw%MR*2Z;6uXIvFVgbk9#?VojqlD% z+f=Npm3CFEW?S;LR&qC%4DJ=%xL|DDFc@QO>NR(9C}OoH5D3MlI51$k=^>#fKtitx zy(N&ukkAq!l#q~+kRblQ-^{(ccO}`7?|r}L`}=vUy)$!W=FFLP=FB-~D0{%YE}gX$ zo14fNLLs(&Y>AF70cA7C2K<{Einf-6yKIJg=Jw+9ik?c`HPsrF)|Z*82SM{- zYAZ>?6zmB0tH_28!HDc^u66=7M(NJxTBCR;R!5y&XAIccTyK=@Y;K4+Q4LWewA1_x z`9Ia48Ftb(lssXoK4Zd81b2n*#f}IBP3R|JW9#DlrEyH>12EzQ=DUD_F2n8gc*p5T zDv#?^T6kk8XjK^-vA|eGv29YO>pkPu1Y|$ppi&VS#E8 zRhL)ihL1NgJC3}O`2#A8$VeQt0d^&-w9W$=pi+v{DOF0rI8&umk6id{(sSt?8Ayn6 znVW!2Y+!P-Eeh4gUbd+}+U@1~V~Bl<{;0Jd)*t2eKlMk%4hB^&P^bo9kizigL$?ZU z?P_yys0&;!UqqNou7@c zduZf?WbpnL68@U2b_uOqDV*0Q6f!MqrW?Ts-Y(inz=(JV1JaYDvQZpA#@%G zr9MG9UHW~*>H;h9N~T)T)dkEbqIfk>?EV)PL(eja39XjNgRo9ANv)H(5lW88=J+x{ zM@4R7Wr~}DLM5)5u|XYYW1%tzsf9C!_Z;vDfh?~ULo=TMxmtH#4%WTTd8kIFcM3Xb znnlY^MkiV^YMu$#@lQ2-;$ckt$R3K%I1{$YUItLia$u&`0$opy6J6_o4RpeFE|_Kz z>vgoJ{^ThE`x`4qp^Mb|Vz2JMavhzkT!;HquA-gF<(W02rA#d~oBpkYQ&8Q!M?O#^ z?#Vot+a(LS|C8T?mFz*BfY9YkF@KCzwy2={t9+mE8rV=;Zue z08b3#hP@NF38c^y*@kDQ_qU}`wBuz`D5`e|NC%;2fL%S~kf^xhVkQ@BDsg)(jQTg# zyR)QZ4@4@;Z8BaWIazuW$%)o;q|V4VVV;5<0|twS6YoYzv=jl?XbKg32?+W{^)5O{ zr$Rl#vy1v7RBG!qHT`CzO?e~CmvIKrfR6Xs{sEdixX~1~Y>T%d)aF$I0$z&B@Q6hI=z=l3;oVy^E>rhd4qDT}FniO)DXhO_I^D2vu!_1| zq7RrTnjNL766-~?0h(sTQJoCivU}ur8pNTQ=P@!;Etss)U_rVlh+~4{XQ9J5lrxx& zvRcWDLfv2I&+uxd?@+4+Q%q=d!^Wx`9E^7#sc}nb-og}BR!OAW??7d`HCJAn17nij zJPN|yBEPhOIWVSZu)=V6ARnwQ2gVc)77TY6nR-sA)<&toBG#|SmIqaCCNmrh_48tad8?^GI<_)Toi{U*KYX`VO z_+rq7bIr)!Izg@~y9bHE!OH=Jr`c{CBpNcX9|<;#t`eR}&%(E_Ic!4cnY6A@frt)V zr2Pb0Grxfcv#h#QibqYLo=np(>Qy6B8p#gKAe0H!fm%PBO z-6z_{h#dXwKr=Lkl$K|Uz`PQD(=ei;-MUIXG(-%}{0560obga%p;%hj4NwwczcU{Wu{N(Rf!)YZrebIG7}4L%?sE{e3_akv;o8@sd%w0d86R!Tv6VjLnxEhSPp z>}nJj)*?qGfbqRq-N5tkM8tzV;F5_SZZ_sld2%xpH1*Qc%psZ+%&?Bu3q@fCU6z~I zv(*#?)gv0(f(`sBOg9n;REXgv-vaD4FOeFei$K~(-83L>U5mOP<*P5){`Hb!a%_t@ z(qAvHY7s+fSd6Pv10g^)h6_X(fNhX(w1|c&*t;RiXa!~zz_VCRXDZzl`|Q)upwx{3 zKUu^T`HT7`f7761n;j7LbO0YC%dYEqHLR0#~CA&1SQbHerezA?zJV(sVGQOe`?)4-!g2ND+l2LP!B2 z5~QD_7~N``_kg|`2pPhuB%o<`-Hu-$bl8JnSU`Q;;?Y)Q17lI=G5pn%C-v7e0@MJ& zEdMJgqeXDOHyfaUss})c9sniI0ARrw$E{Nb;)eDTQ#6Jlu7%(-RxBSjMP<0U*uN=g zKU*r_Fh#wXStzf5$Ul8S6FLIDKZrkpbTfZaH=wBWV19}&#uOG{U9< zmCKxqdw|qBv^w1)w+$0>{jbR13=@~>pE`MAtLXN>dXJG5^ZdhpMU=Gj!1lI)^(QpU zz9Z&`1|VdS(e}6#_4AngxLwq(B@&LGCpaG81?eQOPnCz3B6YSd4z-oRP$FbMfKBd{PF^rG#oNg?BhRNUNKV4>EyW0nWOPI{u#g^5et+3pIpK38VJW~ z?Ir4aAfAzGuCtG*koBWP3*3Bjq?G&2zhTlt3;y?5Hnq{do)|%E8rBhB!sG2OdE6)w zi?^W0uyqI8WZ~janc~=+E98z*VlV$K@}*HCQOY|f-Co?jPL=-{C6@VrEB6~M#`$lQ zr;Qf-jk*c*G8RszA?>`GpL95Yql0qTK~Ev;TqM{&tUEI#%-%c1WfgMoF`};QhsZPG z1kEkOz1u@_;}|iz`p0OYYb+&vuv+lprU&<{L3!60F=JL6ilP91D1Qsmt^6rWCsk}= zx}CpWjBJaEF2=T@&lszDEo=m^nKGZ26UU07)lZ=11qt&O;Ni&R3w`a_YIe!=SX`M7 z#|jHg_&|aAlo}V2Kmp8;h=BP^M5Ngwr~L>LQxLnu^`8+E78qT0eVkp6VI=)~iI|90%KGyH z@iKLpE3mhWLRmIq_t{GvBmNwcKRz#zoc=DV^TAK-ANd;_K<`7J@zW?x>`?1(u@C;w zQ-4MrUM0wfE(?My{wyS0&kre$f zg`lqkl5D)}3KGiWIz*-UAuEEXf{B%2jJ$8-DR7)R)kd?VQr_Ajsxz%5CQX*09##pb z%IpY@;HO09eTB6zsZv=-KdG+HBz#p@I>l?+Av{3z#Qj*+RDYNSob!tK@GSWOijHT% z_t1IUvFfJOdAHE0EJXS{NH@{8q=Q6q--22|(}ZfWFAD&rDD7IH6}7ps)=1!f{4yMV zth?C01_);7lAKO+fW==?Ix4|~luvewy)xi=!QrKT0-!V}gviaG8b@lP=Q0*ZJ;|{` z>RFCuQrnK~G=IwMoLi!cYlJ0W#fZrdmrerx$IT-fT@)|wcn49T@D4OVc1;kG44CYo zVxHCB+y-wvj4^kiF+8i$R;U>MZy2d8h*v4GX|UeQl*@^x7ZRMP6`yHN66>)#wiXvg5irtlr4QCvta$>@GY11R(glj$l{fM-_|CY1k@>1q`^g^}i?$Z5n+VU+sDz=NW0 z=e?YZa90!W3661FrQ3tG#e5K@aLC~?)Xqi?+1-E=Jha%yX+s8*bSC9SQVefdYs}+0 z6i^tAWRCLDAWwIV({p$twT&*eIrwp(_^rCGHV2l`UF_{UMJr$Oh`x2vxF%Z{j0V5W zFsbPcmR}X$v|W`|B$Te4VGV*s;UDX+0k_lZ68~O)+UAkhU5XK2HQ9@N|#4z|991F#U~SKI8en zJgV5!&X~&N%@*1?x$E5j;-Knp{PG=fRFzRP^MA1}w_$nhqS00V?V>8$|M_gegVROT zSbRnrBis6!qoa&b*=q6DZ-48-^4|MKb#J)7lhok`eGvFyIO&GMa4Kw!PApd&B;({$ zGel?R4**C_#4Lori*zFvQePY=rV&^S!8GB>xCu)mL)L|0NN8A|4Or(OCVQ-!?S)fG zkWo$I?0y_eg82}}lld_I@QjX3iu-_dX9j1>@1q>^1&}!wgp(G&qUr=7jnZB2drGSOi3&EKxrM94G~wEK&2R3z~pM9L#A&iH^2*$|!V?Y;wt>q;3XmCE<%Hb!s zGtCTBn8AR!3z6iS#`eN6(;tSo9dW!2Nt&ofN#m+EVruP-KmBdvE zZlL0E40S&h*P8sISPXZ0uTAf0isFny-*xID3lLOI(vYZf#O-<0hI$qSGIPy?aO58B2m9T z5y#Q%5Y9+g8E}*v19h;$sJ9>)iGqvb&+v%z!5xS^6n$Itrl$RLTy`%KtwB}ac6sX} zQB$*sQyP!Il{YDoPzx%6&zWe#TqNIKBs%;fW$j|oIHZGhH=$Daw}~2qpz<*f8GXJA z82#yf1kn#(EINW}RIQX(EEb7QPAs=gE75HCnsOY7^57+6a#(fCKGweX+^|Hf@cTz!yi^Rt%22lyD+9+U z3^^t(g<|-t@|30G&S?a9e6G!RJ*~~tp4KcJ`-8Cs#sclwd7-h8*PXNMuQ9t2Y4HTM z01E4ymWhwOx}CIn+3`t;1)mvJWJ^ z*D6f3Yr3^SXZZ?YV=;JUg%~&}yLuUiTjyiA`x215Rd8u?M*30-1RzISDT+N9t()sX z=7`i27;7#@8@(7EZ5*vJI>tDr?RcMYB*G-GbusHw!DHl>gG6=7k(JgZDh`u>jO<#K zN0A0OeU%uG&d!TpBjVeS{(dy<#Waz@%`b+Ov#@d^W>K+CzExPu}Nv~ zWy?FxIF3(x;r$2Tx9Ut@)!p8zPc=@}Re#s`uCDsj{HjmgZPm+qW3vWh|M`PO-f%lJuj(_rRi9;? zrK>*MI9peJR({oI?Y8O$`PL!*wK^^rtrdo6=vT^97@?N_Wpevk(Nr=V>#;lHmdQuf zikcFCRj;T@`QipqApM7m+N$iNqia82_Hy&%uqQ)=nK}1RF)`DN!Pyp%o!2n|W82tf zoVO!(zRx({;?`ncOF^-^w!6T%0MBtT3cy z5LYn8d=yKQ2?eoa>_X#w(G}-9Y+PvV;%0RqDniZYTg&CZbz)G+i|<$ldNXkDJxi{o zWDO%M0YzD(82*NK6d9J8PsYnD>5dx>#LC+-ip zAzz9T^XB*tV@KP3cY^CQhaiH*=5N238JFeH=*x}EsX%_2n$fXKD?kmnEAsFxKtrB& zn2WPL+~vkJ&ObX$OwK6ATJtZLZdTIf_1tZ)_Ogpdf*8it%7a$y8si!sKXw{B+s61( zFd4&*_%+s%TqJjJbi}U3$N-5IhmAHYMH`H3trMB%OU?j#d8zWm^`gPQR9w>#8c~ugj>#Zw+kc$2@6sH@z)wq?Na;ds4fL0T>D7kF|^h1}*$=Cu)k`3Vh z)D&dzVD_o0HhN(e0sF5g3umtU2z4ExZy;Xb7}o^#K=n5{>-!G&co9Y-Twn;htXiJF zQS8F2ookN}qeIK9A*a2mTJAVPtew!w8II%H1pXGJ_u)@rdLn;vhczbV9oF_nguLS= zIGhRkDlp>T!z2W6uJj3DN{HJ~RbCfMS1i5x6=LB7@`spZIM3inI=~lLWG#iD8SXb; z#pzq8K_Z5es7hO+)9&TTT;1`M1mouG9J0>A7`mx#VLX^&6vWNfFa)bD9d2~O2`60UgyT*a z`BfnqX&w!}8#fLpBnPC!tdfN~u&1(Chyv&_UXuuyC!8zPxm%7wo$Uu`tsDk3+1oUAi6g6 zCzk~Z!#u%5Rci{EQC$FSf*qIXq_6z+SrL-oJ66;ljN48lH5;v=kZCBIg3CxX9J+uQ zUsVVqoI8O1E07FWivWKf>b~+OW9U-uI_4(b=gYjtcV+8tYk5B(ND% z=*D0gV#mdWyARg*25hybphtu`N3~eMlD@dbe!oUueVnKeV{7HDo5Y~u+fi8hAV1(d z>r#3$GQQYAT1*5QsiEkHXkm3~w(Qv?%p#^*|6#^Sauf<{Vgww?{u@yxSg08kU6b%P zV)baS!;izw*EgfHcK7IDxm}^qRK+{ht9mh6lr?Hz%|J(24G^UQ8THKu_wk|Zv_;d@ zKLV?0uwB5-E6iN~givY@y4Bp5Ymr{iai)cG2Trv1&U?|bpWXw~XD{q_%9nl|7%iW( zMY!VizR9o4zby1u$ggY>uQ>U>KDkepLsO!@!swgPkSkJRMCF!REWY_QZmE@5q(s%M z3x3w8I7X!+!2D!r9CfNuYCnI!1LnL^Ytph5>U(y<14x)Auf8oXIe4u8o^rfcRhbxw zDyJbL*T}>`dHeBVvi}_Um*YjP{|;Ha89(>QMN9m({wL%ew+Cwd&&fkJi;DVRJ&aPR z0g=nCqF7*Rp8WduK()MOvnVS+{t*D)LbG5kBs1&fl>Pk`I5)h#SAN7Exy|QjHCm({-aK1I)e@e{`c2La}1kefLs~ z9__w+ioD@FVq!6eqtZNtuC4s^J7Sc7iflRo9Q?s@{0ZVI|62L=326R&Ir&5}e4PI= zr|_(I+yI`I*~Xd!7ABCRsKdLHP7In?6u8`ZqL>}L5*j7;rSj7g!85-nqbG@`N!Am+ zN=qh?DI06FyF-l{k48z1*9ivz;!>4Q{^9OGg-o9$LbabFLf3B}j%t+3Zfuk=Mxny1 zP7?LgwgNQ=K}skcWzkY$uYWQh1z{imOT;`i%IEIy6|r(*FRzndpCl?{nqT3h*7F0b ziX3{fNM=-&=vv0fskw>Qun5C@?O*W&6AUcxI)~^|6Id+_*l#=;KFiA>?D(_!h~P;< zY8i+w_MuVg@>s`WY#5nxrBx8HHmHW;!Kt8WaYC=+h%cvCaPwV+fyDQa#+{Xp+_0gm zFnkFf1VHOxLXU+9@v&NAR@i@i4ufv28X#VxK(8ou5?%pSzJ+1pL$B8?6z-b zw;(;b0T^dO>|Kxq{Y18&A_h-OSwsr@rDr(^!8@B0RDbb8Z-fY8l15U8P78j; z7JvmRFSUNn76^0?ROHw_>+utdL1u~L0;7jB8u44@qBPWdl{&GoZ@l=PKwO@d7O^&t zJkhl>H}JrIsn_K#a9-fJV>JP59SenQQa+j%D+>39`Saegv0Ky?!VB7qN2u4WTKCy$ zcAzmktxo)<&$T1aRJ-IQdM#PaRpUs68Gn?#W}Ux246kIZ&aALx-N&@a9YJq|I9>ay0>I zg7HemCi{%ZEOMGL4epe@;Px7MO-4+vo6glDV5Qh*I6{M~cR(riYhhn5zsiWw8M;BM zAbAxY0i!lyPIKsd4u0Eloj`5?XmJ42#n?!n-aO`%&w=tcMp-mATLT%h;RzoGvFJsW z$%4(R8k2to&T1ic)=GU;we}7A*0INHv#uM}I$ovMaX2JZ*5LcTxp!6vB1h zm>W-MMHxMYtj9q?5@Mb)uPxx~sX?Qa7oFI?=)HYgW$me=>423u*S(HzpvSHReg{Kw z3_rfP2t(ZBt0ZsliN6i0E0GofmjKRI!MpwzYRSskU)Ra=PZbq-f%y7U#bv`*b5IET zPAn5ay-FPZT6XDlSdL%f2=tLW;=AHcMSP;r+<<;G-;P&UnoC16C$joh*T*~4;88{%)U%Ed|!;356S;GI%d*SBj+@Un~Uo- ziRYQXZoM-#&i;Smo9Tm}2bwB{@4M*Rab%C}ZT0?5>FHQQT>r;kj9u?wZAaZO3R ziWa12s?QJ5Z|Pb5#Or!$tZVau8M6LtQNQkEl1iALA|=Xw0NTD%C;%`D*BVv9C99n#E;2p-WJOHV7YlHmsY%x4^of8;xju=_?iR#=HzyO_O zf7u`pJ4cxN{~ei2P{LVU3IE5nfkN>6K1>^6QWej9?x2;_33EZK6Iyb2B(^fo+uPhPM#JepeK3gQqK$ z2BR}!PiunpnqG}P^CML9=CoLW&)$Sov{0Fq6=*dZ>5WxV=4k2_WchDrZz)O2 zv(6Jk8$MGgc_`L!y!AFPK_f|>?Td>m0uMI%<-msm`^pjLi_pQ3qEc%q@q<@HYb8FQ zA3@ll+72u%3rP$D#)M65T1gALP&TG|>r0?hbNt05J$~>sZhz4N(JHoj^jyV@Pi>!i zOr>0S0pu0$$m4zuOOeYi5JMV&fg+&Q{4H|5+b37mx5^c{SPb8O{?P^U$_qr(Dpj8s z@%&*Dw%!AcO5hC%xJS-?mu)$KZSizcL``vjI2OcM4q+S(8>*MES1uG2*I;|WmV|RV z9Qvd%&+wFE_tPMmg~NLk?_=O;&G%V_4;F}zVWL_B1e}G#L%Ag2z7*lgXC@>v-IKCJhbjO9j0lrK_T`bnZ#E2?<)mx{0->1;^Fzh9)iuQZZTr%tp*$}k)VHc9Z zEg3c?`~ltNy;4jLbrC^q>pfCjS@OB+jzy^Qf7Bge`(G@zWSG-zn9U8tw>>Hwk>6pd z!%?H+UX)FEx&sYOfn9(t0{Di{)JDLG(-Yi4YW$6j_&fm5-auFPt|kUFLSQqL+Q`zd zlfv$Ygh_XzI6#K91Dj2|GktCI?2J*_?0Pc3sklRIHLw))PFM#i*s>1r)%A2uIJ(1-EnJr@%?^jZ@eLfZc*oeR2ZC zC15TgAAm?8g^`9SUSa)_bL-9h-=SE2^$Y_QtYG&MJkQBOvGyJ)@|O zi>s(L)~N%^CBQXdK}`dtLk`QXFYMw#;hU*PvW%}0YraV0!uf}ZO)g2l1)X>BkcNnt z838!~xi37?)CuJh5DtAE#hVu1?p{a^qb->icOUw;t*TFywGf~@*5YcV^Cpy+-(u#n z@PNDXRH~nK4NPu?mYLuu9co(veA!)~igK!~oy>TMbN5L1S*i9UoKiEtFh38RjNsk1-y6YmNH0>h5S=v@(3emVfdD_%qR-LfwRb>flp!$VI;YDb_Rii`IWHF;w6+>1KpQHyJwOkCK31j}F zd=SA=%g^OASBOcWGtp))JY`pkKV}MBone7X$QB$TxOC(gO0{t0f@OX@V2B0Eg!@G2 zVLR;ra1!dnq@u1W&sVTFwOUa(%EaY)NpgsX$qJau5C_?W0-P6eytyhhTi$vE`3$=6 zA1n-|&2&n`fsSs9Bbc%UZ$Mn-a9P^gANEiXG)LvbSBZLmk$mefqPDGYr}+xTo%t&M zV3$(mge|ysi~7Q`0$4@i=wmma@uWn{)uMIr7pyV`<1Orn*y~F1QPkn%iggS+qBvac zHwPdtJrP4cbu6MvBH{ED1bp4k1ItJkzq^=f%|=gHAINL27V*R+MD$LJoH9v1f3;XN zyeeO1lO=dmHd&S@I9txYM$8%8D-X-h0mWa$BY#nICg%C^SCcg>1Ip&9+x@Rp$v<2p zf|0(>DyV-zu@rRoP%^o8l7ZS9yUbWX- z^N}rw^rn2I`52!<8XQ_DCbPRrI-Hu;;z6xjF$>jFyV7O|NK4iw=uq52lzPK zmth2+3g|K8vB%y%(DA;h+v-d$Cl2gJO#LTVyCs zeGizycD5ToSeC-(?}+zL*a8?RCaogB6^h;t+KgAx>flFN?3dUNi-$Q<+iPXd_2R&KkXk=b8Az*7I1=HTW3SV1BIau91~JV4rM%(> z(U`z$7`+}GMs3lXEj%*+AgSl`t2c;CBL7zFk^OE`ZoUyu0JOEi<*Yubtj1^Vb}N^l zZ{A)!4XcYfo>}){6xyc)+WHy3ig0{&lhi$GaRB$IShj&)C}Lt44En+m3(l{i+(QJG znRwQXimbXxjIH|*aZ>APw0AWSNgi>N7&j=tilU$iYS5fC1cpl&Eg!x~%z@Kv+?yYV zkpLBl0y6|Dm3A*X6(b^`q#clF*c>TJo&hm-()>OC6hU(V8Yi8zcr;2Oy(AJ$!#beA z7cuKV&lI+rXnGnWbTQpC@vTPR41DwiPf%qJ!}8v|g-Irhwi=KNUQ~fSIm1SV)RO>L z7szYQf|UQso5kQ3mI}t*eNT$>JK>9T>1d3$D>-sHnANYa(bnv&c>>HvapXE4#9sCY9@N7jpahiB)F3pkC`a{TvXK=HUqZ(865pfd*UDE zme-Ibq}76CdPn~~xurrbNkMJ(ZTSOo_>aZRscFpLXsR23ivsZ@;}-aZXiLcc6nzNC z$>hnl;7?0IHZ2%}nt>lhrA|eH`CWPUkHw5k&2Q<^{WQiLpnKbo@aYJ4D;X>egG&#>V88XiFw}~-rd%K`hwIum4~QX8K@JSI zT~9#_^@W+22g6Wb7;MHFPeBOw0|cJH1H+J~Ab22P%fK>tU>NeiI7owu@W3!cn2bXr znDMh9XybZ-80uTlfq5_td0+y%oaK2i4E2S9)TJO=O}E{u&lvOq$8XASKcNDWt=9j%fo^pZv`6D!}4Gl>I<_z z4~C(>Fo%0!RtC}xdVs=uly2|<1=0+8U>u}3=D{%Jf$_`qZDO{+P(H!t*81d!XfA(C zZwE1I<*3^=6_zm=kS8ICpDS*M`jk&Ts$t$E46;P;&{>D$7j#^FhXVQzLqU0|4n25> zrhV{Ez@jf&`3ov9aKg3|z8JqKFUGD)3q#5$SI6Ztr9t=Z$VQ$QWVJHs6` zeIVi~RX;{<`Y9$M<`*uA`alGZC%Sp+gSwC}-~`KmsiD{ln^VtV=W4dqi-$msVyMbD zATk9K{N|gG7OLa-*(1RBqFjDo!tbZC&V#2nxuty{%pb`?>B(bytX?&R$jD7~QD0m7Tf; zgQFmoR5|ZcIUyq7WZkNvx8gfv{Zs|w*1bBi0g8gw?fP31_)h)(1i$a*x7DV{OaBG- zF0W(^@;T)V23JT3#q!{0G zfgmj6`#w%}m0ZkH?Vus9C0_!leSV&n0R(BUAXc5ALrSz(JSgnybC*Oq;U5P|3+8YX zpxlw+oM7KIRvz@AXe=AS$S~B>?Pq|R`KsLdAly;DLo|mu@|VsQN{0v%7>DTJBij5G zkc2L#H_pEIL#Q^r$^>}0rHCAoU}!c4h0UkvAYrdXc6DK$NI+lSV%5N8s9UH#(f!Jp zFQ6FnE&S2%2Kzd$018GipJRvczHJ)NDKXJ#)CF_il5Z-oPkG5jMsXDi<9T8xQJjss zf#O<)Vg~*8Ul-}?z>x%!Dm%?)DB|&spjt_~sdfVG#XNdR)}`nb%TKtiP^HM$hcS>m zFZh<*y&o?vSF1Iiq3-wH-g5gxtmS%&tAm(PZu4=^{1`5;`7!E2-U@x?2z^LLCmvKX z%D){|Ui5U_?XYA4QJ%^Yh1UYmv&C+th=QTu8CdpPS)x>_gaORQA!pyFiL(3=(cChU zqZWRG%u)P+OCbASgxiE8UYmhXU@wN`wU3Bl^cMiVW0p{aSbH4)RGSAw{tWqkLca*= zc_22?hsFt;55#6)sX7SxcQz-C2EI^rtqN3o>xU;s`wkUds}RXJc=4f<2NQA)x)Hz4-uN|vJOm;L0N#_Bde+R$l`Em`gW~(nXMTy8=VI!Qaf5=qAuMM zI0=IIHy?dHZ{)p?fy-Ya-*`-zkue+wP;z-mmOd_8LTZhy9xLmQ5{WXULj{d0+qHo@ z^l>q0y|RI7(Fb*p4OD^AQr_wqKDFk)vhI)t9LYKHdozc(j*C7QhvNqm}qqdE^tY zBU~lVenQMDjdMQ;@Omz4AJQS;d_tJDCzE8vDt_*}kooKGJzHbZ^rTplNvKWa4WQX< zUrAv7Y_Dbme~)Nivl6>oZ>jGB=i&20=izf0VCaX>1Nv24$026Gw+M~#mVKwEY|m4{ zng5l-pY#;|TYi6Q#2b9@7WsEJ&B46Dw;Y(qF>`R^HM~<^@RX<=J*N{Z#76wlD+KPk z>`i^6o@LZ74JBWH3W8YN$FP_`B2G~r_bRYq;gbZ}DDw{#ye12MmCAH!0?d61OQCOv zv5(z;t`3$KmIlqwbX4ugBH!=JeLid;-?aN@a@)Vs_rhftr$A03T*8+Lc`M)62)VY$ zVDZlYbAWN>OXs!jNzz6qGC8ynmYS~oDj zC(o?w@CDVvFBnl6ur9$bFP?Zcb6SC#3ykVsERUNkVj14DH*Z-?*(23(VkN0@oZZmT zDB%rsG*;HJh6`SqHJ%}!9@$v<$DfT-ls8JMUsy94dJ82`cnmi$o!6l%eZFc>f_ zNXvrwS%@FFFYyKuT8!AB`455&G~dJz>4xqzCt#qm;~YJ95{+`$2^aJEs}k@&nJ}WX zwjD0RI#DO7MgN_+&fbobI*m{asn{B7F1&!JKNXh~_O!(fvjBnC>O{fM*d9 z#F750b5R(*;?(zDLB61P+y2oK)-1RX?rY#KUGjBh43^aJg z0Q}pjZi{gbX$3Xz0yW^P27=Hae$-&O2bb1S4~06eBV&@2#>X0c0Od%EHOFHu9k{E4 zUkIaRM{KCi7-~(Ei=Kszg&GM6vEZR<5DEPD8VSRUVY!je9y1!9uzM52p+&E8RlaNz zAk-DVBSeSCKt0s0DZtuk0*orsS_@_gTd=4IE)i&Uk;Jn|i zDbvr23OJ5FXG1`UgV5O)gp=sR;wLv2oecvoYpHcN))a&)gxclhFP?*u@5Lyl4c4dp zwbtPeNdO-_oiIuO>%zlRY`BxW7RlX9^9R*A94~vTLB$mF9gceJrY1JPBt5Ei!XrLA zY=pHBC)22o8yOm9O=M{FOi=R^4kKK$M&Yz)IjTsQAR}y4+gdzn_FL6B*la+dCa#5{ zsGNg0r^s8L7p?ve^G(;c4@`PGCvzkzzB&fqFT=G{pU&j?@=o~lnfrpM8Fv5P z7>^TF=h!VBsDex?fPDb@Ar`^*hjFLTNypb)UjQGg-dsje9qwWjgW*c&)u_cYV4Lkn zS!##o(_)iSdc*$%BKzrChqxQq0UxVv--$VjF`ud!tlz4GGKBIZJD(O}_0r>Z_avvg zCkKtm&gl&(h7-I$r%stVs~SP`JrLCTBmTg$hff%|37kjK+O5$3pq?!Bdi?4lw#?pZ zA1q|kIVxa<^Wt>*(wm}n$dsKX2DVa;&4TuVoI%K#f2L9j$z`a@mEC`aS-ong{-zAG zdu6EkrVMjbhJ@P&^L>&8#=cOx05xRy%VOyQ?9lXF8!|scJQrt}7j-TRfuwq0oJQR` ztZC8MjO3B2lQAb^FbXneP@^K6o`Z>jRcU5Vu#2;0jcj^F3^Z@Tce63Gi>cN%2>6;S ztn1aUJ_+8)Z)=`h{|Zi^^I7=p4(Q$aQl}sxHpiG#KHJ2a5KY4d2-l8bV@^*njil59 zM4EqQ3-&ekwVuNW>RtvAb&;u8`Ev<|6$D!WQ_PPDJhyzVIi441+-KV>oRGZ_db~QL zwqmXgG!UAAdv;?^7wfgIMp4wmh{pCR-^-&KVtz=P&3C|z`PQ`n1ol9B5uhiG*FNQE z_r$TDyV@8jEL_ppbe}P;8$Q)M7-xc8iSqsmWhR*)17&Lo!T0OP6oM+<0H6aaV?XNv zM5pHhDs?I&;mpcdklqhrn2Rl{h%E-K7Irb*6U?yK9KrTC_P1UH!2q+rrrdIXHMj2r zKgXJM+n7O#wmTp3V}Mv4qc9!e8+xwl)zv z)L2VQ)*I{Fz=0xUJp{nzu|v_H>*BG)fC_4G%5usWHP7~hPU_vQ7$-O8VJ3KiFZopQ^Nw0~9SPKx3Ej2b$$Q+CEG?L$$lv^&Gs0m~Evp*f4l83ql`7j4mc?RS z3hUBcGH-H7sW-R1H6`N?xmelzz&~z6dllQSYJWUS2h03B%XJzpr~D4$ab=5s9M;a` zT76R=$B;(rDCa#6|IbFCM73APkA_gV9&wAXQF!BDLKtq}edl2IdgC8Jcn0GA*y0Cx z$~ggZ^8|!HiTY;cWhg9CPl5SxNpqqt%T%V6o_m8!Cz_97zH@lF|dn1itYCLQ5cg$;E($WN-V(WpVk#U1CHF0tHYU z(u^Qn*HUN^$zuZ{ig-nSy-Um9EU8hSUpp@)BiLcvGld>##T2^G{d0sKXvGn>&r+Cp*uer{2b>gOKzYbe*M~*! zmkjlLCWCzBKk(4C=`B(0(CZtU@9@!CdVM1W^62%A6v(4jZND6JA9^{c5Bw(R)#?aP z<)WTPU=F-99$$do$O@(kGy^^$ISz_x z@YlCmiHN{w5OW7V?fPL%(8TeKJ}xm~EuXcaOrdgMFMe$7QIo_S#Tz&<>4%qZ_7 z80=Rx&kQUS%Uq;cW+RVfraJCuVaApBJ0?~~THvhxTO`rXB#J?G#kN$Zz6(kC^K11MHK5LsUPvh;t$+ zPYwyTMiKN!aVBh^jdb%6PH_kXVGKn71W|h%F;`LoWga{N8u<2`gj`3+BKGAMSTyae zKLIxxMbN6{pMm%TFM}(cQr^#%!l#d>vy_gho>DTp7;6CX*>jNsfJI&aPr6cb05^p} z05&n$idN99>0~m4YN(ZlAmGMe^QG;&Spk*x>=#&?`!(XY^H~T_~eBQ*{*&!Ka*gGJZ#x9xw3djEttybol)_V3cuQRQ~ z*{6_2;^xPG5_Q4Q_Gp@gtPUfQEmH0RV&#R-_FHaUiq!+BFT;}R12>tM>5oF|3iT1P zuHvsXbsmZZW&`vkiF$f4ZVcGmNHq9RKp6X?zAQnXW(kBBmT;wm$qv)vB_F|3n*Jw4 zxRt(Oo@vvOz}BwbQ!6Q93*sCc?3T~i(#{B z9m&ryA33I!IbvOcLM%wTqnb(6IU|b2*du?9W!RNKN8E!$qF?rtkj_ctXe}SkX6T>Q z_GD13cD=*h_RnW~pdER2w)p;8ZBGVAUY*U*Kez44pyky=vKjhkxIGyZ!(HE?jv&@Q zu?EA#M+tT}EDi3hVElQ`%4tP8>XL zz~D3M#j5+-#yTI?@m%IgVJNa0A8j>^mREf)YUK-`iQ;Wjc+0Xh|M05Lcx1aS#pMFL(`?(=TUtlh{gR6Y$a}i&o z&Pa-7%^n-#dE#++T!YeHxpf_v2@6f|%EKMD->F>{qd5L@C0#XF%jdtw^JH55*c-@Y z>ou&)(K}FzU|J0ab#t9_C5YwL4u&+pjq>?+cdj>hFzC?MZgwcuS5WB1 z$}1l9#^-V5-h?d4P`qN$HJRE<5zf*pIlfS#(pPfGo>W8NZ+ZyiA1zzu)&CHuuc$ze zpN}oVm1}X!_$cD@H7XuTZ51XQPX?pT_Tgy4hP+ZGJd+e0hz$ZeL1!^`2OI^;Cd%{| zV*fEb>N|p{&^L>gu*0}(esIrgJ|Xj^OW6$lulb$~&K%EX=zrPwWN@Z>Hbei*z9)m8 z@fkNmP6`5HA2;9pg%%uux?K!)Yy<65w_%LY5*(L~6m+DI!ihX}2P65qGrWHE1aC)3 ziz;BBnoJ)}c|xR%KX_YFf8fktOa7IImI-($7ABi_GS?txsF=Txq8Ox${_-Pa-UzHWj@42hrVzXoPRiX!K_E2bgY(a zCGvJ4cVyLfzWtxuwNtL&4Qw_na}a*I|wqyyZ) z2+N1jrAFi?JxS{GMr5m;;tyP2C^2Mq$+!H0Sf+`4pwgj_29?fYK&g1yzs4z0UDT`7 zuvP?e)PQ#JfavJ`D!Za@tv>5(cCNsb@+yvQZ~%p?R^K2Z;R`6ijCB?@I4;1zwC=%I zG?^*)nfKxg2HVyT@Y@!F%dmH}=mKtG4#txHdz@mei;xCSZ%X=MUc~%QASPCjtibv1 zNq!b$ViZ~zpQ;qR*OeQvmYbI^V+8`v1MU&{to1?}Hw0}EyZ?a#8I zsX_beY+x+>LA>j=%unJ8r88aQg5 zgFgxDTz)DaR*n6}&x&qdixVXFIX0cbUsT<10m>m>ERt;MCw;4YHW)B7&7@TA)>lBI z=D7XJnLZk;*x_k3TB)+*>bKgiSHCrO8-Jq$8UMr`lI&QC&t8pK9IH*-ab-(NPgiCy z_C@Nq$|_@*sO+_LTa*CpC8AUyVWE4fqsBBU1&d^2uL;Y6Sr860>wyV@{ zjeR74i$&NeiH;>u()ox*Ns!FvN_uXVF6lk>TV?-k7OZVp)YmGa#!k#e7=Cb_qG*tY zqJ|+BMa@M~H7=zNnWKx^rhcpJtJQC{{Um?kQ`IPN%Aolf%J>NJC?n`CqjIi4qsZMp zmxWc?Gu3akeFT4DpJEg`h0yE_g`9+V6!NI>wCVhL8j-uzZi7-{t9Dy8bw6F$QuSM9Tl|G`q2YEDUsy%v)Ao~)vDalFbx{rI z`6qv?>`N99zCsuk4&oFw0{(Yj_*mKBus&ufcspS+)@b(2ypOAJwf(*-qf!`^P8nq8 zP)6B8g)k520VQa+rdClvGtdcLK!GSF(e~g)a#tkKlG)=JjK!gT@6^C2>QRF;_~3Xx zhh^^>p~rKzedZ#z6vk)?rwmw^wb?mJ-nPhJrJDBw0nxm_s|GRcZwY`bIc<94$hcItS zQNS69M*%g$zIF-3`MgckI{vnCfJ%YOl~xF|VGPeby{qQJ-*OtMmBvI~<#%L`3h zh0{G$81nDU_@peBms>?DW;E75R1dK4Ag%pHtdxa4@rXRO7^95{s5?=NKipF&{jIg= zaHVQ;5*3C{VA;{+e(+;=B0sU0Kyq{vK3%nW_`st*}uplp9J#BzQ}uV=Sw$zaPRQbAY%{6`#PS$@b!{+>@t#9{(;y} zKhVXheUXd(l3d(AZrrL|T(*@*<>GeJN*Ye0l_>z~E*gnej`XxLoE<5rmIrDuv@S0X zRAH3m#sx0vV1S>8|1&Huw-oW2X0;}`xPG}j+omk8Z7Z^ISzPC5<9Nw7))-4%*R1eQ zaF87bWXE}sb#e6!C%zZs?GkxREKoHhAAewv$)i@H-~8LveTc}LV}ZLea21EcnXumi zDqe*XE#}h>_o~r)oRRijiB{uy6D?Br(eN2O{LeU<-HVu(uziZ>`&2+`A9`-;>Q7wA zkohz=?c*nc`7DWuIa)r8EBv4@Vs{g&47A7h_xWw;@B8^(uD-1pe(dKFVZXi#r-2F` zTPX)u1{TkWBjiXP6HLGrQWbuo&8mk)Wwm@T9vBGm)bHYf`G-=BXq}6aEyzHlsq^rs z*dB0@e^brYa>ZzeEinI4a6e&-UirZvgsoqK6z9H+WH6+mo#tNB;aRe_C}RuU(*1=*sGrVP$pG*EMItl?1* zK8}5B1~O9jt@Gu?&29~?%j~L3%oC`DZZ(xx z(E-+J{3`2!9XE|H6Bs4O--y= zJR}5Dij`?tJU<3)jBcufP;Y|rkir((0K{+`s`cbCIq0h_TX$HEm4bn_9Y{cQVSIx zB(`T0p=!v)(;&5A;!-3|J~*2SsVh@gAcCnKNZq#%YmKTD;#VdfqCZy_ z)&;IzpH!1a`P#R04)TivT4-?u`pzRp`7wK5i&2=8bB|vf3bQkV;hbyy618B*;JVYg zLzdJBs+;%h1Rt8LSQ5{W^XdbmGL)fU5>TQO!yt}oY>v#w=GGiGOwms8F;9xL-}hqr zQqfNE;a#`H;{?AHp_~(Z9GuNH9O7kot;`reZ}>6C9exlF*i{6=va}&^__#KbOYc+q zg3mqy-O~_J&k7XT7v%!QsjZ-P305RLi_#FN&8Vpf0SZuvDwgDn_9{%uTV&8_$ z_I>Q_^AQE}IlJT##8l!>HpXHM^~$m_CozVctP>M-S6=;LapH01mD3voY6{eJ zC@Rz%HNB}Y5GL;f`%s})YkSpN56a<#aCpqu_p&q*YU~Y%=15hCg6i11I9$CeQd0v^ zky=ktO%wQQ(V0{~L3N>CFKJEiNXFuPRFSwsuT)y#o^51(BQp6fnokn zksA=H!FaHU zz^2>;ah{;)D~R0~!dvY~4JN8$QAx7L79>$BDr^;v8Bl*vx- z!@=3_ABL$^0$kugS1$w0U}AcR{3sAph;|8FGE8ETcePJ zsqT4q{r|Xo4mmvk5b$62jOv(i-?C>u+kiD!9R>cYp4nvvs)D*_!Y-I3x)@vNz&=SZu(I0cWXQLG3=IC^ zmF8^uaJsI`FVqF%y?K;)G#;KWbbxfxrEpxtvP<0uSG|SP3(P?{WQ zI)RZ_wgwtAUjkWOg|^;O&(gcDUU*9SFI>HNJ-zU{;9Gcl$pq*VCePK&DK3Z6g^!-# zv*a+e-xsE6KO)82yaqf)vGxKoK>K|epuK>=bH4WbQs(jbVSvZRRdmkp3xsZ+^8REX zl3{c#7LQdZoqF=mJNR~MrSjL2@AIXSN+DVOUd}5r-C3V6I@!qyv374yA7GmE3<&t( zNgMRL`C^Bh+ZOOReK9oa1+`j_)0bK}eW~I8t-ZXIIZj{lf=FBp937`GwR?8@;^;Fw zPG1Jl>B|6DKcgh;^o0U%?ewL@{5{I1{Phz2cBk_@>$zNKF-3P4m2SGb^8ueH-~^1= z<}FOoPG6vp<~V)PUH?K3h)Eu&FLm1KOP%iSdUQAEqjvg24n6DirQS0DAc#|^(HI5o zS*I`c+Ubh}cuxj<;+~woK(C@+JAD}fL7;Z}GQ?=!5o_@oEqP-@N&JomYFrAOH2h2g z*#v&4;Md~}2s^GC8088@_<(6}BCNgSdBX#h&A8l(a!2NV(!bLeG(o=ctf-Oi3=fp| z@%f?~2$wL(KZ+Ya6mNMD88`y0hgL*%Kpb;gO&CY*!t0?61lSMAyPAge`95ECB48E* z20yu>=-MndI8HzsgK+<%eZJg1BG6EZ9o^&eMZQJE7)N`KVE2~%0rVor#@=cGF~xj` zva#XDa1&A$<>|$B@G@LGcp0f3yo}TiUPhr?xE5>wE~9qq-=#j4`7^`?ud9tfbH+j!GmV{iTUAkl;`&XkQWWEM|Hbei)m7WZaqFy#b z|H_q~437F{Hbehvbe;^3`ersm|2p-a435HfHbY&%%7&f{T2U|KX2|J#DlapbA^8fQ z9#=E)v(t$OKOoW@hn|Z~&2u&LC}yYE)y(mjqF4>!YUVM{+ch}p=$FOMz-+DPkq?gx zlw>{65O|Mvv40;I7~*)INzQb<&BWm3Vvf?cbF{dD6gAG_YNo9bNjPXa$SqdOZEhE8rvQX_YB~@IW%&sP-prC;F^dn zOvDz&V~cYRTb3G2wZoQQu#L;$=VQP0$*PUZ9EUB-x)|;WK1I?kMNuAyEhizxSk}cK zN;(hB7zb+WHYd{c-l9QN$b|DQdPO3Ww%l0Wxm5`(ryI+9g1=-9%UHu_fYAxb|F|UHG7O?B2#hWRc7#mkU&Z8piT39U1xIE7y zS9dhOMfp0SStl*~b#Y3#CeeLroWVBC;vdH@x_^k-1-|{V#?k$Q;G<5i zdzOt^_beNB(;C9W>srSQhyRx8lS&ADgUuqXE{8}i(2bJDq@fF3jMg1Rwmz zihqRg{`l>|uWR1I_~S~o+m`$B>xDlAZd-6H^G${f$Bm~s43y4&Bfo`kz;apPP*ysC z7!!7?`q8kG1~XRRdg+5if_IQcp~sNMjoKp@rpH zb2E6DILD)6FD5RSbyos~(#|_LvNRJ1Go7He=qZA`k|OP{1Xhy~$6mU4k8Ih@sV-Yq z0=CR+ag$pY9i~JHBf*xH;zeg|N27f8<*{X$ttfT?kYmUD*UKPN65+hb@y= z%nO7wk?!xR?HJziv?SqW?!B5BV~U3vGdl1{C9gXVKt(yr!8|6CEEG+=;Y~$Z{N@Ok9`ZfzuZn$QC`t!r^;ll`pA#D`;NCd?{4Fb#~zd2 zV!ZKr8;ds~O8_XasV#=~eM7LX=Ue*qW9TO@m>y_`*YbO&2i9grVUbEnR8HMP2$m>0 zOmK7Q30{g&Y6t$9cm*tJLhW8XQ5b-cKnA)16@ao&*$6Q(9Axqd*alz7tj9ZUdP&j% zRwp9#-dp%>Jy4Z&209DD`H-#(YV>1HnBXJFCc+T1`f<^J- zWL+q{qlC8jWxyq(@KebG5DgvK>B+ad1&4l`0*UiD*m5y=FZ*S5Z~|pe*Z7Z-gBQhbLPyi`2+o<8Y}v1qjC72rDjLWod@1#3vD6WvGmXX8_gIE2 zJS`&<5QP~Lky=Tgfx8gp{YdBC6J*SHlymxt^2D>$Tr`?KYBcaAZ*g?I(MZ1N3$@Pw z{-Q7E(227D*61e|Yoa|DT%|RA{<+N%_ys z3vs&5i^th?^Fo}-&5P%u>EbaJh;t^ z=b`E5CBcK+yl4*z&5PR=NN!$?)bL*@2)J}1;I%VYNa!{V+kf142J77c)z0AH2d41p zv}i7Ue%EbhGMZ>-Qm3nXNpbV+s{?gIlNq@XXZJB1>F%iEdXXwU+zO?)-El+FOh~H5 zv9GS96p`cT9*=k}t{WxV@Qy~Q8FoRq&WFtvphJcL(I~YJRV~0|0X{34*ea!QJE2ae zFC8Qc+MYzJ<<+!98=I4-6y=45L`9uf2B9B*m^!2{tq!2op$+m0`g)aaQmaFa4l{ZO ztP_Uo*y+cYW+sZEHV1O4+76G6p`!T53o;w~(jzYAS)a^vxj4<-6Y2?2Zc$FrVJ#Id znsQlUlxw&+6a;VF+x2IyT*3Rmb_zgtt#HBTR`U-ASddq%!GB zs_en?EZ;HCg@a}9((BOfxjTSyGGasgEmPXtCOW$Y%c2&~dnh*{DWZ8s&G9IT(%v`G z2@H|#vJ#}g--e0Ku|wps#&r{&X(MFu$*2g>Bo$`VtcMMgCmkg3p=5Cj;Zie)x{=aO z5C)aDdE8Y>^hZNvNyp#fXr;7`Nm^nRe5A+U;GcnQ5=&~rS&AIY8W(|;f2oC6bHSJ;}zGE4hpECpNEUOL?|iV2s)laRY^fN6|zow z#MgOYn9L|jP=d}D1Yj+ZQIt;3x5H%fBKpRgGB{rLt z_H*rUS#WHERU+zfYb1k+t4aw@Jsgg8Ih!X8c>i$Ou0`CU_#Pj&#r9rw2?V zkfm}IYlkz2jd zQ^yDFu?3wJXXr-fh>@Sh`t9#s`apYZ#m%l zD`?Rjd*m@=hL63}U4b_~wVIuI$b4T5RpOcz&{b^Bl(_7g%ODOzYLY@j>MTge!T^zu zyw14_Vt6~N((WTIsG@;fSX>xeek15f#d5KMKUW=(%`mca!vgU~w}^&AWTx1Tr(ARM zu`R-nB_4dSrXV}t-SI#wm8-A|zdda#3iAp$*)u@7?E+n;L*HPc56)i=H+|B6@l}uwGit1C znI1>>O?4W^%7}4rsWY@E2frFqe$NI2Fo zYnrq14B0a~fKhRB)P6lfwrmU|eidiRe#UjvoGE9@o@jy+}~(7dNb`Wf~fjbVBPJ%Y4IXT$zL zW87?`%I5>8pKH{)@hn+1rUwO@7sARVv`GstLD_}aEbN@iv(^I&iJHYKfqq0{SQ`LE zZ^lmsl8ljC@RIAVfyL6*4w#;y>mD$6{4D4+J6l%ee?i`E11xH=nH4q{u)YX7!_JmP z?HENhB2rt!p<(f-C}oOO)NGFPUJKsxI4|#WStbphCbr)N6-Mk;+f z4VMu5g>&9G+1EHB;H>NH>pe11{~g)~T*3N1J+OoD2YSl-ANgU_v1=VWs?WNOp^b_E z{wLRS$@M3{)9W03Av5S)a*m8t1`)9R8#2{4E!aG57`8jK#Tl#u@3jpmyPf6iI7jyL z^>nh&l|{y1ey8KP^342d;-WJZ$aS=E3-B5>oV8%_9q&ARt~^#f+B+@Ilg%|f_B`1! z){84UZs<_m;lKrb(KtQQ!QEnsTN!Y~{WkoDOc*8Hr%d<3-D4CfWcrf7<9C>>Kk(&% z^hh70j#A3P{4X^s5JTGrDS4#TWh@c{nNS$=>Cyxbm7XH>Z>r#sc>%YtU-*uLp$HH)b57jqcMp8VCPAg-F#fkghn#Zbp66Geo2))uz~bZ3e~&b}>7tsBfDn2Unz0 zKsc-&!52MS;JPt83=YW!IhCh1u!fQ1L?+2@zJ9Ex(=Z8oBIOoMlC^1R^ zUzG3sI7#-wN1-S_&d|yKf${0dvXZ21f6R9xW-dYfb+OUHIb{kuv+AX#bIlZ45j!z% z&^*UmkWn)aX{W9)#vx0(214CG?A=M67St2er{TJh`8Wv@zo3{-F61```PO2Z_w{y( zQQG46@_=oWpXD5Nfh_m+cTT@Rb|l>vUVu+F-@&`2oYx+ct^IksGJMOIUYhUs@4C~! zd|WJ77VgS+B2#5av%m~!*B2Q`(s$j(ca?SsYzSvkx(x(Q7g#=kT8=-*Whb-W-4uKC ze`MdpDg{`&vu>%;%4z*LmT1GcP&0yNl8(^hMqTSpR88S#z~-wA;a~#xP}|MVI_j|3Nqe<&BK4>AEMC&?nZ-V zZfixXNw0`U6CPDO&pW%4Qs?)_eMP>nJ)qri%)B?+vZum@!e2w1+?1S@ z#7Wo$MZob@Qyk9wPxv}J6Qi>2r~%xEl;KR+MM&h~W)SLebj(*z{yed+dGv}EHL1kJ zj%fl7wAxXS23++|kXWBY<&oy8lsb<(EoaECzFKG44B0-Y+TyWJY=+ElJ}_Q^svf~h z@Q@xE;5_wZ;O#=z7@Kt|1jm{_1p6Mm!^`uO3 zc3dJS132bVtdCOC2ieZ8k%+4fo-zQ(rPyNAa&Q5#cUz<8pd0}QTWr%DlttO0C6kJ( z-TPkr*`emEw13L4?9_DY0V=*02km@(sjO)ID;!jcrRx;S%h=o8OG~HyOnFKr9slJH z2}VxnY+QLU^`cVjRs5u05e>W6p{hH{xpgKMcSb*pwEYUfz~sR1;8b!(WFo$S5H4`* zSepEVOFLXNk`Wn9(>$m(06Ybe8Ic~s7MBolBtEO)`JvVwEQ8rkG5k=+2|#mZ1wq%A z(6X=7f0oQbDL!qMEN`8tOQEn&1GBU*!*BRBC>RYoH_nnp`6tJVTUD;4jfx?AwDZy| z%yhzF(cLLozHe#S^6Jb`0H>f-jhFA#*2%OYGUWIL5_}^9t?GhjYMpEmV@t-$A+a@S z$$_G!q|qum<8q+f$g4 zlM;~Oj0{ac&SV6iI?%q{6?rL^AxY7{-=lv&G_GN^ z7Z_>eFRffsCEM?}3KbEs@)ZF!i(D#TmAI5?wN%uue#jT@EoKG_!!3}tw-REN!x?*v z{h29NE0^;Gk2BTfB*ZFnMTV@3!$hVfij267=~ny0BxWQ^?BFtHWLi}&+05$Xte=CM zn^;2*_XyW1+v@6yL&w;S3NDUiMnbHkT*h4Mn8O(J5*fR>jQQa$R2?1bz7|+LT&mED z9k0m7c|H>G|4E*!EDs>d1K1=I5*QJQVO$4b0Nmhn9*D`Kj`B*jsXlr984c|*LUS8B zE@6J<^f^0msc+dJ&!S3WPJ?XQ>QY!IzI%e<9bLGfzkov3WqTBY;m-C3Ou?-JQw9y@ zw=#i!D?FH=1C9|i!%*O)&6U-$#Nj&+BjW>jcl;jhi*Y=zCp`fVkrtE%)`_6F+|jsI z3c8`_lmxpbei_E0Bs0wjF+s8V8>ZQ)wXof;@X^NRW^XyL|b z^w{_;VGb@er8i8rr&t{zR(FtiY&AiGX>GV8LX_v0g&Oisni2rP+R$}o*+Ea zJ(2`*Z`8D@E={$LPC%$GO|`lwAY7NGS~UzgJ?5d)sB9;#a4WTWu$|{;I@isUWwB4; znHuLm`N>lj^kJc2F%-o5t*&!bkI-#Faf^A)J8(DZeuCoCIuF5Q`RuG&kYw_`1rnqfmJNCipl4DE5Ep1ZXbg*hYY9C^7c^<_IFE|(pOaxfO9^&aw$JnV*jZ#1#I zeYSHwoKxKdcyqS%Lc;6Uvz^})UNh>Q$ox2SMZI$dUc0(}yVav(lV%UY!|Dtz^lf+9 ziJ*JQoAdB|xq8wWU`-g7m^O)!Iy1J%o^}mA~hr18rk?GtsP9B#L-GcdsdTc%M8@ujszF#N{ zI}wvL8TA{ka+0{f$*3b_Lq)N&@D1Uug@-R>`Jh=P`7wZvv$Kpt#dx4aauR>(mxbv}&G>ZO(+2#s(J4oJs!3(ad4q68l zk!t;>h!pG3U~{-xk3uj$vQmtTj12pteB|YB+@G~bo=`f93WAVBt=*)WcZ*{v(igS= z3}?Y2*{z@tClcN-Mygjmh+;12D!(@u$*|9G4lR;Jlly_C{uWHS&3j$W*9 zpa<7`ykgry?82pKs=?G8|00gNDc;z(Nhya;9e*U0qM02yWJ;RU*#w60R!l*JA9Chi zDf4>%0dI*SEF}U1gJ0nS8A#r|@I54#7Fn@gsC7cJ2b|Zhlt=hZa{^b%ni$89zH}N8 zf1%``t`a0vkXG|0Ud`aD^r#;?;C|wiOus)6=BVDvQAKP6sdYpr#FYBx;e?pF4DpDf z?cj(8L}Z9CnsbKYva3Mjh_*h;$UB}Qnjk^N(~rF7cm@zpzZ*|fO5NH*W3=PS1FqEy zIMa_ZTJ`R>4=`@8{|UKdJ&a6rC4LX#)+hK0UqS1x)VB0=*^)V&g^OibOSGV{BJ814 zlA2)Y&UF!zgRBX0GAT}vAi!`g>c4_Req2_O(Xj|?+bY%K3iNeaUoDS~p<{(>GHbR$ z-DnV=-EUqV3Ap|?q;p~vwI2lV(_Gry**EVNevZ;VQnT8 zPr-B~^%VF^X`#qKx(E*OrHfJR+8d;FVIb)z-K`B9KziZ?K0&dGq;(E75yKG%+4%a#jA#B=4wRrYhV=;ElU)YdjvBtFGF=J*)uM3%7SO7@>*<( zINup`t!#PT`4|OnD7216&;_fkZ%MM5TBz?MPH;tN-;t|`v`6d66BCL%r69$=y&Pld zuPGz3Ya!$^n$i1_1lGTU&W>y4h^$mH8ro>dy4K(BbXtmo+P6ESm!e%^MMcdEu&(Sp zq$^s=S0ITtTXv&W6L_n;9VS(1eML&RZ*~tqO~;ZOOB<8#CeoLhp}Y)v4;X5SS;{_<#C3nRM$3| zf5;4xjUM5QUxuC!MFQV{-GSUuAH8UUdY5xP?58?_v)NV7IsjE@vX?GSJ4zP~2uve^ zL#XiPq40+DsRz@_^_0^}6%-W>lhlBdq zq^mWYo*30fa39(L&>_WS)@_8HxLju49rU7E)dT=X>Ub!LeI1CD4A+ux#fqLRrepmv ztcI4u<)kDRtf~6pKvzNzgaa>_@~{h&x#BDmCatHS^_;s9C~pe76T~4ilWcA~94Z>f zC0qcbn{#(EPc!0qnt9+7^M?z;6f%^&P074jae3sz^1{u*k13sJAp#d$Lqrax=NKwZDH)Lgn$9s)zpSdGVZDM-=G>E zJK#{!KrUe%h{RbGq>0nRk*#9v<=$j3IdL!K5{AN&Fh<6aIh&IiF(fvlud!@$3AZ4| zTTv;hl0ob0`0@e$BP-cO+TE8dA(lrXcC!d_3S-zDnR9C=5WjpC7|&bupQ+EMSp4F`v~gIkV~zShIF+@L*B+Y{*&$z%?vXr*l56N~ov zxTf+@fO}3c#*wD=J_K_8FqevepDP4aFHu=8pz}nu+VX)jXQeDII+tXiqWciOLVGiD zZ|1cKFBskH+_zG;J7*YTPNO}l?Jyd{21YfcV}fRV+9C}~(BxvMgx!6p1oE-df)*ap zz4#H5u!X+50U!P)0qs!t)DssfTCxwU?27Z8ZmZ-H-zewBRdOI6xi`uu(5K&Xqiok| zyebY|kZ8y$>^OZKfeE`O;BkVpevRz!o9G-^BTG*~#|=wkW>cM-^c3uWQU}gb zMN0TKs6S}R4OOgPWFS71SZ5>|F92Z2#+ePyn44tBs`H_B^meE9ebbi$xYbDu-|F7R+iyyz*=kqoZ^gME4yanxNs-~qni#0 zQy4*OiF3zVIU+V3X5J28K;>r*&XI}KR%6whhmu*R+K(Vmb=_Xgat5A?1D7%Iyaz;P zq}n^;Z|A4ld*W}WnXOv8<)U|)u-}1;y$?U;;sdmy;1ooeZ=cTfV~rkf#A6oX^+EBc0CcWk2V@dii(pWG`{zw;6?>A%&dIH_MSNk$^O1*Bj6CRhfPa zjv*sVk7YQbS-nwK_PBtYqAwsasKLWe!-;0-Lurv#IleHB9Z`Sd8^JVC!~=8kA?qbD zWB;8GL$$fL%kIruB5R_hls~U>=<{!uN47XD@RwBJ^!SIscmD4K@8mqYQD(J#ox(Mu z&y&@^nLxiyw6hKRIBRZ^ZJJK9pPA{2Tjb7DNoh(CUAu<&!i_uNs(n@N>2dc@5Nmd- zHe^BgAW0Hf2?&VI;GsX{k@NR7qcd(TUN^|s>7)i)O*RU`Xhrz>Cwam9A%2!bv0@Rb zuxUEhzPm;*EmzpJ1Z?ntFmeqMyYg09-l2~n{r1gp4;$!7A$S0JNkA96oH1-T*W4uw z2fhT(Qoi)J{zMp+VgC^au*(KO>O&p}I=lcX;sE-v0KP&+Q$Nu8{w`UCi)l;m#x}$w zoMY~mEz|n5!5C&rIK?^ZZaL~4ztRaQL4EcsIZco%_W!XOEtX@lxgNs-nux?Slxplk z;z#7wRA<~KSyp61laN_uL@--+$V|ms6bpi(aIJIWCfO!$!#1SwcZg}8w-ma;*}X}2 z&wJ-^mv@}+hxiJEr#vjCr-ZL{dfX#Bpy>RxMw&Gh0s{4zk0oa65E1jUhf5|%F$bv+hRMA_%$oMtVM-9> z%9UZ9^ni`puWGjNZ~{aaOSz%kbi?*P4*z|eb@$5S&1s76HN)tB!*E|wOS%J*)G2I% zH0T4zc=8sua5m2{j`v;V3?1Ps@!jX#w^^2SefTL@GCq;Um-o_TJDliY|=$7Q9C%Tyf|wd{!ch~UXcHlBvCY4XORSNoHeE|uF6okgRL z3SM@{IDalK6m>ybZVu5$M5^AF*&Qv6E|C{FNs^bF?F@cUX1BQsQdvWlPli#46&t@y z$;mP5FmsO^N}Rb5%CZ*LbB$sWDMV5$)Oi9k5#~zfaP~bYOG>^2EiIHVlhx*J54l~8 z>@G;of-SPN7cPoI2bUN)QL%A`^vpKw@y{oRW7soZ0`kHUUK$$qk60`{X{@jH$elPV zBC%5TDxSD&KRY@TYqhxr(pm_?v;c(9hhU!4uupq6S%%_(&$B65%=q9)i**UD{~God z=c_HUyie33S%uPCFo^ND)WvWjrTcQ^pNO5 z5Qoen8WPd11QiYB5}uEaYIq@jtc#TnQ=C;>M&)3broXFKE|5jtUuRR z>b&w0y4WW>&9=!Q*xr2BHd&ly?ty{P($+-{Xx!|uvuK-aWfE$i>D;qTo{}UNQ28s ztqQyHPn~!bRc1STI9}Oot=Z&mokCq4XF1(y3@cAz81pl1q7J!U^bFaHyCG0s!`Hj30VR@h0}V}WlGPu&ekc;fk$O~ z-!v!tF?qUgpflw$IlwoItfG`Q`kIAjRI^Nf~yrHC6floh4rd_{CWeHv4d4jb!;PlI1Cm%^eu# zH&Q%?>F*{q4<~3|hQR6%3k;L)uHu+hiNpt5esL!F=loCnFp?Bft{-Q87c!buyrZ-y zzC@!of@7xAL;q*2%prU&kp8(d`=IZd%WvDq_maJ3&%1Un8yP5VPOHY=xSlrTZF= zrpv}~m>M${jdI)bo1K{$2u9CTKcwWs#In;Xzxsy&EzEc{${{attsGb~>PH$e`o(R? z6^xl_rgJb7k!D5BZdX!Iz>xNR7#0+SFddyczjZK!*e4~L2d zatUJ#Q6!ABW%^dEZb!4opoN{qp_sjLF6IWGLlb3x0xCQl$xhRK<>Yb36*{7OH0aoy7I6%jt-=(}mmx(j} zh2)Gck7qo&xEb$keML?z$9K3QRxv`!4b?mk5z#Q1X(tE1P*wuC{uR^dy#wD`cm+N! z3*ENx2Ph$WA|Gb|C33@De_X3<^dRp`Cy<5lu&T28rkx=vtATUdJNPq=u}K zWK14JQmxaHpnsv~XpJT)7kd-4t(K4v?J(mO3Zo$kb*~Po9f|nTYG)_7Q)RYc)X{nkpP;3~EVMIX&x zC_I*G%o^vdowB?&id9KP!LAM7!M5N6SP?e&BAxSgb>q`=PW7wuGJMeI!nb@SPS$HO zWBHXA6*}L)D*H|DjzrvGVJ-t(@RN7CvkjrNqn2t-ir_RVuEF|-dg8bSE8wPe2IrJc z(+ms!D=*PAta##DEuEWQlch1vAv*&)azS!E+GpYeX>MNGb~R{~Be;Tqa?~ExnEzWk z2%_>fksn*9u$Wl}b!p0lPS4|JNP<+ZW(UrN;c929a@jfPItS@nVwAbb{TMH6lCzbP z43{Jv!an~-`Et`PL^Po#^X#IDir5pb+|(k=xiG(Zhqc6GJQJa2jk<1VJ=|`>F=&YA z3?&A)@kk8c^O)2etH$I1E5Kn10Vc$k!aJKgng0-=I`e$_e;Gq`F~f)+3Iw&_Sg$V< zDRYK8bN0yA{r(Rm4I@eIeDj@K_sB85jziLhd*CO{ey9jXu#=kl)4d$%366}^pw$K% z@rK-Tks8cNvC5rZugkMDf57;u@M`SsqoP^0eCdc>XZ!2&iCEjijLQ?5n%J=8h#eLa za|1PZQ%zK}j((-R9;Lwk5I@C~P2ph|+1`wHxJGlR6MaioG!Y|DpOmD8b+*5S>6L{v zs?Wb+icEFV-o{0JUYwHK%&}gaFf)wKi{A=UVpEmeLj?Ufsa6Mir%B+Bxa7mMD(RKB zapIo4R5K^tiV#3M2{B=mo|{<{qs9|^jrclHwV4N-tekt^mSLmELg$^gWn~H76pHiF zKcWiHrlb7{S?#oZM@C|-1RXY=K}zH(C1^+CI9&d!l%VR5HvZw}{hVk=C{aPXJ}3>X zD!hr@d{lP%ICol&x8&;1i*!-NorD*`%;v#3BtrL_Ce8@dM70T4;YMa74;d6a3}RhQ1V=D zHBD6a=lut_v;TwJgakLtT_pD%PEBxZ>^8BnTNkD8aq7{79+k6_<#}@iZkyD|Ip!r- zyv>p{Gbk{ROH)A!X)#_0AMS_L44FJV;tho{viKkPrTz%HH_uRG9Md?CULZ-$4JLbe zqJef{pav6HIgh_DD>^4A=OuXfM9-MIYGW!9DSi~DBb}TNy**W3CFi)J!w;tp) zMm@?JBMI&Tpk|QoBqvUMs_!WAk5h@3Vf6q(H66BZrdT}>OEfQviHTnuuJuy?_+&u^ z5L96G`tRgmp|i_A+2?#LHPGHLN*g{pl3bsi>7_Du8@j378v&q`!)c7$gz?6?#rv_$ z8XRh*KfB;cBzn+G^!N6mRm*nF{ha8X_sf1&zb(>Re(}jwdlY@7l~yFw-dfIyEH@{z zkQ3|ob56WUkIl{>c<7vHhMdT1loPOXl@n=A<^4}{3gMFQrgSSR2m zxykX8Avq@oc{zavJt|LHP#y&3Sy=1)Z{&mrIp2LOdmp<5IT5Ym0hqsjCk?=`Wj(R3 z8s}vO^{>-Y%sS%2KDu;g$|pD_Z(42@gSX?%HWCpZa=nCT<=+3BJN7 z#QsY6Y6JKO18OI@}(?Qp^#b$~MzTc2M`$6DlQ7i==*w>Z}KIgJ_HR z=ypi_2{X8ctSc|srq1`Gq2|r}D7k6Q_D^ML$#3X6Wu*Eoti0mNDv1r-SED0Kebj55 z^C=y z&O}M$QGcWwI~e^$1_XAanna<)lNqos<>~=gfcnCwHHeIcF6s*6z3L@(mDSDYsJkZ( zo7N)5NayKuHMcjyIrno})_y5RCDDSCwZ>XTj?X&DxeLs(Wn_KTuJyf&yvHoSYh;8? z2guPzt$WDqM59Zr3*bYtloBanEH7i|(XkT-K`%l8Z%J0uZf%JblR=nvBNzJcbR>*p zQ;}SMEE2%AM%0}_H;dcf6?kIxK0DgkRchCNqsxro?Sr7l}c(+f`KA`J3$?FK^nQNM}w1HoLSXOwQurL;t(eW@l zrkPe-=anyId7FgN=CLJp9Y#A@2V`FR8xE7|b>G5cSSkq}>I^!NEY#yl5;|51bq*8i z_3gq~!h@*y4;xN!cST-Jjw}tE6dMb1=eU6w=nId!X#0A zyONbB&slPvhY_L-L@_gjky#yaTbKz52@AtkOh2kZYKR)Ba3iVU507!K_!egX^VI-S z%uz+YJ&DJNEfhtI9%`WVLp${v-}DBW3$j}gMUymk2cnSge!DkO)Wf$Y5QRATZHFit zMc9uLg?Rbx&xoRB0z3CwP&9{SSJA%d2AZ<4#}i0nYgIQ{4-iQ$j{O%= zR4nYmWuU0?rM;o(kE?B+L^yr#lI1PQ%Bzu-tC5sO#}2KZThn4Lj!j1LcvEq=?_{fE z&O~$6Fpa!Uc9&XF`&f84!q7fce<3+x6i8p6_z(qV4T-9=oNK<5C9Q}LpJA@E@#Mj0 z{S5M1r+#hcrSIg)F?va!q%opMj!^wY%&UG`!V>DHA$@RTBwZ>_lF8LVLWSxt21SUH zO>gQxo%%~$2YPaUGtWYLhU(D*LX}G>D~&pO3FA~t#5$X54&VTiwIbofW+4wk^)o@$ z{H&B9+CqMW>Suw1XL>lpCgG;1zrV-60(!MJVFK75gbZ;neJ@dL3LoL&7=&P#3l<#c zVg?m=_KtnpZrl;?JPydHpB)M*0&Q#g5oG zOWUDJ#LWoDsBupoLC zcZ!UgYr=(b)h&PbGRT(X*QQc)PGY4r$xW7voLCe29;?##IhB z>gIuuCq+za0eU^{2)n#7RvpDREzO4cO~`C4vO0=y#hDEYiM3Q(%h1b%O873K*|3O9 zp^fWyu7oS^UGrwS)XAdCbEJhN#2MqRhp!sJB@!~dX<&lTjeTg zoerONhX_{Z#=)AZ(Ca_lS@)C7>lk;SZIT_yfmlZoD;TOhZuFMJqQ)ldeV>X3}6Dl1`RL);ARalu|UR8CK`3Oz|Go=G~kWWDxAU6`V5(1 z)ZGfl5>@aj@0ZqO#MZtSXHkv1+sNBZ&YGWPiwU?x1|MO+9f-?X9leY6-w1><^b5*R zJikFG^!%6m{9eDi?!UUvRq#xFeIb{!_hr`Q0jKpZ*mL_JgtCEpVLeJ=ZK1GElpGU# z%_cY9DO0{gD99qJ${!^rN+~7)Jf;CA06eY%CICF40Vag#z-4d%%HUdRM~(2a2%Xop zJMwkHU2#cuF~iP2sB1iHItPD2e;q4`v;mU4Nf7&_7R$tmdN&RZ4Pq%zok@5~voKK| zMWb#uY$p(A@C=g1e&G`w)UmpfWpt71+T=ZyWQg=;JQ18n#*hH;_B)EJy&YHZx!$y- zFFx=jX=s91wR+)w8|T{Kst|{8W0uk??h!LBFy(!uckDG%ygK?Zz3d`-w6rgpi8+K7 z6qBh4OqpI1JhN$dY18o9rs4Ytj&b=xDit0;n4C&UA-&$T-*20Seao9vx4db%2jG~B zU3K(VN`Ox(0WOpFAo9SMZ8H%x$R!1{Q z@Gm5|n2+qhB(e$mm7v?CHHXq+9>(JKU2WYm+%e0AuL6u~d8vZLc`yf@9rM()s2Wu< z0nPd1O{%QvEdh?fTVdrr(prH8nDYlh<8dwpd&n$+2GP0jP|-jx;c@87RQ7a3y&9oX z_0dIIH^6WBF05J5%c{f|R(l~hDd;BRP#M$WC=$4Hxbo>lKH4VAm48QUZ*JsWw+SfJ z6eoP$mep?@7wDQe14#bOTugxkg2?W0YyVZ?4jEyPy>S!NQ z8ap6$+Z6(K0$~+|fghK_fWN)wA4qOta;sD~Dv`NVM+XxeA$Y41j_HGN85r$_hr1s}3- zY8G9ZW8tH&8%2%M#i;8}Y%302zCdWB0?E#dsJHFlhr3x zptK$Z3$~GwC~{Za9m}QlI6Dl1L*2>r(@3D|?Jl6G4uvyyHEQACj{WL&NbsffMiBSr zq;)cOU2{Ki2z*pdmeyE2skJx_Pn}p4z+gS3xjo)I!Ls9DpF0sr7Uz0A&V>|2zYj4R zO))zx1!J!3m?m7Sqt{cc#!{?MUeBN>m1rgaV1hsaOaQ=GO#w^*I9mfu02rqMCIDod zqY)yU`G@3@vFhlZ6z=)tf=I&n5JkMqA;mwH z@J0!6ane9y8aTpZyTYq$E0_fTKPtHvME{Q^w_Wht z5ljHEHNXUbs0Nro#Y59Q#dtOV8 zeau|>Rb}QC%H=xnP!*E}i#K9*Q_+aH@-Ne^Du%HBt|$~V=rZaS;7xU*s-y3cgoPww znQJH1o9Be0QuF{NO_>ep-A`jZIXxyMu_GM|sl5MSHsdPWdqn`LAk8Uy$1BwLl zi@n_Po(?ucst@c?2R)G^t{6D@LpPcO`E@;MgrenqhTH7u$od)=sAmGeO&VYVz*-G3 z0brd5m_VSzXLb{p=b7*$GZ z8Vtp)MPGC}rud6vm~vFd8tHB;dZ7XM6Nnx?F$YCYI`$kv&!#zvqJwkTBpeVlOTV7y zqc97FX>Hu`VnoKFHNt!oG{MvpelfckT097AgM5gFXTE@97A$08E-hrmFvAu~Lo<$v zxKLFuqo9JPNJB=DrtCsSx-q*B&m134v7bvbjeCdlJYXozm`x0a@?XUE93$WL20`^e z#op!_Myo?K*&0#;Qp0l?&r62GzL;}Ds=rli14pC*JZ?mWBO-Ijd);ODrTb^F>gY?g zFb5X0FzFS-B{N}6a)qk;vC`z#NU2{y58MDf8+BqLjRXbk`MYu1t+jOeZ{GEDkZexh@IYP83H^c{J zK2bhmhCON8geXP*H|+QP0E?F8r;ZSB;078>kMjPf*7n2mQ@kI!-C339uZ&?OUSRq~ zVDUw~i6`+PApVfvE?}@4aSpKW@O(uIURuQ3yuknHvSNE4{#}ND8Tf~s!`}=n5i=o7 zF$xP-!H+P=N5TmGScvjTy zp6h!a^`__dmqkK+xtF9|=~0tCDQ9}h#J-1@FRmj-pWzdI??&fXbjtFHn?RZ32TX*& zj@@yYA|3B7Oga?16e~@{XX0~&nkvSOJMo#~F?8pZ>zAlK6xC*)rjA2sDm^lkqx8@M9JfQbrg%Sw7%Q>|5>q8%b1zvp-lM$~ zBi~he?0!Xv1vx(ST2?gkiL;Ptpdh97Yb0WQxLV3M@dAs~KZ1W{MLKV-j5~zFehZmnl|XtN7Z8 z{5O@VrDFROA=>Q|$edGdQ&dRYge=Lpm5e&$7e$>btarJn0sA=xn{0o-g}hvWI4aL8 z?pKs4&U3RQQ@pWO1vk&9J!gt#DcU}c^sMKmr?mRVpQEUDA|KSUVxMRyZotq}QTwh@ z6gE51Eo916u5#mqk`H!D^h&W92|VN(O4dp@6-;r_9-Y*mjn}!IcDc@+K`138uUK5X zU1K-5P*|mi!2(ELrI>@v9`a0#NXO?BZDGNc;yi4xA*xiQr$S>+%okv6idvMesXZ^L zG%CjNA)i>zg|a2(C$h;DJs?FzDKuH7Lbdn^sg(lBZNy~Q(9{Z|p7;v&ACVz(8VVIv zIUz9{#-%EsJ6)}Dd;13p3yD3GG_?$BDIde|SuV=Nc49K(t`c}XsvJc8R?sZX^3NPv3xRpC-Sp48Nl0qyz? zs+=P5b`ibq6HJ-nndej)I$G2qv|)dcn3X(;X_SGDbq$6$WKM3UZts{AeyjDalx0$uPL^;N@t3b z3sfmFMK8o#Me|;yucEFZdnB@2)LxT?woHIoL`9xahhzlU_5Nd={QHI=Bo=2_Ju{+PJAzC3OltwvXgRN7c zMO0y?xH(hRDFxyWq@a>~8q}iJGe>-nQbJUL82kW|nw)WaI0}sFSfsdOa>O+*V~%*w zqh9c+SuRy7R{o%+*!fzm2R**8JnCy#)l%_}_7M}ike3t_v;uD46^JF!mDI`<|8}cZ zQ~V6iitlzePH2P?3*svk16ujS+54&DTKT>fK>YN+7D%m_s^P9!t*BCQxf_#A@rzq1O>w^p%nhL5v@He6)F%`%@I+q=fW0LnJ94&G{Wg|h47B{0KuBgo}Ws2^QpbYpV z)P%|iKSpWl8)MObRTD%L8OtQ&a)L25<4a+i^>$UT~+7#t^!4W=>PSAt`yH4(G^KU?OAuR z{X*3cm5S+TTvd#pN8+mXU{bzLk5R~kyZ2M(Jh@zr3QRE&vZw_y#m6vPm4d4fM(PGC zb~lBg%)cliLwHbw_?u!La+?^d#X%GnG9UWu+EzW$65_wPm{FiF)srpMdPqOF_8`Py zo=^hPj1gTS6HgZZ3nE26LLmi0d70kHIDrd_ae#njwImffe2Ua;wr?CY19 z_EjOqF=Bgi!a(Li+F$Q!U)3(pA&=(>5sR_6Gj?i0y-_8To=+orRPgkUJTfaEOOc9STvf~fb2x}?Nrie#{uXUEld_*JHiN_cz%s}6lc~*$$7uY1Ke zjL`5zA@_+NIIvTwLgT=;h=a`Y+dW#&hd}1~Vp-zGLmJx0d6*?eqR`FWPjT&mNfEM! z^IT+y=;;eGG7eSFT$GSnAn86b;UAH(gd7lkeT9rX)1Z-)34xsJb}OV7AERO*26M|@b`?Er7#fL7^Cx$wTm}I#{)(g~=E`sXZxR{X#6Oc<7dEjl7Kk`OQm$IPuU8Y(f zGZ}f&%jsi{Iz}>GWS8h+G%yl#6?##eU|i40m!1vP8n-ag*RzH}#uJRx--PyG#r|~T zeTJ?^`=yX`jDIn534RrFuJHpSb3C32#z96-_mB&WfTV;Sj2@rzWf|#=-0dM38rh7@ zAtc6mA2kXj<A}W#7YJBqA@~J6MP3M5QV&AjAlUxy_|l< z7{kapo}AZ>aT2YWXyFybca3Sx^StXTwgbDNr?KeJSGcYleZE?;--t@G;Z1KSM2LMd z%HH0EyW-g=XK~DqJYVq~5MRk_SkB_#w49%SP_|A+*Moc=5I@P~EN7*b6BEC?&>93b z?RTmPg8r4v^oWOq{I@dlfs1_VEA>Cf$gX>YcyYN9&l+X^ZH%mXOChU`_WtJ>*^Trd zo*kmv{|Y1fT%H{w*4e*{pbYGkf|2CKNt6@5Tl?yqB>BJ_QfuSJ9)8aJVs5pqB*@h@QHRFpD> zEcY*nv9~4Y+bVB2xJ)N}t-Y=AU&TDPxk#;8<05lWIF+w;{$(sWx(f?82UiR-mHI*gayFiGZ z`-HgMc+J0)k>5U7$YLOGF_Qg-Laqh!u756kJ?8q_Azt%;;P;{Z5fl#+bU?i6|DL^# zn5sp8?IL5QYveos@67YK$Mc>45F;a>#xV6Kfv)IxxNMmMyBu~-$POTWR8v`ETLMoI z2>L(o!5WF_S>ro@Dto)_Duujj{Oms>;6v>1bdin5ul}PMIgo%H!@gefeEsULVV;!5 zO3s7E@BSW)v`s*Il0q?Yi>u>mFdff=osMs|eMibMVr8F?PR8W|d( znvo`ACStT#i_Z{`WTa~Xa$11Qybjs=?S92Gj*-|wh*nS_Fp;52uzZCC15+7Ey+I=x zfms~P5%XoX10DG%Ji$PZrd9Rgcf&JVFqwYNy%QHH{vx6XkV z8Tr`r)-|x3kw3O*Uq=VtVWf-at0wRvBM+ncdS|H+yF|ahZ;YIY>Wh#U#fgEx8M)zS z*#Eo>1-=nCD3E4SGSWDhkXmtaAje!UFj0hF8zBNnkxAB2i#ks8l$w;VWk@rHObK9J z7)E_uTk=72rUk~DvJ7RaeH=N%l#sJ2jm96$WChM@#56lFftf0U+FN~K5+nVyG!hF; zX5rg!CuU2H3m5q2Z z&5l8I{duOCcn*kWW;OeYXHbEQ;0qS~S1St5&djsXv!UiOvr8k<#pcn>w8FFV)@Bbz zl*N)lW#;jW#LcRW*{hM9a)(heY}PhHBIe0KGMP+NvGi9f zs?4E{1a&q?F%mCkN0_HKlGDW;!#q^&C^^TN<6;bX=70sl^BDgA0nOhi%*Oiv}5F^idDo!^aW`%N|*S;<^A7!3+OEJTInvj@?w`Lca&oa|vUQS

2h>Lt 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 Date: Mon, 15 Jun 2020 16:59:14 +0200 Subject: [PATCH 009/130] Updated MSAL to latest version and forced reference to .NET Standard compiled version due to issue with Azure Runbooks not working otherwise --- Commands/SharePointPnP.PowerShell.Commands.csproj | 5 +++-- Commands/packages.config | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index ed7d2865d..62609677b 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -453,8 +453,9 @@ ..\packages\Microsoft.Graph.Core.1.9.0\lib\net45\Microsoft.Graph.Core.dll - - ..\packages\Microsoft.Identity.Client.4.10.0\lib\net45\Microsoft.Identity.Client.dll + + False + ..\packages\Microsoft.Identity.Client.4.14.0\lib\netstandard1.3\Microsoft.Identity.Client.dll ..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll diff --git a/Commands/packages.config b/Commands/packages.config index 241cf5f20..8dce26edd 100644 --- a/Commands/packages.config +++ b/Commands/packages.config @@ -17,7 +17,7 @@ - + From 6c3a7c0bb18a6656c13c566196580f8e9411166f Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 16 Jun 2020 21:52:16 +0200 Subject: [PATCH 010/130] Adding custom build of MSAL for now to mitigate the Azure Runbook issue --- Binaries/Microsoft.Identity.Client.dll | Bin 0 -> 1338368 bytes .../SharePointPnP.PowerShell.Commands.csproj | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 Binaries/Microsoft.Identity.Client.dll diff --git a/Binaries/Microsoft.Identity.Client.dll b/Binaries/Microsoft.Identity.Client.dll new file mode 100644 index 0000000000000000000000000000000000000000..a62395208521ce4fb49ed98368dadf964031c386 GIT binary patch literal 1338368 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 z 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 z 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 KelhrbKvid%r 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 z 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%0AUP*^KEaOd;sUS3=~*u2qv;Y9k?kRhTEArNPSX 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∓wODiEN=~k&>j0t;VOYk=0yb#_$5AU<# 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 U(|-;&H)9{BiNM3p|92Gle@hk7CIA2c literal 0 HcmV?d00001 diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 62609677b..012060261 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -453,9 +453,9 @@ ..\packages\Microsoft.Graph.Core.1.9.0\lib\net45\Microsoft.Graph.Core.dll - + False - ..\packages\Microsoft.Identity.Client.4.14.0\lib\netstandard1.3\Microsoft.Identity.Client.dll + ..\Binaries\Microsoft.Identity.Client.dll ..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll From 7ae44f6546f0d69a68bf158d2e11abafbdfdc1ea Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 16 Jun 2020 22:27:17 +0200 Subject: [PATCH 011/130] Added ability to CTRL+C out of the waiting period --- .../InitializePowerShellAuthentication.cs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index 5abf1680a..de3d726ab 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -9,6 +9,7 @@ using System.IO; using System.Linq; using System.Management.Automation; +using System.Management.Automation.Host; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; @@ -234,20 +235,36 @@ protected override void ProcessRecord() var waitTime = 60; Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Waiting {waitTime} seconds to launch consent flow in a browser window. This wait is required to make sure that Azure AD is able to initialize all required artifacts."); + + Console.TreatControlCAsInput = true; + for (var i = 0; i < waitTime; i++) { Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, "."); System.Threading.Thread.Sleep(1000); + + // Check if CTRL+C has been pressed and if so, abort the wait + if (Host.UI.RawUI.KeyAvailable) + { + var key = Host.UI.RawUI.ReadKey(ReadKeyOptions.AllowCtrlC | ReadKeyOptions.NoEcho | ReadKeyOptions.IncludeKeyUp); + if((key.ControlKeyState.HasFlag(ControlKeyStates.LeftCtrlPressed) || key.ControlKeyState.HasFlag(ControlKeyStates.RightCtrlPressed)) && key.VirtualKeyCode == 67) + { + + break; + } + } } Host.UI.WriteLine(); + var consentUrl = $"https://login.microsoftonline.com/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope=https://microsoft.sharepoint-df.com/.default"; record.Properties.Add(new PSVariableProperty(new PSVariable("Certificate Thumbprint", cert.GetCertHashString()))); + WriteObject(record); + AzureAuthHelper.OpenConsentFlow(consentUrl, (message) => { Host.UI.WriteLine(ConsoleColor.Red, Host.UI.RawUI.BackgroundColor, message); - }); - WriteObject(record); + }); } } From a10f6f858520b0b06c24548994d5954f8f70d4d0 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 16 Jun 2020 23:12:16 +0200 Subject: [PATCH 012/130] Added sample on how to output the certificates to disk --- Commands/Base/InitializePowerShellAuthentication.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index de3d726ab..ea9acdb0b 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -37,7 +37,11 @@ namespace SharePointPnP.PowerShell.Commands.Base Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -Store CurrentUser -Scopes ""MSGraph.User.Read.All"",""SPO.Sites.Read.All""", Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.Read.All, User.Read.All", SortOrder = 3)] - + [CmdletExample( + Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\", + Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and stores the public and private key certificates in c:\. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All", + SortOrder = 4)] + public class InitializePowerShellAuthentication : BasePSCmdlet, IDynamicParameters { private const string ParameterSet_EXISTINGCERT = "Existing Certificate"; From 2e8b915ac11ec0476b36e0733eb6fa22f647000c Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 16 Jun 2020 23:17:09 +0200 Subject: [PATCH 013/130] Updated write to disk sample with using a password for the pfx file --- Commands/Base/InitializePowerShellAuthentication.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index ea9acdb0b..4620a6ca6 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -38,8 +38,8 @@ namespace SharePointPnP.PowerShell.Commands.Base Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and adds it to the local certificate store. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.Read.All, User.Read.All", SortOrder = 3)] [CmdletExample( - Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\", - Remarks = "Creates a new Azure AD Application registration, creates a new self signed certificate, and stores the public and private key certificates in c:\. It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All", + Code = @"PS:> Initialize-PnPPowerShellAuthentication -ApplicationName TestApp -Tenant yourtenant.onmicrosoft.com -OutPath c:\ -CertificatePassword (ConvertTo-SecureString -String ""password"" -AsPlainText -Force)", + Remarks = @"Creates a new Azure AD Application registration, creates a new self signed certificate, and stores the public and private key certificates in c:\. The private key certificate will be locked with the password ""password"". It will upload the certificate to the azure app registration and it will request the following permissions: Sites.FullControl.All, Group.ReadWrite.All, User.Read.All", SortOrder = 4)] public class InitializePowerShellAuthentication : BasePSCmdlet, IDynamicParameters From a1a08b7b01824902588f6a5ec541d1a5728a3dce Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 20 Jun 2020 00:54:48 +0200 Subject: [PATCH 014/130] Cleaning up documentation on Graph Cmdlets due to the new Graph Permission attribute being introduced which automatically generates the documentation regarding the required rights already --- Commands/Graph/AddSiteClassification.cs | 8 +++----- Commands/Graph/DisableSiteClassification.cs | 5 ++--- Commands/Graph/EnableSiteClassification.cs | 2 +- Commands/Graph/GetAADUser.cs | 4 +++- Commands/Graph/GetGraphSubscription.cs | 2 ++ Commands/Graph/GetSiteClassification.cs | 5 ++--- Commands/Graph/NewGraphSubscription.cs | 1 + Commands/Graph/RemoveGraphSubscription.cs | 1 + Commands/Graph/RemoveSiteClassification.cs | 8 +++----- Commands/Graph/RemoveUnifiedGroup.cs | 2 +- Commands/Graph/ResetUnifiedGroupExpiration.cs | 5 +++-- Commands/Graph/RestoreDeletedUnifiedGroup.cs | 3 ++- Commands/Graph/SetGraphSubscription.cs | 1 + Commands/Graph/SetUnifiedGroup.cs | 2 +- Commands/Graph/UpdateSiteClassification.cs | 13 +++++-------- 15 files changed, 31 insertions(+), 31 deletions(-) diff --git a/Commands/Graph/AddSiteClassification.cs b/Commands/Graph/AddSiteClassification.cs index c312a75a6..2133790f2 100644 --- a/Commands/Graph/AddSiteClassification.cs +++ b/Commands/Graph/AddSiteClassification.cs @@ -8,17 +8,15 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Add, "PnPSiteClassification")] - [CmdletHelp("Adds one ore more site classification values to the list of possible values. Requires a connection to the Microsoft Graph.", + [CmdletHelp("Adds one ore more site classification values to the list of possible values", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Add-PnPSiteClassification -Classifications ""Top Secret""", + Code = @"PS:> Add-PnPSiteClassification -Classifications ""Top Secret""", Remarks = @"Adds the ""Top Secret"" classification to the already existing classification values.", SortOrder = 1)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Add-PnPSiteClassification -Classifications ""Top Secret"",""HBI""", + Code = @"PS:> Add-PnPSiteClassification -Classifications ""Top Secret"",""HBI""", Remarks = @"Adds the ""Top Secret"" and the ""For Your Eyes Only"" classification to the already existing classification values.", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] diff --git a/Commands/Graph/DisableSiteClassification.cs b/Commands/Graph/DisableSiteClassification.cs index e7a39ab7e..5385ca32b 100644 --- a/Commands/Graph/DisableSiteClassification.cs +++ b/Commands/Graph/DisableSiteClassification.cs @@ -7,12 +7,11 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsLifecycle.Disable, "PnPSiteClassification")] - [CmdletHelp("Disables Site Classifications for the tenant. Requires a connection to the Microsoft Graph.", + [CmdletHelp("Disables Site Classifications for the tenant", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Disable-PnPSiteClassification", + Code = @"PS:> Disable-PnPSiteClassification", Remarks = @"Disables Site Classifications for your tenant.", SortOrder = 1)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] diff --git a/Commands/Graph/EnableSiteClassification.cs b/Commands/Graph/EnableSiteClassification.cs index 73749176e..f118e0841 100644 --- a/Commands/Graph/EnableSiteClassification.cs +++ b/Commands/Graph/EnableSiteClassification.cs @@ -7,7 +7,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsLifecycle.Enable, "PnPSiteClassification")] - [CmdletHelp("Enables Site Classifications for the tenant. Requires a connection to the Microsoft Graph.", + [CmdletHelp("Enables Site Classifications for the tenant", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( diff --git a/Commands/Graph/GetAADUser.cs b/Commands/Graph/GetAADUser.cs index a506d81af..92113070c 100644 --- a/Commands/Graph/GetAADUser.cs +++ b/Commands/Graph/GetAADUser.cs @@ -8,8 +8,9 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Get, "PnPAADUser", DefaultParameterSetName = ParameterSet_LIST)] - [CmdletHelp("Gets users from Azure Active Directory. Requires the Azure Active Directory application permission 'User.Read.All'.", + [CmdletHelp("Retrieves users from Azure Active Directory", Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/user-get", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( Code = "PS:> Get-PnPAADUser", @@ -43,6 +44,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPAADUser -Delta -DeltaToken abcdef", Remarks = "Retrieves all the users from Azure Active Directory which have had changes since the provided DeltaToken was given out", SortOrder = 8)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_Read_All | MicrosoftGraphApiPermission.User_ReadWrite_All | MicrosoftGraphApiPermission.Directory_Read_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] public class GetAADUser : PnPGraphCmdlet { const string ParameterSet_BYID = "Return by specific ID"; diff --git a/Commands/Graph/GetGraphSubscription.cs b/Commands/Graph/GetGraphSubscription.cs index 93eaffb53..2b93dc6ef 100644 --- a/Commands/Graph/GetGraphSubscription.cs +++ b/Commands/Graph/GetGraphSubscription.cs @@ -9,6 +9,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph [Cmdlet(VerbsCommon.Get, "PnPGraphSubscription", DefaultParameterSetName = ParameterSet_LIST)] [CmdletHelp("Gets subscriptions from Microsoft Graph. Requires the Azure Active Directory application permission 'Subscription.Read.All'.", Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/subscription-get", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( Code = "PS:> Get-PnPGraphSubscription", @@ -18,6 +19,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPGraphSubscription -Identity 328c7693-5524-44ac-a946-73e02d6b0f98", Remarks = "Retrieves the subscription from Microsoft Graph with the id 328c7693-5524-44ac-a946-73e02d6b0f98", SortOrder = 2)] + // Deliberately omitting the CmdletMicrosoftGraphApiPermission attribute as permissions vary largely by the subscription type being used public class GetGraphSubscription : PnPGraphCmdlet { const string ParameterSet_BYID = "Return by specific ID"; diff --git a/Commands/Graph/GetSiteClassification.cs b/Commands/Graph/GetSiteClassification.cs index 60ab5c28c..bff81485a 100644 --- a/Commands/Graph/GetSiteClassification.cs +++ b/Commands/Graph/GetSiteClassification.cs @@ -7,12 +7,11 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Get, "PnPSiteClassification")] - [CmdletHelp("Returns the defined Site Classifications for the tenant. Requires a connection to the Microsoft Graph.", + [CmdletHelp("Returns the defined Site Classifications for the tenant", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Get-PnPSiteClassification", + Code = @"PS:> Get-PnPSiteClassification", Remarks = @"Returns the currently set site classifications for the tenant.", SortOrder = 1)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.Directory_Read_All)] diff --git a/Commands/Graph/NewGraphSubscription.cs b/Commands/Graph/NewGraphSubscription.cs index 855524a52..f8dd598c9 100644 --- a/Commands/Graph/NewGraphSubscription.cs +++ b/Commands/Graph/NewGraphSubscription.cs @@ -21,6 +21,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> New-PnPGraphSubscription -ChangeType Updates -NotificationUrl https://mywebapiservice/notifications -Resource \"Users\" -ExpirationDateTime (Get-Date).AddHours(1) -ClientState [Guid]::NewGuid().ToString()", Remarks = "Creates a new Microsoft Graph subscription listening for changes to user objects during the next hour and will signal the URL provided through NotificationUrl when a change has been made", SortOrder = 2)] + // Deliberately omitting the CmdletMicrosoftGraphApiPermission attribute as permissions vary largely by the subscription type being used public class NewGraphSubscription : PnPGraphCmdlet { [Parameter(Mandatory = true, HelpMessage = "The event(s) the subscription should trigger on")] diff --git a/Commands/Graph/RemoveGraphSubscription.cs b/Commands/Graph/RemoveGraphSubscription.cs index 7359be891..752bb50d3 100644 --- a/Commands/Graph/RemoveGraphSubscription.cs +++ b/Commands/Graph/RemoveGraphSubscription.cs @@ -16,6 +16,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Remove-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da", Remarks = "Removes the Microsoft Graph subscription with the id 'bc204397-1128-4911-9d70-1d8bceee39da'", SortOrder = 1)] + // Deliberately omitting the CmdletMicrosoftGraphApiPermission attribute as permissions vary largely by the subscription type being used public class RemoveGraphSubscription : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The unique id or an instance of a Microsoft Graph Subscription")] diff --git a/Commands/Graph/RemoveSiteClassification.cs b/Commands/Graph/RemoveSiteClassification.cs index 491b2aa69..5bd0c14d4 100644 --- a/Commands/Graph/RemoveSiteClassification.cs +++ b/Commands/Graph/RemoveSiteClassification.cs @@ -9,17 +9,15 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Remove, "PnPSiteClassification")] - [CmdletHelp("Removes one or more existing site classification values from the list of available values. Requires a connection to the Microsoft Graph", + [CmdletHelp("Removes one or more existing site classification values from the list of available values", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Remove-PnPSiteClassification -Classifications ""HBI""", + Code = @"PS:> Remove-PnPSiteClassification -Classifications ""HBI""", Remarks = @"Removes the ""HBI"" site classification from the list of available values.", SortOrder = 1)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Remove-PnPSiteClassification -Classifications ""HBI"", ""Top Secret""", + Code = @"PS:> Remove-PnPSiteClassification -Classifications ""HBI"", ""Top Secret""", Remarks = @"Removes the ""HBI"" site classification from the list of available values.", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] diff --git a/Commands/Graph/RemoveUnifiedGroup.cs b/Commands/Graph/RemoveUnifiedGroup.cs index 686d41721..f60722762 100644 --- a/Commands/Graph/RemoveUnifiedGroup.cs +++ b/Commands/Graph/RemoveUnifiedGroup.cs @@ -9,7 +9,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Remove, "PnPUnifiedGroup")] - [CmdletHelp("Removes one Microsoft 365 Group (aka Unified Group). Requires the Azure Active Directory application permission 'Group.ReadWrite.All'.", + [CmdletHelp("Removes one Microsoft 365 Group (aka Unified Group)", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete", SupportedPlatform = CmdletSupportedPlatform.Online)] diff --git a/Commands/Graph/ResetUnifiedGroupExpiration.cs b/Commands/Graph/ResetUnifiedGroupExpiration.cs index f7d528bc0..9df4a3177 100644 --- a/Commands/Graph/ResetUnifiedGroupExpiration.cs +++ b/Commands/Graph/ResetUnifiedGroupExpiration.cs @@ -9,14 +9,15 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Reset, "PnPUnifiedGroupExpiration")] [CmdletHelp("Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", - DetailedDescription = "Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory. Requires the Azure Active Directory application permission 'Group.ReadWrite.All' or 'Directory.ReadWrite.All'.", - Category = CmdletHelpCategory.Graph, + DetailedDescription = "Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", + Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-renew", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( Code = "PS:> Reset-PnPUnifiedGroupExpiration", Remarks = "Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class ResetUnifiedGroupExpiration : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Office 365 Group")] diff --git a/Commands/Graph/RestoreDeletedUnifiedGroup.cs b/Commands/Graph/RestoreDeletedUnifiedGroup.cs index 47838688c..6d6da3eb3 100644 --- a/Commands/Graph/RestoreDeletedUnifiedGroup.cs +++ b/Commands/Graph/RestoreDeletedUnifiedGroup.cs @@ -9,8 +9,9 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsData.Restore, "PnPDeletedUnifiedGroup")] - [CmdletHelp("Restores one deleted Office 365 Group (aka Unified Group)", + [CmdletHelp("Restores one deleted Microsoft 365 Group (aka Unified Group)", Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/directory-deleteditems-restore", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( Code = "PS:> Restore-PnPDeletedUnifiedGroup -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", diff --git a/Commands/Graph/SetGraphSubscription.cs b/Commands/Graph/SetGraphSubscription.cs index 9e30196d0..8da9700fd 100644 --- a/Commands/Graph/SetGraphSubscription.cs +++ b/Commands/Graph/SetGraphSubscription.cs @@ -17,6 +17,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Set-PnPGraphSubscription -Identity bc204397-1128-4911-9d70-1d8bceee39da -ExpirationDate \"2020-11-22T18:23:45.9356913Z\"", Remarks = "Updates the Microsoft Graph subscription with the id 'bc204397-1128-4911-9d70-1d8bceee39da' to expire at the mentioned date", SortOrder = 1)] + // Deliberately omitting the CmdletMicrosoftGraphApiPermission attribute as permissions vary largely by the subscription type being used public class SetGraphSubscription : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The unique id or an instance of a Microsoft Graph Subscription")] diff --git a/Commands/Graph/SetUnifiedGroup.cs b/Commands/Graph/SetUnifiedGroup.cs index 7730d2395..e6e3f42c1 100644 --- a/Commands/Graph/SetUnifiedGroup.cs +++ b/Commands/Graph/SetUnifiedGroup.cs @@ -11,7 +11,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Set, "PnPUnifiedGroup")] - [CmdletHelp("Sets Microsoft 365 Group (aka Unified Group) properties. Requires the Azure Active Directory application permission 'Group.ReadWrite.All'.", + [CmdletHelp("Sets Microsoft 365 Group (aka Unified Group) properties", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-update", SupportedPlatform = CmdletSupportedPlatform.Online)] diff --git a/Commands/Graph/UpdateSiteClassification.cs b/Commands/Graph/UpdateSiteClassification.cs index 23cfc09ee..3baa3178f 100644 --- a/Commands/Graph/UpdateSiteClassification.cs +++ b/Commands/Graph/UpdateSiteClassification.cs @@ -9,23 +9,20 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsData.Update, "PnPSiteClassification")] - [CmdletHelp("Updates Site Classifications for the tenant. Requires a connection to the Microsoft Graph with the permission 'Directory.ReadWrite.All'.", + [CmdletHelp("Updates Site Classifications for the tenant", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Update-PnPSiteClassification -Classifications ""HBI"",""Top Secret""", + Code = @"PS:> Update-PnPSiteClassification -Classifications ""HBI"",""Top Secret""", Remarks = @"Replaces the existing values of the site classification settings", SortOrder = 1)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Update-PnPSiteClassification -DefaultClassification ""LBI""", + Code = @"PS:> Update-PnPSiteClassification -DefaultClassification ""LBI""", Remarks = @"Sets the default classification value to ""LBI"". This value needs to be present in the list of classification values.", SortOrder = 2)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Scopes ""Directory.ReadWrite.All"" -PS:> Update-PnPSiteClassification -UsageGuidelinesUrl https://aka.ms/sppnp", - Remarks = @"sets the usage guideliness URL to the specified URL.", + Code = @"PS:> Update-PnPSiteClassification -UsageGuidelinesUrl https://aka.ms/sppnp", + Remarks = @"sets the usage guideliness URL to the specified URL", SortOrder = 3)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] public class UpdateSiteClassification : PnPGraphCmdlet From 04004756dcbc5949a65a2ebb2e1c6e8862f68705 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 20 Jun 2020 03:52:03 +0200 Subject: [PATCH 015/130] Added support for delegation permission login using -Scope parameter --- Commands/Base/ConnectOnline.cs | 38 +++++++------ Commands/Base/PnPConnection.cs | 8 +-- Commands/Graph/SetUnifiedGroup.cs | 36 ++++++++----- .../GetManagementApiAccessToken.cs | 2 +- Commands/Model/GraphToken.cs | 54 ++++++++++++++++--- Commands/Model/OfficeManagementApiToken.cs | 50 ++++++++++++++--- 6 files changed, 139 insertions(+), 49 deletions(-) diff --git a/Commands/Base/ConnectOnline.cs b/Commands/Base/ConnectOnline.cs index cd7b56781..522db8081 100644 --- a/Commands/Base/ConnectOnline.cs +++ b/Commands/Base/ConnectOnline.cs @@ -105,29 +105,33 @@ namespace SharePointPnP.PowerShell.Commands.Base Code = "PS:> Connect-PnPOnline -Scopes \"Mail.Read\",\"Files.Read\",\"ActivityFeed.Read\"", Remarks = "Connects to Azure Active Directory interactively and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP.PowerShell with application id bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71 registered by the PnP PowerShell team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. It will ask you to authenticate for each of the APIs you have listed scopes for.", SortOrder = 15)] + [CmdletExample( + Code = "PS:> Connect-PnPOnline -Scopes \"Mail.Read\",\"Files.Read\",\"ActivityFeed.Read\" -Credentials (New-Object System.Management.Automation.PSCredential (\"johndoe@contoso.onmicrosoft.com\", (ConvertTo-SecureString \"password\" -AsPlainText -Force)))", + Remarks = "Connects to Azure Active Directory using delegated permissions and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP.PowerShell with application id bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71 registered by the PnP PowerShell team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. You must have logged on interactively with the same scopes at least once without using -Credentials to allow for the permission grant dialog to show and allow constent for the user account you would like to use.", + SortOrder = 16)] #endif #endif #if !ONPREMISES [CmdletExample( Code = "PS:> Connect-PnPOnline -ClientId '' -ClientSecret '' -AADDomain 'contoso.onmicrosoft.com'", Remarks = "Connects to the Microsoft Graph API using application permissions via an app's declared permission scopes. See https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/Graph.ConnectUsingAppPermissions for a sample on how to get started.", - SortOrder = 16)] + SortOrder = 17)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId '' -Tenant 'contoso.onmicrosoft.com' -CertificatePath c:\\absolute-path\\to\\pnp.pfx -CertificatePassword ", Remarks = "Connects to SharePoint using app-only tokens via an app's declared permission scopes. See https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/SharePoint.ConnectUsingAppPermissions for a sample on how to get started.", - SortOrder = 17)] + SortOrder = 18)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId '' -Tenant 'contoso.onmicrosoft.com' -Thumbprint 34CFAA860E5FB8C44335A38A097C1E41EEA206AA", Remarks = "Connects to SharePoint using app-only tokens via an app's declared permission scopes. See https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/SharePoint.ConnectUsingAppPermissions for a sample on how to get started.", - SortOrder = 18)] + SortOrder = 19)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId '' -Tenant 'contoso.onmicrosoft.com' -PEMCertificate -PEMPrivateKey -CertificatePassword ", Remarks = "Connects to SharePoint using app-only tokens via an app's declared permission scopes. See https://github.com/SharePoint/PnP-PowerShell/tree/master/Samples/SharePoint.ConnectUsingAppPermissions for a sample on how to get started.", - SortOrder = 19)] + SortOrder = 20)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -ClientId '' -Tenant 'contoso.onmicrosoft.com' -Certificate ", Remarks = "Connects to SharePoint using app-only auth in combination with a certificate. See https://docs.microsoft.com/en-us/sharepoint/dev/solution-guidance/security-apponly-azuread#using-this-principal-in-your-powershell-script-using-the-pnp-sites-core-library for a sample on how to get started.", - SortOrder = 20)] + SortOrder = 21)] #endif #if ONPREMISES [CmdletExample( @@ -174,7 +178,7 @@ public class ConnectOnline : BasePSCmdlet private const string ParameterSet_DEVICELOGIN = "PnP O365 Management Shell / DeviceLogin"; private const string ParameterSet_GRAPHDEVICELOGIN = "PnP Office 365 Management Shell to the Microsoft Graph"; #if !NETSTANDARD2_1 - private const string ParameterSet_GRAPHWITHSCOPE = "Microsoft Graph using Scopes"; + private const string ParameterSet_AADWITHSCOPE = "Azure Active Directory using Scopes"; #endif private const string ParameterSet_GRAPHWITHAAD = "Microsoft Graph using Azure Active Directory"; private const string SPOManagementClientId = "9bc3ab49-b65d-410a-85ad-de819febfddc"; @@ -239,6 +243,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_MAIN, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials.")] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ADFSCREDENTIALS, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials.")] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AADWITHSCOPE, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials.")] public CredentialPipeBind Credentials; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_MAIN, HelpMessage = "If you want to connect with the current user credentials")] @@ -518,8 +523,8 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_APPONLYCLIENTIDCLIENTSECRETURL, HelpMessage = "The Azure environment to use for authentication, the defaults to 'Production' which is the main Azure environment.")] public AzureEnvironment AzureEnvironment = AzureEnvironment.Production; -#if !NETSTANDARD2_1 - [Parameter(Mandatory = true, ParameterSetName = ParameterSet_GRAPHWITHSCOPE, HelpMessage = "The array of permission scopes for the Microsoft Graph API.")] +#if !NETSTANDARD2_1 + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_AADWITHSCOPE, HelpMessage = "The array of permission scopes to request from Azure Active Directory")] public string[] Scopes; #endif @@ -585,7 +590,7 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_APPONLYAADCER, HelpMessage = "Ignores any SSL errors. To be used i.e. when connecting to a SharePoint farm using self signed certificates or using a certificate authority not trusted by this machine.")] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_GRAPHWITHAAD, HelpMessage = "Ignores any SSL errors. To be used i.e. when connecting through a proxy to the Microsoft Graph API which has SSL interception enabled.")] #if !NETSTANDARD2_1 - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_GRAPHWITHSCOPE, HelpMessage = "Ignores any SSL errors. To be used i.e. when connecting through a proxy to the Microsoft Graph API which has SSL interception enabled.")] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AADWITHSCOPE, HelpMessage = "Ignores any SSL errors. To be used i.e. when connecting through a proxy to the Microsoft Graph API which has SSL interception enabled.")] #endif [Parameter(Mandatory = false, ParameterSetName = ParameterSet_GRAPHDEVICELOGIN, HelpMessage = "Ignores any SSL errors. To be used i.e. when connecting through a proxy to the Microsoft Graph API which has SSL interception enabled.")] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SPOMANAGEMENT, HelpMessage = "Ignores any SSL errors. To be used i.e. when connecting to a SharePoint farm using self signed certificates or using a certificate authority not trusted by this machine.")] @@ -697,8 +702,8 @@ protected void Connect() break; #if !NETSTANDARD2_1 - case ParameterSet_GRAPHWITHSCOPE: - connection = ConnectGraphWithScope(); + case ParameterSet_AADWITHSCOPE: + connection = ConnectAadWithScope(credentials); break; #endif case ParameterSet_ACCESSTOKEN: @@ -1082,10 +1087,11 @@ private PnPConnection ConnectAppOnlyAadCer() } ///

- /// Connect using the parameter set GRAPHWITHSCOPE + /// Connect using the parameter set AADWITHSCOPE /// + /// Credentials to authenticate with for delegated access or NULL for application permissions /// PnPConnection based on the parameters provided in the parameter set - private PnPConnection ConnectGraphWithScope() + private PnPConnection ConnectAadWithScope(PSCredential credentials) { #if !ONPREMISES #if !NETSTANDARD2_1 @@ -1100,16 +1106,16 @@ private PnPConnection ConnectGraphWithScope() // If we have Office 365 scopes, get a token for those first if (officeManagementApiScopes.Length > 0) { - var officeManagementApiToken = OfficeManagementApiToken.AcquireTokenInteractive(MSALPnPPowerShellClientId, officeManagementApiScopes); + var officeManagementApiToken = credentials == null ? OfficeManagementApiToken.AcquireApplicationTokenInteractive(MSALPnPPowerShellClientId, officeManagementApiScopes) : OfficeManagementApiToken.AcquireDelegatedTokenWithCredentials(MSALPnPPowerShellClientId, graphScopes, credentials.UserName, credentials.Password); connection = PnPConnection.GetConnectionWithToken(officeManagementApiToken, TokenAudience.OfficeManagementApi, Host, InitializationType.InteractiveLogin, disableTelemetry: NoTelemetry.ToBool()); } // If we have Graph scopes, get a token for it if (graphScopes.Length > 0) { - var graphToken = GraphToken.AcquireTokenInteractive(MSALPnPPowerShellClientId, graphScopes); + var graphToken = credentials == null ? GraphToken.AcquireApplicationTokenInteractive(MSALPnPPowerShellClientId, graphScopes) : GraphToken.AcquireDelegatedTokenWithCredentials(MSALPnPPowerShellClientId, graphScopes, credentials.UserName, credentials.Password); - // If there's a connection already, add the Graph token to it, otherwise set up a new connection with it + // If there's a connection already, add the AAD token to it, otherwise set up a new connection with it if (connection != null) { connection.AddToken(TokenAudience.MicrosoftGraph, graphToken); diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index 37f8a8dc9..d1f9ffdda 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -153,11 +153,11 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] roles = { if (Certificate != null) { - token = GraphToken.AcquireToken(Tenant, ClientId, Certificate); + token = GraphToken.AcquireApplicationToken(Tenant, ClientId, Certificate); } else if (ClientSecret != null) { - token = GraphToken.AcquireToken(Tenant, ClientId, ClientSecret); + token = GraphToken.AcquireApplicationToken(Tenant, ClientId, ClientSecret); } } break; @@ -167,11 +167,11 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] roles = { if (Certificate != null) { - token = OfficeManagementApiToken.AcquireToken(Tenant, ClientId, Certificate); + token = OfficeManagementApiToken.AcquireApplicationToken(Tenant, ClientId, Certificate); } else if (ClientSecret != null) { - token = OfficeManagementApiToken.AcquireToken(Tenant, ClientId, ClientSecret); + token = OfficeManagementApiToken.AcquireApplicationToken(Tenant, ClientId, ClientSecret); } } break; diff --git a/Commands/Graph/SetUnifiedGroup.cs b/Commands/Graph/SetUnifiedGroup.cs index 7730d2395..3051a3b46 100644 --- a/Commands/Graph/SetUnifiedGroup.cs +++ b/Commands/Graph/SetUnifiedGroup.cs @@ -25,15 +25,15 @@ namespace SharePointPnP.PowerShell.Commands.Graph SortOrder = 2)] [CmdletExample( Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -GroupLogoPath "".\MyLogo.png""", - Remarks = "Sets a specific Microsoft 365 Group logo.", + Remarks = "Sets a specific Microsoft 365 Group logo", SortOrder = 3)] [CmdletExample( Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -IsPrivate:$false", - Remarks = "Sets a group to be Public if previously Private.", + Remarks = "Sets a group to be Public if previously Private", SortOrder = 4)] [CmdletExample( Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -Owners demo@contoso.com", - Remarks = "Sets demo@contoso.com as owner of the group.", + Remarks = "Sets demo@contoso.com as owner of the group", SortOrder = 5)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class SetUnifiedGroup : PnPGraphCmdlet @@ -56,7 +56,7 @@ public class SetUnifiedGroup : PnPGraphCmdlet [Parameter(Mandatory = false, HelpMessage = "Makes the group private when selected")] public SwitchParameter IsPrivate; - [Parameter(Mandatory = false, HelpMessage = "The path to the logo file of to set")] + [Parameter(Mandatory = false, HelpMessage = "The path to the logo file of to set. Requires Site.ReadWrite.All permissions.")] public string GroupLogoPath; [Parameter(Mandatory = false, HelpMessage = "Creates a Microsoft Teams team associated with created group")] @@ -88,16 +88,24 @@ protected override void ExecuteCmdlet() { isPrivateGroup = IsPrivate.ToBool(); } - UnifiedGroupsUtility.UpdateUnifiedGroup( - groupId: group.GroupId, - accessToken: AccessToken, - displayName: DisplayName, - description: Description, - owners: Owners, - members: Members, - groupLogo: groupLogoStream, - isPrivate: isPrivateGroup, - createTeam: CreateTeam); + try + { + UnifiedGroupsUtility.UpdateUnifiedGroup( + groupId: group.GroupId, + accessToken: AccessToken, + displayName: DisplayName, + description: Description, + owners: Owners, + members: Members, + groupLogo: groupLogoStream, + isPrivate: isPrivateGroup, + createTeam: CreateTeam); + } + catch(Exception e) + { + while (e.InnerException != null) e = e.InnerException; + WriteError(new ErrorRecord(e, "GROUPUPDATEFAILED", ErrorCategory.InvalidOperation, this)); + } } else { diff --git a/Commands/ManagementApi/GetManagementApiAccessToken.cs b/Commands/ManagementApi/GetManagementApiAccessToken.cs index cc116ed20..fc5477f32 100644 --- a/Commands/ManagementApi/GetManagementApiAccessToken.cs +++ b/Commands/ManagementApi/GetManagementApiAccessToken.cs @@ -29,7 +29,7 @@ public class GetManagementApiAccessToken : BasePSCmdlet protected override void ExecuteCmdlet() { - var officeManagementApiToken = OfficeManagementApiToken.AcquireToken(TenantId, ClientId, ClientSecret); + var officeManagementApiToken = OfficeManagementApiToken.AcquireApplicationToken(TenantId, ClientId, ClientSecret); WriteObject(officeManagementApiToken.AccessToken); } } diff --git a/Commands/Model/GraphToken.cs b/Commands/Model/GraphToken.cs index ce8399249..8f629af0b 100644 --- a/Commands/Model/GraphToken.cs +++ b/Commands/Model/GraphToken.cs @@ -1,6 +1,7 @@ using Microsoft.Identity.Client; using System; using System.Linq; +using System.Security; using System.Security.Cryptography.X509Certificates; namespace SharePointPnP.PowerShell.Commands.Model @@ -35,13 +36,13 @@ public GraphToken(string accesstoken) : base(accesstoken) } /// - /// Tries to acquire a Microsoft Graph Access Token + /// Tries to acquire an application Microsoft Graph Access Token /// /// Name of the tenant to acquire the token for (i.e. contoso.onmicrosoft.com). Required. /// ClientId to use to acquire the token. Required. /// Certificate to use to acquire the token. Required. /// instance with the token - public static GenericToken AcquireToken(string tenant, string clientId, X509Certificate2 certificate) + public static GenericToken AcquireApplicationToken(string tenant, string clientId, X509Certificate2 certificate) { if (string.IsNullOrEmpty(tenant)) { @@ -63,13 +64,13 @@ public static GenericToken AcquireToken(string tenant, string clientId, X509Cert } /// - /// Tries to acquire a Microsoft Graph Access Token + /// Tries to acquire an application Microsoft Graph Access Token /// /// Name of the tenant to acquire the token for (i.e. contoso.onmicrosoft.com). Required. /// ClientId to use to acquire the token. Required. /// Client Secret to use to acquire the token. Required. /// instance with the token - public static GenericToken AcquireToken(string tenant, string clientId, string clientSecret) + public static GenericToken AcquireApplicationToken(string tenant, string clientId, string clientSecret) { if (string.IsNullOrEmpty(tenant)) { @@ -91,18 +92,18 @@ public static GenericToken AcquireToken(string tenant, string clientId, string c } /// - /// Tries to acquire a Microsoft Graph Access Token for the provided scopes interactively by allowing the user to log in + /// Tries to acquire an application Microsoft Graph Access Token for the provided scopes interactively by allowing the user to log in /// /// ClientId to use to acquire the token. Required. /// Array with scopes that should be requested access to. Required. /// instance with the token - public static GenericToken AcquireTokenInteractive(string clientId, string[] scopes) + public static GenericToken AcquireApplicationTokenInteractive(string clientId, string[] scopes) { - if(string.IsNullOrEmpty(clientId)) + if (string.IsNullOrEmpty(clientId)) { throw new ArgumentNullException(nameof(clientId)); } - if(scopes == null || scopes.Length == 0) + if (scopes == null || scopes.Length == 0) { throw new ArgumentNullException(nameof(scopes)); } @@ -112,5 +113,42 @@ public static GenericToken AcquireTokenInteractive(string clientId, string[] sco return new GraphToken(tokenResult.AccessToken); } + + /// + /// Tries to acquire a delegated Microsoft Graph Access Token for the provided scopes using the provided credentials + /// + /// ClientId to use to acquire the token. Required. + /// Array with scopes that should be requested access to. Required. + /// The username to authenticate with. Required. + /// The password to authenticate with. Required. + /// instance with the token + public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId, string[] scopes, string username, SecureString securePassword) + { + if (string.IsNullOrEmpty(clientId)) + { + throw new ArgumentNullException(nameof(clientId)); + } + if (scopes == null || scopes.Length == 0) + { + throw new ArgumentNullException(nameof(scopes)); + } + if (string.IsNullOrEmpty(username)) + { + throw new ArgumentNullException(nameof(username)); + } + if (securePassword == null || securePassword.Length == 0) + { + throw new ArgumentNullException(nameof(securePassword)); + } + + var app = PublicClientApplicationBuilder.Create(clientId) + // Delegated Graph token using credentials is only possible against organizational tenants + .WithAuthority($"{OAuthBaseUrl}organizations/") + .Build(); + + var tokenResult = app.AcquireTokenByUsernamePassword(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray(), username, securePassword).ExecuteAsync().GetAwaiter().GetResult(); + + return new GraphToken(tokenResult.AccessToken); + } } } diff --git a/Commands/Model/OfficeManagementApiToken.cs b/Commands/Model/OfficeManagementApiToken.cs index 556d23dbc..22a1d9a66 100644 --- a/Commands/Model/OfficeManagementApiToken.cs +++ b/Commands/Model/OfficeManagementApiToken.cs @@ -1,6 +1,7 @@ using Microsoft.Identity.Client; using System; using System.Linq; +using System.Security; using System.Security.Cryptography.X509Certificates; namespace SharePointPnP.PowerShell.Commands.Model @@ -35,13 +36,13 @@ public OfficeManagementApiToken(string accesstoken) : base(accesstoken) } /// - /// Tries to acquire an Office 365 Management API Access Token + /// Tries to acquire an application Office 365 Management API Access Token /// /// Name or id of the tenant to acquire the token for (i.e. contoso.onmicrosoft.com). Required. /// ClientId to use to acquire the token. Required. /// Certificate to use to acquire the token. Required. /// instance with the token - public static GenericToken AcquireToken(string tenant, string clientId, X509Certificate2 certificate) + public static GenericToken AcquireApplicationToken(string tenant, string clientId, X509Certificate2 certificate) { if (string.IsNullOrEmpty(tenant)) { @@ -63,13 +64,13 @@ public static GenericToken AcquireToken(string tenant, string clientId, X509Cert } /// - /// Tries to acquire an Office 365 Management API Access Token + /// Tries to acquire an application Office 365 Management API Access Token /// /// Name or id of the tenant to acquire the token for (i.e. contoso.onmicrosoft.com). Required. /// ClientId to use to acquire the token. Required. /// Client Secret to use to acquire the token. Required. /// instance with the token - public static GenericToken AcquireToken(string tenant, string clientId, string clientSecret) + public static GenericToken AcquireApplicationToken(string tenant, string clientId, string clientSecret) { if (string.IsNullOrEmpty(tenant)) { @@ -91,12 +92,12 @@ public static GenericToken AcquireToken(string tenant, string clientId, string c } /// - /// Tries to acquire an Office 365 Management API Access Token for the provided scopes interactively by allowing the user to log in + /// Tries to acquire an application Office 365 Management API Access Token for the provided scopes interactively by allowing the user to log in /// /// ClientId to use to acquire the token. Required. /// Array with scopes that should be requested access to. Required. /// instance with the token - public static GenericToken AcquireTokenInteractive(string clientId, string[] scopes) + public static GenericToken AcquireApplicationTokenInteractive(string clientId, string[] scopes) { if (string.IsNullOrEmpty(clientId)) { @@ -112,5 +113,42 @@ public static GenericToken AcquireTokenInteractive(string clientId, string[] sco return new OfficeManagementApiToken(tokenResult.AccessToken); } + + /// + /// Tries to acquire a delegated Office 365 Management API Access Token for the provided scopes using the provided credentials + /// + /// ClientId to use to acquire the token. Required. + /// Array with scopes that should be requested access to. Required. + /// The username to authenticate with. Required. + /// The password to authenticate with. Required. + /// instance with the token + public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId, string[] scopes, string username, SecureString securePassword) + { + if (string.IsNullOrEmpty(clientId)) + { + throw new ArgumentNullException(nameof(clientId)); + } + if (scopes == null || scopes.Length == 0) + { + throw new ArgumentNullException(nameof(scopes)); + } + if (string.IsNullOrEmpty(username)) + { + throw new ArgumentNullException(nameof(username)); + } + if (securePassword == null || securePassword.Length == 0) + { + throw new ArgumentNullException(nameof(securePassword)); + } + + var app = PublicClientApplicationBuilder.Create(clientId) + // Delegated Graph token using credentials is only possible against organizational tenants + .WithAuthority($"{OAuthBaseUrl}organizations/") + .Build(); + + var tokenResult = app.AcquireTokenByUsernamePassword(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray(), username, securePassword).ExecuteAsync().GetAwaiter().GetResult(); + + return new GraphToken(tokenResult.AccessToken); + } } } From c7a4ae3a3fef63bbce3bb46f0bf7e633a2963dd0 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 20 Jun 2020 04:00:02 +0200 Subject: [PATCH 016/130] Added constraints for group logo --- Commands/Graph/SetUnifiedGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Graph/SetUnifiedGroup.cs b/Commands/Graph/SetUnifiedGroup.cs index 3051a3b46..fe2d51091 100644 --- a/Commands/Graph/SetUnifiedGroup.cs +++ b/Commands/Graph/SetUnifiedGroup.cs @@ -56,7 +56,7 @@ public class SetUnifiedGroup : PnPGraphCmdlet [Parameter(Mandatory = false, HelpMessage = "Makes the group private when selected")] public SwitchParameter IsPrivate; - [Parameter(Mandatory = false, HelpMessage = "The path to the logo file of to set. Requires Site.ReadWrite.All permissions.")] + [Parameter(Mandatory = false, HelpMessage = "The path to the logo file of to set. Logo must be at least 48 pixels wide and may be at most 4 MB in size. Requires Site.ReadWrite.All permissions.")] public string GroupLogoPath; [Parameter(Mandatory = false, HelpMessage = "Creates a Microsoft Teams team associated with created group")] From d78fa35102dfde0340fc6c97ccd08d1f07d59e3a Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 20 Jun 2020 04:01:32 +0200 Subject: [PATCH 017/130] Documentation fix --- Commands/Model/OfficeManagementApiToken.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Model/OfficeManagementApiToken.cs b/Commands/Model/OfficeManagementApiToken.cs index 22a1d9a66..77ecb74f8 100644 --- a/Commands/Model/OfficeManagementApiToken.cs +++ b/Commands/Model/OfficeManagementApiToken.cs @@ -121,7 +121,7 @@ public static GenericToken AcquireApplicationTokenInteractive(string clientId, s /// Array with scopes that should be requested access to. Required. /// The username to authenticate with. Required. /// The password to authenticate with. Required. - /// instance with the token + /// instance with the token public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId, string[] scopes, string username, SecureString securePassword) { if (string.IsNullOrEmpty(clientId)) From c990f8d88fb52be3a3daab99edd9cfff6211cdad Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sat, 20 Jun 2020 23:15:09 +0200 Subject: [PATCH 018/130] Corrected incorrect DefaultParameterSetName --- Commands/Files/CopyFile.cs | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/Commands/Files/CopyFile.cs b/Commands/Files/CopyFile.cs index 062ad6980..59476d941 100644 --- a/Commands/Files/CopyFile.cs +++ b/Commands/Files/CopyFile.cs @@ -11,7 +11,7 @@ namespace SharePointPnP.PowerShell.Commands.Files { - [Cmdlet(VerbsCommon.Copy, "PnPFile", SupportsShouldProcess = true, DefaultParameterSetName = "SOURCEURL")] + [Cmdlet(VerbsCommon.Copy, "PnPFile", SupportsShouldProcess = true, DefaultParameterSetName = ParameterSet_SITE)] [CmdletHelp("Copies a file or folder to a different location, currently there is a 200MB file size limit for the file to be copied.", Category = CmdletHelpCategory.Files)] [CmdletExample( @@ -61,31 +61,49 @@ namespace SharePointPnP.PowerShell.Commands.Files public class CopyFile : PnPWebCmdlet { + private const string ParameterSet_SITE = "Site Relative"; +#if !ONPREMISES + private const string ParameterSet_OTHERSITE = "Other Site Collection"; +#endif private ProgressRecord _progressFolder = new ProgressRecord(0, "Activity", "Status") { Activity = "Copying folder" }; private ProgressRecord _progressFile = new ProgressRecord(1, "Activity", "Status") { Activity = "Copying file" }; private ClientContext _sourceContext; private ClientContext _targetContext; - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SERVER", HelpMessage = "Server relative Url specifying the file or folder to copy.")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SERVER", HelpMessage = "Server relative Url specifying the file or folder to copy")] [Obsolete("Use SourceUrl instead.")] public string ServerRelativeUrl = string.Empty; - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SOURCEURL", HelpMessage = "Site relative Url specifying the file or folder to copy.")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SOURCEURL", HelpMessage = "Site relative Url specifying the file or folder to copy")] [Alias("SiteRelativeUrl")] public string SourceUrl = string.Empty; - [Parameter(Mandatory = true, Position = 1, HelpMessage = "Server relative Url where to copy the file or folder to.")] + [Parameter(Mandatory = true, Position = 1, HelpMessage = "Server relative Url where to copy the file or folder to")] public string TargetUrl = string.Empty; - [Parameter(Mandatory = false, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location.")] + [Parameter(Mandatory = false, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location")] public SwitchParameter OverwriteIfAlreadyExists; [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be requested and the action will be performed")] public SwitchParameter Force; - [Parameter(Mandatory = false, HelpMessage = "If the source is a folder, the source folder name will not be created, only the contents within it.")] + [Parameter(Mandatory = false, HelpMessage = "If the source is a folder, the source folder name will not be created, only the contents within it")] public SwitchParameter SkipSourceFolderName; +#if !ONPREMISES + [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Site relative Url specifying the file to copy. Must include the file name.")] + public string SiteRelativeUrl = string.Empty; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided and the target document library specified using TargetServerRelativeLibrary has different fields than the document library where the document is being copied from, the copy will succeed. If not provided, it will fail to protect against data loss of metadata stored in fields that cannot be copied along.")] + public SwitchParameter AllowSchemaMismatch; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided and the target document library specified using TargetServerRelativeLibrary is configured to keep less historical versions of documents than the document library where the document is being copied from, the copy will succeed. If not provided, it will fail to protect against data loss of historical versions that cannot be copied along.")] + public SwitchParameter AllowSmallerVersionLimitOnDestination; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided, only the latest version of the document will be copied and its history will be discared. If not provided, all historical versions will be copied along.")] + public SwitchParameter IgnoreVersionHistory; +#endif + protected override void ExecuteCmdlet() { #pragma warning disable CS0618 // Type or member is obsolete From a0e481f43c5770790a35b7977bb44ff51081e37d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 00:37:10 +0200 Subject: [PATCH 019/130] Added seperate processing path for copying accross site collections --- Commands/Files/CopyFile.cs | 179 ++++++++++++++++++++----------------- Commands/Files/MoveFile.cs | 2 +- 2 files changed, 98 insertions(+), 83 deletions(-) diff --git a/Commands/Files/CopyFile.cs b/Commands/Files/CopyFile.cs index 59476d941..15cf6a1bd 100644 --- a/Commands/Files/CopyFile.cs +++ b/Commands/Files/CopyFile.cs @@ -11,7 +11,7 @@ namespace SharePointPnP.PowerShell.Commands.Files { - [Cmdlet(VerbsCommon.Copy, "PnPFile", SupportsShouldProcess = true, DefaultParameterSetName = ParameterSet_SITE)] + [Cmdlet(VerbsCommon.Copy, "PnPFile", SupportsShouldProcess = true)] [CmdletHelp("Copies a file or folder to a different location, currently there is a 200MB file size limit for the file to be copied.", Category = CmdletHelpCategory.Files)] [CmdletExample( @@ -61,27 +61,23 @@ namespace SharePointPnP.PowerShell.Commands.Files public class CopyFile : PnPWebCmdlet { - private const string ParameterSet_SITE = "Site Relative"; -#if !ONPREMISES - private const string ParameterSet_OTHERSITE = "Other Site Collection"; -#endif private ProgressRecord _progressFolder = new ProgressRecord(0, "Activity", "Status") { Activity = "Copying folder" }; private ProgressRecord _progressFile = new ProgressRecord(1, "Activity", "Status") { Activity = "Copying file" }; private ClientContext _sourceContext; private ClientContext _targetContext; - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SERVER", HelpMessage = "Server relative Url specifying the file or folder to copy")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SERVERRELATIVEURL", HelpMessage = "Server relative Url specifying the file or folder to copy")] [Obsolete("Use SourceUrl instead.")] public string ServerRelativeUrl = string.Empty; - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SOURCEURL", HelpMessage = "Site relative Url specifying the file or folder to copy")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SOURCEURL", HelpMessage = "Site relative Url specifying the file to copy. Must include the file name.")] [Alias("SiteRelativeUrl")] public string SourceUrl = string.Empty; - [Parameter(Mandatory = true, Position = 1, HelpMessage = "Server relative Url where to copy the file or folder to")] + [Parameter(Mandatory = true, Position = 1, HelpMessage = "Server relative Url where to copy the file or folder to. Must not include the file name.")] public string TargetUrl = string.Empty; - [Parameter(Mandatory = false, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location")] + [Parameter(Mandatory = false, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location.")] public SwitchParameter OverwriteIfAlreadyExists; [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be requested and the action will be performed")] @@ -91,16 +87,7 @@ public class CopyFile : PnPWebCmdlet public SwitchParameter SkipSourceFolderName; #if !ONPREMISES - [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Site relative Url specifying the file to copy. Must include the file name.")] - public string SiteRelativeUrl = string.Empty; - - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided and the target document library specified using TargetServerRelativeLibrary has different fields than the document library where the document is being copied from, the copy will succeed. If not provided, it will fail to protect against data loss of metadata stored in fields that cannot be copied along.")] - public SwitchParameter AllowSchemaMismatch; - - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided and the target document library specified using TargetServerRelativeLibrary is configured to keep less historical versions of documents than the document library where the document is being copied from, the copy will succeed. If not provided, it will fail to protect against data loss of historical versions that cannot be copied along.")] - public SwitchParameter AllowSmallerVersionLimitOnDestination; - - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided, only the latest version of the document will be copied and its history will be discared. If not provided, all historical versions will be copied along.")] + [Parameter(Mandatory = false, HelpMessage = "If provided, only the latest version of the document will be copied and its history will be discared. If not provided, all historical versions will be copied along.")] public SwitchParameter IgnoreVersionHistory; #endif @@ -109,6 +96,7 @@ protected override void ExecuteCmdlet() #pragma warning disable CS0618 // Type or member is obsolete SourceUrl = SourceUrl ?? ServerRelativeUrl; #pragma warning restore CS0618 // Type or member is obsolete + var webServerRelativeUrl = SelectedWeb.EnsureProperty(w => w.ServerRelativeUrl); if (!SourceUrl.StartsWith("/")) @@ -126,6 +114,24 @@ protected override void ExecuteCmdlet() Uri targetUri = new Uri(currentContextUri, TargetUrl); Uri targetWebUri = Microsoft.SharePoint.Client.Web.WebUrlFromFolderUrlDirect(ClientContext, targetUri); + if (Force || ShouldContinue(string.Format(Resources.CopyFile0To1, SourceUrl, TargetUrl), Resources.Confirm)) + { + if (sourceWebUri != targetWebUri) + { + CopyToOtherSiteCollection(sourceUri, targetUri); + } + else + { + CopyWithinSameSiteCollection(currentContextUri, sourceWebUri, targetWebUri); + } + } + } + + /// + /// Allows copying to within the same site collection + /// + private void CopyWithinSameSiteCollection(Uri currentContextUri, Uri sourceWebUri, Uri targetWebUri) + { _sourceContext = ClientContext; if (!currentContextUri.AbsoluteUri.Equals(sourceWebUri.AbsoluteUri, StringComparison.InvariantCultureIgnoreCase)) { @@ -176,54 +182,51 @@ protected override void ExecuteCmdlet() { srcIsFolder = false; } - #endif } - if (Force || ShouldContinue(string.Format(Resources.CopyFile0To1, SourceUrl, TargetUrl), Resources.Confirm)) - { - var srcWeb = _sourceContext.Web; - srcWeb.EnsureProperty(s => s.Url); + var srcWeb = _sourceContext.Web; + srcWeb.EnsureProperty(s => s.Url); - _targetContext = ClientContext.Clone(targetWebUri.AbsoluteUri); - var dstWeb = _targetContext.Web; - dstWeb.EnsureProperties(s => s.Url, s => s.ServerRelativeUrl); - if (srcWeb.Url == dstWeb.Url) + _targetContext = ClientContext.Clone(targetWebUri.AbsoluteUri); + var dstWeb = _targetContext.Web; + dstWeb.EnsureProperties(s => s.Url, s => s.ServerRelativeUrl); + if (srcWeb.Url == dstWeb.Url) + { + try { - try - { - var targetFile = UrlUtility.Combine(TargetUrl, file?.Name); - // If src/dst are on the same Web, then try using CopyTo - backwards compability + var targetFile = UrlUtility.Combine(TargetUrl, file?.Name); + // If src/dst are on the same Web, then try using CopyTo - backwards compability #if ONPREMISES file?.CopyTo(targetFile, OverwriteIfAlreadyExists); #else - file?.CopyToUsingPath(ResourcePath.FromDecodedUrl(targetFile), OverwriteIfAlreadyExists); + file?.CopyToUsingPath(ResourcePath.FromDecodedUrl(targetFile), OverwriteIfAlreadyExists); #endif - _sourceContext.ExecuteQueryRetry(); - return; - } - catch - { - SkipSourceFolderName = true; // target folder exist - //swallow exception, in case target was a lib/folder which exists - } + _sourceContext.ExecuteQueryRetry(); + return; } - - //different site/site collection - Folder targetFolder = null; - string fileOrFolderName = null; - bool targetFolderExists = false; - try + catch { + SkipSourceFolderName = true; // target folder exist + //swallow exception, in case target was a lib/folder which exists + } + } + + //different site/site collection + Folder targetFolder = null; + string fileOrFolderName = null; + bool targetFolderExists = false; + try + { #if ONPREMISES targetFolder = _targetContext.Web.GetFolderByServerRelativeUrl(TargetUrl); #else - targetFolder = _targetContext.Web.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(TargetUrl)); + targetFolder = _targetContext.Web.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(TargetUrl)); #endif #if !SP2013 - targetFolder.EnsureProperties(f => f.Name, f => f.Exists); - if (!targetFolder.Exists) throw new Exception("TargetUrl is an existing file, not folder"); - targetFolderExists = true; + targetFolder.EnsureProperties(f => f.Name, f => f.Exists); + if (!targetFolder.Exists) throw new Exception("TargetUrl is an existing file, not folder"); + targetFolderExists = true; #else targetFolder.EnsureProperties(f => f.Name); try @@ -237,41 +240,54 @@ protected override void ExecuteCmdlet() } if (!targetFolderExists) throw new Exception("TargetUrl is an existing file, not folder"); #endif - } - catch (Exception) - { - targetFolder = null; - Expression> expressionRelativeUrl = l => l.RootFolder.ServerRelativeUrl; - var query = _targetContext.Web.Lists.IncludeWithDefaultProperties(expressionRelativeUrl); - var lists = _targetContext.LoadQuery(query); - _targetContext.ExecuteQueryRetry(); - lists = lists.OrderByDescending(l => l.RootFolder.ServerRelativeUrl); // order descending in case more lists start with the same - foreach (List targetList in lists) - { - if (!TargetUrl.StartsWith(targetList.RootFolder.ServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase)) continue; - fileOrFolderName = Regex.Replace(TargetUrl, _targetContext.Web.ServerRelativeUrl, "", RegexOptions.IgnoreCase).Trim('/'); - targetFolder = srcIsFolder - ? _targetContext.Web.EnsureFolderPath(fileOrFolderName) - : targetList.RootFolder; - //fileOrFolderName = Regex.Replace(TargetUrl, targetList.RootFolder.ServerRelativeUrl, "", RegexOptions.IgnoreCase).Trim('/'); - //targetFolder = srcIsFolder ? targetList.RootFolder.EnsureFolder(fileOrFolderName) : targetList.RootFolder; - break; - } - } - if (targetFolder == null) throw new Exception("Target does not exist"); - if (srcIsFolder) + } + catch (Exception) + { + targetFolder = null; + Expression> expressionRelativeUrl = l => l.RootFolder.ServerRelativeUrl; + var query = _targetContext.Web.Lists.IncludeWithDefaultProperties(expressionRelativeUrl); + var lists = _targetContext.LoadQuery(query); + _targetContext.ExecuteQueryRetry(); + lists = lists.OrderByDescending(l => l.RootFolder.ServerRelativeUrl); // order descending in case more lists start with the same + foreach (List targetList in lists) { - if (!SkipSourceFolderName && targetFolderExists) - { - targetFolder = targetFolder.EnsureFolder(folder.Name); - } - CopyFolder(folder, targetFolder); + if (!TargetUrl.StartsWith(targetList.RootFolder.ServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase)) continue; + fileOrFolderName = Regex.Replace(TargetUrl, _targetContext.Web.ServerRelativeUrl, "", RegexOptions.IgnoreCase).Trim('/'); + targetFolder = srcIsFolder + ? _targetContext.Web.EnsureFolderPath(fileOrFolderName) + : targetList.RootFolder; + //fileOrFolderName = Regex.Replace(TargetUrl, targetList.RootFolder.ServerRelativeUrl, "", RegexOptions.IgnoreCase).Trim('/'); + //targetFolder = srcIsFolder ? targetList.RootFolder.EnsureFolder(fileOrFolderName) : targetList.RootFolder; + break; } - else + } + if (targetFolder == null) throw new Exception("Target does not exist"); + if (srcIsFolder) + { + if (!SkipSourceFolderName && targetFolderExists) { - UploadFile(file, targetFolder, fileOrFolderName); + targetFolder = targetFolder.EnsureFolder(folder.Name); } + CopyFolder(folder, targetFolder); } + else + { + UploadFile(file, targetFolder, fileOrFolderName); + } + } + + /// + /// Allows copying to another site collection + /// + private void CopyToOtherSiteCollection(Uri source, Uri destination) + { + ClientContext.Site.CreateCopyJobs(new[] { source.ToString() }, destination.ToString(), new CopyMigrationOptions + { + IsMoveMode = false, + IgnoreVersionHistory = IgnoreVersionHistory.ToBool(), + NameConflictBehavior = OverwriteIfAlreadyExists.ToBool() ? MigrationNameConflictBehavior.Replace : MigrationNameConflictBehavior.Fail + }); + ClientContext.ExecuteQueryRetry(); } private void CopyFolder(Folder sourceFolder, Folder targetFolder) @@ -320,7 +336,6 @@ private void UploadFile(File srcFile, Folder targetFolder, string filename = "") _targetContext.ExecuteQueryRetry(); } - private File UploadFileWithSpecialCharacters(Folder folder, string fileName, System.IO.Stream stream, bool overwriteIfExists) { if (fileName == null) diff --git a/Commands/Files/MoveFile.cs b/Commands/Files/MoveFile.cs index 910a90bd5..35cde20e5 100644 --- a/Commands/Files/MoveFile.cs +++ b/Commands/Files/MoveFile.cs @@ -6,7 +6,7 @@ namespace SharePointPnP.PowerShell.Commands.Files { - [Cmdlet(VerbsCommon.Move, "PnPFile", SupportsShouldProcess = true)] + [Cmdlet(VerbsCommon.Move, "PnPFile", SupportsShouldProcess = true, DefaultParameterSetName = ParameterSet_SITE)] [CmdletHelp("Moves a file to a different location", #if !ONPREMISES DetailedDescription = "Allows moving a file to a different location inside the same document library, such as in a subfolder, to a different document library on the same site collection or to a document library on another site collection", From e36f4c24ceab0d1b21e0d942b3db6dfb8ae41a4f Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 01:17:41 +0200 Subject: [PATCH 020/130] Finalized copying accross site collections, clarified that move-pnpfile and copy-pnpfile can also be used for folders. Updated documentation of Move-PnPFolder to state that it only supports within same site moves of folders and move-pnpfile should be used instead to move the folder accross site collections. --- Commands/Files/CopyFile.cs | 45 ++++++++++++++++-------------------- Commands/Files/MoveFile.cs | 26 ++++++++++++--------- Commands/Files/MoveFolder.cs | 4 ++-- 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/Commands/Files/CopyFile.cs b/Commands/Files/CopyFile.cs index 15cf6a1bd..415dbf024 100644 --- a/Commands/Files/CopyFile.cs +++ b/Commands/Files/CopyFile.cs @@ -12,52 +12,56 @@ namespace SharePointPnP.PowerShell.Commands.Files { [Cmdlet(VerbsCommon.Copy, "PnPFile", SupportsShouldProcess = true)] - [CmdletHelp("Copies a file or folder to a different location, currently there is a 200MB file size limit for the file to be copied.", + [CmdletHelp("Copies a file or folder to a different location. This location can be within the same document library, same site, same site collection or even to another site collection on the same tenant. Currently there is a 200MB file size limit for the file or folder to be copied.", Category = CmdletHelpCategory.Files)] [CmdletExample( - Remarks = "Copies a file named company.docx located in a document library called Documents in the current site to the site collection otherproject. If a file named company.docx already exists, it won't perform the copy.", - Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl /sites/otherproject/Documents/company.docx", + Remarks = "Copies a file named company.docx located in a document library called Shared Documents in the site collection project to the Shared Documents library in the site collection otherproject. If a file named company.docx already exists, it won't perform the copy.", + Code = @"PS:>Copy-PnPFile -ServerRelativeUrl ""/sites/project/Shared Documents/company.docx"" -TargetServerRelativeLibrary ""/sites/otherproject/Shared Documents""", SortOrder = 1)] + [CmdletExample( + Remarks = "Copies a folder named Archive located in a document library called Shared Documents in the site collection project to the Shared Documents library in the site collection otherproject. If a folder named Archive already exists, it will overwrite it.", + Code = @"PS:>Copy-PnPFile -ServerRelativeUrl ""/sites/project/Shared Documents/Archive"" -TargetServerRelativeLibrary ""/sites/otherproject/Shared Documents"" -OverwriteIfAlreadyExists", + SortOrder = 2)] [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Documents to a new document named company2.docx in the same library.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl Documents/company2.docx", - SortOrder = 2)] + SortOrder = 3)] [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Documents to a document library called Documents2 in the same site. ", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl Documents2/company.docx", - SortOrder = 3)] + SortOrder = 4)] [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Documents to the document library named Document in a subsite named Subsite as a new document named company2.docx.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl Subsite/Documents/company2.docx", - SortOrder = 4)] + SortOrder = 5)] [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Documents to the document library named Document in a subsite named Subsite keeping the file name.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl Subsite/Documents", - SortOrder = 5)] + SortOrder = 6)] [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Documents in the current site to the site collection otherproject. If a file named company.docx already exists, it will still perform the copy and replace the original company.docx file.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl /sites/otherproject/Documents/company.docx -OverwriteIfAlreadyExists", - SortOrder = 6)] + SortOrder = 7)] [CmdletExample( Remarks = "Copies a folder named MyDocs in the document library called Documents located in the current site to the site collection otherproject. If the MyDocs folder exist it will copy into it, if not it will be created.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/MyDocs -TargetUrl /sites/otherproject/Documents -OverwriteIfAlreadyExists", - SortOrder = 7)] + SortOrder = 8)] [CmdletExample( Remarks = "Copies a folder named MyDocs in the document library called Documents located in the current site to the root folder of the library named Documents in the site collection otherproject.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/MyDocs -TargetUrl /sites/otherproject/Documents -SkipSourceFolderName -OverwriteIfAlreadyExists", - SortOrder = 8)] + SortOrder = 0)] [CmdletExample( Remarks = "Copies a folder named MyDocs in the MyDocs folder of the library named Documents. If the MyDocs folder does not exists, it will be created.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/MyDocs -TargetUrl /sites/otherproject/Documents/MyDocs -SkipSourceFolderName -OverwriteIfAlreadyExists", - SortOrder = 9)] + SortOrder = 10)] [CmdletExample( Remarks = "Copies a folder named MyDocs in the root of the library named Documents. If the MyDocs folder exists in the target, a subfolder also named MyDocs is created.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/MyDocs -TargetUrl /sites/otherproject/Documents/MyDocs -OverwriteIfAlreadyExists", - SortOrder = 10)] + SortOrder = 11)] [CmdletExample( Remarks = "Copies a file named company.docx in the library named Documents in SubSite1 to the library named Documents in SubSite2.", Code = @"PS:>Copy-PnPFile -SourceUrl SubSite1/Documents/company.docx -TargetUrl SubSite2/Documents", - SortOrder = 10)] + SortOrder = 12)] public class CopyFile : PnPWebCmdlet { @@ -66,15 +70,12 @@ public class CopyFile : PnPWebCmdlet private ClientContext _sourceContext; private ClientContext _targetContext; - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SERVERRELATIVEURL", HelpMessage = "Server relative Url specifying the file or folder to copy")] - [Obsolete("Use SourceUrl instead.")] - public string ServerRelativeUrl = string.Empty; - - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = "SOURCEURL", HelpMessage = "Site relative Url specifying the file to copy. Must include the file name.")] - [Alias("SiteRelativeUrl")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Site or server relative Url specifying the file or folder to copy. Must include the file name if it's a file or the entire path to the folder if it's a folder.")] + [Alias("SiteRelativeUrl", "ServerRelativeUrl")] // Aliases are present to allow for switching between Move-PnPFile and Copy-PnPFile keeping the same parameters. public string SourceUrl = string.Empty; [Parameter(Mandatory = true, Position = 1, HelpMessage = "Server relative Url where to copy the file or folder to. Must not include the file name.")] + [Alias(nameof(MoveFile.TargetServerRelativeLibrary))] // Aliases is present to allow for switching between Move-PnPFile and Copy-PnPFile keeping the same parameters. public string TargetUrl = string.Empty; [Parameter(Mandatory = false, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location.")] @@ -93,10 +94,6 @@ public class CopyFile : PnPWebCmdlet protected override void ExecuteCmdlet() { -#pragma warning disable CS0618 // Type or member is obsolete - SourceUrl = SourceUrl ?? ServerRelativeUrl; -#pragma warning restore CS0618 // Type or member is obsolete - var webServerRelativeUrl = SelectedWeb.EnsureProperty(w => w.ServerRelativeUrl); if (!SourceUrl.StartsWith("/")) @@ -256,8 +253,6 @@ private void CopyWithinSameSiteCollection(Uri currentContextUri, Uri sourceWebUr targetFolder = srcIsFolder ? _targetContext.Web.EnsureFolderPath(fileOrFolderName) : targetList.RootFolder; - //fileOrFolderName = Regex.Replace(TargetUrl, targetList.RootFolder.ServerRelativeUrl, "", RegexOptions.IgnoreCase).Trim('/'); - //targetFolder = srcIsFolder ? targetList.RootFolder.EnsureFolder(fileOrFolderName) : targetList.RootFolder; break; } } diff --git a/Commands/Files/MoveFile.cs b/Commands/Files/MoveFile.cs index 35cde20e5..f1479f774 100644 --- a/Commands/Files/MoveFile.cs +++ b/Commands/Files/MoveFile.cs @@ -7,9 +7,9 @@ namespace SharePointPnP.PowerShell.Commands.Files { [Cmdlet(VerbsCommon.Move, "PnPFile", SupportsShouldProcess = true, DefaultParameterSetName = ParameterSet_SITE)] - [CmdletHelp("Moves a file to a different location", + [CmdletHelp("Moves a file or folder to a different location", #if !ONPREMISES - DetailedDescription = "Allows moving a file to a different location inside the same document library, such as in a subfolder, to a different document library on the same site collection or to a document library on another site collection", + DetailedDescription = "Allows moving a file or folder to a different location inside the same document library, such as in a subfolder, to a different document library on the same site collection or to a document library on another site collection", #else DetailedDescription = "Allows moving a file to a different location inside the same document library, such as in a subfolder or to a different document library on the same site collection. It is not possible to move files between site collections.", #endif @@ -27,6 +27,10 @@ namespace SharePointPnP.PowerShell.Commands.Files Remarks = @"Moves a file named Document.docx located in the document library named ""Shared Documents"" in the current site to the document library named ""Shared Documents"" in another site collection ""otherproject"" allowing it to overwrite an existing file Document.docx in the destination, allowing the fields to be different on the destination document library from the source document library and allowing a lower document version limit on the destination compared to the source.", Code = @"PS:>Move-PnPFile -ServerRelativeUrl ""/sites/project/Shared Documents/Document.docx"" -TargetServerRelativeLibrary ""/sites/otherproject/Shared Documents"" -OverwriteIfAlreadyExists -AllowSchemaMismatch -AllowSmallerVersionLimitOnDestination", SortOrder = 3)] + [CmdletExample( + Remarks = @"Moves a folder named Archive located in the document library named ""Shared Documents"" in the current site to the document library named ""Project"" in another site collection ""archive"" not allowing it to overwrite an existing folder named ""Archive"" in the destination, allowing the fields to be different on the destination document library from the source document library and allowing a lower document version limit on the destination compared to the source.", + Code = @"PS:>Move-PnPFile -ServerRelativeUrl ""/sites/project/Shared Documents/Archive"" -TargetServerRelativeLibrary ""/sites/archive/Project"" -AllowSchemaMismatch -AllowSmallerVersionLimitOnDestination", + SortOrder = 4)] #endif public class MoveFile : PnPWebCmdlet @@ -39,29 +43,29 @@ public class MoveFile : PnPWebCmdlet [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_SERVER, HelpMessage = "Server relative Url specifying the file to move. Must include the file name.")] #if !ONPREMISES - [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Server relative Url specifying the file to move. Must include the file name.")] + [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Server relative Url specifying the file or folder to move. Must include the file name if it regards a file or the folder name if it regards a folder.")] #endif public string ServerRelativeUrl = string.Empty; - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_SITE, HelpMessage = "Site relative Url specifying the file to move. Must include the file name.")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_SITE, HelpMessage = "Site relative Url specifying the file or folder to move. Must include the file or folder name.")] #if !ONPREMISES - [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Site relative Url specifying the file to move. Must include the file name.")] + [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Site relative Url specifying the file or folder to move. Must include the file or folder name.")] #endif public string SiteRelativeUrl = string.Empty; - [Parameter(Mandatory = true, ParameterSetName = ParameterSet_SITE, Position = 1, HelpMessage = "Server relative Url where to move the file to. Must include the file name.")] - [Parameter(Mandatory = true, ParameterSetName = ParameterSet_SERVER, Position = 1, HelpMessage = "Server relative Url where to move the file to. Must include the file name.")] + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_SITE, Position = 1, HelpMessage = "Server relative Url where to move the file or folder to. Must include the file or folder name.")] + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_SERVER, Position = 1, HelpMessage = "Server relative Url where to move the file or folder to. Must include the file or folder name.")] public string TargetUrl = string.Empty; #if !ONPREMISES - [Parameter(Mandatory = true, Position = 1, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Server relative url of a document library where to move the file to. Must not include the file name.")] + [Parameter(Mandatory = true, Position = 1, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "Server relative url of a document library where to move the fileor folder to. Must not include the file or folder name.")] public string TargetServerRelativeLibrary = string.Empty; #endif - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SERVER, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the move operation will be canceled if the file already exists at the TargetUrl location.")] - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SITE, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the move operation will be canceled if the file already exists at the TargetUrl location.")] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SERVER, HelpMessage = "If provided, if a file or folder already exists at the TargetUrl, it will be overwritten. If omitted, the move operation will be canceled if the file or folder already exists at the TargetUrl location.")] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_SITE, HelpMessage = "If provided, if a file or folder already exists at the TargetUrl, it will be overwritten. If omitted, the move operation will be canceled if the file or folder already exists at the TargetUrl location.")] #if !ONPREMISES - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided, if a file already exists at the TargetServerRelativeLibrary, it will be overwritten. If omitted, the move operation will be canceled if the file already exists at the TargetServerRelativeLibrary location.")] + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_OTHERSITE, HelpMessage = "If provided, if a file or folder already exists at the TargetServerRelativeLibrary, it will be overwritten. If omitted, the move operation will be canceled if the file or folder already exists at the TargetServerRelativeLibrary location.")] #endif public SwitchParameter OverwriteIfAlreadyExists; diff --git a/Commands/Files/MoveFolder.cs b/Commands/Files/MoveFolder.cs index 6eee40c2e..f0c2de22f 100644 --- a/Commands/Files/MoveFolder.cs +++ b/Commands/Files/MoveFolder.cs @@ -7,10 +7,10 @@ namespace SharePointPnP.PowerShell.Commands.Files { [Cmdlet(VerbsCommon.Move, "PnPFolder")] - [CmdletHelp("Move a folder to another location in the current web", + [CmdletHelp("Move a folder to another location in the current web. If you want to move a folder to a different site collection, use the Move-PnPFile cmdlet instead, which also supports moving folders and also accross site collections.", Category = CmdletHelpCategory.Files, OutputType = typeof(Folder), - OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.folder.aspx" + OutputTypeLink = "https://docs.microsoft.com/previous-versions/office/sharepoint-server/ee538057(v=office.15)" )] [CmdletExample( Code = @"PS:> Move-PnPFolder -Folder Documents/Reports -TargetFolder 'Archived Reports'", From a27ff104a061827f7cd726e8d2626d092dafcce9 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 01:19:17 +0200 Subject: [PATCH 021/130] Added changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9bc823a3..3b1e60471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- Updated implementation of `Copy-PnPFile` to now also support copying of files and folders accross site collections +- Updated implementation of `Move-PnPFile` to now also support moving of files and folders accross site collections ### Contributors - Gautam Sheth [gautamdsheth] +- Koen Zomers [koenzomers] ## [3.22.2006.2] From f7e01f6e6831b8c5fc416f357ccc72f823431939 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 01:21:03 +0200 Subject: [PATCH 022/130] Added PR reference --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b1e60471..55c049473 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed -- Updated implementation of `Copy-PnPFile` to now also support copying of files and folders accross site collections -- Updated implementation of `Move-PnPFile` to now also support moving of files and folders accross site collections +- Updated implementation of `Copy-PnPFile` to now also support copying of files and folders accross site collections [PR #2749](https://github.com/pnp/PnP-PowerShell/pull/2749) +- Updated implementation of `Move-PnPFile` to now also support moving of files and folders accross site collections [PR #2749](https://github.com/pnp/PnP-PowerShell/pull/2749) ### Contributors - Gautam Sheth [gautamdsheth] From 43fff43e1015e75670c03de61f961204b4a0983e Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 01:38:19 +0200 Subject: [PATCH 023/130] Clarified the Add-PnPUserToGroup cmdlet is for SharePoint groups, not for M365 Groups --- Commands/Principals/AddUserToGroup.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Commands/Principals/AddUserToGroup.cs b/Commands/Principals/AddUserToGroup.cs index 2d53686bb..e34fd417a 100644 --- a/Commands/Principals/AddUserToGroup.cs +++ b/Commands/Principals/AddUserToGroup.cs @@ -6,15 +6,15 @@ namespace SharePointPnP.PowerShell.Commands.Principals { [Cmdlet(VerbsCommon.Add, "PnPUserToGroup")] - [CmdletHelp("Adds a user to a group", + [CmdletHelp("Adds a user to a SharePoint group", Category = CmdletHelpCategory.Principals)] [CmdletExample( Code = @"PS:> Add-PnPUserToGroup -LoginName user@company.com -Identity 'Marketing Site Members'", - Remarks = @"Add the specified user to the group ""Marketing Site Members""", + Remarks = @"Add the specified user to the SharePoint group ""Marketing Site Members""", SortOrder = 1)] [CmdletExample( Code = @"PS:> Add-PnPUserToGroup -LoginName user@company.com -Identity 5", - Remarks = "Add the specified user to the group with Id 5", + Remarks = "Add the specified user to the SharePoint group with Id 5", SortOrder = 2)] public class AddUserToGroup : PnPWebCmdlet { @@ -22,9 +22,9 @@ public class AddUserToGroup : PnPWebCmdlet [Parameter(Mandatory = true, HelpMessage = "The login name of the user", ParameterSetName = "Internal")] public string LoginName; - [Parameter(Mandatory = true, HelpMessage = "The group id, group name or group object to add the user to.", ValueFromPipeline = true, ParameterSetName = "Internal")] + [Parameter(Mandatory = true, HelpMessage = "The SharePoint group id, SharePoint group name or SharePoint group object to add the user to", ValueFromPipeline = true, ParameterSetName = "Internal")] #if !ONPREMISES - [Parameter(Mandatory = true, HelpMessage = "The group id, group name or group object to add the user to.", ValueFromPipeline = true, ParameterSetName = "External")] + [Parameter(Mandatory = true, HelpMessage = "The SharePoint group id, SharePoint group name or SharePoint group object to add the user to", ValueFromPipeline = true, ParameterSetName = "External")] #endif public GroupPipeBind Identity; From 18420dd7e6e051a8732a364ea9bb825bc2d41ed0 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 02:59:03 +0200 Subject: [PATCH 024/130] Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPUnifiedGroupMember`, `Add-PnPUnifiedGroupOwner`, `Remove-PnPUnifiedGroupMember`, `Remove-PnPUnifiedGroupOwner`, `Clear-PnPUnifiedGroupMember`, `Clear-PnPUnifiedGroupOwner` --- CHANGELOG.md | 1 + Commands/Graph/AddUnifiedGroupMember.cs | 53 +++++++++++++++++++ Commands/Graph/AddUnifiedGroupOwner.cs | 53 +++++++++++++++++++ Commands/Graph/ClearUnifiedGroupMember.cs | 42 +++++++++++++++ Commands/Graph/ClearUnifiedGroupOwner.cs | 42 +++++++++++++++ Commands/Graph/GetUnifiedGroupMembers.cs | 4 +- Commands/Graph/GetUnifiedGroupOwners.cs | 6 +-- Commands/Graph/RemoveUnifiedGroupMember.cs | 45 ++++++++++++++++ Commands/Graph/RemoveUnifiedGroupOwner.cs | 45 ++++++++++++++++ .../SharePointPnP.PowerShell.Commands.csproj | 6 +++ 10 files changed, 290 insertions(+), 7 deletions(-) create mode 100644 Commands/Graph/AddUnifiedGroupMember.cs create mode 100644 Commands/Graph/AddUnifiedGroupOwner.cs create mode 100644 Commands/Graph/ClearUnifiedGroupMember.cs create mode 100644 Commands/Graph/ClearUnifiedGroupOwner.cs create mode 100644 Commands/Graph/RemoveUnifiedGroupMember.cs create mode 100644 Commands/Graph/RemoveUnifiedGroupOwner.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index b9bc823a3..807d667a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added +- Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPUnifiedGroupMember`, `Add-PnPUnifiedGroupOwner`, `Remove-PnPUnifiedGroupMember`, `Remove-PnPUnifiedGroupOwner`, `Clear-PnPUnifiedGroupMember`, `Clear-PnPUnifiedGroupOwner` ### Changed diff --git a/Commands/Graph/AddUnifiedGroupMember.cs b/Commands/Graph/AddUnifiedGroupMember.cs new file mode 100644 index 000000000..0b932fac3 --- /dev/null +++ b/Commands/Graph/AddUnifiedGroupMember.cs @@ -0,0 +1,53 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Add, "PnPUnifiedGroupMember")] + [CmdletHelp("Adds members to a particular Microsoft 365 Group (aka Unified Group)", + Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/group-post-owners", + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = @"PS:> Add-PnPUnifiedGroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Remarks = @"Adds the provided two users as additional members to the Microsoft 365 Group named ""Project Team""", + SortOrder = 1)] + [CmdletExample( + Code = @"PS:> Add-PnPUnifiedGroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com"" -RemoveExisting", + Remarks = @"Sets the provided two users as the only members of the Microsoft 365 Group named ""Project Team"" by removing any current existing members first", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class AddUnifiedGroupMember : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add members to")] + public UnifiedGroupPipeBind Identity; + + [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to add to the Microsoft 365 Group as a member")] + public string[] Users; + + [Parameter(Mandatory = false, HelpMessage = "If provided, all existing members will be removed and only those provided through Users will become members")] + public SwitchParameter RemoveExisting; + + protected override void ExecuteCmdlet() + { + UnifiedGroupEntity group = null; + + if (Identity != null) + { + group = Identity.GetGroup(AccessToken); + } + + if (group != null) + { + UnifiedGroupsUtility.AddUnifiedGroupMembers(group.GroupId, Users, AccessToken, RemoveExisting.ToBool()); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Graph/AddUnifiedGroupOwner.cs b/Commands/Graph/AddUnifiedGroupOwner.cs new file mode 100644 index 000000000..bfd9dacff --- /dev/null +++ b/Commands/Graph/AddUnifiedGroupOwner.cs @@ -0,0 +1,53 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Add, "PnPUnifiedGroupOwner")] + [CmdletHelp("Adds owners to a particular Microsoft 365 Group (aka Unified Group)", + Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/group-post-owners", + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = @"PS:> Add-PnPUnifiedGroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Remarks = @"Adds the provided two users as additional owners to the Microsoft 365 Group named ""Project Team""", + SortOrder = 1)] + [CmdletExample( + Code = @"PS:> Add-PnPUnifiedGroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com"" -RemoveExisting", + Remarks = @"Sets the provided two users as the only owners of the Microsoft 365 Group named ""Project Team"" by removing any current existing owners first", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class AddUnifiedGroupOwner : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add owners to")] + public UnifiedGroupPipeBind Identity; + + [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to add to the Microsoft 365 Group as an owner")] + public string[] Users; + + [Parameter(Mandatory = false, HelpMessage = "If provided, all existing owners will be removed and only those provided through Users will become owners")] + public SwitchParameter RemoveExisting; + + protected override void ExecuteCmdlet() + { + UnifiedGroupEntity group = null; + + if (Identity != null) + { + group = Identity.GetGroup(AccessToken); + } + + if (group != null) + { + UnifiedGroupsUtility.AddUnifiedGroupOwners(group.GroupId, Users, AccessToken, RemoveExisting.ToBool()); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Graph/ClearUnifiedGroupMember.cs b/Commands/Graph/ClearUnifiedGroupMember.cs new file mode 100644 index 000000000..de816bd24 --- /dev/null +++ b/Commands/Graph/ClearUnifiedGroupMember.cs @@ -0,0 +1,42 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Clear, "PnPUnifiedGroupMember")] + [CmdletHelp("Removes all current members from a particular Microsoft 365 Group (aka Unified Group)", + Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-members", + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = @"PS:> Clear-PnPUnifiedGroupMember -Identity ""Project Team""", + Remarks = @"Removes all the current members from the Microsoft 365 Group named ""Project Team""", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.GroupMember_ReadWrite_All)] + public class ClearUnifiedGroupMember : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove all members from")] + public UnifiedGroupPipeBind Identity; + + protected override void ExecuteCmdlet() + { + UnifiedGroupEntity group = null; + + if (Identity != null) + { + group = Identity.GetGroup(AccessToken); + } + + if (group != null) + { + UnifiedGroupsUtility.ClearUnifiedGroupMembers(group.GroupId, AccessToken); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Graph/ClearUnifiedGroupOwner.cs b/Commands/Graph/ClearUnifiedGroupOwner.cs new file mode 100644 index 000000000..a7f65de4c --- /dev/null +++ b/Commands/Graph/ClearUnifiedGroupOwner.cs @@ -0,0 +1,42 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Clear, "PnPUnifiedGroupOwner")] + [CmdletHelp("Removes all current owners from a particular Microsoft 365 Group (aka Unified Group)", + Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-owners", + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = @"PS:> Clear-PnPUnifiedGroupOwner -Identity ""Project Team""", + Remarks = @"Removes all the current owners from the Microsoft 365 Group named ""Project Team""", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + public class ClearUnifiedGroupOwner : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove all owners from")] + public UnifiedGroupPipeBind Identity; + + protected override void ExecuteCmdlet() + { + UnifiedGroupEntity group = null; + + if (Identity != null) + { + group = Identity.GetGroup(AccessToken); + } + + if (group != null) + { + UnifiedGroupsUtility.ClearUnifiedGroupOwners(group.GroupId, AccessToken); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Graph/GetUnifiedGroupMembers.cs b/Commands/Graph/GetUnifiedGroupMembers.cs index 098ea4d63..358c02449 100644 --- a/Commands/Graph/GetUnifiedGroupMembers.cs +++ b/Commands/Graph/GetUnifiedGroupMembers.cs @@ -39,12 +39,10 @@ protected override void ExecuteCmdlet() if (group != null) { - // Get members of the group. - + // Get members of the group List members = UnifiedGroupsUtility.GetUnifiedGroupMembers(group, AccessToken); WriteObject(members); } - } } } diff --git a/Commands/Graph/GetUnifiedGroupOwners.cs b/Commands/Graph/GetUnifiedGroupOwners.cs index a52732b4f..4a3a36718 100644 --- a/Commands/Graph/GetUnifiedGroupOwners.cs +++ b/Commands/Graph/GetUnifiedGroupOwners.cs @@ -25,7 +25,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All | MicrosoftGraphApiPermission.User_Read_All | MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.User_ReadWrite_All)] public class GetUnifiedGroupOwners : PnPGraphCmdlet { - [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group.")] + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group")] public UnifiedGroupPipeBind Identity; protected override void ExecuteCmdlet() @@ -39,12 +39,10 @@ protected override void ExecuteCmdlet() if (group != null) { - // Get Owners of the group. - + // Get Owners of the group List owners = UnifiedGroupsUtility.GetUnifiedGroupOwners(group, AccessToken); WriteObject(owners); } - } } } diff --git a/Commands/Graph/RemoveUnifiedGroupMember.cs b/Commands/Graph/RemoveUnifiedGroupMember.cs new file mode 100644 index 000000000..3535e8c07 --- /dev/null +++ b/Commands/Graph/RemoveUnifiedGroupMember.cs @@ -0,0 +1,45 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPUnifiedGroupMember")] + [CmdletHelp("Removes members from a particular Microsoft 365 Group (aka Unified Group)", + Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-members", + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = @"PS:> Remove-PnPUnifiedGroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Remarks = @"Removes the provided two users as members from the Microsoft 365 Group named ""Project Team""", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.GroupMember_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + public class RemoveUnifiedGroupMember : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove members from")] + public UnifiedGroupPipeBind Identity; + + [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to remove as members from the Microsoft 365 Group")] + public string[] Users; + + protected override void ExecuteCmdlet() + { + UnifiedGroupEntity group = null; + + if (Identity != null) + { + group = Identity.GetGroup(AccessToken); + } + + if (group != null) + { + UnifiedGroupsUtility.RemoveUnifiedGroupMembers(group.GroupId, Users, AccessToken); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Graph/RemoveUnifiedGroupOwner.cs b/Commands/Graph/RemoveUnifiedGroupOwner.cs new file mode 100644 index 000000000..9ebd629a1 --- /dev/null +++ b/Commands/Graph/RemoveUnifiedGroupOwner.cs @@ -0,0 +1,45 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPUnifiedGroupOwner")] + [CmdletHelp("Removes owners from a particular Microsoft 365 Group (aka Unified Group)", + Category = CmdletHelpCategory.Graph, + OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-owners", + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = @"PS:> Remove-PnPUnifiedGroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Remarks = @"Removes the provided two users as owners from the Microsoft 365 Group named ""Project Team""", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + public class RemoveUnifiedGroupOwner : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove owners from")] + public UnifiedGroupPipeBind Identity; + + [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to remove as owners from the Microsoft 365 Group")] + public string[] Users; + + protected override void ExecuteCmdlet() + { + UnifiedGroupEntity group = null; + + if (Identity != null) + { + group = Identity.GetGroup(AccessToken); + } + + if (group != null) + { + UnifiedGroupsUtility.RemoveUnifiedGroupOwners(group.GroupId, Users, AccessToken); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index ed7d2865d..72ebe6852 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -624,6 +624,11 @@ + + + + + @@ -668,6 +673,7 @@ + From 20acbe78489e0e41a49fd2d8f94759f59ee88772 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 03:06:32 +0200 Subject: [PATCH 025/130] Added PR reference --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 807d667a5..a2133f85f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added -- Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPUnifiedGroupMember`, `Add-PnPUnifiedGroupOwner`, `Remove-PnPUnifiedGroupMember`, `Remove-PnPUnifiedGroupOwner`, `Clear-PnPUnifiedGroupMember`, `Clear-PnPUnifiedGroupOwner` +- Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPUnifiedGroupMember`, `Add-PnPUnifiedGroupOwner`, `Remove-PnPUnifiedGroupMember`, `Remove-PnPUnifiedGroupOwner`, `Clear-PnPUnifiedGroupMember`, `Clear-PnPUnifiedGroupOwner` [PR #2750](https://github.com/pnp/PnP-PowerShell/pull/2750) ### Changed ### Contributors - Gautam Sheth [gautamdsheth] +- Koen Zomers [koenzomers] ## [3.22.2006.2] From 9f4210eab1f05ebfefa8c02c2b5f129952ac97d2 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 03:10:47 +0200 Subject: [PATCH 026/130] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9bc823a3..05804b4f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added +- Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) ### Changed ### Contributors - Gautam Sheth [gautamdsheth] +- Koen Zomers [koenzomers] ## [3.22.2006.2] From 1f0d9658d6725e46f82f6b71d67a1e6ca589ba60 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 21 Jun 2020 03:44:09 +0200 Subject: [PATCH 027/130] Updated help generator to add a notice to the synopsis of the Get-Help documentation that it needs access to the SharePoint Admin center in order to run the cmdlet --- CHANGELOG.md | 2 ++ Commands/Admin/AddSiteCollectionAppCatalog.cs | 5 ++--- ModuleFilesGenerator/HelpFileGenerator.cs | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9bc823a3..b740fb80f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- If a certain PnP PowerShell cmdlet needs access to the SharePoint Admin Center site in order to function correctly, it will now list this in the Synopsis section of the Get-Help for the cmdlet ### Contributors - Gautam Sheth [gautamdsheth] +- Koen Zomers [koenzomers] ## [3.22.2006.2] diff --git a/Commands/Admin/AddSiteCollectionAppCatalog.cs b/Commands/Admin/AddSiteCollectionAppCatalog.cs index 1012224e5..6764de139 100644 --- a/Commands/Admin/AddSiteCollectionAppCatalog.cs +++ b/Commands/Admin/AddSiteCollectionAppCatalog.cs @@ -4,20 +4,19 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using System.Management.Automation; -using OfficeDevPnP.Core.Sites; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; -using System; namespace SharePointPnP.PowerShell.Commands.Admin { [Cmdlet(VerbsCommon.Add, "PnPSiteCollectionAppCatalog")] [CmdletHelp("Adds a Site Collection scoped App Catalog to a site", SupportedPlatform = CmdletSupportedPlatform.Online, + OutputTypeLink = "https://docs.microsoft.com/sharepoint/dev/general-development/site-collection-app-catalog#configure-and-manage-site-collection-app-catalogs", Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( Code = @"PS:> Add-PnPSiteCollectionAppCatalog -Site ""https://contoso.sharepoint.com/sites/FinanceTeamsite""", Remarks = @"This will add a SiteCollection app catalog to the specified site", SortOrder = 1)] - public class AddSiteCollectionAppCatalog: PnPAdminCmdlet + public class AddSiteCollectionAppCatalog : PnPAdminCmdlet { [Parameter(Mandatory = true, HelpMessage = @"Url of the site to add the app catalog to.")] public SitePipeBind Site; diff --git a/ModuleFilesGenerator/HelpFileGenerator.cs b/ModuleFilesGenerator/HelpFileGenerator.cs index 2dee1f696..00476ec57 100644 --- a/ModuleFilesGenerator/HelpFileGenerator.cs +++ b/ModuleFilesGenerator/HelpFileGenerator.cs @@ -115,6 +115,12 @@ private XElement GetCommandElement(Model.CmdletInfo cmdletInfo) additionalDescriptionInfo.AppendLine(); } + // Notice if the cmdlet is a PnPAdminCmdlet that access to the SharePoint Tenant Admin site is needed + if (cmdletInfo.CmdletType.BaseType.Name.Equals("PnPAdminCmdlet")) + { + additionalDescriptionInfo.AppendLine("* Required SharePoint permissions: Access to the SharePoint Tenant Administration site"); + } + // Validate if additional information should be prepended to the description if (additionalDescriptionInfo.Length > 0) { From 5f8a072d92eb9ed2c43e4d219f11503625caa433 Mon Sep 17 00:00:00 2001 From: Robin Meure Date: Tue, 23 Jun 2020 10:02:23 +0200 Subject: [PATCH 028/130] Update GetUser.cs --- Commands/Principals/GetUser.cs | 248 ++++++++++++++++++++++++++++++++- 1 file changed, 245 insertions(+), 3 deletions(-) diff --git a/Commands/Principals/GetUser.cs b/Commands/Principals/GetUser.cs index d9cc9815e..666c88737 100644 --- a/Commands/Principals/GetUser.cs +++ b/Commands/Principals/GetUser.cs @@ -6,6 +6,10 @@ using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using System.Linq; using System.Collections.Generic; +using System.Xml.Linq; +using System.Data; +using System.Text; + namespace SharePointPnP.PowerShell.Commands.Principals { @@ -39,6 +43,10 @@ namespace SharePointPnP.PowerShell.Commands.Principals Code = @"PS:> Get-PnPUser -WithRightsAssigned -Web subsite1", Remarks = "Returns only those users from the User Information List of the current site collection who currently have any kind of access rights given either directly to the user or Active Directory Group or given to the user or Active Directory Group via membership of a SharePoint Group to subsite 'subsite1'", SortOrder = 6)] + [CmdletExample( + Code = @"PS:> Get-PnPUser -WithRightsAssignedDetailed", + Remarks = "Returns all users who have been granted explicit access to the current site, lists and listitems.", + SortOrder = 7)] public class GetUser : PnPWebCmdlet { [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0, HelpMessage = "User ID or login name")] @@ -47,6 +55,17 @@ public class GetUser : PnPWebCmdlet [Parameter(Mandatory = false, Position = 1, HelpMessage = "If provided, only users that currently have any kinds of access rights assigned to the current site collection will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] public SwitchParameter WithRightsAssigned; + [Parameter(Mandatory = false, Position = 2, HelpMessage = "If provided, only users that currently have any specific kind of access rights assigned to the current site, lists or listitems/documents will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] + public SwitchParameter WithRightsAssignedDetailed; + + public class DetailedUser + { + public User User { get; set; } + public string Url { get; set; } + public List Permissions { get; set; } + public GroupCollection Groups { get; set; } + } + protected override void ExecuteCmdlet() { var retrievalExpressions = new Expression>[] @@ -73,11 +92,14 @@ protected override void ExecuteCmdlet() g => g.LoginName) }; + if (Identity == null) { SelectedWeb.Context.Load(SelectedWeb.SiteUsers, u => u.Include(retrievalExpressions)); - if (WithRightsAssigned) + List users = new List(); + + if (WithRightsAssigned || WithRightsAssignedDetailed) { // Get all the role assignments and role definition bindings to be able to see which users have been given rights directly on the site level SelectedWeb.Context.Load(SelectedWeb.RoleAssignments, ac => ac.Include(a => a.RoleDefinitionBindings, a => a.Member)); @@ -99,15 +121,196 @@ protected override void ExecuteCmdlet() allUsersWithPermissions.AddRange(usersWithDirectPermissions); allUsersWithPermissions.AddRange(usersWithGroupPermissions); - // Filter out the users that have been given rights at both places so they will only be returned once - WriteObject(allUsersWithPermissions.GroupBy(u => u.Id).Select(u => u.First()), true); + // Add the found users and add them to the custom object + if (WithRightsAssignedDetailed) + { + SelectedWeb.Context.Load(SelectedWeb, s => s.ServerRelativeUrl); + SelectedWeb.Context.ExecuteQueryRetry(); + + WriteWarning("Using the -WithRightsAssignedDetailed parameter will cause the script to take longer than normal because of the all enumerations that take place"); + users.AddRange(GetPermissions(SelectedWeb.RoleAssignments, SelectedWeb.ServerRelativeUrl)); + foreach (var user in allUsersWithPermissions) + { + users.Add(new DetailedUser() + { + Groups = user.Groups, + User = user, + Url = SelectedWeb.ServerRelativeUrl + }); + } + } + else + { + // Filter out the users that have been given rights at both places so they will only be returned once + WriteObject(allUsersWithPermissions.GroupBy(u => u.Id).Select(u => u.First()), true); + } } else { SelectedWeb.Context.ExecuteQueryRetry(); WriteObject(SelectedWeb.SiteUsers, true); } + + if (WithRightsAssignedDetailed) + { + SelectedWeb.Context.Load(SelectedWeb.Lists, l => l.Include(li => li.ItemCount, li => li.IsSystemList, li=>li.IsCatalog, li => li.RootFolder.ServerRelativeUrl, li => li.RoleAssignments, li => li.Title, li => li.HasUniqueRoleAssignments)); + SelectedWeb.Context.ExecuteQueryRetry(); + + var progress = new ProgressRecord(0, $"Getting lists for {SelectedWeb.ServerRelativeUrl}", "Enumerating through lists"); + var progressCounter = 0; + + foreach (var list in SelectedWeb.Lists) + { + WriteProgress(progress, $"Getting list {list.RootFolder.ServerRelativeUrl}", progressCounter++, SelectedWeb.Lists.Count); + + // ignoring the system lists + if (list.IsSystemList || list.IsCatalog) + { + continue; + } + + // if a list or a library has unique permissions then proceed + if (list.HasUniqueRoleAssignments) + { + WriteVerbose(string.Format("List found with HasUniqueRoleAssignments {0}", list.RootFolder.ServerRelativeUrl)); + string url = list.RootFolder.ServerRelativeUrl; + + SelectedWeb.Context.Load(list.RoleAssignments, r => r.Include( + ra => ra.RoleDefinitionBindings, + ra => ra.Member.LoginName, + ra => ra.Member.Title, + ra => ra.Member.PrincipalType)); + SelectedWeb.Context.ExecuteQueryRetry(); + + users.AddRange(GetPermissions(list.RoleAssignments, url)); + + // if the list with unique permissions also has items, check every item which is uniquely permissioned + if (list.ItemCount > 0) + { + WriteVerbose(string.Format("Enumerating through all listitems of {0}", list.RootFolder.ServerRelativeUrl)); + + CamlQuery query = CamlQuery.CreateAllItemsQuery(); + var queryElement = XElement.Parse(query.ViewXml); + + var rowLimit = queryElement.Descendants("RowLimit").FirstOrDefault(); + if (rowLimit != null) + { + rowLimit.RemoveAll(); + } + else + { + rowLimit = new XElement("RowLimit"); + queryElement.Add(rowLimit); + } + + rowLimit.SetAttributeValue("Paged", "TRUE"); + rowLimit.SetValue(1000); + + query.ViewXml = queryElement.ToString(); + + List items = new List(); + + do + { + var listItems = list.GetItems(query); + SelectedWeb.Context.Load(listItems); + SelectedWeb.Context.ExecuteQueryRetry(); + query.ListItemCollectionPosition = listItems.ListItemCollectionPosition; + + items.Add(listItems); + + } while (query.ListItemCollectionPosition != null); + + // Progress bar for item enumerations + var itemProgress = new ProgressRecord(0, $"Getting items for {list.RootFolder.ServerRelativeUrl}", "Enumerating through items"); + var itemProgressCounter = 0; + + foreach (var item in items) + { + WriteProgress(itemProgress, $"Retrieving items", itemProgressCounter++, items.Count); + + WriteVerbose(string.Format("Enumerating though listitemcollections")); + foreach (var listItem in item) + { + WriteVerbose(string.Format("Enumerating though listitems")); + listItem.EnsureProperty(i => i.HasUniqueRoleAssignments); + + if (listItem.HasUniqueRoleAssignments) + { + string listItemUrl = listItem["FileRef"].ToString(); + WriteVerbose(string.Format("List item {0} HasUniqueRoleAssignments", listItemUrl)); + + SelectedWeb.Context.Load(listItem.RoleAssignments, r => r.Include( + ra => ra.RoleDefinitionBindings, + ra => ra.Member.LoginName, + ra => ra.Member.Title, + ra => ra.Member.PrincipalType)); + SelectedWeb.Context.ExecuteQueryRetry(); + + users.AddRange(GetPermissions(listItem.RoleAssignments, listItemUrl)); + } + } + + } + itemProgress.RecordType = ProgressRecordType.Completed; + WriteProgress(itemProgress); + } + } + progress.RecordType = ProgressRecordType.Completed; + WriteProgress(progress); + } + + // Fetch all the unique users from everything that has been collected + var uniqueUsers = (from u in users + select u.User.LoginName).Distinct(); + + // Looping through each user, getting all the details like specific permissions and groups an user belongs to + foreach (var uniqueUser in uniqueUsers) + { + // Getting all the assigned permissions per user + var userPermissions = (from u in users + where u.User.LoginName == uniqueUser && u.Permissions != null + select u).ToList(); + + // Making the permissions readable by getting the name of the permission and the URL of the artifact + Dictionary Permissions = new Dictionary(); + foreach (var userPermission in userPermissions) + { + StringBuilder stringBuilder = new StringBuilder(); + foreach (var permissionMask in userPermission.Permissions) + { + stringBuilder.Append(permissionMask); + } + Permissions.Add(userPermission.Url, stringBuilder.ToString()); + } + + // Getting all the groups where the user is added to + var groupsMemberships = (from u in users + where u.User.LoginName == uniqueUser && u.Groups != null + select u.Groups).ToList(); + + // Getting the titles of the all the groups + List Groups = new List(); + foreach (var groupMembership in groupsMemberships) + { + foreach (var group in groupMembership) + { + Groups.Add(group.Title); + } + } + + // Getting the User object of the user so we can get to the title, loginname, etc + var userInformation = (from u in users + where u.User.LoginName == uniqueUser + select u.User).FirstOrDefault(); + + WriteObject(new { userInformation.Title, userInformation.LoginName, userInformation.Email, Groups, Permissions }, true); + } + } + + } + else { User user = null; @@ -131,5 +334,44 @@ protected override void ExecuteCmdlet() WriteObject(user); } } + + private void WriteProgress(ProgressRecord record, string message, int step, int count) + { + var percentage = Convert.ToInt32((100 / Convert.ToDouble(count)) * Convert.ToDouble(step)); + record.StatusDescription = message; + record.PercentComplete = percentage; + record.RecordType = ProgressRecordType.Processing; + WriteProgress(record); + } + + private static List GetPermissions(RoleAssignmentCollection roleAssignments, string url) + { + List users = new List(); + foreach (var roleAssignment in roleAssignments) + { + if (roleAssignment.Member.PrincipalType == Microsoft.SharePoint.Client.Utilities.PrincipalType.User) + { + var detailedUser = new DetailedUser(); + detailedUser.Url = url; + detailedUser.User = roleAssignment.Member as User; + detailedUser.Permissions = new List(); + + foreach (var roleDefinition in roleAssignment.RoleDefinitionBindings) + { + if (roleDefinition.Name == "Limited Access") + continue; + + detailedUser.Permissions.Add(roleDefinition.Name); + } + + // if no permissions are recorded (hence, limited access, skip the adding of the permissions) + if (detailedUser.Permissions.Count == 0) + continue; + + users.Add(detailedUser); + } + } + return users; + } } } From 6550c4d6147e90db511f7563916b18882d153dc9 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 23 Jun 2020 10:43:05 +0200 Subject: [PATCH 029/130] Updated MSDN reference --- Commands/Principals/GetUser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Principals/GetUser.cs b/Commands/Principals/GetUser.cs index 666c88737..e09f9e494 100644 --- a/Commands/Principals/GetUser.cs +++ b/Commands/Principals/GetUser.cs @@ -18,7 +18,7 @@ namespace SharePointPnP.PowerShell.Commands.Principals Category = CmdletHelpCategory.Principals, DetailedDescription = "This command will return all users that exist in the current site collection's User Information List", OutputType = typeof(User), - OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.user.aspx")] + OutputTypeLink = "https://docs.microsoft.com/previous-versions/office/sharepoint-server/ee540236(v=office.15)")] [CmdletExample( Code = @"PS:> Get-PnPUser", Remarks = "Returns all users from the User Information List of the current site collection regardless if they currently have rights to access the current site", From ccb655c02162ae2388e1b1d4143b83b0cd3f416b Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 23 Jun 2020 10:47:42 +0200 Subject: [PATCH 030/130] Code cleanup and removed output type as we now will have multiple output types based on the arguments passed in --- Commands/Principals/GetUser.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Commands/Principals/GetUser.cs b/Commands/Principals/GetUser.cs index e09f9e494..4d058298c 100644 --- a/Commands/Principals/GetUser.cs +++ b/Commands/Principals/GetUser.cs @@ -10,15 +10,12 @@ using System.Data; using System.Text; - namespace SharePointPnP.PowerShell.Commands.Principals { [Cmdlet(VerbsCommon.Get, "PnPUser")] [CmdletHelp("Returns site users of current web", Category = CmdletHelpCategory.Principals, - DetailedDescription = "This command will return all users that exist in the current site collection's User Information List", - OutputType = typeof(User), - OutputTypeLink = "https://docs.microsoft.com/previous-versions/office/sharepoint-server/ee540236(v=office.15)")] + DetailedDescription = "This command will return all users that exist in the current site collection's User Information List")] [CmdletExample( Code = @"PS:> Get-PnPUser", Remarks = "Returns all users from the User Information List of the current site collection regardless if they currently have rights to access the current site", @@ -45,7 +42,7 @@ namespace SharePointPnP.PowerShell.Commands.Principals SortOrder = 6)] [CmdletExample( Code = @"PS:> Get-PnPUser -WithRightsAssignedDetailed", - Remarks = "Returns all users who have been granted explicit access to the current site, lists and listitems.", + Remarks = "Returns all users who have been granted explicit access to the current site, lists and listitems", SortOrder = 7)] public class GetUser : PnPWebCmdlet { @@ -92,7 +89,6 @@ protected override void ExecuteCmdlet() g => g.LoginName) }; - if (Identity == null) { SelectedWeb.Context.Load(SelectedWeb.SiteUsers, u => u.Include(retrievalExpressions)); @@ -250,7 +246,6 @@ protected override void ExecuteCmdlet() users.AddRange(GetPermissions(listItem.RoleAssignments, listItemUrl)); } } - } itemProgress.RecordType = ProgressRecordType.Completed; WriteProgress(itemProgress); @@ -307,10 +302,7 @@ protected override void ExecuteCmdlet() WriteObject(new { userInformation.Title, userInformation.LoginName, userInformation.Email, Groups, Permissions }, true); } } - - } - else { User user = null; @@ -334,7 +326,6 @@ protected override void ExecuteCmdlet() WriteObject(user); } } - private void WriteProgress(ProgressRecord record, string message, int step, int count) { var percentage = Convert.ToInt32((100 / Convert.ToDouble(count)) * Convert.ToDouble(step)); From 741d958b088077f2e1c04d14229ab36f8b33da63 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 23 Jun 2020 11:28:06 +0200 Subject: [PATCH 031/130] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fce3f535..22746b063 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.21.2005.0] ### Added +- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown ### Changed - Invoke-PnPSearchQuery: Allow SelectProperties to take a comma separated string as well as an array ### Contributors +- Robin Meure [robinmeure] ## [3.20.2004.0] From 98309dd1cb30442bc808c9c32c46429ef2842654 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 23 Jun 2020 11:28:31 +0200 Subject: [PATCH 032/130] Added paramsets to ensure the detailed arguments can't be used in combination with Identity --- Commands/Principals/GetUser.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Commands/Principals/GetUser.cs b/Commands/Principals/GetUser.cs index 4d058298c..bd9e87fde 100644 --- a/Commands/Principals/GetUser.cs +++ b/Commands/Principals/GetUser.cs @@ -12,10 +12,11 @@ namespace SharePointPnP.PowerShell.Commands.Principals { - [Cmdlet(VerbsCommon.Get, "PnPUser")] + [Cmdlet(VerbsCommon.Get, "PnPUser", DefaultParameterSetName = PARAMETERSET_IDENTITY)] [CmdletHelp("Returns site users of current web", Category = CmdletHelpCategory.Principals, - DetailedDescription = "This command will return all users that exist in the current site collection's User Information List")] + DetailedDescription = "This command will return all users that exist in the current site collection's User Information List, optionally identifying their current permissions to this site", + SupportedPlatform = CmdletSupportedPlatform.All)] [CmdletExample( Code = @"PS:> Get-PnPUser", Remarks = "Returns all users from the User Information List of the current site collection regardless if they currently have rights to access the current site", @@ -46,15 +47,22 @@ namespace SharePointPnP.PowerShell.Commands.Principals SortOrder = 7)] public class GetUser : PnPWebCmdlet { - [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0, HelpMessage = "User ID or login name")] + private const string PARAMETERSET_IDENTITY = "Identity based request"; + private const string PARAMETERSET_WITHRIGHTSASSIGNED = "With rights assigned"; + private const string PARAMETERSET_WITHRIGHTSASSIGNEDDETAILED = "With rights assigned detailed"; + + [Parameter(Mandatory = false, ValueFromPipeline = true, ParameterSetName = PARAMETERSET_IDENTITY, HelpMessage = "User ID or login name")] public UserPipeBind Identity; - [Parameter(Mandatory = false, Position = 1, HelpMessage = "If provided, only users that currently have any kinds of access rights assigned to the current site collection will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] + [Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_WITHRIGHTSASSIGNED, HelpMessage = "If provided, only users that currently have any kinds of access rights assigned to the current site collection will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] public SwitchParameter WithRightsAssigned; - [Parameter(Mandatory = false, Position = 2, HelpMessage = "If provided, only users that currently have any specific kind of access rights assigned to the current site, lists or listitems/documents will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] + [Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_WITHRIGHTSASSIGNEDDETAILED, HelpMessage = "If provided, only users that currently have any specific kind of access rights assigned to the current site, lists or listitems/documents will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] public SwitchParameter WithRightsAssignedDetailed; + /// + /// Output type used with parameter WithRightsAssignedDetailed + /// public class DetailedUser { public User User { get; set; } @@ -326,6 +334,7 @@ protected override void ExecuteCmdlet() WriteObject(user); } } + private void WriteProgress(ProgressRecord record, string message, int step, int count) { var percentage = Convert.ToInt32((100 / Convert.ToDouble(count)) * Convert.ToDouble(step)); From fa52440fa41a148ff9ef3cd2f44b16328c573116 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 23 Jun 2020 11:29:15 +0200 Subject: [PATCH 033/130] Added PR reference --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22746b063..4b264ffde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.21.2005.0] ### Added -- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown +- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown [PR #2754](https://github.com/pnp/PnP-PowerShell/pull/2754) ### Changed - Invoke-PnPSearchQuery: Allow SelectProperties to take a comma separated string as well as an array From 3e50e25c732a16abddfa4fa9fe7cb386caf5f73e Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 09:38:15 +0200 Subject: [PATCH 034/130] Fixed that the provided connection will be cleared instead of always the current context --- Commands/Base/DisconnectOnline.cs | 16 +++++++++++----- Commands/Base/PnPConnectionHelper.cs | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/Commands/Base/DisconnectOnline.cs b/Commands/Base/DisconnectOnline.cs index 75e000612..18d0893bf 100644 --- a/Commands/Base/DisconnectOnline.cs +++ b/Commands/Base/DisconnectOnline.cs @@ -9,7 +9,8 @@ namespace SharePointPnP.PowerShell.Commands.Base { [Cmdlet(VerbsCommunications.Disconnect, "PnPOnline")] [CmdletHelp("Disconnects the context", - "Disconnects the current context and requires you to build up a new connection in order to use the Cmdlets again. Using Connect-PnPOnline to connect to a different site has the same effect.", + DetailedDescription = "Disconnects the current context and requires you to build up a new connection in order to use the Cmdlets again. Using Connect-PnPOnline to connect to a different site has the same effect.", + SupportedPlatform = CmdletSupportedPlatform.All, Category = CmdletHelpCategory.Base)] [CmdletExample( Code = @"PS:> Disconnect-PnPOnline", @@ -22,16 +23,21 @@ public class DisconnectOnline : PSCmdlet protected override void ProcessRecord() { + // If no specific connection has been passed in, take the connection from the current context + if(Connection == null) + { + Connection = PnPConnection.CurrentConnection; + } #if !ONPREMISES - if(PnPConnection.CurrentConnection?.Certificate != null) + if(Connection?.Certificate != null) { #if !NETSTANDARD2_1 - PnPConnectionHelper.CleanupCryptoMachineKey(PnPConnection.CurrentConnection.Certificate); + PnPConnectionHelper.CleanupCryptoMachineKey(Connection.Certificate); #endif - PnPConnection.CurrentConnection.Certificate = null; + Connection.Certificate = null; } #endif - var success = false; + var success = false; if (Connection != null) { success = DisconnectProvidedService(Connection); diff --git a/Commands/Base/PnPConnectionHelper.cs b/Commands/Base/PnPConnectionHelper.cs index 729347674..01269629a 100644 --- a/Commands/Base/PnPConnectionHelper.cs +++ b/Commands/Base/PnPConnectionHelper.cs @@ -562,16 +562,28 @@ internal static PnPConnection InitiateAzureAdAppOnlyConnectionWithClientIdClient return spoConnection; } + /// + /// Verifies if a local copy of the certificate has been stored in the machinekeys cache of Windows and if so, will remove it to avoid the cache from growing over time + /// + /// Certificate to validate if there is a local cached copy for and if so, delete it internal static void CleanupCryptoMachineKey(X509Certificate2 certificate) { var privateKey = (RSACryptoServiceProvider)certificate.PrivateKey; string uniqueKeyContainerName = privateKey.CspKeyContainerInfo.UniqueKeyContainerName; certificate.Reset(); - var path = Environment.GetEnvironmentVariable("ProgramData"); - if (string.IsNullOrEmpty(path)) path = @"C:\ProgramData"; + + var programDataPath = Environment.GetEnvironmentVariable("ProgramData"); + if (string.IsNullOrEmpty(programDataPath)) + { + programDataPath = @"C:\ProgramData"; + } try { - System.IO.File.Delete(string.Format(@"{0}\Microsoft\Crypto\RSA\MachineKeys\{1}", path, uniqueKeyContainerName)); + var temporaryCertificateFilePath = $@"{programDataPath}\Microsoft\Crypto\RSA\MachineKeys\{uniqueKeyContainerName}"; + if (System.IO.File.Exists(temporaryCertificateFilePath)) + { + System.IO.File.Delete(temporaryCertificateFilePath); + } } catch (Exception) { From e141c19ee8de626d4491dc05f34faf172fb0b83e Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 09:41:38 +0200 Subject: [PATCH 035/130] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9bc823a3..d63056620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) ### Contributors - Gautam Sheth [gautamdsheth] +- Koen Zomers [koenzomers] ## [3.22.2006.2] From f1343d94e29a00c2d8334e8209a36970391225cc Mon Sep 17 00:00:00 2001 From: Todd Klindt Date: Wed, 24 Jun 2020 14:27:25 -0500 Subject: [PATCH 036/130] Another example Added a second example to Remove-PnPClientSideComponent. --- Commands/ClientSidePages/RemoveClientSideComponent.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Commands/ClientSidePages/RemoveClientSideComponent.cs b/Commands/ClientSidePages/RemoveClientSideComponent.cs index 583b4964c..89b556924 100644 --- a/Commands/ClientSidePages/RemoveClientSideComponent.cs +++ b/Commands/ClientSidePages/RemoveClientSideComponent.cs @@ -14,6 +14,10 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages [CmdletExample( Code = @"PS:> Remove-PnPClientSideComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", Remarks = @"Removes the control specified from the page.", SortOrder = 1)] + [CmdletExample( + Code = @"PS:> $webpart = Get-PnPClientSideComponent -Page "Home" | Where-Object { $_.Title -eq 'Site activity' }", + Code = @"PS:> Remove-PnPClientSideComponent -Page "Home" -InstanceId $webpart.InstanceId -Force", + Remarks = @"Finds a web part with the Title 'Site activity' on the Home.aspx page, then removes it from the page", SortOrder = 2)] public class RemoveClientSideComponent : PnPWebCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, HelpMessage = "The name of the page")] @@ -48,4 +52,4 @@ protected override void ExecuteCmdlet() } } } -#endif \ No newline at end of file +#endif From ce49715a7d4df390cee0e68255ee2fe48257c9da Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 21:46:24 +0200 Subject: [PATCH 037/130] Modified sample so it compiles, uses a shorter syntax and displays correctly --- Commands/ClientSidePages/RemoveClientSideComponent.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Commands/ClientSidePages/RemoveClientSideComponent.cs b/Commands/ClientSidePages/RemoveClientSideComponent.cs index 89b556924..d007e270c 100644 --- a/Commands/ClientSidePages/RemoveClientSideComponent.cs +++ b/Commands/ClientSidePages/RemoveClientSideComponent.cs @@ -15,9 +15,9 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages Code = @"PS:> Remove-PnPClientSideComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", Remarks = @"Removes the control specified from the page.", SortOrder = 1)] [CmdletExample( - Code = @"PS:> $webpart = Get-PnPClientSideComponent -Page "Home" | Where-Object { $_.Title -eq 'Site activity' }", - Code = @"PS:> Remove-PnPClientSideComponent -Page "Home" -InstanceId $webpart.InstanceId -Force", - Remarks = @"Finds a web part with the Title 'Site activity' on the Home.aspx page, then removes it from the page", SortOrder = 2)] + Code = @"PS:> $webpart = Get-PnPClientSideComponent -Page ""Home"" | ? Title -eq ""Site activity"" +PS:> Remove-PnPClientSideComponent -Page ""Home"" -InstanceId $webpart.InstanceId -Force", + Remarks = @"Finds a web part with the Title ""Site activity"" on the Home.aspx page, then removes it from the page", SortOrder = 2)] public class RemoveClientSideComponent : PnPWebCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, HelpMessage = "The name of the page")] From e80970958102016bf2f5bddcc83e9e229625619d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 21:47:03 +0200 Subject: [PATCH 038/130] Added credits to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d63056620..f0432c096 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Contributors - Gautam Sheth [gautamdsheth] - Koen Zomers [koenzomers] +- Todd Klindt [ToddKlindt] ## [3.22.2006.2] From 070ccea6b3d31e489dc34cf8322b88d45149a047 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 22:18:32 +0200 Subject: [PATCH 039/130] Added changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d63056620..4d6a0d220 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) +- Fixed an [issue in the underlying MSAL library](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/pull/1891) which caused many of the `Connect-PnPOnline` options not to work in Azure Runbooks anymore [PR #2735](https://github.com/pnp/PnP-PowerShell/pull/2735) ### Contributors - Gautam Sheth [gautamdsheth] From 960cef34c158e133ead5c8c02004c385a805dc18 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 22:27:58 +0200 Subject: [PATCH 040/130] Reverted Where-Object syntax --- Commands/ClientSidePages/RemoveClientSideComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/ClientSidePages/RemoveClientSideComponent.cs b/Commands/ClientSidePages/RemoveClientSideComponent.cs index d007e270c..c1b79004e 100644 --- a/Commands/ClientSidePages/RemoveClientSideComponent.cs +++ b/Commands/ClientSidePages/RemoveClientSideComponent.cs @@ -15,7 +15,7 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages Code = @"PS:> Remove-PnPClientSideComponent -Page Home -InstanceId a2875399-d6ff-43a0-96da-be6ae5875f82", Remarks = @"Removes the control specified from the page.", SortOrder = 1)] [CmdletExample( - Code = @"PS:> $webpart = Get-PnPClientSideComponent -Page ""Home"" | ? Title -eq ""Site activity"" + Code = @"PS:> $webpart = Get-PnPClientSideComponent -Page ""Home"" | Where-Object { $_.Title -eq ""Site activity"" } PS:> Remove-PnPClientSideComponent -Page ""Home"" -InstanceId $webpart.InstanceId -Force", Remarks = @"Finds a web part with the Title ""Site activity"" on the Home.aspx page, then removes it from the page", SortOrder = 2)] public class RemoveClientSideComponent : PnPWebCmdlet From 857540e6b3e7c9624838fdf50a2468a613b640a2 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 22:47:50 +0200 Subject: [PATCH 041/130] Changed documentation link to CmdletRelatedLink --- Commands/Admin/AddSiteCollectionAppCatalog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Admin/AddSiteCollectionAppCatalog.cs b/Commands/Admin/AddSiteCollectionAppCatalog.cs index 6764de139..230104d22 100644 --- a/Commands/Admin/AddSiteCollectionAppCatalog.cs +++ b/Commands/Admin/AddSiteCollectionAppCatalog.cs @@ -11,11 +11,11 @@ namespace SharePointPnP.PowerShell.Commands.Admin [Cmdlet(VerbsCommon.Add, "PnPSiteCollectionAppCatalog")] [CmdletHelp("Adds a Site Collection scoped App Catalog to a site", SupportedPlatform = CmdletSupportedPlatform.Online, - OutputTypeLink = "https://docs.microsoft.com/sharepoint/dev/general-development/site-collection-app-catalog#configure-and-manage-site-collection-app-catalogs", Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( Code = @"PS:> Add-PnPSiteCollectionAppCatalog -Site ""https://contoso.sharepoint.com/sites/FinanceTeamsite""", Remarks = @"This will add a SiteCollection app catalog to the specified site", SortOrder = 1)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/sharepoint/dev/general-development/site-collection-app-catalog#configure-and-manage-site-collection-app-catalogs")] public class AddSiteCollectionAppCatalog : PnPAdminCmdlet { [Parameter(Mandatory = true, HelpMessage = @"Url of the site to add the app catalog to.")] From ba8b07028b5c5e87e4f70ce961116065b7c09296 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 23:34:59 +0200 Subject: [PATCH 042/130] Change to only remove the certificate from the MachineKeys on Disconnect-PnPOnline if the -CertificatePath has been used to connect --- Commands/Base/DisconnectOnline.cs | 5 ++++- Commands/Base/PnPConnection.cs | 5 +++++ Commands/Base/PnPConnectionHelper.cs | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Commands/Base/DisconnectOnline.cs b/Commands/Base/DisconnectOnline.cs index 18d0893bf..8ae6c5a68 100644 --- a/Commands/Base/DisconnectOnline.cs +++ b/Commands/Base/DisconnectOnline.cs @@ -32,7 +32,10 @@ protected override void ProcessRecord() if(Connection?.Certificate != null) { #if !NETSTANDARD2_1 - PnPConnectionHelper.CleanupCryptoMachineKey(Connection.Certificate); + if (Connection != null && Connection.DeleteCertificateFromCacheOnDisconnect) + { + PnPConnectionHelper.CleanupCryptoMachineKey(Connection.Certificate); + } #endif Connection.Certificate = null; } diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index 37f8a8dc9..239d796a0 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -80,6 +80,11 @@ public class PnPConnection /// public X509Certificate2 Certificate { get; internal set; } + /// + /// Boolean indicating if when using Disconnect-PnPOnline to destruct this PnPConnection instance, if the certificate file should be deleted from C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys + /// + public bool DeleteCertificateFromCacheOnDisconnect { get; internal set; } + public ClientContext Context { get; set; } /// /// Audience to try to get a token for - /// The specific roles to request access to (i.e. Group.ReadWrite.All). Optional, will use default groups assigned to clientId if not specified. + /// The specific roles to request access to (i.e. Group.ReadWrite.All). Optional, will use default groups assigned to clientId if not specified. /// for the audience or NULL if unable to retrieve a token for the audience on the current connection - internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] roles = null) + internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles = null, string[] andRoles = null) { GenericToken token = null; @@ -148,16 +148,43 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] roles = if (token.ExpiresOn > DateTime.Now) { - // Token is still valid, ensure we dont have specific roles to check for or the requested roles to execute the command are present in the token - if (roles == null || roles.Length == 0 || roles.Any(r => token.Roles.Contains(r))) + var andRolesMatched = false; + if (andRoles != null && andRoles.Length != 0) { - return token; + // we have explicitely required roles + andRolesMatched = andRoles.All(r => token.Roles.Contains(r)); + } else + { + andRolesMatched = true; + } + + var orRolesMatched = false; + if (orRoles != null && orRoles.Length != 0) + { + orRolesMatched = orRoles.Any(r => token.Roles.Contains(r)); + } else + { + orRolesMatched = true; } - if (roles != null) + if (orRolesMatched && andRolesMatched) + { + return token; + } + + if (orRoles != null || andRoles != null) { + var message = string.Empty; // Requested role was not part of the access token, throw an exception explaining which application registration is missing which role - throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {(roles.Length != 1 ? "any of " : string.Empty)}the permission{(roles.Length != 1 ? "s" : string.Empty)} {string.Join(", ", roles).TrimEnd(new[] { ',', ' ' })}"); + if(!orRolesMatched) + { + message += "for one of the following roles: " + string.Join(", ", orRoles); + } + if(!andRolesMatched) + { + message += (message != string.Empty ? ", and " : ", ") + "for all of the following roles: " + string.Join(", ", andRoles); + } + throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {message}"); } } @@ -582,7 +609,7 @@ internal ClientContext CloneContext(string url) else { #endif - throw; + throw; #if !ONPREMISES && !NETSTANDARD2_1 } #endif diff --git a/Commands/Base/PnPGraphCmdlet.cs b/Commands/Base/PnPGraphCmdlet.cs index 067110809..2f8e42706 100644 --- a/Commands/Base/PnPGraphCmdlet.cs +++ b/Commands/Base/PnPGraphCmdlet.cs @@ -26,14 +26,22 @@ public GraphToken Token { // Collect the permission attributes to discover required roles var requiredRoleAttributes = (CmdletMicrosoftGraphApiPermission[])Attribute.GetCustomAttributes(GetType(), typeof(CmdletMicrosoftGraphApiPermission)); - var requiredRoles = new List(requiredRoleAttributes.Length); + var orRequiredRoles = new List(requiredRoleAttributes.Length); + var andRequiredRoles = new List(requiredRoleAttributes.Length); foreach (var requiredRoleAttribute in requiredRoleAttributes) { foreach (MicrosoftGraphApiPermission role in Enum.GetValues(typeof(MicrosoftGraphApiPermission))) { - if(requiredRoleAttribute.ApiPermission.HasFlag(role)) + if (role != MicrosoftGraphApiPermission.None) { - requiredRoles.Add(role.ToString().Replace("_", ".")); + if (requiredRoleAttribute.OrApiPermissions.HasFlag(role)) + { + orRequiredRoles.Add(role.ToString().Replace("_", ".")); + } + if (requiredRoleAttribute.AndApiPermissions.HasFlag(role)) + { + andRequiredRoles.Add(role.ToString().Replace("_", ".")); + } } } } @@ -42,7 +50,7 @@ public GraphToken Token if (PnPConnection.CurrentConnection != null) { // There is an active connection, try to get a Microsoft Graph Token on the active connection - if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.MicrosoftGraph, ByPassPermissionCheck.ToBool() ? null : requiredRoles.ToArray()) is GraphToken token) + if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.MicrosoftGraph, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray()) is GraphToken token) { // Microsoft Graph Access Token available, return it return token; diff --git a/Commands/Model/AzureApp.cs b/Commands/Model/AzureApp.cs index 1b4826d58..9a3ca7f7c 100644 --- a/Commands/Model/AzureApp.cs +++ b/Commands/Model/AzureApp.cs @@ -115,6 +115,24 @@ public PermissionScopes() Id = "741f803b-c850-494e-b5df-cde7c675a1ca", Identifier = "MSGraph.User.ReadWrite.All" }); + scopes.Add(new PermissionScope() + { + resourceAppId = "00000003-0000-0000-c000-000000000000", + Id = "88e58d74-d3df-44f3-ad47-e89edf4472e4", + Identifier = "MSGraph.AppCatalog.Read.All" + }); + scopes.Add(new PermissionScope() + { + resourceAppId = "00000003-0000-0000-c000-000000000000", + Id = "1ca167d5-1655-44a1-8adf-1414072e1ef9", + Identifier = "MSGraph.AppCatalog.ReadWrite.All" + }); + scopes.Add(new PermissionScope() + { + resourceAppId = "00000003-0000-0000-c000-000000000000", + Id = "3db89e36-7fa6-4012-b281-85f3d9d9fd2e", + Identifier = "MSGraph.AppCatalog.Submit" + }); #endregion #region SPO // SPO diff --git a/Commands/Model/Teams/TeamApp.cs b/Commands/Model/Teams/TeamApp.cs new file mode 100644 index 000000000..447158ec8 --- /dev/null +++ b/Commands/Model/Teams/TeamApp.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamApp + { + public string DisplayName { get; set; } + public string DistributionMethod { get; set; } + public string ExternalId { get; set; } + public string Id { get; set; } + } +} diff --git a/Commands/Model/Teams/TeamTab.cs b/Commands/Model/Teams/TeamTab.cs index 247cd1a18..29a1032bf 100644 --- a/Commands/Model/Teams/TeamTab.cs +++ b/Commands/Model/Teams/TeamTab.cs @@ -33,7 +33,7 @@ public partial class TeamTab /// /// Declares the ID for the Tab /// - public string ID { get; set; } + public string Id { get; set; } #endregion } diff --git a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml index 49ef10b99..5cd5098ac 100644 --- a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml +++ b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml @@ -1817,5 +1817,113 @@ + + Team + + SharePointPnP.PowerShell.Commands.Model.Teams.Team + + + + + + + + + + + + + + + + + + + + + + + + GroupId + + + DisplayName + + + Visibility + + + IsArchived + + + MailNickname + + + + + + + + TeamChannel + + SharePointPnP.PowerShell.Commands.Model.Teams.TeamChannel + + + + + + + + + + + + + + + + + + ID + + + DisplayName + + + Description + + + + + + + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.TeamTab + + + + + + + + + + + + + + + ID + + + DisplayName + + + + + + \ No newline at end of file diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 96bdf150d..401d0ad55 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -913,6 +913,7 @@ + diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs new file mode 100644 index 000000000..26038e108 --- /dev/null +++ b/Commands/Teams/GetTeamsApp.cs @@ -0,0 +1,43 @@ +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Get, "PnPTeamsApp")] + [CmdletHelp("Gets one Microsoft Teams Team or a list of Teams.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam", + Remarks = "Retrieves all the Microsoft Teams instances", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", + Remarks = "Retrieves a specific Microsoft Teams instance", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam -Visibility Public", + Remarks = "Retrieves all Microsoft Teams instances which are public visible", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + //[CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.AppCatalog_ReadWrite_All)] + public class GetTeamsApp: PnPGraphCmdlet + { + //private const string ParameterSet_GroupId = "Retrieve a specific Team"; + + //[Parameter(Mandatory = false, HelpMessage = "Specify the group id of the team to retrieve.")] + //public GuidPipeBind GroupId; + + //[Parameter(Mandatory = false, HelpMessage = "Specify the visibility of the teams to retrieve.")] + //public GroupVisibility Visibility; + + protected override void ExecuteCmdlet() + { + WriteObject(TeamsUtility.GetApps(AccessToken, HttpClient), true); + } + } +} diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs index 58272d841..89580b4bf 100644 --- a/Commands/Teams/GetTeamsChannel.cs +++ b/Commands/Teams/GetTeamsChannel.cs @@ -21,21 +21,13 @@ namespace SharePointPnP.PowerShell.Commands.Teams Remarks = "Retrieves all channels for the specified team", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", - Remarks = "Retrieves a specific Office 365 Group based on its ID", + Code = "PS:> Get-PnPTeamsChannel -GroupId a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"Test Channel\"", + Remarks = "Retrieves the channel called 'Test Channel'", SortOrder = 2)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", - Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", + Code = "PS:> Get-PnPTeamsChannel -GroupId a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", + Remarks = "Retrieves the channel specified by its channel id", SortOrder = 3)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", - Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", - SortOrder = 4)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $group", - Remarks = "Retrieves a specific Office 365 Group based on its object instance", - SortOrder = 5)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsChannel : PnPGraphCmdlet @@ -43,9 +35,20 @@ public class GetTeamsChannel : PnPGraphCmdlet [Parameter(Mandatory = true)] public GuidPipeBind GroupId; + [Parameter(Mandatory = false)] + public string Identity; + protected override void ExecuteCmdlet() { - WriteObject(TeamsUtility.GetChannels(AccessToken, HttpClient, GroupId.Id.ToString())); + if (ParameterSpecified(nameof(Identity))) + { + var channels = TeamsUtility.GetChannels(AccessToken, HttpClient, GroupId.Id.ToString()); + WriteObject(channels.FirstOrDefault(c => c.DisplayName.Equals(Identity, StringComparison.OrdinalIgnoreCase) || c.Id.Equals(Identity, StringComparison.OrdinalIgnoreCase))); + } + else + { + WriteObject(TeamsUtility.GetChannels(AccessToken, HttpClient, GroupId.Id.ToString())); + } } } } diff --git a/Commands/Teams/GetTeamsTab.cs b/Commands/Teams/GetTeamsTab.cs new file mode 100644 index 000000000..84f334f8c --- /dev/null +++ b/Commands/Teams/GetTeamsTab.cs @@ -0,0 +1,63 @@ +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Linq; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Get, "PnPTeamsTab")] + [CmdletHelp("Gets one or all tabs in a channel.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", + Remarks = "Retrieves the tabs for the Microsoft Teams instances", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity \"Wiki\"", + Remarks = "Retrieves a tab with the display name 'Wiki' from the specified team and channel", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class GetTeamsTab : PnPGraphCmdlet + { + + [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] + public GuidPipeBind GroupId; + + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.")] + public string ChannelId; + + [Parameter(Mandatory = false, HelpMessage = "Identity")] + public TeamTabPipeBind Identity; + + protected override void ExecuteCmdlet() + { + if (ParameterSpecified(nameof(Identity))) + { + var tabs = TeamsUtility.GetTabs(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId); + if (tabs != null) + { + TeamTab tab = null; + if (Identity.Id != Guid.Empty) + { + tab = tabs.FirstOrDefault(t => t.Id == Identity.Id.ToString()); + } + else + { + tab = tabs.FirstOrDefault(t => t.DisplayName.Equals(Identity.DisplayName, System.StringComparison.OrdinalIgnoreCase)); + } + WriteObject(tab); + } + } + else + { + WriteObject(TeamsUtility.GetTabs(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId)); + } + } + } +} diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs index 398a487cd..261ad0262 100644 --- a/Commands/Teams/GetTeamsTeam.cs +++ b/Commands/Teams/GetTeamsTeam.cs @@ -1,14 +1,8 @@ -using Microsoft.Azure.ActiveDirectory.GraphClient; -using OfficeDevPnP.Core.Entities; -using OfficeDevPnP.Core.Framework.Graph; -using OfficeDevPnP.Core.Utilities; -using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; -using System.Collections.Generic; -using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs new file mode 100644 index 000000000..222e82927 --- /dev/null +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -0,0 +1,48 @@ +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPTeamsTab")] + [CmdletHelp("Gets one or all tabs in a channel.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", + Remarks = "Retrieves the tabs for the Microsoft Teams instances", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -DisplayName \"Wiki\"", + Remarks = "Retrieves a tab with the display name 'Wiki' from the specified team and channel", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class RemoveTeamsTab : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] + public GuidPipeBind GroupId; + + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.")] + public string ChannelId; + + [Parameter(Mandatory = true, HelpMessage = "DisplayName")] + public string TabId; + + [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] + public SwitchParameter Force; + + protected override void ExecuteCmdlet() + { + if (Force || ShouldContinue("Removing the tab will remove the settings of this tab too.", Properties.Resources.Confirm)) + { + if (!TeamsUtility.DeleteTab(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId, TabId)) + { + WriteError(new ErrorRecord(new Exception($"Tab remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + } + } + } + } +} diff --git a/Commands/Teams/RemoveTeamsTeam.cs b/Commands/Teams/RemoveTeamsTeam.cs new file mode 100644 index 000000000..f2ca5377d --- /dev/null +++ b/Commands/Teams/RemoveTeamsTeam.cs @@ -0,0 +1,38 @@ +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPTeamsTeam")] + [CmdletHelp("Removes a Microsoft Teams Team instance", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Remove-PnPTeamsTeam -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5", + Remarks = "Removes the specified Team", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class RemoveTeamsTeam : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] + public GuidPipeBind GroupId; + + [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] + public SwitchParameter Force; + + protected override void ExecuteCmdlet() + { + if (Force || ShouldContinue("Removing the team will remove all messages in all channels in the team.", Properties.Resources.Confirm)) + { + if (!TeamsUtility.DeleteTeam(AccessToken, HttpClient, GroupId.Id.ToString())) + { + WriteError(new ErrorRecord(new Exception($"Team remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + } + } + } + } +} diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index a30fb2da1..f8c65207a 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -18,10 +18,10 @@ private static List GetGroupsWithTeam(HttpClient httpClient, string acces List groups = new List(); string url = string.Empty; var collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')&$select=Id,DisplayName,MailNickName,Description,Visibility&$top={PageSize}", accessToken).GetAwaiter().GetResult(); ; - if(collection != null) + if (collection != null) { groups.AddRange(collection.Items); - while(!string.IsNullOrEmpty(collection.NextLink)) + while (!string.IsNullOrEmpty(collection.NextLink)) { collection = GraphHelper.GetAsync>(httpClient, collection.NextLink, accessToken).GetAwaiter().GetResult(); groups.AddRange(collection.Items); @@ -69,12 +69,18 @@ public static Team GetTeam(string accessToken, HttpClient httpClient, string gro team.MailNickname = group.MailNickname; team.Visibility = group.Visibility; return team; - } else + } + else { return null; } } + public static bool DeleteTeam(string accessToken, HttpClient httpClient, string groupId) + { + return GraphHelper.DeleteAsync(httpClient, $"v1.0/groups/{groupId}", accessToken).GetAwaiter().GetResult(); + } + private static Team ParseTeamJson(string accessToken, HttpClient httpClient, string groupId) { // Get Settings @@ -85,11 +91,12 @@ private static Team ParseTeamJson(string accessToken, HttpClient httpClient, str { team.GroupId = groupId; return team; - } else + } + else { - return null; + return null; } - + //team = GetTeamChannels(configuration, accessToken, groupId, team, scope); //team = GetTeamApps(accessToken, groupId, team, scope); //team = GetTeamSecurity(accessToken, groupId, team, scope); @@ -118,13 +125,14 @@ private static Team ParseTeamJson(string accessToken, HttpClient httpClient, str // untested change if (ex.Message.StartsWith("404")) { - // no team, swallow + // no team, swallow } else { throw ex; } #endif + return null; } } #endregion @@ -133,10 +141,11 @@ private static Team ParseTeamJson(string accessToken, HttpClient httpClient, str public static IEnumerable GetChannels(string accessToken, HttpClient httpClient, string groupId) { var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/teams/{groupId}/channels", accessToken).GetAwaiter().GetResult(); - if(collection != null) + if (collection != null) { return collection.Items; - } else + } + else { return null; } @@ -150,7 +159,8 @@ public static bool DeleteChannel(string accessToken, HttpClient httpClient, stri if (channel != null) { return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channel.Id}", accessToken).GetAwaiter().GetResult(); - } else + } + else { return false; } @@ -166,5 +176,35 @@ public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels", channel, accessToken).GetAwaiter().GetResult(); } #endregion + + #region Tabs + public static IEnumerable GetTabs(string accessToken, HttpClient httpClient, string groupId, string channelId) + { + var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs", accessToken).GetAwaiter().GetResult(); + if (collection != null) + { + return collection.Items; + } + return null; + } + + public static bool DeleteTab(string accessToken, HttpClient httpClient, string groupId, string channelId, string tabId) + { + return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); + } + + #endregion + + #region Apps + public static IEnumerable GetApps(string accessToken, HttpClient httpClient) + { + var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/appCatalogs/teamsApps", accessToken).GetAwaiter().GetResult(); + if(collection != null) + { + return collection.Items; + } + return null; + } + #endregion } -} +} \ No newline at end of file diff --git a/HelpAttributes/CmdletMicrosoftGraphApiPermission.cs b/HelpAttributes/CmdletMicrosoftGraphApiPermission.cs index 52bdbb33b..304c7911c 100644 --- a/HelpAttributes/CmdletMicrosoftGraphApiPermission.cs +++ b/HelpAttributes/CmdletMicrosoftGraphApiPermission.cs @@ -9,6 +9,8 @@ namespace SharePointPnP.PowerShell.CmdletHelpAttributes [Flags] public enum MicrosoftGraphApiPermission : int { + None = 0, + #region Groups - https://docs.microsoft.com/graph/permissions-reference#group-permissions /// @@ -89,7 +91,18 @@ public enum MicrosoftGraphApiPermission : int /// Manage all user identities /// [EnumMember(Value = "User.ManageIdentities.All")] - User_ManageIdentities_All = 2048 + User_ManageIdentities_All = 2048, + + + #endregion + + #region AppCatalog - https://docs.microsoft.com/en-gb/graph/permissions-reference#appcatalog-resource-permissions + + [EnumMember(Value = "AppCatalog.Read.All")] + AppCatalog_Read_All = 4096, + + [EnumMember(Value = "AppCatalog.ReadWrite.All")] + AppCatalog_ReadWrite_All = 8192, #endregion } @@ -108,15 +121,18 @@ public sealed class CmdletMicrosoftGraphApiPermission : CmdletApiPermissionBase /// /// One or more permissions of which only one is needed to granted to the token /// - public MicrosoftGraphApiPermission ApiPermission { get; set; } + public MicrosoftGraphApiPermission OrApiPermissions { get; set; } + + public MicrosoftGraphApiPermission AndApiPermissions { get; set; } /// /// Constructs a new ApiPermissionAttribute /// /// One or more possible permissions of which only one is needed to be granted in the token - public CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission apiPermission) + public CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission orPermissions, MicrosoftGraphApiPermission andPermissions = MicrosoftGraphApiPermission.None) { - ApiPermission = apiPermission; + OrApiPermissions = orPermissions; + AndApiPermissions = andPermissions; } } } From d5bef8c457dd79f379645604a2e9cdedb683d255 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 29 Jun 2020 17:36:14 +0200 Subject: [PATCH 080/130] Updated --- Commands/Base/ConnectOnline.cs | 12 ------ Commands/Base/PipeBinds/TeamsAppPipeBind.cs | 36 +++++++++++++++++ ...TeamTabPipeBind.cs => TeamsTabPipeBind.cs} | 6 +-- .../PnP.PowerShell.Core.Format.ps1xml | 40 +++++++++++++++++++ Commands/Teams/GetTeamsApp.cs | 39 +++++++++++------- Commands/Teams/GetTeamsTab.cs | 2 +- 6 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 Commands/Base/PipeBinds/TeamsAppPipeBind.cs rename Commands/Base/PipeBinds/{TeamTabPipeBind.cs => TeamsTabPipeBind.cs} (85%) diff --git a/Commands/Base/ConnectOnline.cs b/Commands/Base/ConnectOnline.cs index 522db8081..38d0ee5f8 100644 --- a/Commands/Base/ConnectOnline.cs +++ b/Commands/Base/ConnectOnline.cs @@ -100,7 +100,6 @@ namespace SharePointPnP.PowerShell.Commands.Base SortOrder = 14)] #endif #if !ONPREMISES -#if !NETSTANDARD2_1 [CmdletExample( Code = "PS:> Connect-PnPOnline -Scopes \"Mail.Read\",\"Files.Read\",\"ActivityFeed.Read\"", Remarks = "Connects to Azure Active Directory interactively and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP.PowerShell with application id bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71 registered by the PnP PowerShell team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. It will ask you to authenticate for each of the APIs you have listed scopes for.", @@ -110,7 +109,6 @@ namespace SharePointPnP.PowerShell.Commands.Base Remarks = "Connects to Azure Active Directory using delegated permissions and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP.PowerShell with application id bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71 registered by the PnP PowerShell team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. You must have logged on interactively with the same scopes at least once without using -Credentials to allow for the permission grant dialog to show and allow constent for the user account you would like to use.", SortOrder = 16)] #endif -#endif #if !ONPREMISES [CmdletExample( Code = "PS:> Connect-PnPOnline -ClientId '' -ClientSecret '' -AADDomain 'contoso.onmicrosoft.com'", @@ -177,9 +175,7 @@ public class ConnectOnline : BasePSCmdlet private const string ParameterSet_SPOMANAGEMENT = "SPO Management Shell Credentials"; private const string ParameterSet_DEVICELOGIN = "PnP O365 Management Shell / DeviceLogin"; private const string ParameterSet_GRAPHDEVICELOGIN = "PnP Office 365 Management Shell to the Microsoft Graph"; -#if !NETSTANDARD2_1 private const string ParameterSet_AADWITHSCOPE = "Azure Active Directory using Scopes"; -#endif private const string ParameterSet_GRAPHWITHAAD = "Microsoft Graph using Azure Active Directory"; private const string SPOManagementClientId = "9bc3ab49-b65d-410a-85ad-de819febfddc"; private const string SPOManagementRedirectUri = "https://oauth.spops.microsoft.com/"; @@ -523,10 +519,8 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_APPONLYCLIENTIDCLIENTSECRETURL, HelpMessage = "The Azure environment to use for authentication, the defaults to 'Production' which is the main Azure environment.")] public AzureEnvironment AzureEnvironment = AzureEnvironment.Production; -#if !NETSTANDARD2_1 [Parameter(Mandatory = true, ParameterSetName = ParameterSet_AADWITHSCOPE, HelpMessage = "The array of permission scopes to request from Azure Active Directory")] public string[] Scopes; -#endif [Parameter(Mandatory = true, ParameterSetName = ParameterSet_GRAPHWITHAAD, HelpMessage = "The AAD where the O365 app is registered. Eg.: contoso.com, or contoso.onmicrosoft.com.")] [Parameter(Mandatory = true, ParameterSetName = ParameterSet_APPONLYCLIENTIDCLIENTSECRETAADDOMAIN, HelpMessage = "The AAD where the O365 app is registered. Eg.: contoso.com, or contoso.onmicrosoft.com.")] @@ -701,11 +695,9 @@ protected void Connect() connection = ConnectAppOnlyAadCer(); break; -#if !NETSTANDARD2_1 case ParameterSet_AADWITHSCOPE: connection = ConnectAadWithScope(credentials); break; -#endif case ParameterSet_ACCESSTOKEN: connection = ConnectAccessToken(); break; @@ -1094,7 +1086,6 @@ private PnPConnection ConnectAppOnlyAadCer() private PnPConnection ConnectAadWithScope(PSCredential credentials) { #if !ONPREMISES -#if !NETSTANDARD2_1 // Filter out the scopes for the Microsoft Office 365 Management API var officeManagementApiScopes = Enum.GetNames(typeof(OfficeManagementApiPermission)).Select(s => s.Replace("_", ".")).Intersect(Scopes).ToArray(); @@ -1126,9 +1117,6 @@ private PnPConnection ConnectAadWithScope(PSCredential credentials) } } return connection; -#else - throw new NotImplementedException(); -#endif #else return null; #endif diff --git a/Commands/Base/PipeBinds/TeamsAppPipeBind.cs b/Commands/Base/PipeBinds/TeamsAppPipeBind.cs new file mode 100644 index 000000000..c8a0d849c --- /dev/null +++ b/Commands/Base/PipeBinds/TeamsAppPipeBind.cs @@ -0,0 +1,36 @@ +using System; + +namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds +{ + public sealed class TeamsAppPipeBind + { + private readonly Guid _id; + private readonly string _stringValue; + + public TeamsAppPipeBind() + + { + _id = Guid.Empty; + } + + public TeamsAppPipeBind(string input) + { + if (string.IsNullOrEmpty(input)) + { + throw new ArgumentException(nameof(input)); + } + if (Guid.TryParse(input, out Guid tabId)) + { + _id = tabId; + } + else + { + _stringValue = input; + } + } + + public Guid Id => _id; + + public string StringValue => _stringValue; + } +} diff --git a/Commands/Base/PipeBinds/TeamTabPipeBind.cs b/Commands/Base/PipeBinds/TeamsTabPipeBind.cs similarity index 85% rename from Commands/Base/PipeBinds/TeamTabPipeBind.cs rename to Commands/Base/PipeBinds/TeamsTabPipeBind.cs index 5873317e7..3009749eb 100644 --- a/Commands/Base/PipeBinds/TeamTabPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsTabPipeBind.cs @@ -3,17 +3,17 @@ namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds { - public sealed class TeamTabPipeBind + public sealed class TeamsTabPipeBind { private readonly Guid _id; private readonly string _displayName; - public TeamTabPipeBind() + public TeamsTabPipeBind() { _id = Guid.Empty; } - public TeamTabPipeBind(string input) + public TeamsTabPipeBind(string input) { if (string.IsNullOrEmpty(input)) { diff --git a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml index 5cd5098ac..c9776ee87 100644 --- a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml +++ b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml @@ -1925,5 +1925,45 @@ + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.TeamApp + + + + + + + + + + + + + + + + + + + + + ID + + + DisplayName + + + DistributionMethod + + + ExternalId + + + + + + \ No newline at end of file diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs index 26038e108..6a11d054f 100644 --- a/Commands/Teams/GetTeamsApp.cs +++ b/Commands/Teams/GetTeamsApp.cs @@ -3,17 +3,19 @@ using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Get, "PnPTeamsApp")] - [CmdletHelp("Gets one Microsoft Teams Team or a list of Teams.", + [CmdletHelp("Gets one Microsoft Teams App or a list of all apps.", Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTeam", - Remarks = "Retrieves all the Microsoft Teams instances", + Code = "PS:> Get-PnPTeamsApp", + Remarks = "Retrieves all the Microsoft Teams Apps", SortOrder = 1)] [CmdletExample( Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", @@ -23,21 +25,30 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPTeamsTeam -Visibility Public", Remarks = "Retrieves all Microsoft Teams instances which are public visible", SortOrder = 2)] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] - //[CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.AppCatalog_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.AppCatalog_Read_All)] public class GetTeamsApp: PnPGraphCmdlet { - //private const string ParameterSet_GroupId = "Retrieve a specific Team"; - - //[Parameter(Mandatory = false, HelpMessage = "Specify the group id of the team to retrieve.")] - //public GuidPipeBind GroupId; - - //[Parameter(Mandatory = false, HelpMessage = "Specify the visibility of the teams to retrieve.")] - //public GroupVisibility Visibility; - + [Parameter(Mandatory = false, HelpMessage = "Specify the name, id or external id of the app.")] + public TeamsAppPipeBind Identity; + protected override void ExecuteCmdlet() { - WriteObject(TeamsUtility.GetApps(AccessToken, HttpClient), true); + if (ParameterSpecified(nameof(Identity))) + { + var apps = TeamsUtility.GetApps(AccessToken, HttpClient); + if (Identity.Id != Guid.Empty) + { + WriteObject(apps.FirstOrDefault(a => a.Id == Identity.Id.ToString() || a.ExternalId == a.Id.ToString())); + } + else + { + WriteObject(apps.FirstOrDefault(a => a.DisplayName.Equals(Identity.StringValue, StringComparison.OrdinalIgnoreCase))); + } + } + else + { + WriteObject(TeamsUtility.GetApps(AccessToken, HttpClient), true); + } } } } diff --git a/Commands/Teams/GetTeamsTab.cs b/Commands/Teams/GetTeamsTab.cs index 84f334f8c..ad8370276 100644 --- a/Commands/Teams/GetTeamsTab.cs +++ b/Commands/Teams/GetTeamsTab.cs @@ -33,7 +33,7 @@ public class GetTeamsTab : PnPGraphCmdlet public string ChannelId; [Parameter(Mandatory = false, HelpMessage = "Identity")] - public TeamTabPipeBind Identity; + public TeamsTabPipeBind Identity; protected override void ExecuteCmdlet() { From 858059e043c553339d476a853c9eedd75613df09 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 29 Jun 2020 18:06:23 +0200 Subject: [PATCH 081/130] Updated cmdlet API checking --- Commands/Base/PnPOfficeManagementApiCmdlet.cs | 23 +++- Commands/Teams/GetTeamsApp.cs | 10 +- .../CmdletOfficeManagementApiPermission.cs | 10 +- ModuleFilesGenerator/HelpFileGenerator.cs | 108 +++++++++++++----- 4 files changed, 110 insertions(+), 41 deletions(-) diff --git a/Commands/Base/PnPOfficeManagementApiCmdlet.cs b/Commands/Base/PnPOfficeManagementApiCmdlet.cs index 2030a655c..b9890496d 100644 --- a/Commands/Base/PnPOfficeManagementApiCmdlet.cs +++ b/Commands/Base/PnPOfficeManagementApiCmdlet.cs @@ -25,17 +25,32 @@ public OfficeManagementApiToken Token { // Collect the permission attributes to discover required roles var requiredRoleAttributes = (CmdletOfficeManagementApiPermissionAttribute[])Attribute.GetCustomAttributes(GetType(), typeof(CmdletOfficeManagementApiPermissionAttribute)); - var requiredRoles = new List(requiredRoleAttributes.Length); - foreach(var requiredRoleAttribute in requiredRoleAttributes) + var orRequiredRoles = new List(requiredRoleAttributes.Length); + var andRequiredRoles = new List(requiredRoleAttributes.Length); + + foreach (var requiredRoleAttribute in requiredRoleAttributes) { - requiredRoles.Add(requiredRoleAttribute.ApiPermission.ToString().Replace("_", ".")); + foreach (OfficeManagementApiPermission role in Enum.GetValues(typeof(OfficeManagementApiPermission))) + { + if (role != OfficeManagementApiPermission.None) + { + if (requiredRoleAttribute.OrApiPermissions.HasFlag(role)) + { + orRequiredRoles.Add(role.ToString().Replace("_", ".")); + } + if (requiredRoleAttribute.AndApiPermissions.HasFlag(role)) + { + andRequiredRoles.Add(role.ToString().Replace("_", ".")); + } + } + } } // Ensure we have an active connection if (PnPConnection.CurrentConnection != null) { // There is an active connection, try to get a Microsoft Office Management API Token on the active connection - if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.OfficeManagementApi, ByPassPermissionCheck.ToBool() ? null : requiredRoles.ToArray()) is OfficeManagementApiToken token) + if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.OfficeManagementApi, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray()) is OfficeManagementApiToken token) { // Microsoft Office Management API Access Token available, return it return token; diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs index 6a11d054f..74c66b109 100644 --- a/Commands/Teams/GetTeamsApp.cs +++ b/Commands/Teams/GetTeamsApp.cs @@ -18,13 +18,13 @@ namespace SharePointPnP.PowerShell.Commands.Graph Remarks = "Retrieves all the Microsoft Teams Apps", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", - Remarks = "Retrieves a specific Microsoft Teams instance", + Code = "PS:> Get-PnPTeamsApp -Identity a54224d7-608b-4839-bf74-1b68148e65d4", + Remarks = "Retrieves a specific Microsoft Teams App", SortOrder = 2)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTeam -Visibility Public", - Remarks = "Retrieves all Microsoft Teams instances which are public visible", - SortOrder = 2)] + Code = "PS:> Get-PnPTeamsApp -Identity \"MyTeamsApp\"", + Remarks = "Retrieves a specific Microsoft Teams App", + SortOrder = 3)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.AppCatalog_Read_All)] public class GetTeamsApp: PnPGraphCmdlet { diff --git a/HelpAttributes/CmdletOfficeManagementApiPermission.cs b/HelpAttributes/CmdletOfficeManagementApiPermission.cs index c77fd437e..61f62b072 100644 --- a/HelpAttributes/CmdletOfficeManagementApiPermission.cs +++ b/HelpAttributes/CmdletOfficeManagementApiPermission.cs @@ -9,6 +9,8 @@ namespace SharePointPnP.PowerShell.CmdletHelpAttributes [Flags] public enum OfficeManagementApiPermission : int { + None = 0, + [EnumMember(Value = "ActivityFeed.Read")] ActivityFeed_Read = 1, @@ -31,15 +33,17 @@ public sealed class CmdletOfficeManagementApiPermissionAttribute : CmdletApiPerm /// /// One or more permissions of which only one is needed to granted to the token /// - public OfficeManagementApiPermission ApiPermission { get; set; } + public OfficeManagementApiPermission OrApiPermissions { get; set; } + public OfficeManagementApiPermission AndApiPermissions { get; set; } /// /// Constructs a new ApiPermissionAttribute /// /// One or more possible permissions of which only one is needed to be granted in the token - public CmdletOfficeManagementApiPermissionAttribute(OfficeManagementApiPermission apiPermission) + public CmdletOfficeManagementApiPermissionAttribute(OfficeManagementApiPermission orApiPermissions, OfficeManagementApiPermission andApiPermissions = OfficeManagementApiPermission.None) { - ApiPermission = apiPermission; + OrApiPermissions = orApiPermissions; + AndApiPermissions = andApiPermissions; } } } diff --git a/ModuleFilesGenerator/HelpFileGenerator.cs b/ModuleFilesGenerator/HelpFileGenerator.cs index 2dee1f696..534aa5a7d 100644 --- a/ModuleFilesGenerator/HelpFileGenerator.cs +++ b/ModuleFilesGenerator/HelpFileGenerator.cs @@ -73,45 +73,60 @@ private XElement GetCommandElement(Model.CmdletInfo cmdletInfo) additionalDescriptionInfo.AppendLine("* Required API permissions:"); // Go through each of the API permissions on this cmdlet and build a dictionary with the API type as the key and the requested scope(s) on it as the value - var requiredPermissionByApiDictionary = new Dictionary>(cmdletInfo.ApiPermissions.Count); + var requiredOrPermissionByApiDictionary = new Dictionary>(cmdletInfo.ApiPermissions.Count); + var requiredAndPermissionByApiDictionary = new Dictionary>(cmdletInfo.ApiPermissions.Count); foreach (var requiredApiPermission in cmdletInfo.ApiPermissions) { - // Through reflection, get the friendly name of the API and the permission scopes. We must use reflection here as generic attribute types do not exist in C# yet. Multiple scopes are returned as a comma-space separated string. - var scopePermission = requiredApiPermission.GetType().GetProperty("ApiPermission")?.GetValue(requiredApiPermission, null); - // If we were unable to retrieve the scopes and/or api through reflection, continue with the next permission attribute - if (scopePermission == null || requiredApiPermission.ApiName == null) continue; + requiredOrPermissionByApiDictionary = ParseApiPermissions("OrApiPermissions", requiredApiPermission, requiredOrPermissionByApiDictionary); + requiredAndPermissionByApiDictionary = ParseApiPermissions("AndApiPermissions", requiredApiPermission, requiredAndPermissionByApiDictionary); + + //// Through reflection, get the friendly name of the API and the permission scopes. We must use reflection here as generic attribute types do not exist in C# yet. Multiple scopes are returned as a comma-space separated string. + //var scopePermission = requiredApiPermission.GetType().GetProperty("OrApiPermissions")?.GetValue(requiredApiPermission, null); + + //// If we were unable to retrieve the scopes and/or api through reflection, continue with the next permission attribute + //if (scopePermission == null || requiredApiPermission.ApiName == null) continue; + + //// Ensure our dictionary with APIs already has an entry for the current API being processed + //if(!requiredPermissionByApiDictionary.ContainsKey(requiredApiPermission.ApiName)) + //{ + // // Add another entry to the dictionary for this API + // requiredPermissionByApiDictionary.Add(requiredApiPermission.ApiName, new List()); + //} + + //// The returned scopes are the enum names which use an underscore instead of a dot for the scope names and are comma-space separated if multiple scopes are possible + //var scopes = scopePermission.ToString().Replace("_", ".").Split(','); + + //// Go through each scope + //foreach (var scope in scopes) + //{ + // // Remove the potential trailing space + // var trimmedScope = scope.Trim(); + + // // If the scope is not known to be required yet, add it to the dictionary with APIs and requested scopes + // if (!requiredPermissionByApiDictionary[requiredApiPermission.ApiName].Contains(trimmedScope)) + // { + // requiredPermissionByApiDictionary[requiredApiPermission.ApiName].Add(trimmedScope); + // } + //} + } - // Ensure our dictionary with APIs already has an entry for the current API being processed - if(!requiredPermissionByApiDictionary.ContainsKey(requiredApiPermission.ApiName)) + // Loop through all the items in our dictionary with API types and requested scopes on the API so we can add it to the help text output + foreach (var requiredPermissionDictionaryItem in requiredOrPermissionByApiDictionary) + { + if (requiredPermissionDictionaryItem.Value.Count > 0) { - // Add another entry to the dictionary for this API - requiredPermissionByApiDictionary.Add(requiredApiPermission.ApiName, new List()); + additionalDescriptionInfo.AppendLine($" * {requiredPermissionDictionaryItem.Key}: {string.Join(" or ", requiredPermissionDictionaryItem.Value.OrderBy(s => s))}"); } - - // The returned scopes are the enum names which use an underscore instead of a dot for the scope names and are comma-space separated if multiple scopes are possible - var scopes = scopePermission.ToString().Replace("_", ".").Split(','); - - // Go through each scope - foreach (var scope in scopes) + } + foreach (var requiredPermissionDictionaryItem in requiredAndPermissionByApiDictionary) + { + if (requiredPermissionDictionaryItem.Value.Count > 0) { - // Remove the potential trailing space - var trimmedScope = scope.Trim(); - - // If the scope is not known to be required yet, add it to the dictionary with APIs and requested scopes - if (!requiredPermissionByApiDictionary[requiredApiPermission.ApiName].Contains(trimmedScope)) - { - requiredPermissionByApiDictionary[requiredApiPermission.ApiName].Add(trimmedScope); - } + additionalDescriptionInfo.AppendLine($" * {requiredPermissionDictionaryItem.Key}: {string.Join(" and ", requiredPermissionDictionaryItem.Value.OrderBy(s => s))}"); } } - // Loop through all the items in our dictionary with API types and requested scopes on the API so we can add it to the help text output - foreach(var requiredPermissionDictionaryItem in requiredPermissionByApiDictionary) - { - additionalDescriptionInfo.AppendLine($" * {requiredPermissionDictionaryItem.Key}: {string.Join(" or ", requiredPermissionDictionaryItem.Value.OrderBy(s => s))}"); - } - additionalDescriptionInfo.AppendLine(); } @@ -157,6 +172,41 @@ private XElement GetSyntaxElement(Model.CmdletInfo cmdletInfo) return syntaxElement; } + private Dictionary> ParseApiPermissions(string propertyName, CmdletApiPermissionBase requiredApiPermission, Dictionary> requiredPermissionByApiDictionary) + { + // Through reflection, get the friendly name of the API and the permission scopes. We must use reflection here as generic attribute types do not exist in C# yet. Multiple scopes are returned as a comma-space separated string. + var scopePermission = requiredApiPermission.GetType().GetProperty(propertyName)?.GetValue(requiredApiPermission, null); + + // If we were unable to retrieve the scopes and/or api through reflection, continue with the next permission attribute + if (scopePermission != null && requiredApiPermission.ApiName != null) + { + + // Ensure our dictionary with APIs already has an entry for the current API being processed + if (!requiredPermissionByApiDictionary.ContainsKey(requiredApiPermission.ApiName)) + { + // Add another entry to the dictionary for this API + requiredPermissionByApiDictionary.Add(requiredApiPermission.ApiName, new List()); + } + + // The returned scopes are the enum names which use an underscore instead of a dot for the scope names and are comma-space separated if multiple scopes are possible + var scopes = scopePermission.ToString().Replace("_", ".").Split(',').Where(s => s != "None"); + + // Go through each scope + foreach (var scope in scopes) + { + // Remove the potential trailing space + var trimmedScope = scope.Trim(); + + // If the scope is not known to be required yet, add it to the dictionary with APIs and requested scopes + if (!requiredPermissionByApiDictionary[requiredApiPermission.ApiName].Contains(trimmedScope)) + { + requiredPermissionByApiDictionary[requiredApiPermission.ApiName].Add(trimmedScope); + } + } + } + return requiredPermissionByApiDictionary; + } + private XElement GetParametersElement(Model.CmdletInfo cmdletInfo) { var parametersElement = new XElement(command + "parameters"); From 3ba9fec148c1f752cc8789a1853d3851a508fd9a Mon Sep 17 00:00:00 2001 From: Todd Klindt Date: Mon, 29 Jun 2020 11:08:31 -0500 Subject: [PATCH 082/130] Add GetList.cs example This adds an example on how to work with the "Url" column since its Title and the properly it comes from aren't the same. For beginners it's not obvious how to work with columns like that. --- Commands/Lists/GetList.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Commands/Lists/GetList.cs b/Commands/Lists/GetList.cs index 1cb813d44..6edfed518 100644 --- a/Commands/Lists/GetList.cs +++ b/Commands/Lists/GetList.cs @@ -25,6 +25,10 @@ namespace SharePointPnP.PowerShell.Commands.Lists Code = "PS:> Get-PnPList -Identity Lists/Announcements", Remarks = "Returns a list with the given url", SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPList | Where-Object {$_.RootFolder.ServerRelativeUrl -like ""/lists/*""}", + Remarks = "This examples shows how to do wildcard searches on the list URL. It returns all lists whose URL starts with ""/lists/"" This could also be used to search for strings inside of the URL.", + SortOrder = 4)] public class GetList : PnPWebRetrievalsCmdlet { [Parameter(Mandatory = false, ValueFromPipeline = true, Position = 0, HelpMessage = "The ID, name or Url (Lists/MyList) of the list")] @@ -58,4 +62,4 @@ protected override void ExecuteCmdlet() } } } -} \ No newline at end of file +} From 8b5298adcbba21658a45a99e86e0ec8599bd8633 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 29 Jun 2020 18:14:23 +0200 Subject: [PATCH 083/130] updated changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f682400..ef31cd0cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) -- Added Get-PnPTeamsTeam, Get-PnPTeamsChannel, Add-PnPTeamsChannel, Remove-PnPTeamsChannel cmdlets +- Added Add-PnPTeamsChannel, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsTab, Get-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam cmdlets ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) From e8c257f8696bdfba00bfc7648add36709e1639df Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 29 Jun 2020 18:23:01 +0200 Subject: [PATCH 084/130] Fixed compilation issue --- Commands/Lists/GetList.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Commands/Lists/GetList.cs b/Commands/Lists/GetList.cs index 6edfed518..d3f5232b0 100644 --- a/Commands/Lists/GetList.cs +++ b/Commands/Lists/GetList.cs @@ -26,8 +26,8 @@ namespace SharePointPnP.PowerShell.Commands.Lists Remarks = "Returns a list with the given url", SortOrder = 3)] [CmdletExample( - Code = "PS:> Get-PnPList | Where-Object {$_.RootFolder.ServerRelativeUrl -like ""/lists/*""}", - Remarks = "This examples shows how to do wildcard searches on the list URL. It returns all lists whose URL starts with ""/lists/"" This could also be used to search for strings inside of the URL.", + Code = @"PS:> Get-PnPList | Where-Object {$_.RootFolder.ServerRelativeUrl -like ""/lists/*""}", + Remarks = @"This examples shows how to do wildcard searches on the list URL. It returns all lists whose URL starts with ""/lists/"" This could also be used to search for strings inside of the URL.", SortOrder = 4)] public class GetList : PnPWebRetrievalsCmdlet { From 234131b26bcd782845c77a35b0b2908852f0e7d8 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 30 Jun 2020 01:49:41 +0200 Subject: [PATCH 085/130] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebb95c124..ef2a69d54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,11 +13,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) - Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) +- Fixed timeouts on `Get-PnPSiteCollectionAdmin` when the site has a lot of users [PR #2769](https://github.com/pnp/PnP-PowerShell/pull/2769) ### Contributors - Erwin van Hunen [erwinvanhunen] - Gautam Sheth [gautamdsheth] - Koen Zomers [koenzomers] +- Maximilian L. [MrTantum] ## [3.22.2006.2] From 38bd5c32dd6f0986696437307b441095649f4dc1 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 30 Jun 2020 02:04:43 +0200 Subject: [PATCH 086/130] Updating MSDN reference to docs --- Commands/Fields/SetField.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Fields/SetField.cs b/Commands/Fields/SetField.cs index 5d41525d3..cedc6ecd3 100644 --- a/Commands/Fields/SetField.cs +++ b/Commands/Fields/SetField.cs @@ -11,7 +11,7 @@ namespace SharePointPnP.PowerShell.Commands.Fields [CmdletHelp("Changes one or more properties of a field in a specific list or for the whole web", Category = CmdletHelpCategory.Fields, OutputType = typeof(Field), - OutputTypeLink = "https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.field.aspx")] + OutputTypeLink = "https://docs.microsoft.com/previous-versions/office/sharepoint-server/ee545882(v=office.15)")] [CmdletExample( Code = @"PS:> Set-PnPField -Identity AssignedTo -Values @{JSLink=""customrendering.js"";Group=""My fields""}", Remarks = @"Updates the AssignedTo field on the current web to use customrendering.js for the JSLink and sets the group name the field is categorized in to ""My Fields"". Lists that are already using the AssignedTo field will not be updated.", From a64d638b26f9121538d26bc6cafce8536ac01cf3 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 30 Jun 2020 02:08:01 +0200 Subject: [PATCH 087/130] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28260ca83..1e13168e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) - Added Add-PnPTeamsChannel, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsTab, Get-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam cmdlets +- Added support for enabling and disabling fields using `Set-PnPField -Identity FieldName -Values @{AllowDeletion=$false}` [PR #2766](https://github.com/pnp/PnP-PowerShell/pull/2766) ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) @@ -22,6 +23,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Koen Zomers [koenzomers] - Ellie Hussey [Professr] - Todd Klindt [ToddKlindt] +- Jens Otto Hatlevold [jensotto] ## [3.22.2006.2] From ddb62c19964bb57c510a6154aad3e2cee66b1513 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Jun 2020 11:37:39 +0200 Subject: [PATCH 088/130] fixed compilation issues --- .../InitializePowerShellAuthentication.cs | 1 - Commands/Base/PnPConnection.cs | 26 +++++++----- Commands/Base/PnPGraphCmdlet.cs | 12 +++++- Commands/Base/PnPOfficeManagementApiCmdlet.cs | 12 +++++- Commands/Model/GenericToken.cs | 7 ++++ ...P.PowerShell.Online.Commands.Format.ps1xml | 40 +++++++++++++++++++ Commands/Publishing/AddMasterPage.cs | 2 +- .../SharePointPnP.PowerShell.Commands.csproj | 3 ++ Commands/Teams/GetTeamsApp.cs | 9 +++-- Commands/Teams/RemoveTeamsTab.cs | 29 +++++++++++--- HelpAttributes/CmdletTokenTypeAttribute.cs | 24 +++++++++++ ...PnP.PowerShell.CmdletHelpAttributes.csproj | 1 + 12 files changed, 144 insertions(+), 22 deletions(-) create mode 100644 HelpAttributes/CmdletTokenTypeAttribute.cs diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index c92d3d891..8ac256a4c 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -165,7 +165,6 @@ protected override void ProcessRecord() scopes.Add(permissionScopes.GetScope("MSGraph.Group.ReadWrite.All")); scopes.Add(permissionScopes.GetScope("SPO.User.Read.All")); scopes.Add(permissionScopes.GetScope("MSGraph.User.Read.All")); - scopes.Add(permissionScopes.GetScope("MSGraph.AppCatalog.ReadWrite.All"); } var scopesPayload = GetScopesPayload(scopes); diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index bc272d8dd..164d4f085 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -3,6 +3,7 @@ using OfficeDevPnP.Core.Extensions; using SharePointPnP.PowerShell.Commands.Enums; using SharePointPnP.PowerShell.Commands.Model; +using SharePointPnP.PowerShell.Core.Attributes; using System; using System.Collections.Generic; using System.Linq; @@ -136,7 +137,7 @@ internal string TryGetAccessToken(TokenAudience tokenAudience, string[] roles = /// Audience to try to get a token for /// The specific roles to request access to (i.e. Group.ReadWrite.All). Optional, will use default groups assigned to clientId if not specified. /// for the audience or NULL if unable to retrieve a token for the audience on the current connection - internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles = null, string[] andRoles = null) + internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles = null, string[] andRoles = null, TokenType tokenType = TokenType.All) { GenericToken token = null; @@ -148,12 +149,18 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles if (token.ExpiresOn > DateTime.Now) { + // check token type if needed + if (tokenType != TokenType.All && token.TokenType != tokenType) + { + throw new PSSecurityException($"Access to {tokenAudience} failed because the API requires a {tokenType} token while you currently use a {token.TokenType} token."); + } var andRolesMatched = false; if (andRoles != null && andRoles.Length != 0) { // we have explicitely required roles andRolesMatched = andRoles.All(r => token.Roles.Contains(r)); - } else + } + else { andRolesMatched = true; } @@ -162,25 +169,26 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles if (orRoles != null && orRoles.Length != 0) { orRolesMatched = orRoles.Any(r => token.Roles.Contains(r)); - } else + } + else { orRolesMatched = true; } if (orRolesMatched && andRolesMatched) - { - return token; + { + return token; } - + if (orRoles != null || andRoles != null) { var message = string.Empty; // Requested role was not part of the access token, throw an exception explaining which application registration is missing which role - if(!orRolesMatched) + if (!orRolesMatched) { message += "for one of the following roles: " + string.Join(", ", orRoles); } - if(!andRolesMatched) + if (!andRolesMatched) { message += (message != string.Empty ? ", and " : ", ") + "for all of the following roles: " + string.Join(", ", andRoles); } @@ -459,7 +467,7 @@ public static PnPConnection GetConnectionWithToken(GenericToken token, #endregion internal PnPConnection(ClientContext context, ConnectionType connectionType, int minimalHealthScore, int retryCount, int retryWait, PSCredential credential, string clientId, string clientSecret, string url, string tenantAdminUrl, string pnpVersionTag, PSHost host, bool disableTelemetry, InitializationType initializationType) - : this(context, connectionType, minimalHealthScore, retryCount, retryWait, credential, url, tenantAdminUrl, pnpVersionTag, host, disableTelemetry, initializationType) + : this(context, connectionType, minimalHealthScore, retryCount, retryWait, credential, url, tenantAdminUrl, pnpVersionTag, host, disableTelemetry, initializationType) { ClientId = clientId; ClientSecret = clientSecret; diff --git a/Commands/Base/PnPGraphCmdlet.cs b/Commands/Base/PnPGraphCmdlet.cs index 2f8e42706..605a60305 100644 --- a/Commands/Base/PnPGraphCmdlet.cs +++ b/Commands/Base/PnPGraphCmdlet.cs @@ -2,6 +2,7 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Model; using SharePointPnP.PowerShell.Commands.Properties; +using SharePointPnP.PowerShell.Core.Attributes; using System; using System.Collections.Generic; using System.Management.Automation; @@ -24,12 +25,21 @@ public GraphToken Token { get { + var tokenType = TokenType.All; + + // Collect, if present, the token type attribute + var tokenTypeAttribute = (CmdletTokenTypeAttribute)Attribute.GetCustomAttribute(GetType(), typeof(CmdletTokenTypeAttribute)); + if(tokenTypeAttribute != null) + { + tokenType = tokenTypeAttribute.TokenType; + } // Collect the permission attributes to discover required roles var requiredRoleAttributes = (CmdletMicrosoftGraphApiPermission[])Attribute.GetCustomAttributes(GetType(), typeof(CmdletMicrosoftGraphApiPermission)); var orRequiredRoles = new List(requiredRoleAttributes.Length); var andRequiredRoles = new List(requiredRoleAttributes.Length); foreach (var requiredRoleAttribute in requiredRoleAttributes) { + foreach (MicrosoftGraphApiPermission role in Enum.GetValues(typeof(MicrosoftGraphApiPermission))) { if (role != MicrosoftGraphApiPermission.None) @@ -50,7 +60,7 @@ public GraphToken Token if (PnPConnection.CurrentConnection != null) { // There is an active connection, try to get a Microsoft Graph Token on the active connection - if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.MicrosoftGraph, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray()) is GraphToken token) + if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.MicrosoftGraph, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray(), tokenType) is GraphToken token) { // Microsoft Graph Access Token available, return it return token; diff --git a/Commands/Base/PnPOfficeManagementApiCmdlet.cs b/Commands/Base/PnPOfficeManagementApiCmdlet.cs index b9890496d..7a855c599 100644 --- a/Commands/Base/PnPOfficeManagementApiCmdlet.cs +++ b/Commands/Base/PnPOfficeManagementApiCmdlet.cs @@ -2,6 +2,7 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Model; using SharePointPnP.PowerShell.Commands.Properties; +using SharePointPnP.PowerShell.Core.Attributes; using System; using System.Collections.Generic; using System.Management.Automation; @@ -23,6 +24,15 @@ public OfficeManagementApiToken Token { get { + var tokenType = TokenType.All; + + // Collect, if present, the token type attribute + var tokenTypeAttribute = (CmdletTokenTypeAttribute)Attribute.GetCustomAttribute(GetType(), typeof(CmdletTokenTypeAttribute)); + if (tokenTypeAttribute != null) + { + tokenType = tokenTypeAttribute.TokenType; + } + // Collect the permission attributes to discover required roles var requiredRoleAttributes = (CmdletOfficeManagementApiPermissionAttribute[])Attribute.GetCustomAttributes(GetType(), typeof(CmdletOfficeManagementApiPermissionAttribute)); var orRequiredRoles = new List(requiredRoleAttributes.Length); @@ -50,7 +60,7 @@ public OfficeManagementApiToken Token if (PnPConnection.CurrentConnection != null) { // There is an active connection, try to get a Microsoft Office Management API Token on the active connection - if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.OfficeManagementApi, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray()) is OfficeManagementApiToken token) + if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.OfficeManagementApi, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray(), tokenType) is OfficeManagementApiToken token) { // Microsoft Office Management API Access Token available, return it return token; diff --git a/Commands/Model/GenericToken.cs b/Commands/Model/GenericToken.cs index 63e4707fe..13cd28f0a 100644 --- a/Commands/Model/GenericToken.cs +++ b/Commands/Model/GenericToken.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Web; using System.Collections.Generic; +using SharePointPnP.PowerShell.Core.Attributes; namespace SharePointPnP.PowerShell.Commands.Model { @@ -52,6 +53,10 @@ public class GenericToken /// public Guid? TenantId { get; protected set; } + /// + /// The type of the token, e.g. Application or Generic + /// + public TokenType TokenType { get; protected set; } /// /// Instantiates a new token /// @@ -78,6 +83,8 @@ public GenericToken(string accesstoken) rolesList.AddRange(scope.Value.Split(' ')); } Roles = rolesList.ToArray(); + + TokenType = ParsedToken.Claims.FirstOrDefault(c => c.Type == "upn") != null ? TokenType.Delegate : TokenType.Application; } private object List() diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index b5cfa06d1..45dfefc3f 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2128,5 +2128,45 @@ + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.TeamApp + + + + + + + + + + + + + + + + + + + + + ID + + + DisplayName + + + DistributionMethod + + + ExternalId + + + + + + diff --git a/Commands/Publishing/AddMasterPage.cs b/Commands/Publishing/AddMasterPage.cs index 4024eee65..0b8404e8e 100644 --- a/Commands/Publishing/AddMasterPage.cs +++ b/Commands/Publishing/AddMasterPage.cs @@ -44,4 +44,4 @@ protected override void ExecuteCmdlet() WriteObject(masterPageFile); } } -} +} \ No newline at end of file diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 401d0ad55..1ef14a37c 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -622,6 +622,8 @@ + + @@ -707,6 +709,7 @@ + diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs index 74c66b109..5b310b722 100644 --- a/Commands/Teams/GetTeamsApp.cs +++ b/Commands/Teams/GetTeamsApp.cs @@ -3,6 +3,7 @@ using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Core.Attributes; using System; using System.Linq; using System.Management.Automation; @@ -25,12 +26,14 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPTeamsApp -Identity \"MyTeamsApp\"", Remarks = "Retrieves a specific Microsoft Teams App", SortOrder = 3)] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.AppCatalog_Read_All)] - public class GetTeamsApp: PnPGraphCmdlet + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.AppCatalog_Read_All)] + [CmdletTokenType(TokenType = TokenType.Delegate)] + public class GetTeamsApp : PnPGraphCmdlet { [Parameter(Mandatory = false, HelpMessage = "Specify the name, id or external id of the app.")] public TeamsAppPipeBind Identity; - + protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs index 222e82927..51fb8065c 100644 --- a/Commands/Teams/RemoveTeamsTab.cs +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -3,16 +3,17 @@ using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; using System; +using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Remove, "PnPTeamsTab")] - [CmdletHelp("Gets one or all tabs in a channel.", + [CmdletHelp("Removes a Microsoft Teams tab in a channel.", Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", + Code = "PS:> Remove-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -TabId ", Remarks = "Retrieves the tabs for the Microsoft Teams instances", SortOrder = 1)] [CmdletExample( @@ -28,8 +29,8 @@ public class RemoveTeamsTab : PnPGraphCmdlet [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.")] public string ChannelId; - [Parameter(Mandatory = true, HelpMessage = "DisplayName")] - public string TabId; + [Parameter(Mandatory = true, HelpMessage = "Identity")] + public TeamsTabPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] public SwitchParameter Force; @@ -38,9 +39,25 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the tab will remove the settings of this tab too.", Properties.Resources.Confirm)) { - if (!TeamsUtility.DeleteTab(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId, TabId)) + var tabId = string.Empty; + if(Identity.Id != Guid.Empty) { - WriteError(new ErrorRecord(new Exception($"Tab remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + tabId = Identity.Id.ToString(); + } else + { + var tabs = TeamsUtility.GetTabs(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId); + var tab = tabs.FirstOrDefault(t => t.DisplayName.Equals(Identity.DisplayName, StringComparison.OrdinalIgnoreCase)); + if(tab != null) + { + tabId = tab.Id; + } else + { + throw new PSArgumentException("Cannot find tab"); + } + } + if (!TeamsUtility.DeleteTab(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId, tabId)) + { + throw new PSInvalidOperationException("Tab remove failed"); } } } diff --git a/HelpAttributes/CmdletTokenTypeAttribute.cs b/HelpAttributes/CmdletTokenTypeAttribute.cs new file mode 100644 index 000000000..d74b5d3e9 --- /dev/null +++ b/HelpAttributes/CmdletTokenTypeAttribute.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SharePointPnP.PowerShell.Core.Attributes +{ + public enum TokenType : short + { + All = 0, + Application = 1, + Delegate = 2 + } + + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public sealed class CmdletTokenTypeAttribute : Attribute + { + public TokenType TokenType { get; set; } + + public CmdletTokenTypeAttribute(TokenType tokenType = TokenType.All) + { + TokenType = tokenType; + } + } +} diff --git a/HelpAttributes/SharePointPnP.PowerShell.CmdletHelpAttributes.csproj b/HelpAttributes/SharePointPnP.PowerShell.CmdletHelpAttributes.csproj index 946daf062..6b49f4543 100644 --- a/HelpAttributes/SharePointPnP.PowerShell.CmdletHelpAttributes.csproj +++ b/HelpAttributes/SharePointPnP.PowerShell.CmdletHelpAttributes.csproj @@ -112,6 +112,7 @@ + From 4d0509cf4875daae26fe7b03c24c89e77bbab1a6 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Jun 2020 11:39:18 +0200 Subject: [PATCH 089/130] Added extra cmdlets in .NET framework build --- Commands/SharePointPnP.PowerShell.Commands.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 1ef14a37c..9ab5f1656 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -915,10 +915,13 @@ + + + From 88bbcfc7a4b510e7974ee5ce82a6e6ba47226a39 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 30 Jun 2020 11:55:42 +0200 Subject: [PATCH 090/130] Renamed Unified to Microsoft365 --- ...peBind.cs => Microsoft365GroupPipeBind.cs} | 8 ++--- ...roup.cs => GetDeletedMicrosoft365Group.cs} | 14 ++++---- ...nifiedGroup.cs => GetMicrosoft365Group.cs} | 21 ++++++------ ...bers.cs => GetMicrosoft365GroupMembers.cs} | 11 +++--- ...wners.cs => GetMicrosoft365GroupOwners.cs} | 13 +++---- ...nifiedGroup.cs => NewMicrosoft365Group.cs} | 17 +++++----- ...p.cs => RemoveDeletedMicrosoft365Group.cs} | 16 ++++----- ...iedGroup.cs => RemoveMicrosoft365Group.cs} | 15 ++++---- .../Graph/ResetMicrosoft365GroupExpiration.cs | 34 +++++++++++++++++++ Commands/Graph/ResetUnifiedGroupExpiration.cs | 33 ------------------ ....cs => RestoreDeletedMicrosoft365Group.cs} | 18 +++++----- ...nifiedGroup.cs => SetMicrosoft365Group.cs} | 21 ++++++------ .../SharePointPnP.PowerShell.Commands.csproj | 22 ++++++------ Tests/GraphTests.cs | 32 ++++++++--------- 14 files changed, 141 insertions(+), 134 deletions(-) rename Commands/Base/PipeBinds/{UnifiedGroupPipeBind.cs => Microsoft365GroupPipeBind.cs} (92%) rename Commands/Graph/{GetDeletedUnifiedGroup.cs => GetDeletedMicrosoft365Group.cs} (77%) rename Commands/Graph/{GetUnifiedGroup.cs => GetMicrosoft365Group.cs} (82%) rename Commands/Graph/{GetUnifiedGroupMembers.cs => GetMicrosoft365GroupMembers.cs} (85%) rename Commands/Graph/{GetUnifiedGroupOwners.cs => GetMicrosoft365GroupOwners.cs} (81%) rename Commands/Graph/{NewUnifiedGroup.cs => NewMicrosoft365Group.cs} (81%) rename Commands/Graph/{RemoveDeletedUnifiedGroup.cs => RemoveDeletedMicrosoft365Group.cs} (71%) rename Commands/Graph/{RemoveUnifiedGroup.cs => RemoveMicrosoft365Group.cs} (74%) create mode 100644 Commands/Graph/ResetMicrosoft365GroupExpiration.cs delete mode 100644 Commands/Graph/ResetUnifiedGroupExpiration.cs rename Commands/Graph/{RestoreDeletedUnifiedGroup.cs => RestoreDeletedMicrosoft365Group.cs} (62%) rename Commands/Graph/{SetUnifiedGroup.cs => SetMicrosoft365Group.cs} (83%) diff --git a/Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs b/Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs similarity index 92% rename from Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs rename to Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs index 170e574d7..a4aa9d021 100644 --- a/Commands/Base/PipeBinds/UnifiedGroupPipeBind.cs +++ b/Commands/Base/PipeBinds/Microsoft365GroupPipeBind.cs @@ -5,22 +5,22 @@ namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds { - public class UnifiedGroupPipeBind + public class Microsoft365GroupPipeBind { private readonly UnifiedGroupEntity _group; private readonly String _groupId; private readonly String _displayName; - public UnifiedGroupPipeBind() + public Microsoft365GroupPipeBind() { } - public UnifiedGroupPipeBind(UnifiedGroupEntity group) + public Microsoft365GroupPipeBind(UnifiedGroupEntity group) { _group = group; } - public UnifiedGroupPipeBind(String input) + public Microsoft365GroupPipeBind(String input) { Guid idValue; if (Guid.TryParse(input, out idValue)) diff --git a/Commands/Graph/GetDeletedUnifiedGroup.cs b/Commands/Graph/GetDeletedMicrosoft365Group.cs similarity index 77% rename from Commands/Graph/GetDeletedUnifiedGroup.cs rename to Commands/Graph/GetDeletedMicrosoft365Group.cs index 688944165..61e987d97 100644 --- a/Commands/Graph/GetDeletedUnifiedGroup.cs +++ b/Commands/Graph/GetDeletedMicrosoft365Group.cs @@ -9,24 +9,24 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Get, "PnPDeletedUnifiedGroup")] - - [CmdletHelp("Gets one deleted Microsoft 365 Group (aka Unified Group) or a list of deleted Microsoft 365 Groups", + [Cmdlet(VerbsCommon.Get, "PnPDeletedMicrosoft365Group")] + [Alias("Get-PnPDeletedUnifiedGroup")] + [CmdletHelp("Gets one deleted Microsoft 365 Group or a list of deleted Microsoft 365 Groups", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPDeletedUnifiedGroup", + Code = "PS:> Get-PnPDeletedMicrosoft365Group", Remarks = "Retrieves all deleted Microsoft 365 Groups", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPDeletedUnifiedGroup -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", + Code = "PS:> Get-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", Remarks = "Retrieves a specific deleted Microsoft 365 Group based on its ID", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Group_Read_All)] - public class GetDeletedUnifiedGroup : PnPGraphCmdlet + public class GetDeletedMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = false, HelpMessage = "The Identity of the Microsoft 365 Group")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/GetUnifiedGroup.cs b/Commands/Graph/GetMicrosoft365Group.cs similarity index 82% rename from Commands/Graph/GetUnifiedGroup.cs rename to Commands/Graph/GetMicrosoft365Group.cs index 6a384d9b5..94d78f2e6 100644 --- a/Commands/Graph/GetUnifiedGroup.cs +++ b/Commands/Graph/GetMicrosoft365Group.cs @@ -9,40 +9,41 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Get, "PnPUnifiedGroup")] - [CmdletHelp("Gets one Microsoft 365 Group (aka Unified Group) or a list of Microsoft 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", + [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365Group")] + [Alias("Get-PnPUnifiedGroup")] + [CmdletHelp("Gets one Microsoft 365 Group or a list of Microsoft 365 Groups", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-list", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup", + Code = "PS:> Get-Microsoft365Group", Remarks = "Retrieves all the Microsoft 365 Groups", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", + Code = "PS:> Get-Microsoft365Group -Identity $groupId", Remarks = "Retrieves a specific Microsoft 365 Group based on its ID", SortOrder = 2)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", + Code = "PS:> Get-Microsoft365Group -Identity $groupDisplayName", Remarks = "Retrieves a specific or list of Microsoft 365 Groups that start with the given DisplayName", SortOrder = 3)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", + Code = "PS:> Get-Microsoft365Group -Identity $groupSiteMailNickName", Remarks = "Retrieves a specific or list of Microsoft 365 Groups for which the email starts with the provided mail nickName", SortOrder = 4)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $group", + Code = "PS:> Get-Microsoft365Group -Identity $group", Remarks = "Retrieves a specific Microsoft 365 Group based on its object instance", SortOrder = 5)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -IncludeIfHasTeam", + Code = "PS:> Get-Microsoft365Group -IncludeIfHasTeam", Remarks = "Retrieves all the Microsoft 365 Groups and checks for each of them if it has a Microsoft Team provisioned for it", SortOrder = 6)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All | MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.GroupMember_ReadWrite_All | MicrosoftGraphApiPermission.GroupMember_Read_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.Directory_Read_All)] - public class GetUnifiedGroup : PnPGraphCmdlet + public class GetMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = false, HelpMessage = "The Identity of the Microsoft 365 Group")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "Exclude fetching the site URL for Microsoft 365 Groups. This speeds up large listings.")] public SwitchParameter ExcludeSiteUrl; diff --git a/Commands/Graph/GetUnifiedGroupMembers.cs b/Commands/Graph/GetMicrosoft365GroupMembers.cs similarity index 85% rename from Commands/Graph/GetUnifiedGroupMembers.cs rename to Commands/Graph/GetMicrosoft365GroupMembers.cs index 098ea4d63..3bf0998b5 100644 --- a/Commands/Graph/GetUnifiedGroupMembers.cs +++ b/Commands/Graph/GetMicrosoft365GroupMembers.cs @@ -9,24 +9,25 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Get, "PnPUnifiedGroupMembers")] + [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupMembers")] + [Alias("Get-PnPUnifiedGroupMembers")] [CmdletHelp("Gets members of a particular Microsoft 365 Group (aka Unified Group). Requires the Azure Active Directory application permissions 'Group.Read.All' and 'User.Read.All'.", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-list-members", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroupMembers -Identity $groupId", + Code = "PS:> Get-PnPMicrosoft365GroupMembers -Identity $groupId", Remarks = "Retrieves all the members of a specific Microsoft 365 Group based on its ID", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroupMembers -Identity $group", + Code = "PS:> Get-PnPMicrosoft365GroupMembers -Identity $group", Remarks = "Retrieves all the members of a specific Microsoft 365 Group based on the group's object instance", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.Directory_Read_All | MicrosoftGraphApiPermission.GroupMember_Read_All | MicrosoftGraphApiPermission.GroupMember_ReadWrite_All | MicrosoftGraphApiPermission.User_Read_All | MicrosoftGraphApiPermission.User_ReadWrite_All | MicrosoftGraphApiPermission.Group_Read_All | MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class GetUnifiedGroupMembers : PnPGraphCmdlet + public class GetMicrosoft365GroupMembers : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/GetUnifiedGroupOwners.cs b/Commands/Graph/GetMicrosoft365GroupOwners.cs similarity index 81% rename from Commands/Graph/GetUnifiedGroupOwners.cs rename to Commands/Graph/GetMicrosoft365GroupOwners.cs index a52732b4f..5fdbd9f23 100644 --- a/Commands/Graph/GetUnifiedGroupOwners.cs +++ b/Commands/Graph/GetMicrosoft365GroupOwners.cs @@ -9,24 +9,25 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Get, "PnPUnifiedGroupOwners")] - [CmdletHelp("Gets owners of a particular Microsoft 365 Group (aka Unified Group). Requires the Azure Active Directory application permissions 'Group.Read.All' and 'User.Read.All'.", + [Cmdlet(VerbsCommon.Get, "PnPMicrosoft365GroupOwners")] + [Alias("Get-PnPUnifiedGroupOwners")] + [CmdletHelp("Gets owners of a particular Microsoft 365 Group", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-list-owners", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroupOwners -Identity $groupId", + Code = "PS:> Get-PnPMicrosoft365GroupOwners -Identity $groupId", Remarks = "Retrieves all the owners of a specific Microsoft 365 Group based on its ID", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroupOwners -Identity $group", + Code = "PS:> Get-PnPMicrosoft365GroupOwners -Identity $group", Remarks = "Retrieves all the owners of a specific Microsoft 365 Group based on the group's object instance", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All | MicrosoftGraphApiPermission.User_Read_All | MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.User_ReadWrite_All)] - public class GetUnifiedGroupOwners : PnPGraphCmdlet + public class GetMicrosoft365GroupOwners : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group.")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/NewUnifiedGroup.cs b/Commands/Graph/NewMicrosoft365Group.cs similarity index 81% rename from Commands/Graph/NewUnifiedGroup.cs rename to Commands/Graph/NewMicrosoft365Group.cs index 523a84ae6..17521f1db 100644 --- a/Commands/Graph/NewUnifiedGroup.cs +++ b/Commands/Graph/NewMicrosoft365Group.cs @@ -9,29 +9,30 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.New, "PnPUnifiedGroup")] - [CmdletHelp("Creates a new Microsoft 365 Group (aka Unified Group). Requires the Azure Active Directory application permission 'Group.ReadWrite.All'.", + [Cmdlet(VerbsCommon.New, "PnPMicrosoft365Group")] + [Alias("New-PnPUnifiedGroup")] + [CmdletHelp("Creates a new Microsoft 365 Group", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-post-groups", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> New-PnPUnifiedGroup -DisplayName $displayName -Description $description -MailNickname $nickname", + Code = "PS:> New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname", Remarks = "Creates a public Microsoft 365 Group with all the required properties", SortOrder = 1)] [CmdletExample( - Code = "PS:> New-PnPUnifiedGroup -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers", + Code = "PS:> New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers", Remarks = "Creates a public Microsoft 365 Group with all the required properties, and with a custom list of Owners and a custom list of Members", SortOrder = 2)] [CmdletExample( - Code = "PS:> New-PnPUnifiedGroup -DisplayName $displayName -Description $description -MailNickname $nickname -IsPrivate", + Code = "PS:> New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -IsPrivate", Remarks = "Creates a private Microsoft 365 Group with all the required properties", SortOrder = 3)] [CmdletExample( - Code = "PS:> New-PnPUnifiedGroup -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate", + Code = "PS:> New-PnPMicrosoft365Group -DisplayName $displayName -Description $description -MailNickname $nickname -Owners $arrayOfOwners -Members $arrayOfMembers -IsPrivate", Remarks = "Creates a private Microsoft 365 Group with all the required properties, and with a custom list of Owners and a custom list of Members", SortOrder = 4)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-post-groups")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Create | MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] - public class NewPnPUnifiedGroup : PnPGraphCmdlet + public class NewPnPMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = true, HelpMessage = "The Display Name of the Microsoft 365 Group")] public String DisplayName; diff --git a/Commands/Graph/RemoveDeletedUnifiedGroup.cs b/Commands/Graph/RemoveDeletedMicrosoft365Group.cs similarity index 71% rename from Commands/Graph/RemoveDeletedUnifiedGroup.cs rename to Commands/Graph/RemoveDeletedMicrosoft365Group.cs index b5caf3e96..63d93eafc 100644 --- a/Commands/Graph/RemoveDeletedUnifiedGroup.cs +++ b/Commands/Graph/RemoveDeletedMicrosoft365Group.cs @@ -7,25 +7,25 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Remove, "PnPDeletedUnifiedGroup")] - - [CmdletHelp("Permanently removes one deleted Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Remove, "PnPDeletedMicrosoft365Group")] + [Alias("Remove-PnPDeletedUnifiedGroup")] + [CmdletHelp("Permanently removes one deleted Microsoft 365 Group", Category = CmdletHelpCategory.Graph, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Remove-PnPDeletedUnifiedGroup -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", + Code = "PS:> Remove-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", Remarks = "Permanently removes a deleted Microsoft 365 Group based on its ID", SortOrder = 1)] [CmdletExample( - Code = @"PS:> $group = Get-PnPDeletedUnifiedGroup -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f -PS:> Remove-PnPDeletedUnifiedGroup -Identity $group", + Code = @"PS:> $group = Get-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f +PS:> Remove-PnPDeletedMicrosoft365Group -Identity $group", Remarks = "Permanently removes the provided deleted Microsoft 365 Group", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class RemoveDeletedUnifiedGroup : PnPGraphCmdlet + public class RemoveDeletedMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the deleted Microsoft 365 Group")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/RemoveUnifiedGroup.cs b/Commands/Graph/RemoveMicrosoft365Group.cs similarity index 74% rename from Commands/Graph/RemoveUnifiedGroup.cs rename to Commands/Graph/RemoveMicrosoft365Group.cs index f60722762..0d9305fbc 100644 --- a/Commands/Graph/RemoveUnifiedGroup.cs +++ b/Commands/Graph/RemoveMicrosoft365Group.cs @@ -8,28 +8,29 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Remove, "PnPUnifiedGroup")] - [CmdletHelp("Removes one Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Remove, "PnPMicrosoft365Group")] + [Alias("Remove-PnPUnifiedGroup")] + [CmdletHelp("Removes one Microsoft 365 Group", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Remove-PnPUnifiedGroup -Identity $groupId", + Code = "PS:> Remove-PnPMicrosoft365Group -Identity $groupId", Remarks = "Removes an Microsoft 365 Group based on its ID", SortOrder = 1)] [CmdletExample( - Code = "PS:> Remove-PnPUnifiedGroup -Identity $group", + Code = "PS:> Remove-PnPMicrosoft365Group -Identity $group", Remarks = "Removes the provided Microsoft 365 Group", SortOrder = 2)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup | ? Visibility -eq \"Public\" | Remove-PnPUnifiedGroup", + Code = "PS:> Get-PnPMicrosoft365Group | ? Visibility -eq \"Public\" | Remove-PnPMicrosoft365Group", Remarks = "Removes all the public Microsoft 365 Groups", SortOrder = 3)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class RemoveUnifiedGroup : PnPGraphCmdlet + public class RemoveMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/ResetMicrosoft365GroupExpiration.cs b/Commands/Graph/ResetMicrosoft365GroupExpiration.cs new file mode 100644 index 000000000..c25b8fff2 --- /dev/null +++ b/Commands/Graph/ResetMicrosoft365GroupExpiration.cs @@ -0,0 +1,34 @@ +#if !ONPREMISES && !NETSTANDARD2_1 +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Reset, "PnPMicrosoft365GroupExpiration")] + [Alias("Reset-PnPUnifiedGroupExpiration")] + [CmdletHelp("Renews the Microsoft 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", + DetailedDescription = "Renews the Microsoft 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", + Category = CmdletHelpCategory.Graph, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Reset-PnPMicrosoft365GroupExpiration", + Remarks = "Renews the Microsoft 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", + SortOrder = 1)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-renew")] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class ResetMicrosoft365GroupExpiration : PnPGraphCmdlet + { + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group")] + public Microsoft365GroupPipeBind Identity; + + protected override void ExecuteCmdlet() + { + var group = Identity.GetGroup(AccessToken); + UnifiedGroupsUtility.RenewUnifiedGroup(group.GroupId, AccessToken); + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Graph/ResetUnifiedGroupExpiration.cs b/Commands/Graph/ResetUnifiedGroupExpiration.cs deleted file mode 100644 index 9df4a3177..000000000 --- a/Commands/Graph/ResetUnifiedGroupExpiration.cs +++ /dev/null @@ -1,33 +0,0 @@ -#if !ONPREMISES && !NETSTANDARD2_1 -using OfficeDevPnP.Core.Framework.Graph; -using SharePointPnP.PowerShell.CmdletHelpAttributes; -using SharePointPnP.PowerShell.Commands.Base; -using SharePointPnP.PowerShell.Commands.Base.PipeBinds; -using System.Management.Automation; - -namespace SharePointPnP.PowerShell.Commands.Graph -{ - [Cmdlet(VerbsCommon.Reset, "PnPUnifiedGroupExpiration")] - [CmdletHelp("Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", - DetailedDescription = "Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", - Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-renew", - SupportedPlatform = CmdletSupportedPlatform.Online)] - [CmdletExample( - Code = "PS:> Reset-PnPUnifiedGroupExpiration", - Remarks = "Renews the Office 365 Group by extending its expiration with the number of days defined in the group expiration policy set on the Azure Active Directory", - SortOrder = 1)] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class ResetUnifiedGroupExpiration : PnPGraphCmdlet - { - [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Office 365 Group")] - public UnifiedGroupPipeBind Identity; - - protected override void ExecuteCmdlet() - { - var group = Identity.GetGroup(AccessToken); - UnifiedGroupsUtility.RenewUnifiedGroup(group.GroupId, AccessToken); - } - } -} -#endif \ No newline at end of file diff --git a/Commands/Graph/RestoreDeletedUnifiedGroup.cs b/Commands/Graph/RestoreDeletedMicrosoft365Group.cs similarity index 62% rename from Commands/Graph/RestoreDeletedUnifiedGroup.cs rename to Commands/Graph/RestoreDeletedMicrosoft365Group.cs index 6d6da3eb3..80acd930c 100644 --- a/Commands/Graph/RestoreDeletedUnifiedGroup.cs +++ b/Commands/Graph/RestoreDeletedMicrosoft365Group.cs @@ -7,26 +7,26 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsData.Restore, "PnPDeletedUnifiedGroup")] - - [CmdletHelp("Restores one deleted Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsData.Restore, "PnPDeletedMicrosoft365Group")] + [Alias("Restore-PnPDeletedUnifiedGroup")] + [CmdletHelp("Restores one deleted Microsoft 365 Group", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/directory-deleteditems-restore", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Restore-PnPDeletedUnifiedGroup -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", + Code = "PS:> Restore-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f", Remarks = "Restores a deleted Microsoft 365 Group based on its ID", SortOrder = 1)] [CmdletExample( - Code = @"PS:> $group = Get-PnPDeletedUnifiedGroup -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f -PS:> Restore-PnPDeletedUnifiedGroup -Identity $group", + Code = @"PS:> $group = Get-PnPDeletedMicrosoft365Group -Identity 38b32e13-e900-4d95-b860-fb52bc07ca7f +PS:> Restore-PnPDeletedMicrosoft365Group -Identity $group", Remarks = "Restores the provided deleted Microsoft 365 Group", SortOrder = 2)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/directory-deleteditems-restore")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class RestoreDeletedUnifiedGroup : PnPGraphCmdlet + public class RestoreDeletedMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the deleted Microsoft 365 Group")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/SetUnifiedGroup.cs b/Commands/Graph/SetMicrosoft365Group.cs similarity index 83% rename from Commands/Graph/SetUnifiedGroup.cs rename to Commands/Graph/SetMicrosoft365Group.cs index 16d894a18..f5885661b 100644 --- a/Commands/Graph/SetUnifiedGroup.cs +++ b/Commands/Graph/SetMicrosoft365Group.cs @@ -10,36 +10,37 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Set, "PnPUnifiedGroup")] - [CmdletHelp("Sets Microsoft 365 Group (aka Unified Group) properties", + [Cmdlet(VerbsCommon.Set, "PnPMicrosoft365Group")] + [Alias("Set-PnPUnifiedGroup")] + [CmdletHelp("Sets Microsoft 365 Group properties", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-update", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -DisplayName ""My Displayname""", + Code = @"PS:> Set-PnPMicrosoft365Group -Identity $group -DisplayName ""My Displayname""", Remarks = "Sets the display name of the group where $group is a Group entity", SortOrder = 1)] [CmdletExample( - Code = @"PS:> Set-PnPUnifiedGroup -Identity $groupId -Descriptions ""My Description"" -DisplayName ""My DisplayName""", + Code = @"PS:> Set-PnPMicrosoft365Group -Identity $groupId -Descriptions ""My Description"" -DisplayName ""My DisplayName""", Remarks = "Sets the display name and description of a group based upon its ID", SortOrder = 2)] [CmdletExample( - Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -GroupLogoPath "".\MyLogo.png""", + Code = @"PS:> Set-PnPMicrosoft365Group -Identity $group -GroupLogoPath "".\MyLogo.png""", Remarks = "Sets a specific Microsoft 365 Group logo", SortOrder = 3)] [CmdletExample( - Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -IsPrivate:$false", + Code = @"PS:> Set-PnPMicrosoft365Group -Identity $group -IsPrivate:$false", Remarks = "Sets a group to be Public if previously Private", SortOrder = 4)] [CmdletExample( - Code = @"PS:> Set-PnPUnifiedGroup -Identity $group -Owners demo@contoso.com", + Code = @"PS:> Set-PnPMicrosoft365Group -Identity $group -Owners demo@contoso.com", Remarks = "Sets demo@contoso.com as owner of the group", SortOrder = 5)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-update")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class SetUnifiedGroup : PnPGraphCmdlet + public class SetMicrosoft365Group : PnPGraphCmdlet { [Parameter(Mandatory = true, HelpMessage = "The Identity of the Microsoft 365 Group", ValueFromPipeline = true)] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "The DisplayName of the group to set")] public string DisplayName; diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 9ab5f1656..5a7fba9bd 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -668,14 +668,14 @@ - + - + - + - + @@ -836,19 +836,19 @@ - - + + - + - - + + Code @@ -861,7 +861,7 @@ - + @@ -889,7 +889,7 @@ - + diff --git a/Tests/GraphTests.cs b/Tests/GraphTests.cs index aae6275ed..3ccb6e23c 100644 --- a/Tests/GraphTests.cs +++ b/Tests/GraphTests.cs @@ -16,14 +16,14 @@ public void Initialize() { var random = new Random(); - var group = scope.ExecuteCommand("New-PnPUnifiedGroup", - new CommandParameter("DisplayName", "PnPDeletedUnifiedGroup test"), - new CommandParameter("Description", "PnPDeletedUnifiedGroup test"), + var group = scope.ExecuteCommand("New-PnPMicrosoft365Group", + new CommandParameter("DisplayName", "PnPDeletedMicrosoft365Group test"), + new CommandParameter("Description", "PnPDeletedMicrosoft365Group test"), new CommandParameter("MailNickname", $"pnp-unit-test-{random.Next(1, 1000)}"), new CommandParameter("Force")); _groupId = group[0].Properties["GroupId"].Value.ToString(); - scope.ExecuteCommand("Remove-PnPUnifiedGroup", new CommandParameter("Identity", _groupId)); + scope.ExecuteCommand("Remove-PnPMicrosoft365Group", new CommandParameter("Identity", _groupId)); } } @@ -34,7 +34,7 @@ public void Cleanup() { try { - scope.ExecuteCommand("Remove-PnPUnifiedGroup", new CommandParameter("Identity", _groupId)); + scope.ExecuteCommand("Remove-PnPMicrosoft365Group", new CommandParameter("Identity", _groupId)); } catch (Exception) { @@ -42,7 +42,7 @@ public void Cleanup() } try { - scope.ExecuteCommand("Remove-PnPDeletedUnifiedGroup", new CommandParameter("Identity", _groupId)); + scope.ExecuteCommand("Remove-PnPDeletedMicrosoft365Group", new CommandParameter("Identity", _groupId)); } catch (Exception) { @@ -52,49 +52,49 @@ public void Cleanup() } [TestMethod] - public void GetDeletedUnifiedGroups() + public void GetDeletedMicrosoft365Groups() { using (var scope = new PSTestScope()) { - var results = scope.ExecuteCommand("Get-PnPDeletedUnifiedGroup"); + var results = scope.ExecuteCommand("Get-PnPDeletedMicrosoft365Group"); Assert.IsTrue(results.Count > 0); } } [TestMethod] - public void GetDeletedUnifiedGroup() + public void GetDeletedMicrosoft365Group() { using (var scope = new PSTestScope()) { - var results = scope.ExecuteCommand("Get-PnPDeletedUnifiedGroup", new CommandParameter("Identity", _groupId)); + var results = scope.ExecuteCommand("Get-PnPDeletedMicrosoft365Group", new CommandParameter("Identity", _groupId)); Assert.IsTrue(results != null && results[0].Properties["GroupId"].Value.ToString() == _groupId); } } [TestMethod] - public void RestoreDeletedUnifiedGroup() + public void RestoreDeletedMicrosoft365Group() { using (var scope = new PSTestScope()) { - scope.ExecuteCommand("Restore-PnPDeletedUnifiedGroup", new CommandParameter("Identity", _groupId)); - var results = scope.ExecuteCommand("Get-PnPUnifiedGroup", new CommandParameter("Identity", _groupId)); + scope.ExecuteCommand("Restore-PnPDeletedMicrosoft365Group", new CommandParameter("Identity", _groupId)); + var results = scope.ExecuteCommand("Get-PnPMicrosoft365Group", new CommandParameter("Identity", _groupId)); Assert.IsTrue(results != null && results[0].Properties["GroupId"].Value.ToString() == _groupId); } } [TestMethod] - public void RemoveDeletedUnifiedGroup() + public void RemoveDeletedMicrosoft365Group() { using (var scope = new PSTestScope()) { - scope.ExecuteCommand("Remove-PnPDeletedUnifiedGroup", new CommandParameter("Identity", _groupId)); + scope.ExecuteCommand("Remove-PnPDeletedMicrosoft365Group", new CommandParameter("Identity", _groupId)); // The group should no longer be found in deleted groups try { - var results = scope.ExecuteCommand("Get-PnPDeletedUnifiedGroup", new CommandParameter("Identity", _groupId)); + var results = scope.ExecuteCommand("Get-PnPDeletedMicrosoft365Group", new CommandParameter("Identity", _groupId)); Assert.IsFalse(results != null); } catch (Exception) From f7c71165b20112078f0fa8acd7b4393566e88fb3 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 30 Jun 2020 11:59:05 +0200 Subject: [PATCH 091/130] Added changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28260ca83..504bfcd00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) - Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) +- All UnifiedGroup cmdlets have been renamed to Microsoft365Group. I.e. `New-PnPUnifiedGroup` -> `New-Microsoft365Group`. An alias has been added to provide for backwards compatibility [PR #2771](https://github.com/pnp/PnP-PowerShell/pull/2771) ### Contributors - Erwin van Hunen [erwinvanhunen] From 9e6251c909834194c6ce662bf98a43e2af51d951 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Tue, 30 Jun 2020 11:59:28 +0200 Subject: [PATCH 092/130] Typo fix --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 504bfcd00..7b7afaed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) - Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) -- All UnifiedGroup cmdlets have been renamed to Microsoft365Group. I.e. `New-PnPUnifiedGroup` -> `New-Microsoft365Group`. An alias has been added to provide for backwards compatibility [PR #2771](https://github.com/pnp/PnP-PowerShell/pull/2771) +- All UnifiedGroup cmdlets have been renamed to Microsoft365Group. I.e. `New-PnPUnifiedGroup` -> `New-PnPMicrosoft365Group`. An alias has been added to provide for backwards compatibility [PR #2771](https://github.com/pnp/PnP-PowerShell/pull/2771) ### Contributors - Erwin van Hunen [erwinvanhunen] From 1600951dc25fae4dc8a2c9e9fc64ada3b678ebdb Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Jun 2020 13:09:53 +0200 Subject: [PATCH 093/130] Refactored check for permissions --- Commands/Base/PnPConnection.cs | 102 +++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index 164d4f085..5b0399e74 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -149,51 +149,12 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles if (token.ExpiresOn > DateTime.Now) { - // check token type if needed - if (tokenType != TokenType.All && token.TokenType != tokenType) - { - throw new PSSecurityException($"Access to {tokenAudience} failed because the API requires a {tokenType} token while you currently use a {token.TokenType} token."); - } - var andRolesMatched = false; - if (andRoles != null && andRoles.Length != 0) - { - // we have explicitely required roles - andRolesMatched = andRoles.All(r => token.Roles.Contains(r)); - } - else - { - andRolesMatched = true; - } - - var orRolesMatched = false; - if (orRoles != null && orRoles.Length != 0) - { - orRolesMatched = orRoles.Any(r => token.Roles.Contains(r)); - } - else - { - orRolesMatched = true; - } - - if (orRolesMatched && andRolesMatched) + var validationResults = ValidateTokenForPermissions(token, tokenAudience, orRoles, andRoles, tokenType); + if (validationResults.valid) { return token; } - - if (orRoles != null || andRoles != null) - { - var message = string.Empty; - // Requested role was not part of the access token, throw an exception explaining which application registration is missing which role - if (!orRolesMatched) - { - message += "for one of the following roles: " + string.Join(", ", orRoles); - } - if (!andRolesMatched) - { - message += (message != string.Empty ? ", and " : ", ") + "for all of the following roles: " + string.Join(", ", andRoles); - } - throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {message}"); - } + throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {validationResults.message}"); } // Token was no longer valid, proceed with trying to create a new token @@ -237,6 +198,11 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles if (token != null) { + var validationResults = ValidateTokenForPermissions(token, tokenAudience, orRoles, andRoles, tokenType); + if (!validationResults.valid) + { + throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {validationResults.message}"); + } // Managed to create a token for the requested audience, add it to our collection with tokens AccessTokens[tokenAudience] = token; return token; @@ -264,6 +230,58 @@ internal void ClearTokens() AccessTokens.Clear(); } + private (bool valid, string message) ValidateTokenForPermissions(GenericToken token, TokenAudience tokenAudience, string[] orRoles = null, string[] andRoles = null, TokenType tokenType = TokenType.All) + { + bool valid = false; + var message = string.Empty; + if (tokenType != TokenType.All && token.TokenType != tokenType) + { + throw new PSSecurityException($"Access to {tokenAudience} failed because the API requires {(tokenType == TokenType.Application ? "an" : "a")} {tokenType} token while you currently use {(token.TokenType == TokenType.Application ? "an" : "a")} {token.TokenType} token."); + } + var andRolesMatched = false; + if (andRoles != null && andRoles.Length != 0) + { + // we have explicitely required roles + andRolesMatched = andRoles.All(r => token.Roles.Contains(r)); + } + else + { + andRolesMatched = true; + } + + var orRolesMatched = false; + if (orRoles != null && orRoles.Length != 0) + { + orRolesMatched = orRoles.Any(r => token.Roles.Contains(r)); + } + else + { + orRolesMatched = true; + } + + if (orRolesMatched && andRolesMatched) + { + valid = true; + } + + if (orRoles != null || andRoles != null) + { + if (!valid) + { // Requested role was not part of the access token, throw an exception explaining which application registration is missing which role + if (!orRolesMatched) + { + message += "for one of the following roles: " + string.Join(", ", orRoles); + } + if (!andRolesMatched) + { + message += (message != string.Empty ? ", and " : ", ") + "for all of the following roles: " + string.Join(", ", andRoles); + } + throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {message}"); + } + } + return (valid, message); + } + #endregion #region Constructors From 2fa14c5dadb4a3385d0a8b3e650c5f91c0c40096 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Jun 2020 13:55:53 +0200 Subject: [PATCH 094/130] updated documentation --- Commands/Teams/RemoveTeamsTab.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs index 51fb8065c..d8ca55435 100644 --- a/Commands/Teams/RemoveTeamsTab.cs +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -13,12 +13,12 @@ namespace SharePointPnP.PowerShell.Commands.Graph Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Remove-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -TabId ", - Remarks = "Retrieves the tabs for the Microsoft Teams instances", + Code = "PS:> Remove-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity Wiki", + Remarks = "Removes the tab with the display name 'Wiki' from the channel", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -DisplayName \"Wiki\"", - Remarks = "Retrieves a tab with the display name 'Wiki' from the specified team and channel", + Code = "PS:> Remove-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity fcef815d-2e8e-47a5-b06b-9bebba5c7852", + Remarks = "Removes a tab with the specified id from the channel", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class RemoveTeamsTab : PnPGraphCmdlet From c1b1503440d9b22ac44b1d6827b87eb94c71d64f Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 30 Jun 2020 22:40:02 +0200 Subject: [PATCH 095/130] Added New-PnPTeamsTeam cmdlet --- CHANGELOG.md | 2 +- Commands/Base/PipeBinds/TeamsTeamPipeBind.cs | 36 +++++ Commands/Model/Teams/Group.cs | 20 ++- Commands/Model/Teams/Team.cs | 5 +- Commands/Model/Teams/TeamDiscoverySettings.cs | 2 +- Commands/Model/Teams/TeamFunSettings.cs | 30 +--- Commands/Model/Teams/TeamGuestSettings.cs | 4 +- Commands/Model/Teams/TeamMemberSettings.cs | 12 +- Commands/Model/Teams/TeamMessagingSettings.cs | 10 +- Commands/Model/Teams/TeamSettings.cs | 138 +++++++++++++++++ Commands/Model/Teams/User.cs | 11 ++ .../SharePointPnP.PowerShell.Commands.csproj | 4 + Commands/Teams/GetTeamsTeam.cs | 5 +- Commands/Teams/NewTeamsTeam.cs | 143 ++++++++++++++++++ Commands/Teams/RemoveTeamsTeam.cs | 41 ++++- Commands/Utilities/REST/GraphHelper.cs | 16 ++ Commands/Utilities/TeamsUtility.cs | 119 +++++++++++++-- 17 files changed, 537 insertions(+), 61 deletions(-) create mode 100644 Commands/Base/PipeBinds/TeamsTeamPipeBind.cs create mode 100644 Commands/Model/Teams/TeamSettings.cs create mode 100644 Commands/Model/Teams/User.cs create mode 100644 Commands/Teams/NewTeamsTeam.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 28260ca83..9145f235b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) -- Added Add-PnPTeamsChannel, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsTab, Get-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam cmdlets +- Added New-PnPTeamsTeam, Add-PnPTeamsChannel, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsTab, Get-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam cmdlets ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) diff --git a/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs b/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs new file mode 100644 index 000000000..6ed94da40 --- /dev/null +++ b/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs @@ -0,0 +1,36 @@ +using System; + +namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds +{ + public sealed class TeamsTeamPipeBind + { + private readonly Guid _id; + private readonly string _stringValue; + + public TeamsTeamPipeBind() + + { + _id = Guid.Empty; + } + + public TeamsTeamPipeBind(string input) + { + if (string.IsNullOrEmpty(input)) + { + throw new ArgumentException(nameof(input)); + } + if (Guid.TryParse(input, out Guid tabId)) + { + _id = tabId; + } + else + { + _stringValue = input; + } + } + + public Guid Id => _id; + + public string StringValue => _stringValue; + } +} diff --git a/Commands/Model/Teams/Group.cs b/Commands/Model/Teams/Group.cs index def19abfa..6c1da8b42 100644 --- a/Commands/Model/Teams/Group.cs +++ b/Commands/Model/Teams/Group.cs @@ -1,4 +1,6 @@ -using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -12,6 +14,22 @@ public class Group public string DisplayName { get; set; } public string MailNickname { get; set; } public string Description { get; set; } + + [Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))] public GroupVisibility Visibility { get; set; } + + [JsonProperty("owners@odata.bind")] + public List Owners { get; set; } + + [JsonProperty("members@odata.bind")] + public List Members { get; set; } + + public string Classification { get; set; } + + public bool MailEnabled { get; set; } + + public List GroupTypes { get; set; } + + public bool? SecurityEnabled { get; set; } } } diff --git a/Commands/Model/Teams/Team.cs b/Commands/Model/Teams/Team.cs index 40a2e103f..fe01a5d3a 100644 --- a/Commands/Model/Teams/Team.cs +++ b/Commands/Model/Teams/Team.cs @@ -16,6 +16,8 @@ public class Team { #region Public Members public string DisplayName { get; set; } + + public string Classification { get; set; } /// /// The Fun Settings for the Team /// @@ -71,7 +73,7 @@ public class Team /// /// Declares whether the Team is archived or not /// - public bool Archived { get; set; } + public bool? IsArchived { get; set; } /// /// Declares the nickname for the Team, optional attribute @@ -85,7 +87,6 @@ public class Team public GroupVisibility? Visibility { get; set; } - public bool IsArchived { get; set; } #endregion } diff --git a/Commands/Model/Teams/TeamDiscoverySettings.cs b/Commands/Model/Teams/TeamDiscoverySettings.cs index b5f9823e8..0d530a625 100644 --- a/Commands/Model/Teams/TeamDiscoverySettings.cs +++ b/Commands/Model/Teams/TeamDiscoverySettings.cs @@ -13,7 +13,7 @@ public partial class TeamDiscoverySettings /// /// Defines whether the Team is visible via search and suggestions from the Teams client /// - public bool ShowInTeamsSearchAndSuggestions { get; set; } + public bool? ShowInTeamsSearchAndSuggestions { get; set; } #endregion } diff --git a/Commands/Model/Teams/TeamFunSettings.cs b/Commands/Model/Teams/TeamFunSettings.cs index 2b58379f6..4a5f39467 100644 --- a/Commands/Model/Teams/TeamFunSettings.cs +++ b/Commands/Model/Teams/TeamFunSettings.cs @@ -19,32 +19,22 @@ public partial class TeamFunSettings /// /// Defines whether Giphys are consented or not /// - public bool AllowGiphy { get; set; } + public bool? AllowGiphy { get; set; } /// /// Defines the Content Rating for Giphys /// - public string GiphyContentRating - { - get - { - return (_giphyContentRating); - } - set - { - _giphyContentRating = value?.ToLower(); - } - } + public TeamGiphyContentRating GiphyContentRating { get; set; } /// /// Defines whether Stickers and Memes are consented or not /// - public bool AllowStickersAndMemes { get; set; } + public bool? AllowStickersAndMemes { get; set; } /// /// Defines whether Custom Memes are consented or not /// - public bool AllowCustomMemes { get; set; } + public bool? AllowCustomMemes { get; set; } #endregion } @@ -52,15 +42,9 @@ public string GiphyContentRating /// /// Defines the Content Rating for Giphys /// - public static class TeamGiphyContentRating + public enum TeamGiphyContentRating { - /// - /// Moderate Content Rating - /// - public const string Moderate = "moderate"; - /// - /// Strict Content Rating - /// - public const string Strict = "strict"; + moderate, + strict } } diff --git a/Commands/Model/Teams/TeamGuestSettings.cs b/Commands/Model/Teams/TeamGuestSettings.cs index 9e7c6f9fa..02d94bc75 100644 --- a/Commands/Model/Teams/TeamGuestSettings.cs +++ b/Commands/Model/Teams/TeamGuestSettings.cs @@ -13,12 +13,12 @@ public partial class TeamGuestSettings /// /// Defines whether Guests are allowed to create Channels or not /// - public bool AllowCreateUpdateChannels { get; set; } + public bool? AllowCreateUpdateChannels { get; set; } /// /// Defines whether Guests are allowed to delete Channels or not /// - public bool AllowDeleteChannels { get; set; } + public bool? AllowDeleteChannels { get; set; } #endregion } diff --git a/Commands/Model/Teams/TeamMemberSettings.cs b/Commands/Model/Teams/TeamMemberSettings.cs index 2f2141a1b..066266ab7 100644 --- a/Commands/Model/Teams/TeamMemberSettings.cs +++ b/Commands/Model/Teams/TeamMemberSettings.cs @@ -14,32 +14,32 @@ public partial class TeamMemberSettings /// /// Defines if members can add and update channels /// - public bool AllowCreateUpdateChannels { get; set; } + public bool? AllowCreateUpdateChannels { get; set; } /// /// Defines if members can delete channels /// - public bool AllowDeleteChannels { get; set; } + public bool? AllowDeleteChannels { get; set; } /// /// Defines if members can add and remove apps /// - public bool AllowAddRemoveApps { get; set; } + public bool? AllowAddRemoveApps { get; set; } /// /// Defines if members can add, update, and remove tabs /// - public bool AllowCreateUpdateRemoveTabs { get; set; } + public bool? AllowCreateUpdateRemoveTabs { get; set; } /// /// Defines if members can add, update, and remove connectors /// - public bool AllowCreateUpdateRemoveConnectors { get; set; } + public bool? AllowCreateUpdateRemoveConnectors { get; set; } /// /// Defines if members can create private channels /// - public bool AllowCreatePrivateChannels { get; set; } + public bool? AllowCreatePrivateChannels { get; set; } #endregion } diff --git a/Commands/Model/Teams/TeamMessagingSettings.cs b/Commands/Model/Teams/TeamMessagingSettings.cs index c1048205a..0037e3bb7 100644 --- a/Commands/Model/Teams/TeamMessagingSettings.cs +++ b/Commands/Model/Teams/TeamMessagingSettings.cs @@ -13,27 +13,27 @@ public partial class TeamMessagingSettings /// /// Defines if users can edit their messages /// - public bool AllowUserEditMessages { get; set; } + public bool? AllowUserEditMessages { get; set; } /// /// Defines if users can delete their messages /// - public bool AllowUserDeleteMessages { get; set; } + public bool? AllowUserDeleteMessages { get; set; } /// /// Defines if owners can delete any message /// - public bool AllowOwnerDeleteMessages { get; set; } + public bool? AllowOwnerDeleteMessages { get; set; } /// /// Defines if @team mentions are allowed /// - public bool AllowTeamMentions { get; set; } + public bool? AllowTeamMentions { get; set; } /// /// Defines if @channel mentions are allowed /// - public bool AllowChannelMentions { get; set; } + public bool? AllowChannelMentions { get; set; } #endregion diff --git a/Commands/Model/Teams/TeamSettings.cs b/Commands/Model/Teams/TeamSettings.cs new file mode 100644 index 000000000..8fafc631e --- /dev/null +++ b/Commands/Model/Teams/TeamSettings.cs @@ -0,0 +1,138 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Text; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public class TeamCreationInformation + { + public string GroupId { get; set; } + + public string DisplayName { get; set; } + + public string Description { get; set; } + + [JsonConverter(typeof(StringEnumConverter))] + public GroupVisibility Visibility { get; set; } + + public string Classification { get; set; } + + public bool? Archived { get; set; } + + public bool? AllowGiphy { get; set; } + + public TeamGiphyContentRating GiphyContentRating { get; set; } + + public bool? AllowStickersAndMemes { get; set; } + + public bool? AllowCustomMemes { get; set; } + + public bool? AllowGuestCreateUpdateChannels { get; set; } + + public bool? AllowGuestDeleteChannels { get; set; } + + public bool? AllowCreateUpdateChannels { get; set; } + + public bool? AllowDeleteChannels { get; set; } + + public bool? AllowAddRemoveApps { get; set; } + + public bool? AllowCreateUpdateRemoveTabs { get; set; } + + public bool? AllowCreateUpdateRemoveConnectors { get; set; } + + public bool? AllowUserEditMessages { get; set; } + + public bool? AllowUserDeleteMessages { get; set; } + + public bool? AllowOwnerDeleteMessages { get; set; } + + public bool? AllowTeamMentions { get; set; } + + public bool? AllowChannelMentions { get; set; } + + public bool? ShowInTeamsSearchAndSuggestions { get; set; } + + public TeamCreationInformation() + { + } + + public TeamCreationInformation(Team team) + { + GroupId = team.GroupId; + DisplayName = team.DisplayName; + Description = team.Description; + Visibility = team.Visibility.Value; + Archived = team.IsArchived; + Classification = team.Classification; + AllowGiphy = team.FunSettings.AllowGiphy; + GiphyContentRating = team.FunSettings.GiphyContentRating; + AllowStickersAndMemes = team.FunSettings.AllowStickersAndMemes; + AllowCustomMemes = team.FunSettings.AllowCustomMemes; + AllowGuestCreateUpdateChannels = team.GuestSettings.AllowCreateUpdateChannels; + AllowGuestDeleteChannels = team.GuestSettings.AllowDeleteChannels; + AllowCreateUpdateChannels = team.MemberSettings.AllowCreateUpdateChannels; + AllowDeleteChannels = team.MemberSettings.AllowDeleteChannels; + AllowAddRemoveApps = team.MemberSettings.AllowAddRemoveApps; + AllowCreateUpdateRemoveTabs = team.MemberSettings.AllowCreateUpdateRemoveTabs; + AllowCreateUpdateRemoveConnectors = team.MemberSettings.AllowCreateUpdateRemoveConnectors; + AllowUserEditMessages = team.MessagingSettings.AllowUserEditMessages; + AllowUserDeleteMessages = team.MessagingSettings.AllowUserDeleteMessages; + AllowOwnerDeleteMessages = team.MessagingSettings.AllowOwnerDeleteMessages; + AllowTeamMentions = team.MessagingSettings.AllowTeamMentions; + AllowChannelMentions = team.MessagingSettings.AllowChannelMentions; + ShowInTeamsSearchAndSuggestions = team.DiscoverySettings.ShowInTeamsSearchAndSuggestions; + } + + public Team ToTeam() + { + return new Team + { + FunSettings = new TeamFunSettings + { + AllowGiphy = AllowGiphy, + AllowCustomMemes = AllowCustomMemes, + GiphyContentRating = GiphyContentRating, + AllowStickersAndMemes = AllowStickersAndMemes + }, + GuestSettings = new TeamGuestSettings + { + AllowCreateUpdateChannels = AllowGuestCreateUpdateChannels, + AllowDeleteChannels = AllowGuestDeleteChannels + }, + MemberSettings = new TeamMemberSettings + { + AllowCreateUpdateChannels = AllowCreateUpdateChannels, + AllowDeleteChannels = AllowDeleteChannels, + AllowAddRemoveApps = AllowAddRemoveApps, + AllowCreateUpdateRemoveTabs = AllowCreateUpdateRemoveTabs, + AllowCreateUpdateRemoveConnectors = AllowCreateUpdateRemoveConnectors + }, + MessagingSettings = new TeamMessagingSettings + { + AllowUserEditMessages = AllowUserEditMessages, + AllowUserDeleteMessages = AllowUserDeleteMessages, + AllowOwnerDeleteMessages = AllowOwnerDeleteMessages, + AllowTeamMentions = AllowTeamMentions, + AllowChannelMentions = AllowChannelMentions + }, + DiscoverySettings = new TeamDiscoverySettings + { + ShowInTeamsSearchAndSuggestions = ShowInTeamsSearchAndSuggestions + } + }; + } + + public string ToJsonString() + { + return JsonConvert.SerializeObject(this, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore + }); + } + } +} diff --git a/Commands/Model/Teams/User.cs b/Commands/Model/Teams/User.cs new file mode 100644 index 000000000..8b1560424 --- /dev/null +++ b/Commands/Model/Teams/User.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public class User + { + public string Id { get; set; } + } +} diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 9ab5f1656..16dbe09db 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -624,6 +624,7 @@ + @@ -720,9 +721,11 @@ + + @@ -919,6 +922,7 @@ + diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs index 261ad0262..a5a2bfdf4 100644 --- a/Commands/Teams/GetTeamsTeam.cs +++ b/Commands/Teams/GetTeamsTeam.cs @@ -3,6 +3,7 @@ using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; +using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -43,7 +44,9 @@ protected override void ExecuteCmdlet() } else if (ParameterSpecified(nameof(Visibility))) { - WriteObject(TeamsUtility.GetTeams(AccessToken, HttpClient, Visibility), true); + var teams = TeamsUtility.GetTeams(AccessToken, HttpClient); + + WriteObject(teams.Where(t => t.Visibility == Visibility), true); } else { diff --git a/Commands/Teams/NewTeamsTeam.cs b/Commands/Teams/NewTeamsTeam.cs new file mode 100644 index 000000000..945d9badc --- /dev/null +++ b/Commands/Teams/NewTeamsTeam.cs @@ -0,0 +1,143 @@ +using OfficeDevPnP.Core.Framework.Provisioning.Model.Teams; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Management.Automation; +using System.Reflection; +using System.Security.Cryptography; +using System.Text.RegularExpressions; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.New, "PnPTeamsTeam")] + [CmdletHelp("Creates a new Team in Microsoft Teams. The cmdlet will create a Microsoft 365 group and then add a team to the group.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam", + Remarks = "Retrieves all the Microsoft Teams instances", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", + Remarks = "Retrieves a specific Microsoft Teams instance", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam -Visibility Public", + Remarks = "Retrieves all Microsoft Teams instances which are public visible", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class NewTeamsTeam : PnPGraphCmdlet + { + private const string ParameterSet_EXISTINGGROUP = "For an existing group"; + private const string ParameterSet_NEWGROUP = "For a new group"; + + [Parameter(Mandatory = true, ParameterSetName =ParameterSet_EXISTINGGROUP, HelpMessage = "Specify a GroupId to convert to a Team. If specified, you cannot provide the other values that are already specified by the existing group, namely: Visibility, Alias, Description, or DisplayName.")] + public string GroupId; + + [Parameter(Mandatory = true, ParameterSetName = ParameterSet_NEWGROUP, HelpMessage = "Team display name. Characters Limit - 256.")] + [ValidateLength(1, 256)] + public string DisplayName; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_NEWGROUP, HelpMessage = "The MailNickName parameter specifies the alias for the associated Microsoft 365 Group. This value will be used for the mail enabled object and will be used as PrimarySmtpAddress for this Microsoft 365 Group.The value of the MailNickName parameter has to be unique across your tenant.")] + public string MailNickName; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_NEWGROUP, HelpMessage = "Team description. Characters Limit - 1024.")] + [ValidateLength(0, 1024)] + public string Description; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "An admin who is allowed to create on behalf of another user should use this flag to specify the desired owner of the group.This user will be added as both a member and an owner of the group. If not specified, the user who creates the team will be added as both a member and an owner.")] + public string Owner; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Boolean value that determines whether or not members (not only owners) are allowed to add apps to the team.")] + public bool? AllowAddRemoveApps; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Boolean value that determines whether or not channels in the team can be @ mentioned so that all users who follow the channel are notified.")] + public bool? AllowChannelMentions; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not just owners) are allowed to create channels.")] + public bool? AllowCreateUpdateChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not only owners) can manage connectors in the team.")] + public bool? AllowCreateUpdateRemoveConnectors; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not only owners) can manage tabs in channels.") ] + public bool? AllowCreateUpdateRemoveTabs; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members can use the custom memes functionality in teams.")] + public bool? AllowCustomMemes; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not only owners) can delete channels in the team.")] + public bool? AllowDeleteChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not giphy can be used in the team.")] + public bool? AllowGiphy; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not guests can create channels in the team.")] + public bool? AllowGuestCreateUpdateChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not guests can delete in the team.")] + public bool? AllowGuestDeleteChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not owners can delete messages that they or other members of the team have posted.")] + public bool? AllowOwnerDeleteMessages; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether stickers and memes usage is allowed in the team.")] + public bool? AllowStickersAndMemes; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether the entire team can be @ mentioned (which means that all users will be notified)")] + public bool? AllowTeamMentions; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members can delete messages that they have posted.")] + public bool? AllowUserDeleteMessages; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not users can edit messages that they have posted.")] + public bool? AllowUserEditMessages; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines the level of sensitivity of giphy usage that is allowed in the team. Accepted values are \"Strict\" or \"Moderate\"")] + public Model.Teams.TeamGiphyContentRating GiphyContentRating; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_NEWGROUP, HelpMessage = "Set to Public to allow all users in your organization to join the group by default. Set to Private to require that an owner approve the join request.")] + public TeamVisibility Visibility; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not private teams should be searchable from Teams clients for users who do not belong to that team. Set to $false to make those teams not discoverable from Teams clients.")] + public bool? ShowInTeamsSearchAndSuggestions; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] + public string Classification; + + + protected override void ExecuteCmdlet() + { + var teamCI = new TeamCreationInformation() + { + AllowAddRemoveApps = AllowAddRemoveApps, + AllowChannelMentions = AllowChannelMentions, + AllowCreateUpdateChannels = AllowCreateUpdateChannels, + AllowCreateUpdateRemoveConnectors = AllowCreateUpdateRemoveConnectors, + AllowCreateUpdateRemoveTabs = AllowCreateUpdateRemoveTabs, + AllowCustomMemes = AllowCustomMemes, + AllowDeleteChannels = AllowDeleteChannels, + AllowGiphy = AllowGiphy, + AllowGuestCreateUpdateChannels = AllowGuestCreateUpdateChannels, + AllowGuestDeleteChannels = AllowGuestDeleteChannels, + AllowOwnerDeleteMessages = AllowOwnerDeleteMessages, + AllowStickersAndMemes = AllowStickersAndMemes, + AllowTeamMentions = AllowTeamMentions, + AllowUserDeleteMessages = AllowUserDeleteMessages, + AllowUserEditMessages = AllowUserEditMessages, + Classification = Classification, + Description = Description, + DisplayName = DisplayName, + GiphyContentRating = GiphyContentRating, + GroupId = GroupId, + ShowInTeamsSearchAndSuggestions = ShowInTeamsSearchAndSuggestions, + Visibility = (GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()), + }; + WriteObject(TeamsUtility.NewTeam(AccessToken, HttpClient, GroupId, DisplayName, Description, Classification, MailNickName, Owner, (GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()), teamCI)); + } + } +} diff --git a/Commands/Teams/RemoveTeamsTeam.cs b/Commands/Teams/RemoveTeamsTeam.cs index f2ca5377d..15e727cc1 100644 --- a/Commands/Teams/RemoveTeamsTeam.cs +++ b/Commands/Teams/RemoveTeamsTeam.cs @@ -1,8 +1,10 @@ -using SharePointPnP.PowerShell.CmdletHelpAttributes; +using Microsoft.SharePoint.Client; +using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; using System; +using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -12,14 +14,18 @@ namespace SharePointPnP.PowerShell.Commands.Graph Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Remove-PnPTeamsTeam -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5", + Code = "PS:> Remove-PnPTeamsTeam -Identity 5beb63c5-0571-499e-94d5-3279fdd9b6b5", Remarks = "Removes the specified Team", SortOrder = 1)] + [CmdletExample( + Code = "PS:> Remove-PnPTeamsTeam -Identity testteam", + Remarks = "Removes the specified Team. If there are multiple teams with the same display name it will not proceed deleting the team.", + SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class RemoveTeamsTeam : PnPGraphCmdlet { [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] - public GuidPipeBind GroupId; + public TeamsTeamPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] public SwitchParameter Force; @@ -28,9 +34,34 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the team will remove all messages in all channels in the team.", Properties.Resources.Confirm)) { - if (!TeamsUtility.DeleteTeam(AccessToken, HttpClient, GroupId.Id.ToString())) + var groupId = string.Empty; + if (Identity.Id != Guid.Empty) + { + groupId = Identity.Id.ToString(); + } + else + { + var groups = TeamsUtility.GetGroupsWithTeam(HttpClient, AccessToken); + var groupCollection = groups.Where(t => t.DisplayName.Equals(Identity.StringValue, StringComparison.OrdinalIgnoreCase)); + if (groupCollection.Any() && groupCollection.Count() == 1) + { + groupId = groupCollection.First().Id; + } + else + { + throw new PSArgumentException("Found multiple Teams with the same display name. Specify the group id to remove the correct Teams instance, e.g. Remove-PnPTeamsTeam -Identity . Use Get-PnPTeamsTeam to list all teams."); + } + } + if (groupId != string.Empty) + { + if (!TeamsUtility.DeleteTeam(AccessToken, HttpClient, groupId.ToString())) + { + WriteError(new ErrorRecord(new Exception($"Team remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + } + } + else { - WriteError(new ErrorRecord(new Exception($"Team remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + throw new PSArgumentException("Cannot find team"); } } } diff --git a/Commands/Utilities/REST/GraphHelper.cs b/Commands/Utilities/REST/GraphHelper.cs index aea5f814f..cdc1ebeda 100644 --- a/Commands/Utilities/REST/GraphHelper.cs +++ b/Commands/Utilities/REST/GraphHelper.cs @@ -96,6 +96,22 @@ public static async Task PostAsync(HttpClient httpClient, string url, T co } } + public static async Task PutAsync(HttpClient httpClient, string url, T content, string accessToken) + { + var requestContent = new StringContent(JsonConvert.SerializeObject(content, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() })); + requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + var message = GetMessage(url, HttpMethod.Put, accessToken, requestContent); + var returnValue = await SendMessageAsync(httpClient, message); + if (!string.IsNullOrEmpty(returnValue)) + { + return JsonConvert.DeserializeObject(returnValue); + } + else + { + return default; + } + } + public static async Task DeleteAsync(HttpClient httpClient, string url, string accessToken) { var message = GetMessage(url, HttpMethod.Delete, accessToken); diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index f8c65207a..3fb89f251 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -1,8 +1,11 @@ -using SharePointPnP.PowerShell.Commands.Model.Teams; +using Microsoft.BusinessData.MetadataModel; +using Microsoft.IdentityModel.Tokens; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities.REST; using System; using System.Collections.Generic; using System.Linq; +using System.Management.Automation; using System.Net.Http; using System.Web; @@ -13,7 +16,7 @@ internal static class TeamsUtility private const int PageSize = 100; #region Team - private static List GetGroupsWithTeam(HttpClient httpClient, string accessToken, GroupVisibility visibility = GroupVisibility.NotSpecified) + public static List GetGroupsWithTeam(HttpClient httpClient, string accessToken) { List groups = new List(); string url = string.Empty; @@ -27,21 +30,14 @@ private static List GetGroupsWithTeam(HttpClient httpClient, string acces groups.AddRange(collection.Items); } } - if (visibility != GroupVisibility.NotSpecified) - { - return groups.Where(g => g.Visibility == visibility).ToList(); - } - else - { - return groups; - } + return groups; } - public static List GetTeams(string accessToken, HttpClient httpClient, GroupVisibility visibility = GroupVisibility.NotSpecified) + public static List GetTeams(string accessToken, HttpClient httpClient) { List teams = new List(); - var groups = GetGroupsWithTeam(httpClient, accessToken, visibility); + var groups = GetGroupsWithTeam(httpClient, accessToken); foreach (var group in groups) { Team team = ParseTeamJson(accessToken, httpClient, group.Id); @@ -135,6 +131,101 @@ private static Team ParseTeamJson(string accessToken, HttpClient httpClient, str return null; } } + + public static Team NewTeam(string accessToken, HttpClient httpClient, string groupId, string displayName, string description, string classification, string mailNickname, string owner, GroupVisibility visibility, TeamCreationInformation teamCI) + { + Group group = null; + Team returnTeam = null; + // Create group + if (string.IsNullOrEmpty(groupId)) + { + group = CreateGroup(accessToken, httpClient, displayName, description, classification, mailNickname, owner, visibility); + } + else + { + group = GraphHelper.GetAsync(httpClient, $"v1.0/groups/{groupId}", accessToken).GetAwaiter().GetResult(); + if (group == null) + { + throw new PSArgumentException($"Cannot find group with id {groupId}"); + } + teamCI.Visibility = group.Visibility; + teamCI.Description = group.Description; + } + if (group != null) + { + Team team = teamCI.ToTeam(); + var teamSettings = GraphHelper.PutAsync(httpClient, $"v1.0/groups/{group.Id}/team", team, accessToken).GetAwaiter().GetResult(); + if (teamSettings != null) + { + returnTeam = TeamsUtility.GetTeam(accessToken, httpClient, group.Id); + } + } + return returnTeam; + } + + private static Group CreateGroup(string accessToken, HttpClient httpClient, string displayName, string description, string classification, string mailNickname, string owner, GroupVisibility visibility) + { + Group group = new Group(); + // get the owner if no owner was specified + var ownerId = string.Empty; + if (string.IsNullOrEmpty(owner)) + { + var user = GraphHelper.GetAsync(httpClient, "v1.0/me?$select=Id", accessToken).GetAwaiter().GetResult(); + ownerId = user.Id; + } + else + { + var user = GraphHelper.GetAsync(httpClient, $"v1.0/users/{owner}?$select=Id", accessToken).GetAwaiter().GetResult(); + if (user != null) + { + ownerId = user.Id; + } + else + { + // find the user in the organization + var collection = GraphHelper.GetAsync>(httpClient, "v1.0/myorganization/users?$filter=mail eq '{owner}'&$select=Id", accessToken).GetAwaiter().GetResult(); + if (collection != null) + { + if (collection.Items.Any()) + { + ownerId = collection.Items.First().Id; + } + } + } + } + + group.DisplayName = displayName; + group.Description = description; + group.Classification = classification; + group.MailEnabled = true; + group.MailNickname = mailNickname ?? CreateAlias(httpClient, accessToken); + group.GroupTypes = new List() { "Unified" }; + group.SecurityEnabled = false; + group.Owners = new List() { $"https://graph.microsoft.com/v1.0/users/{ownerId}" }; + group.Members = new List() { $"https://graph.microsoft.com/v1.0/users/{ownerId}" }; + group.Visibility = visibility == GroupVisibility.NotSpecified ? GroupVisibility.Private : visibility; + + return GraphHelper.PostAsync(httpClient, "v1.0/groups", group, accessToken).GetAwaiter().GetResult(); + + } + + private static string CreateAlias(HttpClient httpClient, string accessToken) + { + var guid = Guid.NewGuid().ToString(); + var teamName = string.Empty; + // check if the group exists + do + { + var teamNameTemp = $"msteams_{guid.Substring(0, 8)}{guid.Substring(9, 4)}"; + var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') and (mailNickname eq '{teamNameTemp}')", accessToken).GetAwaiter().GetResult(); + if (collection != null) + { + if (!collection.Items.Any()) teamName = teamNameTemp; + } + + } while (teamName == string.Empty); + return teamName; + } #endregion #region Channel @@ -190,7 +281,7 @@ public static IEnumerable GetTabs(string accessToken, HttpClient httpCl public static bool DeleteTab(string accessToken, HttpClient httpClient, string groupId, string channelId, string tabId) { - return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); + return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); } #endregion @@ -199,7 +290,7 @@ public static bool DeleteTab(string accessToken, HttpClient httpClient, string g public static IEnumerable GetApps(string accessToken, HttpClient httpClient) { var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/appCatalogs/teamsApps", accessToken).GetAwaiter().GetResult(); - if(collection != null) + if (collection != null) { return collection.Items; } From b6d2a2e7ca8c18e92fd081e123bb0d209159b93a Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 2 Jul 2020 00:04:57 +0200 Subject: [PATCH 096/130] Added better error handling, use of the resource file for strings, optimization by not fetching the list id as that's done already by the PnP Core code and fixed the ValueFromPipeline not being specified and thus not working --- Commands/Properties/Resources.Designer.cs | 9 ++++++++ Commands/Properties/Resources.resx | 3 +++ Commands/Webhooks/GetWebhookSubscriptions.cs | 24 ++++++++++++++------ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Commands/Properties/Resources.Designer.cs b/Commands/Properties/Resources.Designer.cs index c6164ea12..d8cc54e27 100644 --- a/Commands/Properties/Resources.Designer.cs +++ b/Commands/Properties/Resources.Designer.cs @@ -726,5 +726,14 @@ internal static string Web0CreatedAt1 { return ResourceManager.GetString("Web0CreatedAt1", resourceCulture); } } + + /// + /// Looks up a localized string similar to This Cmdlet currently only supports List Webhooks. + /// + internal static string WebhooksOnlySupportsLists { + get { + return ResourceManager.GetString("WebhooksOnlySupportsLists", resourceCulture); + } + } } } diff --git a/Commands/Properties/Resources.resx b/Commands/Properties/Resources.resx index 198ae2253..534c7f84c 100644 --- a/Commands/Properties/Resources.resx +++ b/Commands/Properties/Resources.resx @@ -339,4 +339,7 @@ Parameter set {0} has not yet been implemented. Please create an issue for this on GitHub. + + This Cmdlet currently only supports List Webhooks + \ No newline at end of file diff --git a/Commands/Webhooks/GetWebhookSubscriptions.cs b/Commands/Webhooks/GetWebhookSubscriptions.cs index 8dd6d894d..b291e0981 100644 --- a/Commands/Webhooks/GetWebhookSubscriptions.cs +++ b/Commands/Webhooks/GetWebhookSubscriptions.cs @@ -4,8 +4,8 @@ using OfficeDevPnP.Core.Entities; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; -using System; using System.Management.Automation; +using Resources = SharePointPnP.PowerShell.Commands.Properties.Resources; namespace SharePointPnP.PowerShell.Commands.Webhooks { @@ -18,9 +18,13 @@ namespace SharePointPnP.PowerShell.Commands.Webhooks Code = "PS:> Get-PnPWebhookSubscriptions -List MyList", Remarks = "Gets all Webhook subscriptions of the list MyList", SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPList | Get-PnPWebhookSubscriptions", + Remarks = "Gets all Webhook subscriptions of the all the lists", + SortOrder = 2)] public class GetWebhookSubscriptions : PnPWebCmdlet { - [Parameter(Mandatory = false, HelpMessage = "The list object or name to get the Webhook subscriptions from")] + [Parameter(Mandatory = false, ValueFromPipeline = true, HelpMessage = "The list object or name to get the Webhook subscriptions from")] public ListPipeBind List; protected override void ExecuteCmdlet() @@ -28,23 +32,29 @@ protected override void ExecuteCmdlet() // NOTE: Currently only supports List Webhooks if (ParameterSpecified(nameof(List))) { + // Ensure we didn't get piped in a null, i.e. when running Get-PnPList -Identity "ThisListDoesNotExist" | Get-PnPWebhookSubscriptions + if(List == null) + { + throw new PSArgumentNullException(nameof(List)); + } + // Get the list from the currently selected web List list = List.GetList(SelectedWeb); if (list != null) { - // Ensure we have list Id (TODO Should be changed in the Core extension method) - list.EnsureProperty(l => l.Id); - // Get all the webhook subscriptions for the specified list WriteObject(list.GetWebhookSubscriptions()); } + else + { + throw new PSArgumentOutOfRangeException(nameof(List), List.ToString(), string.Format(Resources.ListNotFound, List.ToString())); + } } else { - throw new PSNotImplementedException("This Cmdlet only supports List Webhooks currently"); + throw new PSNotImplementedException(Resources.WebhooksOnlySupportsLists); } } - } } From 4a9d72d95efc0a7a596e2fccc52788e231a2e324 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 2 Jul 2020 00:22:35 +0200 Subject: [PATCH 097/130] Renamed cmdlets from UnifiedGroup to Microsoft365Group adding an alias for UnifiedGroup for backwards compatibility with the other M365 Group cmdlets, updated documentarion URL --- ...GroupMember.cs => AddMicrosoft365GroupMember.cs} | 13 +++++++------ ...edGroupOwner.cs => AddMicrosoft365GroupOwner.cs} | 12 +++++++----- ...oupMember.cs => ClearMicrosoft365GroupMember.cs} | 11 ++++++----- ...GroupOwner.cs => ClearMicrosoft365GroupOwner.cs} | 9 +++++---- ...upMember.cs => RemoveMicrosoft365GroupMember.cs} | 11 ++++++----- ...roupOwner.cs => RemoveMicrosoft365GroupOwner.cs} | 11 ++++++----- Commands/SharePointPnP.PowerShell.Commands.csproj | 12 ++++++------ 7 files changed, 43 insertions(+), 36 deletions(-) rename Commands/Graph/{AddUnifiedGroupMember.cs => AddMicrosoft365GroupMember.cs} (77%) rename Commands/Graph/{AddUnifiedGroupOwner.cs => AddMicrosoft365GroupOwner.cs} (78%) rename Commands/Graph/{ClearUnifiedGroupMember.cs => ClearMicrosoft365GroupMember.cs} (78%) rename Commands/Graph/{ClearUnifiedGroupOwner.cs => ClearMicrosoft365GroupOwner.cs} (79%) rename Commands/Graph/{RemoveUnifiedGroupMember.cs => RemoveMicrosoft365GroupMember.cs} (78%) rename Commands/Graph/{RemoveUnifiedGroupOwner.cs => RemoveMicrosoft365GroupOwner.cs} (77%) diff --git a/Commands/Graph/AddUnifiedGroupMember.cs b/Commands/Graph/AddMicrosoft365GroupMember.cs similarity index 77% rename from Commands/Graph/AddUnifiedGroupMember.cs rename to Commands/Graph/AddMicrosoft365GroupMember.cs index 0b932fac3..19cb591d9 100644 --- a/Commands/Graph/AddUnifiedGroupMember.cs +++ b/Commands/Graph/AddMicrosoft365GroupMember.cs @@ -8,22 +8,23 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Add, "PnPUnifiedGroupMember")] - [CmdletHelp("Adds members to a particular Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Add, "PnPMicrosoft365GroupMember")] + [Alias("Add-PnPUnifiedGroupMember")] + [CmdletHelp("Adds members to a particular Microsoft 365 Group", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-post-owners", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Add-PnPUnifiedGroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Code = @"PS:> Add-PnPMicrosoft365GroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", Remarks = @"Adds the provided two users as additional members to the Microsoft 365 Group named ""Project Team""", SortOrder = 1)] [CmdletExample( - Code = @"PS:> Add-PnPUnifiedGroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com"" -RemoveExisting", + Code = @"PS:> Add-PnPMicrosoft365GroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com"" -RemoveExisting", Remarks = @"Sets the provided two users as the only members of the Microsoft 365 Group named ""Project Team"" by removing any current existing members first", SortOrder = 2)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-post-members")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_ReadWrite_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class AddUnifiedGroupMember : PnPGraphCmdlet + public class AddMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add members to")] public UnifiedGroupPipeBind Identity; diff --git a/Commands/Graph/AddUnifiedGroupOwner.cs b/Commands/Graph/AddMicrosoft365GroupOwner.cs similarity index 78% rename from Commands/Graph/AddUnifiedGroupOwner.cs rename to Commands/Graph/AddMicrosoft365GroupOwner.cs index bfd9dacff..f64975bd6 100644 --- a/Commands/Graph/AddUnifiedGroupOwner.cs +++ b/Commands/Graph/AddMicrosoft365GroupOwner.cs @@ -8,22 +8,24 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Add, "PnPUnifiedGroupOwner")] - [CmdletHelp("Adds owners to a particular Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Add, "PnPMicrosoft365GroupOwner")] + [Alias("Add-PnPUnifiedGroupOwner")] + [CmdletHelp("Adds owners to a particular Microsoft 365 Group", Category = CmdletHelpCategory.Graph, OutputTypeLink = "https://docs.microsoft.com/graph/api/group-post-owners", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Add-PnPUnifiedGroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Code = @"PS:> Add-PnPMicrosoft365GroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", Remarks = @"Adds the provided two users as additional owners to the Microsoft 365 Group named ""Project Team""", SortOrder = 1)] [CmdletExample( - Code = @"PS:> Add-PnPUnifiedGroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com"" -RemoveExisting", + Code = @"PS:> Add-PnPMicrosoft365GroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com"" -RemoveExisting", Remarks = @"Sets the provided two users as the only owners of the Microsoft 365 Group named ""Project Team"" by removing any current existing owners first", SortOrder = 2)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-post-owners")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_ReadWrite_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] - public class AddUnifiedGroupOwner : PnPGraphCmdlet + public class AddMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add owners to")] public UnifiedGroupPipeBind Identity; diff --git a/Commands/Graph/ClearUnifiedGroupMember.cs b/Commands/Graph/ClearMicrosoft365GroupMember.cs similarity index 78% rename from Commands/Graph/ClearUnifiedGroupMember.cs rename to Commands/Graph/ClearMicrosoft365GroupMember.cs index de816bd24..54903f967 100644 --- a/Commands/Graph/ClearUnifiedGroupMember.cs +++ b/Commands/Graph/ClearMicrosoft365GroupMember.cs @@ -8,17 +8,18 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Clear, "PnPUnifiedGroupMember")] - [CmdletHelp("Removes all current members from a particular Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Clear, "PnPMicrosoft365GroupMember")] + [Alias("Clear-PnPMicrosoft365GroupMember")] + [CmdletHelp("Removes all current members from a particular Microsoft 365 Group", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-members", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Clear-PnPUnifiedGroupMember -Identity ""Project Team""", + Code = @"PS:> Clear-PnPMicrosoft365GroupMember -Identity ""Project Team""", Remarks = @"Removes all the current members from the Microsoft 365 Group named ""Project Team""", SortOrder = 1)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-delete-members")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All | MicrosoftGraphApiPermission.GroupMember_ReadWrite_All)] - public class ClearUnifiedGroupMember : PnPGraphCmdlet + public class ClearMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove all members from")] public UnifiedGroupPipeBind Identity; diff --git a/Commands/Graph/ClearUnifiedGroupOwner.cs b/Commands/Graph/ClearMicrosoft365GroupOwner.cs similarity index 79% rename from Commands/Graph/ClearUnifiedGroupOwner.cs rename to Commands/Graph/ClearMicrosoft365GroupOwner.cs index a7f65de4c..c1d1dec27 100644 --- a/Commands/Graph/ClearUnifiedGroupOwner.cs +++ b/Commands/Graph/ClearMicrosoft365GroupOwner.cs @@ -8,17 +8,18 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Clear, "PnPUnifiedGroupOwner")] + [Cmdlet(VerbsCommon.Clear, "PnPMicrosoft365GroupOwner")] + [Alias("Clear-PnPUnifiedGroupOwner")] [CmdletHelp("Removes all current owners from a particular Microsoft 365 Group (aka Unified Group)", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-owners", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Clear-PnPUnifiedGroupOwner -Identity ""Project Team""", + Code = @"PS:> Clear-PnPMicrosoft365GroupOwner -Identity ""Project Team""", Remarks = @"Removes all the current owners from the Microsoft 365 Group named ""Project Team""", SortOrder = 1)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-delete-owners")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] - public class ClearUnifiedGroupOwner : PnPGraphCmdlet + public class ClearMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove all owners from")] public UnifiedGroupPipeBind Identity; diff --git a/Commands/Graph/RemoveUnifiedGroupMember.cs b/Commands/Graph/RemoveMicrosoft365GroupMember.cs similarity index 78% rename from Commands/Graph/RemoveUnifiedGroupMember.cs rename to Commands/Graph/RemoveMicrosoft365GroupMember.cs index 3535e8c07..c21e8852e 100644 --- a/Commands/Graph/RemoveUnifiedGroupMember.cs +++ b/Commands/Graph/RemoveMicrosoft365GroupMember.cs @@ -8,17 +8,18 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Remove, "PnPUnifiedGroupMember")] - [CmdletHelp("Removes members from a particular Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Remove, "PnPMicrosoft365GroupMember")] + [Alias("Remove-PnPUnifiedGroupMember")] + [CmdletHelp("Removes members from a particular Microsoft 365 Group", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-members", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Remove-PnPUnifiedGroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Code = @"PS:> Remove-PnPMicrosoft365GroupMember -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", Remarks = @"Removes the provided two users as members from the Microsoft 365 Group named ""Project Team""", SortOrder = 1)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-delete-members")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.GroupMember_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] - public class RemoveUnifiedGroupMember : PnPGraphCmdlet + public class RemoveMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove members from")] public UnifiedGroupPipeBind Identity; diff --git a/Commands/Graph/RemoveUnifiedGroupOwner.cs b/Commands/Graph/RemoveMicrosoft365GroupOwner.cs similarity index 77% rename from Commands/Graph/RemoveUnifiedGroupOwner.cs rename to Commands/Graph/RemoveMicrosoft365GroupOwner.cs index 9ebd629a1..296d22bb3 100644 --- a/Commands/Graph/RemoveUnifiedGroupOwner.cs +++ b/Commands/Graph/RemoveMicrosoft365GroupOwner.cs @@ -8,17 +8,18 @@ namespace SharePointPnP.PowerShell.Commands.Graph { - [Cmdlet(VerbsCommon.Remove, "PnPUnifiedGroupOwner")] - [CmdletHelp("Removes owners from a particular Microsoft 365 Group (aka Unified Group)", + [Cmdlet(VerbsCommon.Remove, "PnPMicrosoft365GroupOwner")] + [Alias("Remove-PnPUnifiedGroupOwner")] + [CmdletHelp("Removes owners from a particular Microsoft 365 Group", Category = CmdletHelpCategory.Graph, - OutputTypeLink = "https://docs.microsoft.com/graph/api/group-delete-owners", SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = @"PS:> Remove-PnPUnifiedGroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", + Code = @"PS:> Remove-PnPMicrosoft365GroupOwner -Identity ""Project Team"" -Users ""john@contoso.onmicrosoft.com"",""jane@contoso.onmicrosoft.com""", Remarks = @"Removes the provided two users as owners from the Microsoft 365 Group named ""Project Team""", SortOrder = 1)] + [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-delete-owners")] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All | MicrosoftGraphApiPermission.Directory_ReadWrite_All)] - public class RemoveUnifiedGroupOwner : PnPGraphCmdlet + public class RemoveMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove owners from")] public UnifiedGroupPipeBind Identity; diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 72ebe6852..6e022454c 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -624,11 +624,11 @@ - - - - - + + + + + @@ -673,7 +673,7 @@ - + From 151dff403f26749f19b53a9a69f2793535b846e8 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 2 Jul 2020 00:27:00 +0200 Subject: [PATCH 098/130] Applied new AND permission attribute --- Commands/Graph/AddMicrosoft365GroupMember.cs | 3 +-- Commands/Graph/AddMicrosoft365GroupOwner.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Commands/Graph/AddMicrosoft365GroupMember.cs b/Commands/Graph/AddMicrosoft365GroupMember.cs index 19cb591d9..d09e89ee1 100644 --- a/Commands/Graph/AddMicrosoft365GroupMember.cs +++ b/Commands/Graph/AddMicrosoft365GroupMember.cs @@ -22,8 +22,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Remarks = @"Sets the provided two users as the only members of the Microsoft 365 Group named ""Project Team"" by removing any current existing members first", SortOrder = 2)] [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-post-members")] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_ReadWrite_All)] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.None, MicrosoftGraphApiPermission.User_ReadWrite_All | MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class AddMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add members to")] diff --git a/Commands/Graph/AddMicrosoft365GroupOwner.cs b/Commands/Graph/AddMicrosoft365GroupOwner.cs index f64975bd6..2ba3cc26c 100644 --- a/Commands/Graph/AddMicrosoft365GroupOwner.cs +++ b/Commands/Graph/AddMicrosoft365GroupOwner.cs @@ -23,8 +23,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Remarks = @"Sets the provided two users as the only owners of the Microsoft 365 Group named ""Project Team"" by removing any current existing owners first", SortOrder = 2)] [CmdletRelatedLink(Text = "Documentation", Url = "https://docs.microsoft.com/graph/api/group-post-owners")] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.User_ReadWrite_All)] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.None, MicrosoftGraphApiPermission.User_ReadWrite_All | MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class AddMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add owners to")] From 0017720db30b54e429197cdeae335b09ef698e49 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 2 Jul 2020 00:46:07 +0200 Subject: [PATCH 099/130] Updated help text, added supported platform and replaced literal error message by a reference to the resources --- Commands/Lists/RemoveListItem.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Commands/Lists/RemoveListItem.cs b/Commands/Lists/RemoveListItem.cs index 4a8d6d749..7696d3f3f 100644 --- a/Commands/Lists/RemoveListItem.cs +++ b/Commands/Lists/RemoveListItem.cs @@ -2,43 +2,47 @@ using Microsoft.SharePoint.Client; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using Resources = SharePointPnP.PowerShell.Commands.Properties.Resources; namespace SharePointPnP.PowerShell.Commands.Lists { [Cmdlet(VerbsCommon.Remove, "PnPListItem", SupportsShouldProcess = true)] [CmdletHelp("Deletes an item from a list", - Category = CmdletHelpCategory.Lists)] + Category = CmdletHelpCategory.Lists, + SupportedPlatform = CmdletSupportedPlatform.All)] [CmdletExample( Code = @"PS:> Remove-PnPListItem -List ""Demo List"" -Identity ""1"" -Force", SortOrder = 1, - Remarks = @"Removes the listitem with id ""1"" from the ""Demo List"" list.")] + Remarks = @"Removes the listitem with id ""1"" from the ""Demo List"" list")] [CmdletExample( Code = @"PS:> Remove-PnPListItem -List ""Demo List"" -Identity ""1"" -Force -Recycle", SortOrder = 2, - Remarks = @"Removes the listitem with id ""1"" from the ""Demo List"" list and saves it in the Recycle Bin.")] + Remarks = @"Removes the listitem with id ""1"" from the ""Demo List"" list and saves it in the Recycle Bin")] public class RemoveListItem : PnPWebCmdlet { - [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, HelpMessage = "The ID, Title or Url of the list.")] + [Parameter(Mandatory = true, ValueFromPipeline = true, Position = 0, HelpMessage = "The ID, Title or Url of the list")] public ListPipeBind List; [Parameter(Mandatory = true, HelpMessage = "The ID of the listitem, or actual ListItem object")] public ListItemPipeBind Identity; - [Parameter(Mandatory = false)] + [Parameter(Mandatory = false, HelpMessage = "When provided, items will be sent to the recycle bin. When omitted, items will permanently be deleted.")] public SwitchParameter Recycle; - [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] + [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question")] public SwitchParameter Force; protected override void ExecuteCmdlet() { var list = List.GetList(SelectedWeb); if (list == null) - throw new PSArgumentException($"No list found with id, title or url '{List}'", "List"); + { + throw new PSArgumentException(string.Format(Resources.ListNotFound, List.ToString())); + } if (Identity != null) { var item = Identity.GetListItem(list); - if (Force || ShouldContinue(string.Format(Properties.Resources.RemoveListItemWithId0,item.Id), Properties.Resources.Confirm)) + if (Force || ShouldContinue(string.Format(Resources.RemoveListItemWithId0, item.Id), Resources.Confirm)) { if (Recycle) { From cc8767b9e748695f2c393a9e2593168ce49262db Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 2 Jul 2020 10:10:56 +0200 Subject: [PATCH 100/130] fixed on-prem builds --- Commands/Base/ConnectOnline.cs | 5 +- .../Base/PipeBinds/TeamsChannelPipeBind.cs | 54 ++++++++++++++++++ Commands/Base/PipeBinds/TeamsTabPipeBind.cs | 36 ++++++++++-- Commands/Base/PipeBinds/TeamsTeamPipeBind.cs | 52 +++++++++++++++-- Commands/Teams/AddTeamsChannel.cs | 23 +++++--- Commands/Teams/GetTeamsApp.cs | 4 +- Commands/Teams/GetTeamsChannel.cs | 33 +++++++---- Commands/Teams/GetTeamsTab.cs | 42 +++++++++----- Commands/Teams/GetTeamsTeam.cs | 31 +++++----- Commands/Teams/NewTeamsTeam.cs | 5 +- Commands/Teams/RemoveTeamsChannel.cs | 17 ++++-- Commands/Teams/RemoveTeamsTab.cs | 57 ++++++++++++------- Commands/Teams/RemoveTeamsTeam.cs | 29 +++------- Commands/Utilities/TeamsUtility.cs | 10 ++++ 14 files changed, 287 insertions(+), 111 deletions(-) create mode 100644 Commands/Base/PipeBinds/TeamsChannelPipeBind.cs diff --git a/Commands/Base/ConnectOnline.cs b/Commands/Base/ConnectOnline.cs index 38d0ee5f8..4251813f5 100644 --- a/Commands/Base/ConnectOnline.cs +++ b/Commands/Base/ConnectOnline.cs @@ -239,7 +239,10 @@ public class ConnectOnline : BasePSCmdlet [Parameter(Mandatory = false, ParameterSetName = ParameterSet_MAIN, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials.")] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_ADFSCREDENTIALS, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials.")] - [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AADWITHSCOPE, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials.")] +#if !ONPREMISES + [Parameter(Mandatory = false, ParameterSetName = ParameterSet_AADWITHSCOPE, HelpMessage = "Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows " + + "Credential Manager for the correct credentials.")] +#endif public CredentialPipeBind Credentials; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_MAIN, HelpMessage = "If you want to connect with the current user credentials")] diff --git a/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs b/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs new file mode 100644 index 000000000..6413d3148 --- /dev/null +++ b/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs @@ -0,0 +1,54 @@ +using Microsoft.Graph; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Linq; +using System.Net.Http; +using System.Threading; + +namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds +{ + public sealed class TeamsChannelPipeBind + { + private readonly string _id; + private readonly string _displayName; + public TeamsChannelPipeBind() + { + + } + + public TeamsChannelPipeBind(string input) + { + // check if it's a channel id + if (input.EndsWith("@tread.skype") && input.Substring(2, 1) == ":") + { + _id = input; + } + else + { + _displayName = input; + } + } + + public TeamsChannelPipeBind(Model.Teams.TeamChannel channel) + { + _id = channel.Id; + } + + + public string Id => _id; + + public string GetId(HttpClient httpClient, string accessToken, string groupId) + { + if (!string.IsNullOrEmpty(_id)) + { + return _id; + } + else + { + var channels = TeamsUtility.GetChannels(accessToken, httpClient, groupId); + return channels.FirstOrDefault(c => c.DisplayName.Equals(_displayName, StringComparison.OrdinalIgnoreCase)).Id; + } + } + + } +} diff --git a/Commands/Base/PipeBinds/TeamsTabPipeBind.cs b/Commands/Base/PipeBinds/TeamsTabPipeBind.cs index 3009749eb..ceb1f91b6 100644 --- a/Commands/Base/PipeBinds/TeamsTabPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsTabPipeBind.cs @@ -1,16 +1,20 @@ using Microsoft.SharePoint.Client; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; using System; +using System.Linq; +using System.Management.Automation; +using System.Net.Http; namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds { public sealed class TeamsTabPipeBind { - private readonly Guid _id; + private readonly string _id; private readonly string _displayName; public TeamsTabPipeBind() { - _id = Guid.Empty; } public TeamsTabPipeBind(string input) @@ -21,7 +25,7 @@ public TeamsTabPipeBind(string input) } if (Guid.TryParse(input, out Guid tabId)) { - _id = tabId; + _id = input; } else { @@ -29,9 +33,31 @@ public TeamsTabPipeBind(string input) } } + public string Id => _id; - public Guid Id => _id; + public TeamTab GetTab(HttpClient httpClient, string accessToken, string groupId, string channelId) + { + // find the tab by the displayName + var tabs = TeamsUtility.GetTabs(accessToken, httpClient, groupId, channelId); + if (tabs != null) + { + var tab = tabs.FirstOrDefault(t => t.DisplayName.Equals(_displayName, System.StringComparison.OrdinalIgnoreCase)); + if (tab != null) + { + return tab; + } + else + { + throw new PSArgumentException("Cannot find tab"); + } + } + return null; + } - public string DisplayName => _displayName; + public TeamTab GetTabById(HttpClient httpClient, string accessToken, string groupId, string channelId) + { + return TeamsUtility.GetTab(accessToken, httpClient, groupId, channelId, _id); + } } } + diff --git a/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs b/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs index 6ed94da40..fae601ae7 100644 --- a/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs @@ -1,16 +1,22 @@ -using System; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities.REST; +using System; +using System.Linq; +using System.Management.Automation; +using System.Net.Http; namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds { public sealed class TeamsTeamPipeBind { - private readonly Guid _id; + private readonly string _id; private readonly string _stringValue; public TeamsTeamPipeBind() { - _id = Guid.Empty; + _id = string.Empty; + _stringValue = string.Empty; } public TeamsTeamPipeBind(string input) @@ -21,7 +27,7 @@ public TeamsTeamPipeBind(string input) } if (Guid.TryParse(input, out Guid tabId)) { - _id = tabId; + _id = input; } else { @@ -29,8 +35,42 @@ public TeamsTeamPipeBind(string input) } } - public Guid Id => _id; + public TeamsTeamPipeBind(Team team) + { + _id = team.GroupId; + } + + public string GetGroupId(HttpClient httpClient, string accessToken) + { + if (!string.IsNullOrEmpty(_id)) + { + return _id.ToString(); + } + else + { + var collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{_stringValue}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken).GetAwaiter().GetResult(); + if(collection != null && collection.Items.Any()) + { + return collection.Items.First().Id; + } + else + { + // find the team by displayName + var byDisplayNamecollection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{_stringValue}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken).GetAwaiter().GetResult(); + if (byDisplayNamecollection != null) + { + if (byDisplayNamecollection.Items.Count() == 1) + { + return byDisplayNamecollection.Items.First().Id; + } else + { + throw new PSArgumentException("We found more matches based on the identity value you entered. Use Get-PnPTeamsTeam to find the correct instance and use the GroupId from a team to select the correct team instead."); + } + } + return null; + } + } + } - public string StringValue => _stringValue; } } diff --git a/Commands/Teams/AddTeamsChannel.cs b/Commands/Teams/AddTeamsChannel.cs index 94a9e3480..fd5eab5f1 100644 --- a/Commands/Teams/AddTeamsChannel.cs +++ b/Commands/Teams/AddTeamsChannel.cs @@ -1,11 +1,9 @@ -using OfficeDevPnP.Core.Entities; -using OfficeDevPnP.Core.Framework.Graph; -using OfficeDevPnP.Core.Utilities; +#if !ONPREMISES using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; -using System.Collections.Generic; +using System; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -15,14 +13,14 @@ namespace SharePointPnP.PowerShell.Commands.Graph Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Add-PnPTeamsChannel -GroupId 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", + Code = "PS:> Add-PnPTeamsChannel -TeamIdentity 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", Remarks = "Adds a new channel to the specified Teams instance", SortOrder = 1)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class AddTeamsChannel : PnPGraphCmdlet { - [Parameter(Mandatory = true)] - public string GroupId; + [Parameter(Mandatory = true, HelpMessage = "Either group id (4efdf392-8225-4763-9e7f-4edeb7f721aa) or mailNickName of the group (e.g. 'mymailnickname'")] + public TeamsTeamPipeBind TeamIdentity; [Parameter(Mandatory = true)] public string DisplayName; @@ -32,7 +30,16 @@ public class AddTeamsChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - WriteObject(TeamsUtility.AddChannel(AccessToken, HttpClient, GroupId, DisplayName, Description)); + Model.Teams.TeamChannel channel = null; + + var groupId = TeamIdentity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + channel = TeamsUtility.AddChannel(AccessToken, HttpClient, groupId, DisplayName, Description); + WriteObject(channel); + } + } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs index 5b310b722..712d2737a 100644 --- a/Commands/Teams/GetTeamsApp.cs +++ b/Commands/Teams/GetTeamsApp.cs @@ -1,4 +1,5 @@ -using SharePointPnP.PowerShell.CmdletHelpAttributes; +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; @@ -55,3 +56,4 @@ protected override void ExecuteCmdlet() } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs index 89580b4bf..70c71dfb1 100644 --- a/Commands/Teams/GetTeamsChannel.cs +++ b/Commands/Teams/GetTeamsChannel.cs @@ -1,4 +1,5 @@ -using OfficeDevPnP.Core.Framework.Graph; +#if !ONPREMISES +using OfficeDevPnP.Core.Framework.Graph; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; @@ -17,38 +18,46 @@ namespace SharePointPnP.PowerShell.Commands.Teams Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPTeamsChannel -GroupId a6c1e0d7-f579-4993-81ab-4b666f8edea8", + Code = "PS:> Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8", Remarks = "Retrieves all channels for the specified team", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPTeamsChannel -GroupId a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"Test Channel\"", + Code = "PS:> Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"Test Channel\"", Remarks = "Retrieves the channel called 'Test Channel'", SortOrder = 2)] [CmdletExample( - Code = "PS:> Get-PnPTeamsChannel -GroupId a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", + Code = "PS:> Get-PnPTeamsChannel -Team a6c1e0d7-f579-4993-81ab-4b666f8edea8 -Identity \"19:796d063b63e34497aeaf092c8fb9b44e@thread.skype\"", Remarks = "Retrieves the channel specified by its channel id", SortOrder = 3)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsChannel : PnPGraphCmdlet { - [Parameter(Mandatory = true)] - public GuidPipeBind GroupId; + [Parameter(Mandatory = true, ValueFromPipeline = true)] + public TeamsTeamPipeBind Team; [Parameter(Mandatory = false)] public string Identity; protected override void ExecuteCmdlet() { - if (ParameterSpecified(nameof(Identity))) + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - var channels = TeamsUtility.GetChannels(AccessToken, HttpClient, GroupId.Id.ToString()); - WriteObject(channels.FirstOrDefault(c => c.DisplayName.Equals(Identity, StringComparison.OrdinalIgnoreCase) || c.Id.Equals(Identity, StringComparison.OrdinalIgnoreCase))); - } - else + if (ParameterSpecified(nameof(Identity))) + { + var channels = TeamsUtility.GetChannels(AccessToken, HttpClient, groupId); + WriteObject(channels.FirstOrDefault(c => c.DisplayName.Equals(Identity, StringComparison.OrdinalIgnoreCase) || c.Id.Equals(Identity, StringComparison.OrdinalIgnoreCase))); + } + else + { + WriteObject(TeamsUtility.GetChannels(AccessToken, HttpClient, groupId)); + } + } else { - WriteObject(TeamsUtility.GetChannels(AccessToken, HttpClient, GroupId.Id.ToString())); + throw new PSArgumentException("Cannot find team", nameof(Team)); } } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/GetTeamsTab.cs b/Commands/Teams/GetTeamsTab.cs index ad8370276..517adeeb7 100644 --- a/Commands/Teams/GetTeamsTab.cs +++ b/Commands/Teams/GetTeamsTab.cs @@ -1,4 +1,6 @@ -using SharePointPnP.PowerShell.CmdletHelpAttributes; +#if !ONPREMISES +using OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml.V201807; +using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; @@ -26,38 +28,50 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class GetTeamsTab : PnPGraphCmdlet { - [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] - public GuidPipeBind GroupId; + [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.", ValueFromPipeline = true)] + public TeamsTeamPipeBind Team; - [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.")] - public string ChannelId; + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.", ValueFromPipeline = true)] + public TeamsChannelPipeBind Channel; [Parameter(Mandatory = false, HelpMessage = "Identity")] public TeamsTabPipeBind Identity; protected override void ExecuteCmdlet() { - if (ParameterSpecified(nameof(Identity))) + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - var tabs = TeamsUtility.GetTabs(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId); - if (tabs != null) + var channelId = Channel.GetId(HttpClient, AccessToken, groupId); + if (!string.IsNullOrEmpty(channelId)) { - TeamTab tab = null; - if (Identity.Id != Guid.Empty) + if (ParameterSpecified(nameof(Identity))) { - tab = tabs.FirstOrDefault(t => t.Id == Identity.Id.ToString()); + + if (string.IsNullOrEmpty(Identity.Id)) + { + WriteObject(Identity.GetTab(HttpClient, AccessToken, groupId, channelId)); + } + else + { + WriteObject(Identity.GetTabById(HttpClient, AccessToken, groupId, channelId)); + } } else { - tab = tabs.FirstOrDefault(t => t.DisplayName.Equals(Identity.DisplayName, System.StringComparison.OrdinalIgnoreCase)); + WriteObject(TeamsUtility.GetTabs(AccessToken, HttpClient, groupId, channelId)); } - WriteObject(tab); + } + else + { + throw new PSArgumentException("Channel not found"); } } else { - WriteObject(TeamsUtility.GetTabs(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId)); + throw new PSArgumentException("Team not found"); } } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs index a5a2bfdf4..80e981e47 100644 --- a/Commands/Teams/GetTeamsTeam.cs +++ b/Commands/Teams/GetTeamsTeam.cs @@ -1,4 +1,5 @@ -using SharePointPnP.PowerShell.CmdletHelpAttributes; +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; @@ -20,10 +21,6 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", Remarks = "Retrieves a specific Microsoft Teams instance", SortOrder = 2)] - [CmdletExample( - Code = "PS:> Get-PnPTeamsTeam -Visibility Public", - Remarks = "Retrieves all Microsoft Teams instances which are public visible", - SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsTeam : PnPGraphCmdlet @@ -31,22 +28,21 @@ public class GetTeamsTeam : PnPGraphCmdlet private const string ParameterSet_GroupId = "Retrieve a specific Team"; [Parameter(Mandatory = false, HelpMessage = "Specify the group id of the team to retrieve.")] - public GuidPipeBind GroupId; - - [Parameter(Mandatory = false, HelpMessage = "Specify the visibility of the teams to retrieve.")] - public GroupVisibility Visibility; + public TeamsTeamPipeBind Identity; protected override void ExecuteCmdlet() { - if (ParameterSpecified(nameof(GroupId))) + if (ParameterSpecified(nameof(Identity))) { - WriteObject(TeamsUtility.GetTeam(AccessToken, HttpClient, GroupId.Id.ToString())); - } - else if (ParameterSpecified(nameof(Visibility))) - { - var teams = TeamsUtility.GetTeams(AccessToken, HttpClient); - - WriteObject(teams.Where(t => t.Visibility == Visibility), true); + var groupId = Identity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + WriteObject(TeamsUtility.GetTeam(AccessToken, HttpClient, groupId)); + } + else + { + throw new PSArgumentException("Team not found"); + } } else { @@ -55,3 +51,4 @@ protected override void ExecuteCmdlet() } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/NewTeamsTeam.cs b/Commands/Teams/NewTeamsTeam.cs index 945d9badc..b38f5c654 100644 --- a/Commands/Teams/NewTeamsTeam.cs +++ b/Commands/Teams/NewTeamsTeam.cs @@ -1,4 +1,5 @@ -using OfficeDevPnP.Core.Framework.Provisioning.Model.Teams; +#if !ONPREMISES +using OfficeDevPnP.Core.Framework.Provisioning.Model.Teams; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; @@ -28,7 +29,6 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPTeamsTeam -Visibility Public", Remarks = "Retrieves all Microsoft Teams instances which are public visible", SortOrder = 2)] - [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class NewTeamsTeam : PnPGraphCmdlet { @@ -141,3 +141,4 @@ protected override void ExecuteCmdlet() } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/RemoveTeamsChannel.cs b/Commands/Teams/RemoveTeamsChannel.cs index 7b1bf17c2..f3a17ad11 100644 --- a/Commands/Teams/RemoveTeamsChannel.cs +++ b/Commands/Teams/RemoveTeamsChannel.cs @@ -1,4 +1,5 @@ -using OfficeDevPnP.Core.Framework.Graph; +#if !ONPREMISES +using OfficeDevPnP.Core.Framework.Graph; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; @@ -24,7 +25,7 @@ namespace SharePointPnP.PowerShell.Commands.Teams public class RemoveTeamsChannel : PnPGraphCmdlet { [Parameter(Mandatory = true)] - public GuidPipeBind GroupId; + public TeamsTeamPipeBind TeamIdentity; [Parameter(Mandatory = true)] public string DisplayName; @@ -36,11 +37,19 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the channel will also remove all the messages in the channel.", Properties.Resources.Confirm)) { - if (!TeamsUtility.DeleteChannel(AccessToken, HttpClient, GroupId.Id.ToString(), DisplayName)) + var groupId = TeamIdentity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - WriteError(new ErrorRecord(new Exception($"Channel remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + if (!TeamsUtility.DeleteChannel(AccessToken, HttpClient, groupId, DisplayName)) + { + WriteError(new ErrorRecord(new Exception($"Channel remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + } + } else + { + throw new PSArgumentException("Team not found"); } } } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs index d8ca55435..777eb1796 100644 --- a/Commands/Teams/RemoveTeamsTab.cs +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -1,4 +1,5 @@ -using SharePointPnP.PowerShell.CmdletHelpAttributes; +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; @@ -23,13 +24,13 @@ namespace SharePointPnP.PowerShell.Commands.Graph [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class RemoveTeamsTab : PnPGraphCmdlet { - [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] - public GuidPipeBind GroupId; + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; - [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.")] - public string ChannelId; + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id or display name of the channel to use.")] + public TeamsChannelPipeBind Channel; - [Parameter(Mandatory = true, HelpMessage = "Identity")] + [Parameter(Mandatory = true, HelpMessage = "Specify the id of the tab ")] public TeamsTabPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] @@ -39,27 +40,45 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the tab will remove the settings of this tab too.", Properties.Resources.Confirm)) { - var tabId = string.Empty; - if(Identity.Id != Guid.Empty) + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - tabId = Identity.Id.ToString(); - } else - { - var tabs = TeamsUtility.GetTabs(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId); - var tab = tabs.FirstOrDefault(t => t.DisplayName.Equals(Identity.DisplayName, StringComparison.OrdinalIgnoreCase)); - if(tab != null) + var channelId = Channel.GetId(HttpClient, AccessToken, groupId); + if (channelId != null) { - tabId = tab.Id; - } else + var tabId = string.Empty; + if (string.IsNullOrEmpty(Identity.Id)) + { + tabId = Identity.Id.ToString(); + } + else + { + var tab = Identity.GetTab(HttpClient, AccessToken, groupId, channelId); + if (tab != null) + { + tabId = tab.Id; + } + else + { + throw new PSArgumentException("Cannot find tab"); + } + } + if (!TeamsUtility.DeleteTab(AccessToken, HttpClient, groupId, channelId, tabId)) + { + throw new PSInvalidOperationException("Tab remove failed"); + } + } + else { - throw new PSArgumentException("Cannot find tab"); + throw new PSArgumentException("Cannot find channel"); } } - if (!TeamsUtility.DeleteTab(AccessToken, HttpClient, GroupId.Id.ToString(), ChannelId, tabId)) + else { - throw new PSInvalidOperationException("Tab remove failed"); + throw new PSArgumentException("Team not found", nameof(Team)); } } } } } +#endif \ No newline at end of file diff --git a/Commands/Teams/RemoveTeamsTeam.cs b/Commands/Teams/RemoveTeamsTeam.cs index 15e727cc1..b7306a259 100644 --- a/Commands/Teams/RemoveTeamsTeam.cs +++ b/Commands/Teams/RemoveTeamsTeam.cs @@ -1,4 +1,5 @@ -using Microsoft.SharePoint.Client; +#if !ONPREMISES +using Microsoft.SharePoint.Client; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; @@ -24,7 +25,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class RemoveTeamsTeam : PnPGraphCmdlet { - [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.")] + [Parameter(Mandatory = true, HelpMessage = "Either the group id or the mailnickname of the group to remove.")] public TeamsTeamPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] @@ -34,27 +35,10 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the team will remove all messages in all channels in the team.", Properties.Resources.Confirm)) { - var groupId = string.Empty; - if (Identity.Id != Guid.Empty) + var groupId = Identity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - groupId = Identity.Id.ToString(); - } - else - { - var groups = TeamsUtility.GetGroupsWithTeam(HttpClient, AccessToken); - var groupCollection = groups.Where(t => t.DisplayName.Equals(Identity.StringValue, StringComparison.OrdinalIgnoreCase)); - if (groupCollection.Any() && groupCollection.Count() == 1) - { - groupId = groupCollection.First().Id; - } - else - { - throw new PSArgumentException("Found multiple Teams with the same display name. Specify the group id to remove the correct Teams instance, e.g. Remove-PnPTeamsTeam -Identity . Use Get-PnPTeamsTeam to list all teams."); - } - } - if (groupId != string.Empty) - { - if (!TeamsUtility.DeleteTeam(AccessToken, HttpClient, groupId.ToString())) + if (!TeamsUtility.DeleteTeam(AccessToken, HttpClient, groupId)) { WriteError(new ErrorRecord(new Exception($"Team remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); } @@ -67,3 +51,4 @@ protected override void ExecuteCmdlet() } } } +#endif \ No newline at end of file diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index 3fb89f251..0e3d3a86c 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -33,6 +33,11 @@ public static List GetGroupsWithTeam(HttpClient httpClient, string access return groups; } + public static Group GetGroupWithTeam(HttpClient httpClient, string accessToken, string mailNickname) + { + return GraphHelper.GetAsync(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{mailNickname}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken).GetAwaiter().GetResult(); + + } public static List GetTeams(string accessToken, HttpClient httpClient) { List teams = new List(); @@ -279,6 +284,11 @@ public static IEnumerable GetTabs(string accessToken, HttpClient httpCl return null; } + public static TeamTab GetTab(string accessToken, HttpClient httpClient, string groupId, string channelId, string tabId) + { + return GraphHelper.GetAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); + } + public static bool DeleteTab(string accessToken, HttpClient httpClient, string groupId, string channelId, string tabId) { return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); From ff28436dcba5741477c568391ce7d70f0005414e Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 2 Jul 2020 10:25:32 +0200 Subject: [PATCH 101/130] fixed compilation issue --- Commands/RecycleBin/ClearRecycleBinItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/RecycleBin/ClearRecycleBinItem.cs b/Commands/RecycleBin/ClearRecycleBinItem.cs index 5c76c7ce0..7c7bde4f2 100644 --- a/Commands/RecycleBin/ClearRecycleBinItem.cs +++ b/Commands/RecycleBin/ClearRecycleBinItem.cs @@ -67,7 +67,7 @@ protected override void ExecuteCmdlet() } break; case PARAMETERSET_ALL: -#if !SP2013 +#if !ONPREMISES if (ParameterSpecified(nameof(RowLimit))) { if (Force || ShouldContinue(SecondStageOnly ? Resources.ClearSecondStageRecycleBin : Resources.ClearBothRecycleBins, Resources.Confirm)) From ca6c2536bde28ffc63285e3d4cb8657a47f2ce0d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 2 Jul 2020 10:30:44 +0200 Subject: [PATCH 102/130] Added section on syncing fork --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7aa6ab034..fe6e2adb8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,6 @@ Please see following page for additional insights on the model. --- ## Building the source code ## - Once you have downloaded the code, in the folder with the PnP PowerShell source code, open the solution file SharePointPnP.PowerShell.sln. If you have set up the projects and you are ready to build the source code, make sure to build the SharePointPnP.PowerShellModuleFilesGenerator project first. This project will be executed after every build and it will generate the required PSD1 and XML files with cmdlet documentation in them. @@ -23,6 +22,9 @@ When you build the solution a postbuild script will copy the required files to a To debug the cmdlets: launch PowerShell and attach Visual Studio to the powershell.exe process. In case you want to debug methods in PnP Sites Core, make sure that you open the PnP Sites Core project instead, and then attach Visual Studio to the powershell.exe. In case you see strange debug behavior, like it wants to debug PSReadLine.ps1, uninstall the PowerShell extension from Visual Studio. +## Keeping your fork up to date +Before starting on any new submissions, please ensure your fork is up to date with the upstream repository. This avoids frustration and challenges for us to valdate and test your submission. Steps on how to easily keep your fork up to date can be found [on this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Update-your-fork-with-the-latest-code). + ## Code contributions In order to succesfully compile the PnP PowerShell solution you will _also_ have to download *and build in Visual Studio* the [PnP-Sites-Core](https://github.com/OfficeDev/PnP-Sites-Core) repository and make the dev branch available. The PowerShell solution depends on it. In order to succesfully compile it, make sure that PnP-Sites-Core is located at the same level as PnP-PowerShell and you open the solution file OfficeDevPnP.Core.sln located in the Core subfolder of the sourcecode. From 2e44b43d478cbf12d1750eb44a75215c428dc0a6 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 2 Jul 2020 10:48:02 +0200 Subject: [PATCH 103/130] fixed compilation --- Commands/SharePointPnP.PowerShell.Commands.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 16dbe09db..1a720fdc1 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -623,6 +623,7 @@ + From b0a1943fefba83408ed0a36fcbe1e5c3e093cf48 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 2 Jul 2020 13:13:37 +0200 Subject: [PATCH 104/130] Added Submit-PnPTeamsChannelMessage cmdlet --- .../Base/PipeBinds/TeamsChannelPipeBind.cs | 17 +++ Commands/Model/Teams/TeamChannelMessage.cs | 12 +- .../SharePointPnP.PowerShell.Commands.csproj | 1 + Commands/Teams/AddTeamsChannel.cs | 13 ++- Commands/Teams/GetTeamsApp.cs | 1 - Commands/Teams/GetTeamsChannel.cs | 11 +- Commands/Teams/GetTeamsTab.cs | 18 +-- Commands/Teams/GetTeamsTeam.cs | 4 +- Commands/Teams/NewTeamsTeam.cs | 4 - Commands/Teams/RemoveTeamsChannel.cs | 11 +- Commands/Teams/RemoveTeamsTab.cs | 2 - Commands/Teams/RemoveTeamsTeam.cs | 2 - Commands/Teams/SubmitTeamsChannelMessage.cs | 45 ++++++++ Commands/Utilities/TeamsUtility.cs | 11 +- PostBuild.ps1 | 103 ++++++++++-------- 15 files changed, 159 insertions(+), 96 deletions(-) create mode 100644 Commands/Teams/SubmitTeamsChannelMessage.cs diff --git a/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs b/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs index 6413d3148..0b36684e5 100644 --- a/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsChannelPipeBind.cs @@ -1,4 +1,5 @@ using Microsoft.Graph; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; using System; using System.Linq; @@ -50,5 +51,21 @@ public string GetId(HttpClient httpClient, string accessToken, string groupId) } } + public TeamChannel GetChannel(HttpClient httpClient, string accessToken, string groupId) + { + var channels = TeamsUtility.GetChannels(accessToken, httpClient, groupId); + if(channels != null && channels.Any()) + { + if(!string.IsNullOrEmpty(_id)) + { + return channels.FirstOrDefault(c => c.Id.Equals(_id, StringComparison.OrdinalIgnoreCase)); + } else + { + return channels.FirstOrDefault(c => c.DisplayName.Equals(_displayName, StringComparison.OrdinalIgnoreCase)); + } + } + return null; + } + } } diff --git a/Commands/Model/Teams/TeamChannelMessage.cs b/Commands/Model/Teams/TeamChannelMessage.cs index 3937041ed..fb1e1c3f4 100644 --- a/Commands/Model/Teams/TeamChannelMessage.cs +++ b/Commands/Model/Teams/TeamChannelMessage.cs @@ -8,13 +8,11 @@ namespace SharePointPnP.PowerShell.Commands.Model.Teams { public partial class TeamChannelMessage { - #region Public Members - - /// - /// Defines a Message for a Channel in a Team - /// - public string Message { get; set; } + public TeamChannelMessageBody Body { get; set; } + } - #endregion + public class TeamChannelMessageBody + { + public string Content { get; set; } } } diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 1a720fdc1..89521fae5 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -927,6 +927,7 @@ + diff --git a/Commands/Teams/AddTeamsChannel.cs b/Commands/Teams/AddTeamsChannel.cs index fd5eab5f1..c7732ff24 100644 --- a/Commands/Teams/AddTeamsChannel.cs +++ b/Commands/Teams/AddTeamsChannel.cs @@ -3,7 +3,6 @@ using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; -using System; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -13,14 +12,18 @@ namespace SharePointPnP.PowerShell.Commands.Graph Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Add-PnPTeamsChannel -TeamIdentity 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", + Code = "PS:> Add-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", Remarks = "Adds a new channel to the specified Teams instance", SortOrder = 1)] + [CmdletExample( + Code = "PS:> Add-PnPTeamsChannel -Team MyTeam -DisplayName \"My Channel\"", + Remarks = "Adds a new channel to the specified Teams instance", + SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class AddTeamsChannel : PnPGraphCmdlet { - [Parameter(Mandatory = true, HelpMessage = "Either group id (4efdf392-8225-4763-9e7f-4edeb7f721aa) or mailNickName of the group (e.g. 'mymailnickname'")] - public TeamsTeamPipeBind TeamIdentity; + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; [Parameter(Mandatory = true)] public string DisplayName; @@ -32,7 +35,7 @@ protected override void ExecuteCmdlet() { Model.Teams.TeamChannel channel = null; - var groupId = TeamIdentity.GetGroupId(HttpClient, AccessToken); + var groupId = Team.GetGroupId(HttpClient, AccessToken); if (groupId != null) { channel = TeamsUtility.AddChannel(AccessToken, HttpClient, groupId, DisplayName, Description); diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs index 712d2737a..9529c1f3c 100644 --- a/Commands/Teams/GetTeamsApp.cs +++ b/Commands/Teams/GetTeamsApp.cs @@ -2,7 +2,6 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; -using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; using SharePointPnP.PowerShell.Core.Attributes; using System; diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs index 70c71dfb1..5aa90087c 100644 --- a/Commands/Teams/GetTeamsChannel.cs +++ b/Commands/Teams/GetTeamsChannel.cs @@ -8,8 +8,6 @@ using System.Collections.Generic; using System.Linq; using System.Management.Automation; -using System.Text; -using System.Threading.Tasks; namespace SharePointPnP.PowerShell.Commands.Teams { @@ -33,11 +31,11 @@ namespace SharePointPnP.PowerShell.Commands.Teams [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsChannel : PnPGraphCmdlet { - [Parameter(Mandatory = true, ValueFromPipeline = true)] + [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] public TeamsTeamPipeBind Team; - [Parameter(Mandatory = false)] - public string Identity; + [Parameter(Mandatory = false, HelpMessage = "")] + public TeamsChannelPipeBind Identity; protected override void ExecuteCmdlet() { @@ -46,8 +44,7 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - var channels = TeamsUtility.GetChannels(AccessToken, HttpClient, groupId); - WriteObject(channels.FirstOrDefault(c => c.DisplayName.Equals(Identity, StringComparison.OrdinalIgnoreCase) || c.Id.Equals(Identity, StringComparison.OrdinalIgnoreCase))); + WriteObject(Identity.GetChannel(HttpClient, AccessToken, groupId)); } else { diff --git a/Commands/Teams/GetTeamsTab.cs b/Commands/Teams/GetTeamsTab.cs index 517adeeb7..de1bcd4ef 100644 --- a/Commands/Teams/GetTeamsTab.cs +++ b/Commands/Teams/GetTeamsTab.cs @@ -1,12 +1,8 @@ #if !ONPREMISES -using OfficeDevPnP.Core.Framework.Provisioning.Providers.Xml.V201807; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; -using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; -using System; -using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -16,13 +12,21 @@ namespace SharePointPnP.PowerShell.Commands.Graph Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", - Remarks = "Retrieves the tabs for the Microsoft Teams instances", + Code = "PS:> Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype", + Remarks = "Retrieves the tabs for the specified Microsoft Teams instance and channel", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTab -GroupId 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -ChannelId 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity \"Wiki\"", + Code = "PS:> Get-PnPTeamsTab -Team 5beb63c5-0571-499e-94d5-3279fdd9b6b5 -Channel 19:796d063b63e34497aeaf092c8fb9b44e@thread.skype -Identity \"Wiki\"", Remarks = "Retrieves a tab with the display name 'Wiki' from the specified team and channel", SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\"", + Remarks = "Retrieves the tabs for the specified Microsoft Teams instance and channel", + SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTab \"My Team\" -Channel \"My Channel\" -Identity \"Wiki\"", + Remarks = "Retrieves a tab with the display name 'Wiki' from the specified team and channel", + SortOrder = 4)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsTab : PnPGraphCmdlet diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs index 80e981e47..c277b49db 100644 --- a/Commands/Teams/GetTeamsTeam.cs +++ b/Commands/Teams/GetTeamsTeam.cs @@ -2,9 +2,7 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; -using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; -using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -18,7 +16,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Remarks = "Retrieves all the Microsoft Teams instances", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", + Code = "PS:> Get-PnPTeamsTeam -Identity $groupId", Remarks = "Retrieves a specific Microsoft Teams instance", SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] diff --git a/Commands/Teams/NewTeamsTeam.cs b/Commands/Teams/NewTeamsTeam.cs index b38f5c654..a77be77b0 100644 --- a/Commands/Teams/NewTeamsTeam.cs +++ b/Commands/Teams/NewTeamsTeam.cs @@ -2,14 +2,10 @@ using OfficeDevPnP.Core.Framework.Provisioning.Model.Teams; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; -using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; using System; using System.Management.Automation; -using System.Reflection; -using System.Security.Cryptography; -using System.Text.RegularExpressions; namespace SharePointPnP.PowerShell.Commands.Graph { diff --git a/Commands/Teams/RemoveTeamsChannel.cs b/Commands/Teams/RemoveTeamsChannel.cs index f3a17ad11..0c788446e 100644 --- a/Commands/Teams/RemoveTeamsChannel.cs +++ b/Commands/Teams/RemoveTeamsChannel.cs @@ -1,15 +1,10 @@ #if !ONPREMISES -using OfficeDevPnP.Core.Framework.Graph; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; using System; -using System.Collections.Generic; -using System.Linq; using System.Management.Automation; -using System.Text; -using System.Threading.Tasks; namespace SharePointPnP.PowerShell.Commands.Teams { @@ -18,14 +13,14 @@ namespace SharePointPnP.PowerShell.Commands.Teams Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Remove-PnPTeamsChannel -GroupId 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", + Code = "PS:> Remove-PnPTeamsChannel -Team 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", Remarks = "Removes the channel specified from the team specified", SortOrder = 1)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class RemoveTeamsChannel : PnPGraphCmdlet { [Parameter(Mandatory = true)] - public TeamsTeamPipeBind TeamIdentity; + public TeamsTeamPipeBind Team; [Parameter(Mandatory = true)] public string DisplayName; @@ -37,7 +32,7 @@ protected override void ExecuteCmdlet() { if (Force || ShouldContinue("Removing the channel will also remove all the messages in the channel.", Properties.Resources.Confirm)) { - var groupId = TeamIdentity.GetGroupId(HttpClient, AccessToken); + var groupId = Team.GetGroupId(HttpClient, AccessToken); if (groupId != null) { if (!TeamsUtility.DeleteChannel(AccessToken, HttpClient, groupId, DisplayName)) diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs index 777eb1796..5cb6feaf2 100644 --- a/Commands/Teams/RemoveTeamsTab.cs +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -3,8 +3,6 @@ using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; -using System; -using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph diff --git a/Commands/Teams/RemoveTeamsTeam.cs b/Commands/Teams/RemoveTeamsTeam.cs index b7306a259..874bd3d21 100644 --- a/Commands/Teams/RemoveTeamsTeam.cs +++ b/Commands/Teams/RemoveTeamsTeam.cs @@ -1,11 +1,9 @@ #if !ONPREMISES -using Microsoft.SharePoint.Client; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; using System; -using System.Linq; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph diff --git a/Commands/Teams/SubmitTeamsChannelMessage.cs b/Commands/Teams/SubmitTeamsChannelMessage.cs new file mode 100644 index 000000000..e41b1cd30 --- /dev/null +++ b/Commands/Teams/SubmitTeamsChannelMessage.cs @@ -0,0 +1,45 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsLifecycle.Submit, "PnPTeamsChannelMessage")] + [CmdletHelp("Sends a message to a Microsoft Teams Channel.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A new message\"", + Remarks = "Sends \"A new message\" to the specified channel", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class SubmitTeamsChannelMessage : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsChannelPipeBind Channel; + + [Parameter(Mandatory = true, HelpMessage = "The message to send to the channel.")] + public string Message; + + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + var channel = Channel.GetChannel(HttpClient, AccessToken, groupId); + if (channel != null) + { + TeamsUtility.PostMessage(HttpClient, AccessToken, groupId, channel.Id, Message); + } + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index 0e3d3a86c..d8d3f3a04 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -1,13 +1,10 @@ -using Microsoft.BusinessData.MetadataModel; -using Microsoft.IdentityModel.Tokens; -using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities.REST; using System; using System.Collections.Generic; using System.Linq; using System.Management.Automation; using System.Net.Http; -using System.Web; namespace SharePointPnP.PowerShell.Commands.Utilities { @@ -271,6 +268,12 @@ public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, }; return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels", channel, accessToken).GetAwaiter().GetResult(); } + + public static void PostMessage(HttpClient httpClient, string accessToken, string groupId, string channelId, string message) + { + var channelMessage = new TeamChannelMessage() { Body = new TeamChannelMessageBody() { Content = message } }; + GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/messages", channelMessage, accessToken).GetAwaiter().GetResult(); + } #endregion #region Tabs diff --git a/PostBuild.ps1 b/PostBuild.ps1 index 401fb72ed..5eab131b8 100644 --- a/PostBuild.ps1 +++ b/PostBuild.ps1 @@ -83,23 +83,28 @@ if($ConfigurationName -like "Debug*") } elseif ($ConfigurationName -like "Release*") { $documentsFolder = [environment]::getfolderpath("mydocuments"); - switch($ConfigurationName) + if($TargetDir -like "*Core*") { - "Release15" - { - $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShell2013" - } - "Release16" - { - $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShell2016" - } - "Release19" - { - $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShell2019" - } - "Release" + $DestinationFolder = "$documentsFolder\PowerShell\Modules\PnPPowerShellCore" + } else { + switch($ConfigurationName) { - $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShellOnline" + "Release15" + { + $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShell2013" + } + "Release16" + { + $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShell2016" + } + "Release19" + { + $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShell2019" + } + "Release" + { + $DestinationFolder = "$documentsFolder\WindowsPowerShell\Modules\SharePointPnPPowerShellOnline" + } } } @@ -119,38 +124,44 @@ if($ConfigurationName -like "Debug*") { Copy-Item "$TargetDir\*.dll" -Destination "$DestinationFolder" Copy-Item "$TargetDir\*help.xml" -Destination "$DestinationFolder" - switch($ConfigurationName) + if($TargetDir -like "*Core*") { - "Release15" { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2013.psd1" -Destination "$DestinationFolder" - Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.2013.Commands.Format.ps1xml" -Destination "$DestinationFolder" - if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShell2013Aliases.psm1") - { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2013Aliases.psm1" -Destination "$DestinationFolder" - } - } - "Release16" { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2016.psd1" -Destination "$DestinationFolder" - Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.2016.Commands.Format.ps1xml" -Destination "$DestinationFolder" - if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShell2016Aliases.psm1") - { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2016Aliases.psm1" -Destination "$DestinationFolder" - } - } - "Release19" { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2019.psd1" -Destination "$DestinationFolder" - Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.2019.Commands.Format.ps1xml" -Destination "$DestinationFolder" - if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShell2019Aliases.psm1") - { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2019Aliases.psm1" -Destination "$DestinationFolder" - } - } - "Release" { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShellOnline.psd1" -Destination "$DestinationFolder" - Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.Online.Commands.Format.ps1xml" -Destination "$DestinationFolder" - if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShellOnlineAliases.psm1") - { - Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShellOnlineAliases.psm1" -Destination "$DestinationFolder" + Copy-Item "$TargetDir\ModuleFiles\PnPPowerShellCore.psd1" -Destination "$DestinationFolder" + Copy-Item "$TargetDir\ModuleFiles\PnP.PowerShell.Core.Format.ps1xml" -Destination "$DestinationFolder" + } else { + switch($ConfigurationName) + { + "Release15" { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2013.psd1" -Destination "$DestinationFolder" + Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.2013.Commands.Format.ps1xml" -Destination "$DestinationFolder" + if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShell2013Aliases.psm1") + { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2013Aliases.psm1" -Destination "$DestinationFolder" + } + } + "Release16" { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2016.psd1" -Destination "$DestinationFolder" + Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.2016.Commands.Format.ps1xml" -Destination "$DestinationFolder" + if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShell2016Aliases.psm1") + { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2016Aliases.psm1" -Destination "$DestinationFolder" + } + } + "Release19" { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2019.psd1" -Destination "$DestinationFolder" + Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.2019.Commands.Format.ps1xml" -Destination "$DestinationFolder" + if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShell2019Aliases.psm1") + { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShell2019Aliases.psm1" -Destination "$DestinationFolder" + } + } + "Release" { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShellOnline.psd1" -Destination "$DestinationFolder" + Copy-Item "$TargetDir\ModuleFiles\SharePointPnP.PowerShell.Online.Commands.Format.ps1xml" -Destination "$DestinationFolder" + if(Test-Path -Path "$TargetDir\ModuleFiles\SharePointPnPPowerShellOnlineAliases.psm1") + { + Copy-Item "$TargetDir\ModuleFiles\SharePointPnPPowerShellOnlineAliases.psm1" -Destination "$DestinationFolder" + } } } } From 2a521c80685691d33bd4cc2443431e968fb5e35b Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Thu, 2 Jul 2020 20:28:16 +0100 Subject: [PATCH 105/130] Fixed formatting and added param help based, class initialise --- Tests/Admin/AddPnPHubSiteAssociationTests.cs | 41 ++- .../Admin/AddPnPOffice365GroupToSiteTests.cs | 63 ++++- Tests/Admin/AddPnPOrgAssetsLibraryTests.cs | 43 +++- Tests/Admin/AddPnPOrgNewsSiteTests.cs | 37 ++- .../AddPnPSiteCollectionAppCatalogTests.cs | 37 ++- Tests/Admin/AddPnPTenantCdnOriginTests.cs | 41 ++- Tests/Admin/AddPnPTenantThemeTests.cs | 48 +++- Tests/Admin/GetPnPHideDefaultThemesTests.cs | 31 ++- Tests/Admin/GetPnPHomeSiteTests.cs | 31 ++- Tests/Admin/GetPnPHubSiteChildTests.cs | 37 ++- Tests/Admin/GetPnPHubSiteTests.cs | 35 ++- Tests/Admin/GetPnPKnowledgeHubSiteTests.cs | 31 ++- Tests/Admin/GetPnPOrgAssetsLibraryTests.cs | 31 ++- Tests/Admin/GetPnPOrgNewsSiteTests.cs | 31 ++- Tests/Admin/GetPnPTenantCdnEnabledTests.cs | 37 ++- Tests/Admin/GetPnPTenantCdnOriginTests.cs | 37 ++- Tests/Admin/GetPnPTenantCdnPoliciesTests.cs | 37 ++- Tests/Admin/GetPnPTenantIdTests.cs | 35 ++- .../GetPnPTenantSyncClientRestrictionTests.cs | 31 ++- Tests/Admin/GetPnPTenantTests.cs | 31 ++- Tests/Admin/GetPnPTenantThemeTests.cs | 36 ++- Tests/Admin/GrantPnPHubSiteRightsTests.cs | 44 +++- Tests/Admin/InvokePnPSPRestMethodTests.cs | 46 +++- Tests/Admin/RegisterPnPHubSiteTests.cs | 37 ++- Tests/Admin/RemovePnPHomeSiteTests.cs | 36 ++- .../Admin/RemovePnPHubSiteAssociationTests.cs | 37 ++- Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs | 31 ++- Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs | 43 +++- Tests/Admin/RemovePnPOrgNewsSiteTests.cs | 37 ++- .../RemovePnPSiteCollectionAppCatalogTests.cs | 37 ++- Tests/Admin/RemovePnPTenantCdnOriginTests.cs | 41 ++- Tests/Admin/RemovePnPTenantThemeTests.cs | 37 ++- Tests/Admin/RevokePnPHubSiteRightsTests.cs | 41 ++- Tests/Admin/SetPnPHideDefaultThemesTests.cs | 37 ++- Tests/Admin/SetPnPHomeSiteTests.cs | 37 ++- Tests/Admin/SetPnPHubSiteTests.cs | 53 +++- Tests/Admin/SetPnPKnowledgeHubSiteTests.cs | 36 ++- Tests/Admin/SetPnPTenantCdnEnabledTests.cs | 43 +++- Tests/Admin/SetPnPTenantCdnPolicyTests.cs | 45 +++- .../SetPnPTenantSyncClientRestrictionTests.cs | 51 +++- Tests/Admin/SetPnPTenantTests.cs | 240 +++++++++++++++++- Tests/Admin/UnregisterPnPHubSiteTests.cs | 37 ++- Tests/Apps/AddPnPAppTests.cs | 52 +++- ...tServicePrincipalPermissionRequestTests.cs | 39 ++- ...tServicePrincipalPermissionRequestTests.cs | 39 ++- .../DisablePnPTenantServicePrincipalTests.cs | 36 ++- .../EnablePnPTenantServicePrincipalTests.cs | 36 ++- Tests/Apps/GetPnPAppInstanceTests.cs | 36 ++- Tests/Apps/GetPnPAppTests.cs | 39 ++- ...ntServicePrincipalPermissionGrantsTests.cs | 31 ++- ...ServicePrincipalPermissionRequestsTests.cs | 31 ++- .../Apps/GetPnPTenantServicePrincipalTests.cs | 31 ++- ...nPTenantServicePrincipalPermissionTests.cs | 41 ++- Tests/Apps/ImportPnPAppPackageTests.cs | 46 +++- Tests/Apps/InstallPnPAppTests.cs | 43 +++- Tests/Apps/PublishPnPAppTests.cs | 42 ++- Tests/Apps/RegisterPnPAppCatalogSiteTests.cs | 48 +++- Tests/Apps/RemovePnPAppTests.cs | 40 ++- ...nPTenantServicePrincipalPermissionTests.cs | 39 ++- Tests/Apps/SyncPnPAppToTeamsTests.cs | 37 ++- Tests/Apps/UninstallPnPAppInstanceTests.cs | 40 ++- Tests/Apps/UninstallPnPAppTests.cs | 40 ++- Tests/Apps/UnpublishPnPAppTests.cs | 40 ++- Tests/Apps/UpdatePnPAppTests.cs | 40 ++- Tests/Base/AddPnPStoredCredentialTests.cs | 44 +++- Tests/Base/ConnectPnPOnlineTests.cs | 197 +++++++++++++- .../DisablePnPPowerShellTelemetryTests.cs | 36 ++- Tests/Base/DisconnectPnPOnlineTests.cs | 36 ++- .../Base/EnablePnPPowerShellTelemetryTests.cs | 36 ++- Tests/Base/GetPnPAccessTokenTests.cs | 36 ++- Tests/Base/GetPnPAppAuthAccessTokenTests.cs | 31 ++- Tests/Base/GetPnPAzureCertificateTests.cs | 40 ++- Tests/Base/GetPnPConnectionTests.cs | 31 ++- Tests/Base/GetPnPContextTests.cs | 31 ++- Tests/Base/GetPnPExceptionTests.cs | 36 ++- Tests/Base/GetPnPGraphAccessTokenTests.cs | 36 ++- Tests/Base/GetPnPHealthScoreTests.cs | 36 ++- .../GetPnPPowerShellTelemetryEnabledTests.cs | 31 ++- Tests/Base/GetPnPPropertyTests.cs | 41 ++- Tests/Base/GetPnPStoredCredentialTests.cs | 40 ++- ...tializePnPPowerShellAuthenticationTests.cs | 75 +++++- Tests/Base/InvokePnPQueryTests.cs | 39 ++- Tests/Base/NewPnPAzureCertificateTests.cs | 66 ++++- Tests/Base/RemovePnPStoredCredentialTests.cs | 40 ++- Tests/Base/RequestPnPAccessTokenTests.cs | 54 +++- Tests/Base/SetPnPContextTests.cs | 37 ++- Tests/Base/SetPnPTraceLogTests.cs | 59 ++++- .../AddPnPApplicationCustomizerTests.cs | 55 +++- Tests/Branding/AddPnPCustomActionTests.cs | 87 ++++++- Tests/Branding/AddPnPJavaScriptBlockTests.cs | 49 +++- Tests/Branding/AddPnPJavaScriptLinkTests.cs | 49 +++- Tests/Branding/AddPnPNavigationNodeTests.cs | 56 +++- Tests/Branding/DisablePnPResponsiveUITests.cs | 31 ++- Tests/Branding/EnablePnPResponsiveUITests.cs | 36 ++- .../GetPnPApplicationCustomizerTests.cs | 46 +++- Tests/Branding/GetPnPCustomActionTests.cs | 42 ++- Tests/Branding/GetPnPFooterTests.cs | 31 ++- Tests/Branding/GetPnPHomePageTests.cs | 31 ++- Tests/Branding/GetPnPJavaScriptLinkTests.cs | 42 ++- Tests/Branding/GetPnPNavigationNodeTests.cs | 42 ++- Tests/Branding/GetPnPThemeTests.cs | 36 ++- .../RemovePnPApplicationCustomizerTests.cs | 46 +++- Tests/Branding/RemovePnPCustomActionTests.cs | 42 ++- .../Branding/RemovePnPJavaScriptLinkTests.cs | 44 +++- .../Branding/RemovePnPNavigationNodeTests.cs | 55 +++- .../SetPnPApplicationCustomizerTests.cs | 54 +++- Tests/Branding/SetPnPFooterTests.cs | 48 +++- Tests/Branding/SetPnPHomePageTests.cs | 37 ++- Tests/Branding/SetPnPMasterPageTests.cs | 45 +++- .../SetPnPMinimalDownloadStrategyTests.cs | 44 +++- Tests/Branding/SetPnPThemeTests.cs | 51 +++- Tests/Branding/SetPnPWebThemeTests.cs | 39 ++- .../AddPnPClientSidePageSectionTests.cs | 47 +++- .../AddPnPClientSidePageTests.cs | 58 ++++- .../AddPnPClientSideTextTests.cs | 52 +++- .../ConvertToPnPClientSidePageTests.cs | 204 +++++++++++++++ .../ExportPnPClientSidePageMappingTests.cs | 98 +++++++ ...etPnPAvailableClientSideComponentsTests.cs | 40 ++- .../GetPnPClientSideComponentTests.cs | 40 ++- .../GetPnPClientSidePageTests.cs | 37 ++- .../MovePnPClientSideComponentTests.cs | 52 +++- .../RemovePnPClientSideComponentTests.cs | 44 +++- .../RemovePnPClientSidePageTests.cs | 40 ++- ...SavePnPClientSidePageConversionLogTests.cs | 74 ++++++ .../SetPnPClientSidePageTests.cs | 67 ++++- .../SetPnPClientSideTextTests.cs | 45 +++- .../SetPnPClientSideWebPartTests.cs | 47 +++- Tests/ContentTypes/AddPnPContentTypeTests.cs | 49 +++- .../AddPnPContentTypeToListTests.cs | 44 +++- .../AddPnPFieldToContentTypeTests.cs | 47 +++- .../GetPnPContentTypePublishingHubUrlTests.cs | 31 ++- Tests/ContentTypes/GetPnPContentTypeTests.cs | 42 ++- .../RemovePnPContentTypeFromListTests.cs | 41 ++- .../ContentTypes/RemovePnPContentTypeTests.cs | 40 ++- .../RemovePnPFieldFromContentTypeTests.cs | 44 +++- .../SetPnPDefaultContentTypeToListTests.cs | 41 ++- Tests/Diagnostic/MeasurePnPListTests.cs | 42 ++- .../Diagnostic/MeasurePnPResponseTimeTests.cs | 50 +++- Tests/Diagnostic/MeasurePnPWebTests.cs | 41 ++- .../AddPnPContentTypeToDocumentSetTests.cs | 41 ++- Tests/DocumentSets/AddPnPDocumentSetTests.cs | 45 +++- .../GetPnPDocumentSetTemplateTests.cs | 37 ++- ...emovePnPContentTypeFromDocumentSetTests.cs | 41 ++- .../SetPnPDocumentSetFieldTests.cs | 53 +++- Tests/Events/AddPnPEventReceiverTests.cs | 58 ++++- Tests/Events/GetPnPEventReceiverTests.cs | 39 ++- Tests/Events/RemovePnPEventReceiverTests.cs | 43 +++- .../NewPnPExtensibilityHandlerObjectTests.cs | 47 +++- Tests/Features/DisablePnPFeatureTests.cs | 43 +++- Tests/Features/EnablePnPFeatureTests.cs | 46 +++- Tests/Features/GetPnPFeatureTests.cs | 39 ++- Tests/Fields/AddPnPFieldFromXmlTests.cs | 40 ++- Tests/Fields/AddPnPFieldTests.cs | 70 ++++- Tests/Fields/AddPnPTaxonomyFieldTests.cs | 72 +++++- Tests/Fields/GetPnPFieldTests.cs | 45 +++- Tests/Fields/RemovePnPFieldTests.cs | 43 +++- Tests/Fields/SetPnPFieldTests.cs | 47 +++- Tests/Fields/SetPnPViewTests.cs | 49 +++- Tests/Files/AddPnPFileTests.cs | 97 ++++++- Tests/Files/AddPnPFolderTests.cs | 41 ++- Tests/Files/CopyPnPFileTests.cs | 54 +++- Tests/Files/FindPnPFileTests.cs | 45 +++- Tests/Files/GetPnPFileTests.cs | 61 ++++- Tests/Files/GetPnPFolderItemTests.cs | 48 +++- Tests/Files/GetPnPFolderTests.cs | 41 ++- Tests/Files/MovePnPFileTests.cs | 64 ++++- Tests/Files/MovePnPFolderTests.cs | 41 ++- Tests/Files/RemovePnPFileTests.cs | 45 +++- Tests/Files/RemovePnPFolderTests.cs | 45 +++- Tests/Files/RenamePnPFileTests.cs | 51 +++- Tests/Files/RenamePnPFolderTests.cs | 41 ++- Tests/Files/ResetPnPFileVersionTests.cs | 43 +++- Tests/Files/ResolvePnPFolderTests.cs | 37 ++- Tests/Files/SetPnPFileCheckedInTests.cs | 46 +++- Tests/Files/SetPnPFileCheckedOutTests.cs | 37 ++- Tests/Files/SetPnPFolderPermissionTests.cs | 62 ++++- Tests/Graph/AddPnPSiteClassificationTests.cs | 36 ++- .../DisablePnPSiteClassificationTests.cs | 31 ++- .../Graph/EnablePnPSiteClassificationTests.cs | 41 ++- Tests/Graph/GetPnPAADUserTests.cs | 52 +++- Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs | 36 ++- Tests/Graph/GetPnPGraphSubscriptionTests.cs | 36 ++- Tests/Graph/GetPnPSiteClassificationTests.cs | 31 ++- Tests/Graph/GetPnPUnifiedGroupMembersTests.cs | 37 ++- Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs | 37 ++- Tests/Graph/GetPnPUnifiedGroupTests.cs | 45 +++- Tests/Graph/NewPnPGraphSubscriptionTests.cs | 54 +++- Tests/Graph/NewPnPUnifiedGroupTests.cs | 63 ++++- .../RemovePnPDeletedUnifiedGroupTests.cs | 37 ++- .../Graph/RemovePnPGraphSubscriptionTests.cs | 37 ++- .../Graph/RemovePnPSiteClassificationTests.cs | 39 ++- Tests/Graph/RemovePnPUnifiedGroupTests.cs | 37 ++- .../ResetPnPUnifiedGroupExpirationTests.cs | 37 ++- .../RestorePnPDeletedUnifiedGroupTests.cs | 37 ++- Tests/Graph/SetPnPGraphSubscriptionTests.cs | 41 ++- Tests/Graph/SetPnPUnifiedGroupTests.cs | 58 ++++- .../Graph/UpdatePnPSiteClassificationTests.cs | 46 +++- .../InformationManagement/GetPnPLabelTests.cs | 40 ++- ...PnPListInformationRightsManagementTests.cs | 36 ++- .../GetPnPSiteClosureTests.cs | 31 ++- .../GetPnPSitePolicyTests.cs | 39 ++- .../ResetPnPLabelTests.cs | 40 ++- .../InformationManagement/SetPnPLabelTests.cs | 50 +++- ...PnPListInformationRightsManagementTests.cs | 90 ++++++- .../SetPnPSiteClosureTests.cs | 37 ++- .../SetPnPSitePolicyTests.cs | 37 ++- Tests/Lists/AddPnPListItemTests.cs | 68 ++++- Tests/Lists/AddPnPViewTests.cs | 66 ++++- .../Lists/ClearPnPDefaultColumnValuesTests.cs | 44 +++- Tests/Lists/GetPnPDefaultColumnValuesTests.cs | 37 ++- Tests/Lists/GetPnPListItemTests.cs | 58 ++++- Tests/Lists/GetPnPListTests.cs | 39 ++- Tests/Lists/GetPnPViewTests.cs | 40 ++- .../Lists/MovePnPListItemToRecycleBinTests.cs | 44 +++- Tests/Lists/NewPnPListTests.cs | 59 ++++- Tests/Lists/RemovePnPListItemTests.cs | 46 +++- Tests/Lists/RemovePnPListTests.cs | 43 +++- Tests/Lists/RemovePnPViewTests.cs | 44 +++- Tests/Lists/RequestPnPReIndexListTests.cs | 37 ++- Tests/Lists/SetPnPDefaultColumnValuesTests.cs | 48 +++- Tests/Lists/SetPnPListItemPermissionTests.cs | 62 ++++- Tests/Lists/SetPnPListItemTests.cs | 72 +++++- Tests/Lists/SetPnPListPermissionTests.cs | 49 +++- Tests/Lists/SetPnPListTests.cs | 88 ++++++- .../GetPnPManagementApiAccessTokenTests.cs | 45 +++- ...etPnPOffice365CurrentServiceStatusTests.cs | 36 ++- ...nPOffice365HistoricalServiceStatusTests.cs | 36 ++- .../GetPnPOffice365ServiceMessageTests.cs | 36 ++- .../GetPnPOffice365ServicesTests.cs | 31 ++- ...tPnPOfficeManagementApiAccessTokenTests.cs | 36 ++- .../GetPnPUnifiedAuditLogTests.cs | 42 ++- Tests/Principals/AddPnPAlertTests.cs | 58 ++++- Tests/Principals/AddPnPUserToGroupTests.cs | 49 +++- Tests/Principals/GetPnPAlertTests.cs | 42 ++- Tests/Principals/GetPnPGroupMembersTests.cs | 37 ++- .../Principals/GetPnPGroupPermissionsTests.cs | 37 ++- Tests/Principals/GetPnPGroupTests.cs | 45 +++- Tests/Principals/GetPnPUserTests.cs | 39 ++- Tests/Principals/NewPnPGroupTests.cs | 63 ++++- Tests/Principals/NewPnPUserTests.cs | 37 ++- Tests/Principals/RemovePnPAlertTests.cs | 43 +++- Tests/Principals/RemovePnPGroupTests.cs | 39 ++- .../Principals/RemovePnPUserFromGroupTests.cs | 41 ++- Tests/Principals/RemovePnPUserTests.cs | 43 +++- .../Principals/SetPnPGroupPermissionsTests.cs | 46 +++- Tests/Principals/SetPnPGroupTests.cs | 70 ++++- ...dPnPDataRowsToProvisioningTemplateTests.cs | 56 +++- .../AddPnPFileToProvisioningTemplateTests.cs | 61 ++++- ...PListFoldersToProvisioningTemplateTests.cs | 50 +++- .../ApplyPnPProvisioningTemplateTests.cs | 76 +++++- ...xportPnPListToProvisioningTemplateTests.cs | 49 +++- .../GetPnPProvisioningTemplateTests.cs | 126 ++++++++- .../GetPnPTenantTemplateTests.cs | 49 +++- ...ovePnPFileFromProvisioningTemplateTests.cs | 44 +++- ...SetPnPProvisioningTemplateMetadataTests.cs | 49 +++- .../AddPnPProvisioningTemplateTests.cs | 41 ++- .../AddPnPTenantSequenceSiteTests.cs | 40 ++- .../AddPnPTenantSequenceSubSiteTests.cs | 41 ++- .../AddPnPTenantSequenceTests.cs | 41 ++- .../ApplyPnPTenantTemplateTests.cs | 78 +++++- .../ExportPnPClientSidePageTests.cs | 49 +++- .../GetPnPTenantSequenceSiteTests.cs | 40 ++- .../GetPnPTenantSequenceTests.cs | 40 ++- ...PnPTenantSequenceCommunicationSiteTests.cs | 55 +++- ...ewPnPTenantSequenceTeamNoGroupSiteTests.cs | 52 +++- ...nPTenantSequenceTeamNoGroupSubSiteTests.cs | 52 +++- .../NewPnPTenantSequenceTeamSiteTests.cs | 51 +++- .../NewPnPTenantSequenceTests.cs | 36 ++- .../NewPnPTenantTemplateTests.cs | 41 ++- .../ReadPnPTenantTemplateTests.cs | 40 ++- .../SavePnPTenantTemplateTests.cs | 47 +++- .../TestPnPTenantTemplateTests.cs | 37 ++- .../AddPnPHtmlPublishingPageLayoutTests.cs | 52 +++- Tests/Publishing/AddPnPMasterPageTests.cs | 54 +++- .../AddPnPPublishingImageRenditionTests.cs | 45 +++- .../AddPnPPublishingPageLayoutTests.cs | 52 +++- Tests/Publishing/AddPnPPublishingPageTests.cs | 50 +++- Tests/Publishing/AddPnPWikiPageTests.cs | 43 +++- .../GetPnPPublishingImageRenditionTests.cs | 36 ++- .../Publishing/GetPnPWikiPageContentTests.cs | 37 ++- .../RemovePnPPublishingImageRenditionTests.cs | 40 ++- Tests/Publishing/RemovePnPWikiPageTests.cs | 39 ++- .../SetPnPAvailablePageLayoutsTests.cs | 45 +++- .../SetPnPDefaultPageLayoutTests.cs | 41 ++- .../Publishing/SetPnPWikiPageContentTests.cs | 43 +++- .../ClearPnPListItemAsRecordTests.cs | 41 ++- ...PnPInPlaceRecordsManagementForSiteTests.cs | 31 ++- ...PnPInPlaceRecordsManagementForSiteTests.cs | 31 ++- .../GetPnPInPlaceRecordsManagementTests.cs | 31 ++- .../GetPnPListRecordDeclarationTests.cs | 37 ++- .../SetPnPInPlaceRecordsManagementTests.cs | 44 +++- .../SetPnPListItemAsRecordTests.cs | 44 +++- .../SetPnPListRecordDeclarationTests.cs | 43 +++- .../TestPnPListItemIsRecordTests.cs | 41 ++- .../RecycleBin/ClearPnPRecycleBinItemTests.cs | 46 +++- .../ClearPnPTenantRecycleBinItemTests.cs | 43 +++- Tests/RecycleBin/GetPnPRecycleBinItemTests.cs | 45 +++- .../GetPnPTenantRecycleBinItemTests.cs | 31 ++- .../RecycleBin/MovePnPRecycleBinItemTests.cs | 39 ++- .../RestorePnPRecycleBinItemTests.cs | 44 +++- .../RestorePnPTenantRecycleBinItemTests.cs | 43 +++- .../Search/GetPnPSearchConfigurationTests.cs | 42 ++- Tests/Search/GetPnPSearchCrawlLogTests.cs | 54 +++- Tests/Search/GetPnPSearchSettingsTests.cs | 31 ++- .../GetPnPSiteSearchQueryResultsTests.cs | 45 +++- .../RemovePnPSearchConfigurationTests.cs | 43 +++- .../Search/SetPnPSearchConfigurationTests.cs | 43 +++- Tests/Search/SetPnPSearchSettingsTests.cs | 48 +++- Tests/Search/SubmitPnPSearchQueryTests.cs | 106 +++++++- Tests/Site/AddPnPRoleDefinitionTests.cs | 49 +++- Tests/Site/AddPnPSiteCollectionAdminTests.cs | 37 ++- Tests/Site/AddPnPTeamsTeamTests.cs | 31 ++- ...isablePnPSharingForNonOwnersOfSiteTests.cs | 35 ++- Tests/Site/EnablePnPCommSiteTests.cs | 36 ++- Tests/Site/GetPnPAuditingTests.cs | 31 ++- Tests/Site/GetPnPRoleDefinitionTests.cs | 36 ++- .../GetPnPSharingForNonOwnersOfSiteTests.cs | 35 ++- Tests/Site/GetPnPSiteCollectionAdminTests.cs | 31 ++- Tests/Site/GetPnPSiteTests.cs | 31 ++- Tests/Site/InstallPnPSolutionTests.cs | 47 +++- Tests/Site/RemovePnPRoleDefinitionTests.cs | 40 ++- .../Site/RemovePnPSiteCollectionAdminTests.cs | 37 ++- Tests/Site/SetPnPAppSideLoadingTests.cs | 39 ++- Tests/Site/SetPnPAuditingTests.cs | 68 ++++- Tests/Site/SetPnPSiteTests.cs | 102 +++++++- .../TestPnPOffice365GroupAliasIsUsedTests.cs | 37 ++- Tests/Site/UninstallPnPSolutionTests.cs | 47 +++- .../SiteDesigns/AddPnPSiteDesignTaskTests.cs | 40 ++- .../GetPnPSiteDesignRunStatusTests.cs | 37 ++- Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs | 39 ++- .../SiteDesigns/GetPnPSiteDesignTaskTests.cs | 39 ++- Tests/Taxonomy/ExportPnPTaxonomyTests.cs | 57 ++++- .../Taxonomy/ExportPnPTermGroupToXmlTests.cs | 48 +++- .../GetPnPSiteCollectionTermStoreTests.cs | 31 ++- Tests/Taxonomy/GetPnPTaxonomyItemTests.cs | 37 ++- Tests/Taxonomy/GetPnPTaxonomySessionTests.cs | 31 ++- Tests/Taxonomy/GetPnPTermGroupTests.cs | 39 ++- Tests/Taxonomy/GetPnPTermSetTests.cs | 43 +++- Tests/Taxonomy/GetPnPTermTests.cs | 54 +++- Tests/Taxonomy/ImportPnPTaxonomyTests.cs | 51 +++- .../ImportPnPTermGroupFromXmlTests.cs | 39 ++- Tests/Taxonomy/ImportPnPTermSetTests.cs | 59 ++++- Tests/Taxonomy/NewPnPTermGroupTests.cs | 46 +++- Tests/Taxonomy/NewPnPTermLabelTests.cs | 48 +++- Tests/Taxonomy/NewPnPTermSetTests.cs | 70 ++++- Tests/Taxonomy/NewPnPTermTests.cs | 63 ++++- Tests/Taxonomy/RemovePnPTaxonomyItemTests.cs | 39 ++- Tests/Taxonomy/RemovePnPTermGroupTests.cs | 42 ++- .../Taxonomy/SetPnPTaxonomyFieldValueTests.cs | 55 +++- .../GetPnPUPABulkImportStatusTests.cs | 39 ++- .../GetPnPUserOneDriveQuotaTests.cs | 37 ++- .../GetPnPUserProfilePropertyTests.cs | 37 ++- Tests/UserProfiles/NewPnPPersonalSiteTests.cs | 37 ++- .../NewPnPUPABulkImportJobTests.cs | 52 +++- ...ResetPnPUserOneDriveQuotaToDefaultTests.cs | 37 ++- .../SetPnPUserOneDriveQuotaTests.cs | 45 +++- .../SetPnPUserProfilePropertyTests.cs | 49 +++- Tests/Utilities/SendPnPMailTests.cs | 56 +++- .../WebParts/AddPnPClientSideWebPartTests.cs | 59 ++++- .../AddPnPWebPartToWebPartPageTests.cs | 53 +++- .../WebParts/AddPnPWebPartToWikiPageTests.cs | 56 +++- Tests/WebParts/GetPnPWebPartPropertyTests.cs | 44 +++- Tests/WebParts/GetPnPWebPartTests.cs | 40 ++- Tests/WebParts/GetPnPWebPartXmlTests.cs | 41 ++- Tests/WebParts/RemovePnPWebPartTests.cs | 45 +++- Tests/WebParts/SetPnPWebPartPropertyTests.cs | 49 +++- .../AddPnPWebhookSubscriptionTests.cs | 46 +++- .../GetPnPWebhookSubscriptionsTests.cs | 36 ++- .../RemovePnPWebhookSubscriptionTests.cs | 43 +++- .../SetPnPWebhookSubscriptionTests.cs | 46 +++- .../AddPnPWorkflowDefinitionTests.cs | 40 ++- .../AddPnPWorkflowSubscriptionTests.cs | 64 ++++- .../GetPnPWorkflowDefinitionTests.cs | 39 ++- .../Workflows/GetPnPWorkflowInstanceTests.cs | 45 +++- .../GetPnPWorkflowSubscriptionTests.cs | 39 ++- .../RemovePnPWorkflowDefinitionTests.cs | 37 ++- .../RemovePnPWorkflowSubscriptionTests.cs | 37 ++- .../ResumePnPWorkflowInstanceTests.cs | 37 ++- .../StartPnPWorkflowInstanceTests.cs | 41 ++- .../Workflows/StopPnPWorkflowInstanceTests.cs | 40 ++- 380 files changed, 13349 insertions(+), 4113 deletions(-) create mode 100644 Tests/ClientSidePages/ConvertToPnPClientSidePageTests.cs create mode 100644 Tests/ClientSidePages/ExportPnPClientSidePageMappingTests.cs create mode 100644 Tests/ClientSidePages/SavePnPClientSidePageConversionLogTests.cs diff --git a/Tests/Admin/AddPnPHubSiteAssociationTests.cs b/Tests/Admin/AddPnPHubSiteAssociationTests.cs index 65f3c7b80..28c338484 100644 --- a/Tests/Admin/AddPnPHubSiteAssociationTests.cs +++ b/Tests/Admin/AddPnPHubSiteAssociationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddHubSiteAssociationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPHubSiteAssociationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPHubSiteAssociation",new CommandParameter("Site", "null"),new CommandParameter("HubSite", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The site to connect to the hubsite + var site = ""; + // This is a mandatory parameter + // From Cmdlet Help: The hubsite to connect the site to + var hubSite = ""; + + var results = scope.ExecuteCommand("Add-PnPHubSiteAssociation", + new CommandParameter("Site", site), + new CommandParameter("HubSite", hubSite)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs b/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs index 5684e14bb..293e1b13e 100644 --- a/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs +++ b/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddOffice365GroupToSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,53 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPOffice365GroupToSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPOffice365GroupToSite",new CommandParameter("Url", "null"),new CommandParameter("Alias", "null"),new CommandParameter("Description", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Classification", "null"),new CommandParameter("IsPublic", "null"),new CommandParameter("KeepOldHomePage", "null"),new CommandParameter("HubSiteId", "null"),new CommandParameter("Owners", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Url of the site to be connected to an Microsoft 365 Group + var url = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifies the alias of the group. Cannot contain spaces. + var alias = ""; + // From Cmdlet Help: The optional description of the group + var description = ""; + // This is a mandatory parameter + // From Cmdlet Help: The display name of the group + var displayName = ""; + // From Cmdlet Help: Specifies the classification of the group + var classification = ""; + // From Cmdlet Help: Specifies if the group is public. Defaults to false. + var isPublic = ""; + // From Cmdlet Help: Specifies if the current site home page is kept. Defaults to false. + var keepOldHomePage = ""; + // From Cmdlet Help: If specified the site will be associated to the hubsite as identified by this id + var hubSiteId = ""; + // From Cmdlet Help: The array UPN values of the group's owners. + var owners = ""; + + var results = scope.ExecuteCommand("Add-PnPOffice365GroupToSite", + new CommandParameter("Url", url), + new CommandParameter("Alias", alias), + new CommandParameter("Description", description), + new CommandParameter("DisplayName", displayName), + new CommandParameter("Classification", classification), + new CommandParameter("IsPublic", isPublic), + new CommandParameter("KeepOldHomePage", keepOldHomePage), + new CommandParameter("HubSiteId", hubSiteId), + new CommandParameter("Owners", owners)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs b/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs index 755abf1e3..25d7d3060 100644 --- a/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs +++ b/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddOrgAssetsLibraryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPOrgAssetsLibraryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPOrgAssetsLibrary",new CommandParameter("LibraryUrl", "null"),new CommandParameter("ThumbnailUrl", "null"),new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The full url of the document library to be marked as one of organization's assets sources + var libraryUrl = ""; + // From Cmdlet Help: The full url to an image that should be used as a thumbnail for showing this source. The image must reside in the same site as the document library you specify. + var thumbnailUrl = ""; + // From Cmdlet Help: Indicates what type of Office 365 CDN source the document library will be added to + var cdnType = ""; + + var results = scope.ExecuteCommand("Add-PnPOrgAssetsLibrary", + new CommandParameter("LibraryUrl", libraryUrl), + new CommandParameter("ThumbnailUrl", thumbnailUrl), + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/AddPnPOrgNewsSiteTests.cs b/Tests/Admin/AddPnPOrgNewsSiteTests.cs index 4f0bb241c..02b1fc340 100644 --- a/Tests/Admin/AddPnPOrgNewsSiteTests.cs +++ b/Tests/Admin/AddPnPOrgNewsSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddOrgNewsSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPOrgNewsSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPOrgNewsSite",new CommandParameter("OrgNewsSiteUrl", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The url of the site to be marked as one of organization's news sites + var orgNewsSiteUrl = ""; + + var results = scope.ExecuteCommand("Add-PnPOrgNewsSite", + new CommandParameter("OrgNewsSiteUrl", orgNewsSiteUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs b/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs index 277895f22..d6f9474fb 100644 --- a/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs +++ b/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddSiteCollectionAppCatalogTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPSiteCollectionAppCatalogTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPSiteCollectionAppCatalog",new CommandParameter("Site", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Url of the site to add the app catalog to. + var site = ""; + + var results = scope.ExecuteCommand("Add-PnPSiteCollectionAppCatalog", + new CommandParameter("Site", site)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/AddPnPTenantCdnOriginTests.cs b/Tests/Admin/AddPnPTenantCdnOriginTests.cs index bb071c2dd..be278a1b7 100644 --- a/Tests/Admin/AddPnPTenantCdnOriginTests.cs +++ b/Tests/Admin/AddPnPTenantCdnOriginTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddTenantCdnOriginTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTenantCdnOriginTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPTenantCdnOrigin",new CommandParameter("OriginUrl", "null"),new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies a path to the doc library to be configured. It can be provided in two ways: relative path, or a mask.Relative-Relative path depends on the OriginScope. If the originScope is Tenant, a path must be a relative path under the tenant root. If the originScope is Site, a path must be a relative path under the given Site. The path must point to the valid Document Library or a folder with a document library. + var originUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifies the CDN type. The valid values are: public or private. + var cdnType = ""; + + var results = scope.ExecuteCommand("Add-PnPTenantCdnOrigin", + new CommandParameter("OriginUrl", originUrl), + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/AddPnPTenantThemeTests.cs b/Tests/Admin/AddPnPTenantThemeTests.cs index a977d3b6a..8a4af5c8d 100644 --- a/Tests/Admin/AddPnPTenantThemeTests.cs +++ b/Tests/Admin/AddPnPTenantThemeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class AddTenantThemeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,38 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTenantThemeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPTenantTheme",new CommandParameter("Overwrite", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Palette", "null"),new CommandParameter("IsInverted", "null")); + + // From Cmdlet Help: If a theme is already present, specifying this will overwrite the existing theme + var overwrite = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the theme to add or update + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: The palette to add. See examples for more information. + var palette = ""; + // This is a mandatory parameter + // From Cmdlet Help: If the theme is inverted or not + var isInverted = ""; + + var results = scope.ExecuteCommand("Add-PnPTenantTheme", + new CommandParameter("Overwrite", overwrite), + new CommandParameter("Identity", identity), + new CommandParameter("Palette", palette), + new CommandParameter("IsInverted", isInverted)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPHideDefaultThemesTests.cs b/Tests/Admin/GetPnPHideDefaultThemesTests.cs index 5b2fdfa8c..41747104e 100644 --- a/Tests/Admin/GetPnPHideDefaultThemesTests.cs +++ b/Tests/Admin/GetPnPHideDefaultThemesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetHideDefaultThemesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPHideDefaultThemesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPHideDefaultThemes"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPHomeSiteTests.cs b/Tests/Admin/GetPnPHomeSiteTests.cs index 152feed22..8a89b6832 100644 --- a/Tests/Admin/GetPnPHomeSiteTests.cs +++ b/Tests/Admin/GetPnPHomeSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetHomeSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPHomeSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPHomeSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPHubSiteChildTests.cs b/Tests/Admin/GetPnPHubSiteChildTests.cs index 3a411e5a7..4fe765392 100644 --- a/Tests/Admin/GetPnPHubSiteChildTests.cs +++ b/Tests/Admin/GetPnPHubSiteChildTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetHubSiteChildTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPHubSiteChildTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPHubSiteChild",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The URL of the hubsite for which to receive the sites refering to it + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPHubSiteChild", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPHubSiteTests.cs b/Tests/Admin/GetPnPHubSiteTests.cs index d441fbe0e..84c21d66e 100644 --- a/Tests/Admin/GetPnPHubSiteTests.cs +++ b/Tests/Admin/GetPnPHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,25 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPHubSite",new CommandParameter("Identity", "null")); + + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPHubSite", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs b/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs index c8790a82e..aa4311dd6 100644 --- a/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs +++ b/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetKnowledgeHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPKnowledgeHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPKnowledgeHubSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs b/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs index 81402805c..94e626ef4 100644 --- a/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs +++ b/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetOrgAssetsLibraryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOrgAssetsLibraryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPOrgAssetsLibrary"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPOrgNewsSiteTests.cs b/Tests/Admin/GetPnPOrgNewsSiteTests.cs index db8fee138..02596d39a 100644 --- a/Tests/Admin/GetPnPOrgNewsSiteTests.cs +++ b/Tests/Admin/GetPnPOrgNewsSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetOrgNewsSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOrgNewsSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPOrgNewsSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantCdnEnabledTests.cs b/Tests/Admin/GetPnPTenantCdnEnabledTests.cs index 1a07cf312..cec67e04e 100644 --- a/Tests/Admin/GetPnPTenantCdnEnabledTests.cs +++ b/Tests/Admin/GetPnPTenantCdnEnabledTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetTenantCdnEnabledTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantCdnEnabledTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantCdnEnabled",new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The type of cdn to retrieve the origins from + var cdnType = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantCdnEnabled", + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantCdnOriginTests.cs b/Tests/Admin/GetPnPTenantCdnOriginTests.cs index 48acf3c1a..972cdb09e 100644 --- a/Tests/Admin/GetPnPTenantCdnOriginTests.cs +++ b/Tests/Admin/GetPnPTenantCdnOriginTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetTenantCdnOriginTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantCdnOriginTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantCdnOrigin",new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The type of cdn to retrieve the origins from + var cdnType = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantCdnOrigin", + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs b/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs index c1a8f3f02..d3a8d7796 100644 --- a/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs +++ b/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetTenantCdnPoliciesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantCdnPoliciesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantCdnPolicies",new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The type of cdn to retrieve the policies from + var cdnType = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantCdnPolicies", + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantIdTests.cs b/Tests/Admin/GetPnPTenantIdTests.cs index 0ef05183b..ffe0b24ba 100644 --- a/Tests/Admin/GetPnPTenantIdTests.cs +++ b/Tests/Admin/GetPnPTenantIdTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetTenantIdTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,25 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantIdTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantId",new CommandParameter("TenantUrl", "null")); + + var tenantUrl = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantId", + new CommandParameter("TenantUrl", tenantUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs b/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs index 8b9ddb5b9..436e37ac0 100644 --- a/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs +++ b/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetPnPTenantSyncClientRestrictionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantSyncClientRestrictionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPTenantSyncClientRestriction"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantTests.cs b/Tests/Admin/GetPnPTenantTests.cs index 618525a4c..82a27b1c2 100644 --- a/Tests/Admin/GetPnPTenantTests.cs +++ b/Tests/Admin/GetPnPTenantTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetTenantTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPTenant"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GetPnPTenantThemeTests.cs b/Tests/Admin/GetPnPTenantThemeTests.cs index 8dbd29161..2c6740a19 100644 --- a/Tests/Admin/GetPnPTenantThemeTests.cs +++ b/Tests/Admin/GetPnPTenantThemeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GetTenantThemeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantThemeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantTheme",new CommandParameter("Name", "null")); + + // From Cmdlet Help: The name of the theme to retrieve + var name = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantTheme", + new CommandParameter("Name", name)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/GrantPnPHubSiteRightsTests.cs b/Tests/Admin/GrantPnPHubSiteRightsTests.cs index 8fc750395..743eaf24c 100644 --- a/Tests/Admin/GrantPnPHubSiteRightsTests.cs +++ b/Tests/Admin/GrantPnPHubSiteRightsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class GrantHubSiteRightsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GrantPnPHubSiteRightsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Grant-PnPHubSiteRights",new CommandParameter("Identity", "null"),new CommandParameter("Principals", "null"),new CommandParameter("Rights", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Hub Site to set the permissions on to associate another site with this Hub Site + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: One or more usernames that will be given or revoked the permission to associate a site with this Hub Site. It does not replace permissions given out before but adds to the already existing permissions. + var principals = ""; + // From Cmdlet Help: Provide Join to give permissions to associate a site with this Hub Site or use None to revoke the permissions for the user(s) specified with the Principals argument + var rights = ""; + + var results = scope.ExecuteCommand("Grant-PnPHubSiteRights", + new CommandParameter("Identity", identity), + new CommandParameter("Principals", principals), + new CommandParameter("Rights", rights)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/InvokePnPSPRestMethodTests.cs b/Tests/Admin/InvokePnPSPRestMethodTests.cs index 51c873f6b..e809ad394 100644 --- a/Tests/Admin/InvokePnPSPRestMethodTests.cs +++ b/Tests/Admin/InvokePnPSPRestMethodTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class InvokeSPRestMethodTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void InvokePnPSPRestMethodTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Invoke-PnPSPRestMethod",new CommandParameter("Method", "null"),new CommandParameter("Url", "null"),new CommandParameter("Content", "null"),new CommandParameter("ContentType", "null")); + + // From Cmdlet Help: The Http method to execute. Defaults to GET. + var method = ""; + // This is a mandatory parameter + // From Cmdlet Help: The url to execute. + var url = ""; + // From Cmdlet Help: A string or object to send + var content = ""; + // From Cmdlet Help: The content type of the object to send. Defaults to 'application/json' + var contentType = ""; + + var results = scope.ExecuteCommand("Invoke-PnPSPRestMethod", + new CommandParameter("Method", method), + new CommandParameter("Url", url), + new CommandParameter("Content", content), + new CommandParameter("ContentType", contentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RegisterPnPHubSiteTests.cs b/Tests/Admin/RegisterPnPHubSiteTests.cs index 3f832a5e4..cfc40ad45 100644 --- a/Tests/Admin/RegisterPnPHubSiteTests.cs +++ b/Tests/Admin/RegisterPnPHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RegisterHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RegisterPnPHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Register-PnPHubSite",new CommandParameter("Site", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The site to register as a hubsite + var site = ""; + + var results = scope.ExecuteCommand("Register-PnPHubSite", + new CommandParameter("Site", site)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPHomeSiteTests.cs b/Tests/Admin/RemovePnPHomeSiteTests.cs index 92566d0ba..dc7a3720a 100644 --- a/Tests/Admin/RemovePnPHomeSiteTests.cs +++ b/Tests/Admin/RemovePnPHomeSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveHomeSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPHomeSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPHomeSite",new CommandParameter("Force", "null")); + + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPHomeSite", + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPHubSiteAssociationTests.cs b/Tests/Admin/RemovePnPHubSiteAssociationTests.cs index 3b356fb2a..259e236f7 100644 --- a/Tests/Admin/RemovePnPHubSiteAssociationTests.cs +++ b/Tests/Admin/RemovePnPHubSiteAssociationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveHubSiteAssociationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPHubSiteAssociationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPHubSiteAssociation",new CommandParameter("Site", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The site to disconnect from its hubsite + var site = ""; + + var results = scope.ExecuteCommand("Remove-PnPHubSiteAssociation", + new CommandParameter("Site", site)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs b/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs index ec5e64ad2..b0b9c0325 100644 --- a/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs +++ b/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveKnowledgeHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPKnowledgeHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Remove-PnPKnowledgeHubSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs b/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs index 3bb731ce9..aee0b3589 100644 --- a/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs +++ b/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveOrgAssetsLibraryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPOrgAssetsLibraryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPOrgAssetsLibrary",new CommandParameter("LibraryUrl", "null"),new CommandParameter("ShouldRemoveFromCdn", "null"),new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The server relative url of the document library flagged as organizational asset which you want to remove, i.e. "sites/branding/logos" + var libraryUrl = ""; + // From Cmdlet Help: Boolean indicating if the document library that will no longer be flagged as an organizational asset also needs to be removed as an Office 365 CDN source + var shouldRemoveFromCdn = ""; + // From Cmdlet Help: Indicates what type of Office 365 CDN source the document library that will no longer be flagged as an organizational asset was of + var cdnType = ""; + + var results = scope.ExecuteCommand("Remove-PnPOrgAssetsLibrary", + new CommandParameter("LibraryUrl", libraryUrl), + new CommandParameter("ShouldRemoveFromCdn", shouldRemoveFromCdn), + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPOrgNewsSiteTests.cs b/Tests/Admin/RemovePnPOrgNewsSiteTests.cs index 2ce92e694..cb949ae67 100644 --- a/Tests/Admin/RemovePnPOrgNewsSiteTests.cs +++ b/Tests/Admin/RemovePnPOrgNewsSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveOrgNewsSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPOrgNewsSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPOrgNewsSite",new CommandParameter("OrgNewsSiteUrl", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The site to be removed from list of organization's news sites + var orgNewsSiteUrl = ""; + + var results = scope.ExecuteCommand("Remove-PnPOrgNewsSite", + new CommandParameter("OrgNewsSiteUrl", orgNewsSiteUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs b/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs index ce5de5b71..cf7f06dda 100644 --- a/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs +++ b/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveSiteCollectionAppCatalogTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPSiteCollectionAppCatalogTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPSiteCollectionAppCatalog",new CommandParameter("Site", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Url of the site to remove the app catalog from. + var site = ""; + + var results = scope.ExecuteCommand("Remove-PnPSiteCollectionAppCatalog", + new CommandParameter("Site", site)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPTenantCdnOriginTests.cs b/Tests/Admin/RemovePnPTenantCdnOriginTests.cs index 51df7f601..be66409d5 100644 --- a/Tests/Admin/RemovePnPTenantCdnOriginTests.cs +++ b/Tests/Admin/RemovePnPTenantCdnOriginTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveTenantCdnOriginTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPTenantCdnOriginTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPTenantCdnOrigin",new CommandParameter("OriginUrl", "null"),new CommandParameter("CdnType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The origin to remove. + var originUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: The cdn type to remove the origin from. + var cdnType = ""; + + var results = scope.ExecuteCommand("Remove-PnPTenantCdnOrigin", + new CommandParameter("OriginUrl", originUrl), + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RemovePnPTenantThemeTests.cs b/Tests/Admin/RemovePnPTenantThemeTests.cs index 9dcd6b77b..d507e5da9 100644 --- a/Tests/Admin/RemovePnPTenantThemeTests.cs +++ b/Tests/Admin/RemovePnPTenantThemeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RemoveTenantThemeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPTenantThemeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPTenantTheme",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the theme to retrieve + var identity = ""; + + var results = scope.ExecuteCommand("Remove-PnPTenantTheme", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/RevokePnPHubSiteRightsTests.cs b/Tests/Admin/RevokePnPHubSiteRightsTests.cs index c3061d58c..aa7814c81 100644 --- a/Tests/Admin/RevokePnPHubSiteRightsTests.cs +++ b/Tests/Admin/RevokePnPHubSiteRightsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class RevokeHubSiteRightsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RevokePnPHubSiteRightsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Revoke-PnPHubSiteRights",new CommandParameter("Identity", "null"),new CommandParameter("Principals", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Hub Site to revoke the permissions on to associate another site with this Hub Site + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: One or more usernames that will be revoked the permission to associate a site with this Hub Site. + var principals = ""; + + var results = scope.ExecuteCommand("Revoke-PnPHubSiteRights", + new CommandParameter("Identity", identity), + new CommandParameter("Principals", principals)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPHideDefaultThemesTests.cs b/Tests/Admin/SetPnPHideDefaultThemesTests.cs index 84f6d03ed..9e9083fda 100644 --- a/Tests/Admin/SetPnPHideDefaultThemesTests.cs +++ b/Tests/Admin/SetPnPHideDefaultThemesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetHideDefaultThemesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPHideDefaultThemesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPHideDefaultThemes",new CommandParameter("HideDefaultThemes", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Defines if the default themes should be visible or hidden + var hideDefaultThemes = ""; + + var results = scope.ExecuteCommand("Set-PnPHideDefaultThemes", + new CommandParameter("HideDefaultThemes", hideDefaultThemes)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPHomeSiteTests.cs b/Tests/Admin/SetPnPHomeSiteTests.cs index 5e0737a44..0d4f9d7d0 100644 --- a/Tests/Admin/SetPnPHomeSiteTests.cs +++ b/Tests/Admin/SetPnPHomeSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetHomeSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPHomeSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPHomeSite",new CommandParameter("Url", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The url of the site to set as the home site + var url = ""; + + var results = scope.ExecuteCommand("Set-PnPHomeSite", + new CommandParameter("Url", url)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPHubSiteTests.cs b/Tests/Admin/SetPnPHubSiteTests.cs index 84afd5cf0..ca1015d72 100644 --- a/Tests/Admin/SetPnPHubSiteTests.cs +++ b/Tests/Admin/SetPnPHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,43 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPHubSite",new CommandParameter("Identity", "null"),new CommandParameter("Title", "null"),new CommandParameter("LogoUrl", "null"),new CommandParameter("Description", "null"),new CommandParameter("SiteDesignId", "null"),new CommandParameter("HideNameInNavigation", "null"),new CommandParameter("RequiresJoinApproval", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Id or Url of a hub site to configure + var identity = ""; + // From Cmdlet Help: The title to set on the hub which will be shown in the hub navigation bar + var title = ""; + // From Cmdlet Help: Full url to the image to use for the hub site logo. Can either be a logo hosted on SharePoint or outside of SharePoint and must be an absolute URL to the image. + var logoUrl = ""; + // From Cmdlet Help: The description of the hub site + var description = ""; + // From Cmdlet Help: GUID of the SharePoint Site Design which should be applied when a site joins the hub site + var siteDesignId = ""; + var hideNameInNavigation = ""; + var requiresJoinApproval = ""; + + var results = scope.ExecuteCommand("Set-PnPHubSite", + new CommandParameter("Identity", identity), + new CommandParameter("Title", title), + new CommandParameter("LogoUrl", logoUrl), + new CommandParameter("Description", description), + new CommandParameter("SiteDesignId", siteDesignId), + new CommandParameter("HideNameInNavigation", hideNameInNavigation), + new CommandParameter("RequiresJoinApproval", requiresJoinApproval)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs b/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs index 7eb9957a0..36ed5ecf3 100644 --- a/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs +++ b/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetKnowledgeHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPKnowledgeHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPKnowledgeHubSite",new CommandParameter("KnowledgeHubSiteUrl", "null")); + + // This is a mandatory parameter + var knowledgeHubSiteUrl = ""; + + var results = scope.ExecuteCommand("Set-PnPKnowledgeHubSite", + new CommandParameter("KnowledgeHubSiteUrl", knowledgeHubSiteUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPTenantCdnEnabledTests.cs b/Tests/Admin/SetPnPTenantCdnEnabledTests.cs index 3520ea840..a94a523df 100644 --- a/Tests/Admin/SetPnPTenantCdnEnabledTests.cs +++ b/Tests/Admin/SetPnPTenantCdnEnabledTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetTenantCdnEnabledTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPTenantCdnEnabledTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPTenantCdnEnabled",new CommandParameter("NoDefaultOrigins", "null"),new CommandParameter("Enable", "null"),new CommandParameter("CdnType", "null")); + + var noDefaultOrigins = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specify to enable or disable + var enable = ""; + // This is a mandatory parameter + // From Cmdlet Help: The type of cdn to enable or disable + var cdnType = ""; + + var results = scope.ExecuteCommand("Set-PnPTenantCdnEnabled", + new CommandParameter("NoDefaultOrigins", noDefaultOrigins), + new CommandParameter("Enable", enable), + new CommandParameter("CdnType", cdnType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPTenantCdnPolicyTests.cs b/Tests/Admin/SetPnPTenantCdnPolicyTests.cs index 366a3872f..2dd9349e1 100644 --- a/Tests/Admin/SetPnPTenantCdnPolicyTests.cs +++ b/Tests/Admin/SetPnPTenantCdnPolicyTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetTenantCdnPolicyTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPTenantCdnPolicyTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPTenantCdnPolicy",new CommandParameter("CdnType", "null"),new CommandParameter("PolicyType", "null"),new CommandParameter("PolicyValue", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The type of cdn to retrieve the policies from + var cdnType = ""; + // This is a mandatory parameter + // From Cmdlet Help: The type of the policy to set + var policyType = ""; + // This is a mandatory parameter + // From Cmdlet Help: The value of the policy to set + var policyValue = ""; + + var results = scope.ExecuteCommand("Set-PnPTenantCdnPolicy", + new CommandParameter("CdnType", cdnType), + new CommandParameter("PolicyType", policyType), + new CommandParameter("PolicyValue", policyValue)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs b/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs index fad2cdc29..7a67ede2f 100644 --- a/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs +++ b/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetTenantSyncClientRestrictionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,41 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPTenantSyncClientRestrictionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPTenantSyncClientRestriction",new CommandParameter("BlockMacSync", "null"),new CommandParameter("DisableReportProblemDialog", "null"),new CommandParameter("DomainGuids", "null"),new CommandParameter("Enable", "null"),new CommandParameter("ExcludedFileExtensions", "null"),new CommandParameter("GrooveBlockOption", "null")); + + // From Cmdlet Help: Block Mac sync clients-- the Beta version and the new sync client (OneDrive.exe). The values for this parameter are $true and $false. The default value is $false. + var blockMacSync = ""; + // From Cmdlet Help: Specifies if the Report Problem Dialog is disabled or not. + var disableReportProblemDialog = ""; + // From Cmdlet Help: Sets the domain GUID to add to the safe recipient list. Requires a minimum of 1 domain GUID. The maximum number of domain GUIDs allowed are 125. I.e. 634c71f6-fa83-429c-b77b-0dba3cb70b93,4fbc735f-0ac2-48ba-b035-b1ae3a480887. + var domainGuids = ""; + // From Cmdlet Help: Enables the feature to block sync originating from domains that are not present in the safe recipients list. + var enable = ""; + // From Cmdlet Help: Blocks certain file types from syncing with the new sync client (OneDrive.exe). Provide as one string separating the extensions using a semicolon (;). I.e. "docx;pptx" + var excludedFileExtensions = ""; + // From Cmdlet Help: Controls whether or not a tenant's users can sync OneDrive for Business libraries with the old OneDrive for Business sync client. The valid values are OptOut, HardOptin, and SoftOptin. + var grooveBlockOption = ""; + + var results = scope.ExecuteCommand("Set-PnPTenantSyncClientRestriction", + new CommandParameter("BlockMacSync", blockMacSync), + new CommandParameter("DisableReportProblemDialog", disableReportProblemDialog), + new CommandParameter("DomainGuids", domainGuids), + new CommandParameter("Enable", enable), + new CommandParameter("ExcludedFileExtensions", excludedFileExtensions), + new CommandParameter("GrooveBlockOption", grooveBlockOption)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/SetPnPTenantTests.cs b/Tests/Admin/SetPnPTenantTests.cs index 75f173ac6..8ad3dcaa1 100644 --- a/Tests/Admin/SetPnPTenantTests.cs +++ b/Tests/Admin/SetPnPTenantTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class SetTenantTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,230 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPTenantTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPTenant",new CommandParameter("SpecialCharactersStateInFileFolderNames", "null"),new CommandParameter("MinCompatibilityLevel", "null"),new CommandParameter("MaxCompatibilityLevel", "null"),new CommandParameter("ExternalServicesEnabled", "null"),new CommandParameter("NoAccessRedirectUrl", "null"),new CommandParameter("SharingCapability", "null"),new CommandParameter("DisplayStartASiteOption", "null"),new CommandParameter("StartASiteFormUrl", "null"),new CommandParameter("ShowEveryoneClaim", "null"),new CommandParameter("ShowAllUsersClaim", "null"),new CommandParameter("ShowEveryoneExceptExternalUsersClaim", "null"),new CommandParameter("SearchResolveExactEmailOrUPN", "null"),new CommandParameter("OfficeClientADALDisabled", "null"),new CommandParameter("LegacyAuthProtocolsEnabled", "null"),new CommandParameter("RequireAcceptingAccountMatchInvitedAccount", "null"),new CommandParameter("ProvisionSharedWithEveryoneFolder", "null"),new CommandParameter("SignInAccelerationDomain", "null"),new CommandParameter("EnableGuestSignInAcceleration", "null"),new CommandParameter("UsePersistentCookiesForExplorerView", "null"),new CommandParameter("BccExternalSharingInvitations", "null"),new CommandParameter("BccExternalSharingInvitationsList", "null"),new CommandParameter("UserVoiceForFeedbackEnabled", "null"),new CommandParameter("PublicCdnEnabled", "null"),new CommandParameter("PublicCdnAllowedFileTypes", "null"),new CommandParameter("RequireAnonymousLinksExpireInDays", "null"),new CommandParameter("SharingAllowedDomainList", "null"),new CommandParameter("SharingBlockedDomainList", "null"),new CommandParameter("SharingDomainRestrictionMode", "null"),new CommandParameter("OneDriveStorageQuota", "null"),new CommandParameter("OneDriveForGuestsEnabled", "null"),new CommandParameter("IPAddressEnforcement", "null"),new CommandParameter("IPAddressAllowList", "null"),new CommandParameter("IPAddressWACTokenLifetime", "null"),new CommandParameter("UseFindPeopleInPeoplePicker", "null"),new CommandParameter("DefaultSharingLinkType", "null"),new CommandParameter("ODBMembersCanShare", "null"),new CommandParameter("ODBAccessRequests", "null"),new CommandParameter("PreventExternalUsersFromResharing", "null"),new CommandParameter("ShowPeoplePickerSuggestionsForGuestUsers", "null"),new CommandParameter("FileAnonymousLinkType", "null"),new CommandParameter("FolderAnonymousLinkType", "null"),new CommandParameter("NotifyOwnersWhenItemsReshared", "null"),new CommandParameter("NotifyOwnersWhenInvitationsAccepted", "null"),new CommandParameter("NotificationsInOneDriveForBusinessEnabled", "null"),new CommandParameter("NotificationsInSharePointEnabled", "null"),new CommandParameter("OwnerAnonymousNotification", "null"),new CommandParameter("CommentsOnSitePagesDisabled", "null"),new CommandParameter("SocialBarOnSitePagesDisabled", "null"),new CommandParameter("OrphanedPersonalSitesRetentionPeriod", "null"),new CommandParameter("DisallowInfectedFileDownload", "null"),new CommandParameter("DefaultLinkPermission", "null"),new CommandParameter("ConditionalAccessPolicy", "null"),new CommandParameter("AllowDownloadingNonWebViewableFiles", "null"),new CommandParameter("AllowEditing", "null"),new CommandParameter("ApplyAppEnforcedRestrictionsToAdHocRecipients", "null"),new CommandParameter("FilePickerExternalImageSearchEnabled", "null"),new CommandParameter("EmailAttestationRequired", "null"),new CommandParameter("EmailAttestationReAuthDays", "null"),new CommandParameter("HideDefaultThemes", "null"),new CommandParameter("DisabledWebPartIds", "null"),new CommandParameter("EnableAIPIntegration", "null")); + + // From Cmdlet Help: Permits the use of special characters in file and folder names in SharePoint Online and OneDrive for Business document libraries.Note: + // The only two characters that can be managed at this time are the # and % characters.The following are the valid values:NoPreference- Support for feature will be enabled by Microsoft on your Office 365 tenant.Allowed- Lets the # and % characters in file and folder names in SharePoint Online and OneDrive for Business document libraries.Disallowed- Disallows the # and % characters in file and folder names in SharePoint Online and OneDrive for Business document libraries. + var specialCharactersStateInFileFolderNames = ""; + // From Cmdlet Help: Specifies the lower bound on the compatibility level for new sites. + var minCompatibilityLevel = ""; + // From Cmdlet Help: Specifies the upper bound on the compatibility level for new sites. + var maxCompatibilityLevel = ""; + // From Cmdlet Help: Enables external services for a tenant. + // External services are defined as services that are not in the Office 365 datacenters.The valid values are: + // True (default) - External services are enabled for the tenant. + // False - External services that are outside of the Office 365 datacenters cannot interact with SharePoint. + var externalServicesEnabled = ""; + // From Cmdlet Help: Specifies the URL of the redirected site for those site collections which have the locked state "NoAccess"The valid values are: + // ""(default) - Blank by default, this will also remove or clear any value that has been set. + // Full URL - Example: https://contoso.sharepoint.com/Pages/Locked.aspx + var noAccessRedirectUrl = ""; + // From Cmdlet Help: Determines what level of sharing is available for the site.The valid values are: + // ExternalUserAndGuestSharing (default) - External user sharing (share by email) and guest link sharing are both enabled. Disabled - External user sharing (share by email) and guest link sharing are both disabled. + // ExternalUserSharingOnly - External user sharing (share by email) is enabled, but guest link sharing is disabled.For more information about sharing, see Manage external sharing for your SharePoint online environment (http://office.microsoft.com/en-us/office365-sharepoint-online-enterprise-help/manage-external-sharing-for-your-sharepoint-online-environment-HA102849864.aspx). + var sharingCapability = ""; + // From Cmdlet Help: Determines whether tenant users see the Start a Site menu option.The valid values are: + // True (default) - Tenant users will see the Start a Site menu option. + // False - Start a Site is hidden from the menu. + var displayStartASiteOption = ""; + // From Cmdlet Help: Specifies URL of the form to load in the Start a Site dialog.The valid values are: + // "" (default) - Blank by default, this will also remove or clear any value that has been set. + // Full URL - Example: "https://contoso.sharepoint.com/path/to/form" + var startASiteFormUrl = ""; + // From Cmdlet Help: Enables the administrator to hide the Everyone claim in the People Picker. + // When users share an item with Everyone, it is accessible to all authenticated users in the tenant's Azure Active Directory, including any active external users who have previously accepted invitations.Note, that some SharePoint system resources such as templates and pages are required to be shared to Everyone and this type of sharing does not expose any user data or metadata.The valid values are: + // True (default) - The Everyone claim group is displayed in People Picker. + // False - The Everyone claim group is hidden from the People Picker. + var showEveryoneClaim = ""; + // From Cmdlet Help: Enables the administrator to hide the All Users claim groups in People Picker.When users share an item with "All Users (x)", it is accessible to all organization members in the tenant's Azure Active Directory who have authenticated with via this method. When users share an item with "All Users (x)" it is accessible to all organization members in the tenant that used NTLM to authentication with SharePoint.Note, the All Users(authenticated) group is equivalent to the Everyone claim, and shows as Everyone.To change this, see - ShowEveryoneClaim.The valid values are: + // True(default) - The All Users claim groups are displayed in People Picker. + // False - The All Users claim groups are hidden in People Picker. + var showAllUsersClaim = ""; + // From Cmdlet Help: Enables the administrator to hide the "Everyone except external users" claim in the People Picker. + // When users share an item with "Everyone except external users", it is accessible to all organization members in the tenant's Azure Active Directory, but not to any users who have previously accepted invitations.The valid values are: + // True(default) - The Everyone except external users is displayed in People Picker. + // False - The Everyone except external users claim is not visible in People Picker. + var showEveryoneExceptExternalUsersClaim = ""; + // From Cmdlet Help: Removes the search capability from People Picker. Note, recently resolved names will still appear in the list until browser cache is cleared or expired.SharePoint Administrators will still be able to use starts with or partial name matching when enabled.The valid values are: + // False (default) - Starts with / partial name search functionality is available. + // True - Disables starts with / partial name search functionality for all SharePoint users, except SharePoint Admins. + var searchResolveExactEmailOrUPN = ""; + // From Cmdlet Help: When set to true this will disable the ability to use Modern Authentication that leverages ADAL across the tenant.The valid values are: + // False (default) - Modern Authentication is enabled/allowed. + // True - Modern Authentication via ADAL is disabled. + var officeClientADALDisabled = ""; + // From Cmdlet Help: By default this value is set to $true.Setting this parameter prevents Office clients using non-modern authentication protocols from accessing SharePoint Online resources.A value of $true - Enables Office clients using non-modern authentication protocols(such as, Forms-Based Authentication (FBA) or Identity Client Runtime Library (IDCRL)) to access SharePoint resources.A value of $false - Prevents Office clients using non-modern authentication protocols from accessing SharePoint Online resources.Note: + // This may also prevent third-party apps from accessing SharePoint Online resources.Also, this will also block apps using the SharePointOnlineCredentials class to access SharePoint Online resources.For additional information about SharePointOnlineCredentials, see SharePointOnlineCredentials class. + var legacyAuthProtocolsEnabled = ""; + // From Cmdlet Help: Ensures that an external user can only accept an external sharing invitation with an account matching the invited email address.Administrators who desire increased control over external collaborators should consider enabling this feature.Note, this only applies to new external users accepting new sharing invitations. Also, the resource owner must share with an organizational or Microsoft account or the external user will be unable to access the resource.The valid values are: + // False (default) - When a document is shared with an external user, bob@contoso.com, it can be accepted by any user with access to the invitation link in the original e-mail. + // True - User must accept this invitation with bob@contoso.com. + var requireAcceptingAccountMatchInvitedAccount = ""; + // From Cmdlet Help: Creates a Shared with Everyone folder in every user's new OneDrive for Business document library.The valid values are: + // True (default) - The Shared with Everyone folder is created. + // False - No folder is created when the site and OneDrive for Business document library is created.The default behavior of the Shared with Everyone folder changed in August 2015. + // For additional information about the change, see Provision the Shared with Everyone folder in OneDrive for Business (https://support.office.com/en-us/article/Provision-the-Shared-with-Everyone-folder-in-OneDrive-for-Business-6bb02c91-fd0b-42ba-9457-3921cb6dc5b2?ui=en-US&rs=en-US&ad=US) + var provisionSharedWithEveryoneFolder = ""; + // From Cmdlet Help: Specifies the home realm discovery value to be sent to Azure Active Directory (AAD) during the user sign-in process.When the organization uses a third-party identity provider, this prevents the user from seeing the Azure Active Directory Home Realm Discovery web page and ensures the user only sees their company's Identity Provider's portal. + // This value can also be used with Azure Active Directory Premium to customize the Azure Active Directory login page.Acceleration will not occur on site collections that are shared externally.This value should be configured with the login domain that is used by your company (that is, example@contoso.com).If your company has multiple third-party identity providers, configuring the sign-in acceleration value will break sign-in for your organization.The valid values are: + // "" (default) - Blank by default, this will also remove or clear any value that has been set. + // Login Domain - For example: "contoso.com" + var signInAccelerationDomain = ""; + // From Cmdlet Help: Accelerates guest-enabled site collections as well as member-only site collections when the SignInAccelerationDomain parameter is set.Note: + // If enabled, your identity provider must be capable of authenticating guest users. If it is not, guest users will be unable to log in and access content that was shared with them. + var enableGuestSignInAcceleration = ""; + // From Cmdlet Help: Lets SharePoint issue a special cookie that will allow this feature to work even when "Keep Me Signed In" is not selected."Open with Explorer" requires persisted cookies to operate correctly. + // When the user does not select "Keep Me Signed in" at the time of sign -in, "Open with Explorer" will fail.This special cookie expires after 30 minutes and cannot be cleared by closing the browser or signing out of SharePoint Online.To clear this cookie, the user must log out of their Windows session.The valid values are: + // False(default) - No special cookie is generated and the normal Office 365 sign -in length / timing applies. + // True - Generates a special cookie that will allow "Open with Explorer" to function if the "Keep Me Signed In" box is not checked at sign -in. + var usePersistentCookiesForExplorerView = ""; + // From Cmdlet Help: When the feature is enabled, all external sharing invitations that are sent will blind copy the e-mail messages listed in the BccExternalSharingInvitationsList.The valid values are: + // False (default) - BCC for external sharing is disabled. + // True - All external sharing invitations that are sent will blind copy the e-mail messages listed in the BccExternalSharingInvitationsList. + var bccExternalSharingInvitations = ""; + // From Cmdlet Help: Specifies a list of e-mail addresses to be BCC'd when the BCC for External Sharing feature is enabled. + // Multiple addresses can be specified by creating a comma separated list with no spaces.The valid values are: + // "" (default) - Blank by default, this will also clear any value that has been set. + // Single or Multiple e-mail addresses - joe@contoso.com or joe@contoso.com,bob@contoso.com + var bccExternalSharingInvitationsList = ""; + var userVoiceForFeedbackEnabled = ""; + var publicVarCdnEnabled = ""; + var publicVarCdnAllowedFileTypes = ""; + // From Cmdlet Help: Specifies all anonymous links that have been created (or will be created) will expire after the set number of days .To remove the expiration requirement, set the value to zero (0). + var requireAnonymousLinksExpireInDays = ""; + // From Cmdlet Help: Specifies a list of email domains that is allowed for sharing with the external collaborators. Use the space character as the delimiter for entering multiple values. For example, "contoso.com fabrikam.com".For additional information about how to restrict a domain sharing, see Restricted Domains Sharing in Office 365 SharePoint Online and OneDrive for Business + var sharingAllowedDomainList = ""; + // From Cmdlet Help: Specifies a list of email domains that is blocked or prohibited for sharing with the external collaborators. Use space character as the delimiter for entering multiple values. For example, "contoso.com fabrikam.com".For additional information about how to restrict a domain sharing, see Restricted Domains Sharing in Office 365 SharePoint Online and OneDrive for Business + var sharingBlockedDomainList = ""; + // From Cmdlet Help: Specifies the external sharing mode for domains.The following values are: None AllowList BlockListFor additional information about how to restrict a domain sharing, see Restricted Domains Sharing in Office 365 SharePoint Online and OneDrive for Business. + var sharingDomainRestrictionMode = ""; + // From Cmdlet Help: Sets a default OneDrive for Business storage quota for the tenant. It will be used for new OneDrive for Business sites created.A typical use will be to reduce the amount of storage associated with OneDrive for Business to a level below what the License entitles the users. For example, it could be used to set the quota to 10 gigabytes (GB) by default.If value is set to 0, the parameter will have no effect.If the value is set larger than the Maximum allowed OneDrive for Business quota, it will have no effect. + var oneDriveStorageQuota = ""; + // From Cmdlet Help: Lets OneDrive for Business creation for administrator managed guest users. Administrator managed Guest users use credentials in the resource tenant to access the resources.The valid values are the following:$true-Administrator managed Guest users can be given OneDrives, provided needed licenses are assigned.$false- Administrator managed Guest users can't be given OneDrives as functionality is turned off. + var oneDriveForGuestsEnabled = ""; + // From Cmdlet Help: Allows access from network locations that are defined by an administrator.The values are $true and $false. The default value is $false which means the setting is disabled.Before the IPAddressEnforcement parameter is set, make sure you add a valid IPv4 or IPv6 address to the IPAddressAllowList parameter. + var iPAddressEnforcement = ""; + // From Cmdlet Help: Configures multiple IP addresses or IP address ranges (IPv4 or IPv6).Use commas to separate multiple IP addresses or IP address ranges. Verify there are no overlapping IP addresses and ensure IP ranges use Classless Inter-Domain Routing (CIDR) notation. For example, 172.16.0.0, 192.168.1.0/27.Note: + // The IPAddressAllowList parameter only lets administrators set IP addresses or ranges that are recognized as trusted. To only grant access from these IP addresses or ranges, set the IPAddressEnforcement parameter to $true. + var iPAddressAllowList = ""; + var iPAddressWACTokenLifetime = ""; + // From Cmdlet Help: Note: + // When set to $true, users aren't able to share with security groups or SharePoint groups. + var useFindPeopleInPeoplePicker = ""; + // From Cmdlet Help: Lets administrators choose what type of link appears is selected in the “Get a link” sharing dialog box in OneDrive for Business and SharePoint Online.For additional information about how to change the default link type, see Change the default link type when users get links for sharing.Note: + // Setting this value to “none” will default “get a link” to the most permissive link available (that is, if anonymous links are enabled, the default link will be anonymous access; if they are disabled then the default link will be internal.The values are: None Direct Internal AnonymousAccess + var defaultSharingLinkType = ""; + // From Cmdlet Help: Lets administrators set policy on re-sharing behavior in OneDrive for Business.Values:On- Users with edit permissions can re-share.Off- Only OneDrive for Business owner can share. The value of ODBAccessRequests defines whether a request to share gets sent to the owner.Unspecified- Let each OneDrive for Business owner enable or disable re-sharing behavior on their OneDrive. + var oDBMembersCanShare = ""; + // From Cmdlet Help: Lets administrators set policy on access requests and requests to share in OneDrive for Business.Values:On- Users without permission to share can trigger sharing requests to the OneDrive for Business owner when they attempt to share. Also, users without permission to a file or folder can trigger access requests to the OneDrive for Business owner when they attempt to access an item they do not have permissions to.Off- Prevent access requests and requests to share on OneDrive for Business.Unspecified- Let each OneDrive for Business owner enable or disable access requests and requests to share on their OneDrive. + var oDBAccessRequests = ""; + var preventExternalUsersFromResharing = ""; + var showPeoplePickerSuggestionsForGuestUsers = ""; + var fileAnonymousLinkType = ""; + var folderAnonymousLinkType = ""; + // From Cmdlet Help: When this parameter is set to $true and another user re-shares a document from a user’s OneDrive for Business, the OneDrive for Business owner is notified by e-mail.For additional information about how to configure notifications for external sharing, see Configure notifications for external sharing for OneDrive for Business.The values are $true and $false. + var notifyOwnersWhenItemsReshared = ""; + // From Cmdlet Help: When this parameter is set to $true and when an external user accepts an invitation to a resource in a user’s OneDrive for Business, the OneDrive for Business owner is notified by e-mail.For additional information about how to configure notifications for external sharing, see Configure notifications for external sharing for OneDrive for Business.The values are $true and $false. + var notifyOwnersWhenInvitationsAccepted = ""; + var notificationsInOneDriveForBusinessEnabled = ""; + var notificationsInSharePointEnabled = ""; + var ownerAnonymousNotification = ""; + var commentsOnSitePagesDisabled = ""; + var socialBarOnSitePagesDisabled = ""; + // From Cmdlet Help: Specifies the number of days after a user's Active Directory account is deleted that their OneDrive for Business content will be deleted.The value range is in days, between 30 and 3650. The default value is 30. + var orphanedPersonalSitesRetentionPeriod = ""; + // From Cmdlet Help: Prevents the Download button from being displayed on the Virus Found warning page.Accepts a value of true (enabled) to hide the Download button or false (disabled) to display the Download button. By default this feature is set to false. + var disallowInfectedFileDownload = ""; + var defaultLinkPermission = ""; + var conditionalAccessPolicy = ""; + var allowDownloadingNonWebViewableFiles = ""; + var allowEditing = ""; + var applyAppEnforcedRestrictionsToAdHocRecipients = ""; + var filePickerExternalImageSearchEnabled = ""; + var emailAttestationRequired = ""; + var emailAttestationReAuthDays = ""; + // From Cmdlet Help: Defines if the default themes are visible or hidden + var hideDefaultThemes = ""; + // From Cmdlet Help: Guids of out of the box modern web part id's to hide + var disabledWebPartIds = ""; + // From Cmdlet Help: Boolean indicating if Azure Information Protection (AIP) should be enabled on the tenant. For more information, see https://docs.microsoft.com/microsoft-365/compliance/sensitivity-labels-sharepoint-onedrive-files#use-powershell-to-enable-support-for-sensitivity-labels + var enableAIPIntegration = ""; + + var results = scope.ExecuteCommand("Set-PnPTenant", + new CommandParameter("SpecialCharactersStateInFileFolderNames", specialCharactersStateInFileFolderNames), + new CommandParameter("MinCompatibilityLevel", minCompatibilityLevel), + new CommandParameter("MaxCompatibilityLevel", maxCompatibilityLevel), + new CommandParameter("ExternalServicesEnabled", externalServicesEnabled), + new CommandParameter("NoAccessRedirectUrl", noAccessRedirectUrl), + new CommandParameter("SharingCapability", sharingCapability), + new CommandParameter("DisplayStartASiteOption", displayStartASiteOption), + new CommandParameter("StartASiteFormUrl", startASiteFormUrl), + new CommandParameter("ShowEveryoneClaim", showEveryoneClaim), + new CommandParameter("ShowAllUsersClaim", showAllUsersClaim), + new CommandParameter("ShowEveryoneExceptExternalUsersClaim", showEveryoneExceptExternalUsersClaim), + new CommandParameter("SearchResolveExactEmailOrUPN", searchResolveExactEmailOrUPN), + new CommandParameter("OfficeClientADALDisabled", officeClientADALDisabled), + new CommandParameter("LegacyAuthProtocolsEnabled", legacyAuthProtocolsEnabled), + new CommandParameter("RequireAcceptingAccountMatchInvitedAccount", requireAcceptingAccountMatchInvitedAccount), + new CommandParameter("ProvisionSharedWithEveryoneFolder", provisionSharedWithEveryoneFolder), + new CommandParameter("SignInAccelerationDomain", signInAccelerationDomain), + new CommandParameter("EnableGuestSignInAcceleration", enableGuestSignInAcceleration), + new CommandParameter("UsePersistentCookiesForExplorerView", usePersistentCookiesForExplorerView), + new CommandParameter("BccExternalSharingInvitations", bccExternalSharingInvitations), + new CommandParameter("BccExternalSharingInvitationsList", bccExternalSharingInvitationsList), + new CommandParameter("UserVoiceForFeedbackEnabled", userVoiceForFeedbackEnabled), + new CommandParameter("PublicCdnEnabled", publicVarCdnEnabled), + new CommandParameter("PublicCdnAllowedFileTypes", publicVarCdnAllowedFileTypes), + new CommandParameter("RequireAnonymousLinksExpireInDays", requireAnonymousLinksExpireInDays), + new CommandParameter("SharingAllowedDomainList", sharingAllowedDomainList), + new CommandParameter("SharingBlockedDomainList", sharingBlockedDomainList), + new CommandParameter("SharingDomainRestrictionMode", sharingDomainRestrictionMode), + new CommandParameter("OneDriveStorageQuota", oneDriveStorageQuota), + new CommandParameter("OneDriveForGuestsEnabled", oneDriveForGuestsEnabled), + new CommandParameter("IPAddressEnforcement", iPAddressEnforcement), + new CommandParameter("IPAddressAllowList", iPAddressAllowList), + new CommandParameter("IPAddressWACTokenLifetime", iPAddressWACTokenLifetime), + new CommandParameter("UseFindPeopleInPeoplePicker", useFindPeopleInPeoplePicker), + new CommandParameter("DefaultSharingLinkType", defaultSharingLinkType), + new CommandParameter("ODBMembersCanShare", oDBMembersCanShare), + new CommandParameter("ODBAccessRequests", oDBAccessRequests), + new CommandParameter("PreventExternalUsersFromResharing", preventExternalUsersFromResharing), + new CommandParameter("ShowPeoplePickerSuggestionsForGuestUsers", showPeoplePickerSuggestionsForGuestUsers), + new CommandParameter("FileAnonymousLinkType", fileAnonymousLinkType), + new CommandParameter("FolderAnonymousLinkType", folderAnonymousLinkType), + new CommandParameter("NotifyOwnersWhenItemsReshared", notifyOwnersWhenItemsReshared), + new CommandParameter("NotifyOwnersWhenInvitationsAccepted", notifyOwnersWhenInvitationsAccepted), + new CommandParameter("NotificationsInOneDriveForBusinessEnabled", notificationsInOneDriveForBusinessEnabled), + new CommandParameter("NotificationsInSharePointEnabled", notificationsInSharePointEnabled), + new CommandParameter("OwnerAnonymousNotification", ownerAnonymousNotification), + new CommandParameter("CommentsOnSitePagesDisabled", commentsOnSitePagesDisabled), + new CommandParameter("SocialBarOnSitePagesDisabled", socialBarOnSitePagesDisabled), + new CommandParameter("OrphanedPersonalSitesRetentionPeriod", orphanedPersonalSitesRetentionPeriod), + new CommandParameter("DisallowInfectedFileDownload", disallowInfectedFileDownload), + new CommandParameter("DefaultLinkPermission", defaultLinkPermission), + new CommandParameter("ConditionalAccessPolicy", conditionalAccessPolicy), + new CommandParameter("AllowDownloadingNonWebViewableFiles", allowDownloadingNonWebViewableFiles), + new CommandParameter("AllowEditing", allowEditing), + new CommandParameter("ApplyAppEnforcedRestrictionsToAdHocRecipients", applyAppEnforcedRestrictionsToAdHocRecipients), + new CommandParameter("FilePickerExternalImageSearchEnabled", filePickerExternalImageSearchEnabled), + new CommandParameter("EmailAttestationRequired", emailAttestationRequired), + new CommandParameter("EmailAttestationReAuthDays", emailAttestationReAuthDays), + new CommandParameter("HideDefaultThemes", hideDefaultThemes), + new CommandParameter("DisabledWebPartIds", disabledWebPartIds), + new CommandParameter("EnableAIPIntegration", enableAIPIntegration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Admin/UnregisterPnPHubSiteTests.cs b/Tests/Admin/UnregisterPnPHubSiteTests.cs index 2518a919d..96e723b8e 100644 --- a/Tests/Admin/UnregisterPnPHubSiteTests.cs +++ b/Tests/Admin/UnregisterPnPHubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Admin { - [TestClass] public class UnregisterHubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UnregisterPnPHubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Unregister-PnPHubSite",new CommandParameter("Site", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The site to unregister as a hubsite + var site = ""; + + var results = scope.ExecuteCommand("Unregister-PnPHubSite", + new CommandParameter("Site", site)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/AddPnPAppTests.cs b/Tests/Apps/AddPnPAppTests.cs index 9738d9052..d16bc05f7 100644 --- a/Tests/Apps/AddPnPAppTests.cs +++ b/Tests/Apps/AddPnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class AddAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPApp",new CommandParameter("Path", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Publish", "null"),new CommandParameter("SkipFeatureDeployment", "null"),new CommandParameter("Overwrite", "null"),new CommandParameter("Timeout", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id or an actual app metadata instance + var path = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + // This is a mandatory parameter + // From Cmdlet Help: This will deploy/trust an app into the app catalog + var publish = ""; + var skipFeatureDeployment = ""; + // From Cmdlet Help: Overwrites the existing app package if it already exists + var overwrite = ""; + // From Cmdlet Help: Specifies the timeout in seconds. Defaults to 200. + var timeoutVar = ""; + + var results = scope.ExecuteCommand("Add-PnPApp", + new CommandParameter("Path", path), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Publish", publish), + new CommandParameter("SkipFeatureDeployment", skipFeatureDeployment), + new CommandParameter("Overwrite", overwrite), + new CommandParameter("Timeout", timeoutVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs b/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs index 488eeb542..bb6c95ba2 100644 --- a/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs +++ b/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class ApproveTenantServicePrincipalPermissionRequestsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ApprovePnPTenantServicePrincipalPermissionRequestTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Approve-PnPTenantServicePrincipalPermissionRequest",new CommandParameter("RequestId", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + var requestId = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Approve-PnPTenantServicePrincipalPermissionRequest", + new CommandParameter("RequestId", requestId), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs b/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs index f7b81c7ee..f166c03dc 100644 --- a/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs +++ b/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class DenyTenantServicePrincipalPermissionRequestsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DenyPnPTenantServicePrincipalPermissionRequestTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Deny-PnPTenantServicePrincipalPermissionRequest",new CommandParameter("RequestId", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + var requestId = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Deny-PnPTenantServicePrincipalPermissionRequest", + new CommandParameter("RequestId", requestId), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs b/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs index ce9cf4346..d4107919f 100644 --- a/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs +++ b/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class DisableTenantServicePrincipalTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPTenantServicePrincipalTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Disable-PnPTenantServicePrincipal",new CommandParameter("Force", "null")); + + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Disable-PnPTenantServicePrincipal", + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs b/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs index ed6bb2e06..e93ce6bc6 100644 --- a/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs +++ b/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class EnableTenantServicePrincipalTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPTenantServicePrincipalTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Enable-PnPTenantServicePrincipal",new CommandParameter("Force", "null")); + + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Enable-PnPTenantServicePrincipal", + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/GetPnPAppInstanceTests.cs b/Tests/Apps/GetPnPAppInstanceTests.cs index fdec1437f..a1c2db0d4 100644 --- a/Tests/Apps/GetPnPAppInstanceTests.cs +++ b/Tests/Apps/GetPnPAppInstanceTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class GetAppInstanceTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAppInstanceTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPAppInstance",new CommandParameter("Identity", "null")); + + // From Cmdlet Help: Specifies the Id of the App Instance + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPAppInstance", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/GetPnPAppTests.cs b/Tests/Apps/GetPnPAppTests.cs index fde5dfac2..8e0dafb8d 100644 --- a/Tests/Apps/GetPnPAppTests.cs +++ b/Tests/Apps/GetPnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class GetAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + + // From Cmdlet Help: Specifies the Id of an app which is available in the app catalog + var identity = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + + var results = scope.ExecuteCommand("Get-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs b/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs index 76ba19714..c953feeaa 100644 --- a/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs +++ b/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class GetTenantServicePrincipalPermissionGrantsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantServicePrincipalPermissionGrantsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPTenantServicePrincipalPermissionGrants"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs b/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs index 66f47be94..41b8a9f0b 100644 --- a/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs +++ b/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class GetTenantServicePrincipalPermissionRequestsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantServicePrincipalPermissionRequestsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPTenantServicePrincipalPermissionRequests"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/GetPnPTenantServicePrincipalTests.cs b/Tests/Apps/GetPnPTenantServicePrincipalTests.cs index 3c5a4089a..8a4e53fe5 100644 --- a/Tests/Apps/GetPnPTenantServicePrincipalTests.cs +++ b/Tests/Apps/GetPnPTenantServicePrincipalTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class GetTenantServicePrincipalTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantServicePrincipalTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPTenantServicePrincipal"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs b/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs index c8cef1b75..3bd6acf12 100644 --- a/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs +++ b/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class GrantTenantServicePrincipalPermissionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GrantPnPTenantServicePrincipalPermissionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Grant-PnPTenantServicePrincipalPermission",new CommandParameter("Scope", "null"),new CommandParameter("Resource", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The scope to grant the permission for + var scopeVar = ""; + // This is a mandatory parameter + // From Cmdlet Help: The resource to grant the permission for + var resource = ""; + + var results = scope.ExecuteCommand("Grant-PnPTenantServicePrincipalPermission", + new CommandParameter("Scope", scopeVar), + new CommandParameter("Resource", resource)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/ImportPnPAppPackageTests.cs b/Tests/Apps/ImportPnPAppPackageTests.cs index 6a319777f..bc522dfae 100644 --- a/Tests/Apps/ImportPnPAppPackageTests.cs +++ b/Tests/Apps/ImportPnPAppPackageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class ImportAppPackageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ImportPnPAppPackageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Import-PnPAppPackage",new CommandParameter("Path", "null"),new CommandParameter("Force", "null"),new CommandParameter("LoadOnly", "null"),new CommandParameter("Locale", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path pointing to the .app file + var path = ""; + // From Cmdlet Help: Will forcibly install the app by activating the addin sideloading feature, installing the addin, and deactivating the sideloading feature + var force = ""; + // From Cmdlet Help: Will only upload the addin, but not install it + var loadOnly = ""; + // From Cmdlet Help: Will install the addin for the specified locale + var locale = ""; + + var results = scope.ExecuteCommand("Import-PnPAppPackage", + new CommandParameter("Path", path), + new CommandParameter("Force", force), + new CommandParameter("LoadOnly", loadOnly), + new CommandParameter("Locale", locale)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/InstallPnPAppTests.cs b/Tests/Apps/InstallPnPAppTests.cs index 702ddfa85..5e7d5e0f3 100644 --- a/Tests/Apps/InstallPnPAppTests.cs +++ b/Tests/Apps/InstallPnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class InstallAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void InstallPnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Install-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Wait", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id or an actual app metadata instance + var identity = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + // From Cmdlet Help: If specified the execution will pause until the app has been installed in the site. + var wait = ""; + + var results = scope.ExecuteCommand("Install-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Wait", wait)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/PublishPnPAppTests.cs b/Tests/Apps/PublishPnPAppTests.cs index f445d9366..90e9c20c1 100644 --- a/Tests/Apps/PublishPnPAppTests.cs +++ b/Tests/Apps/PublishPnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class PublishAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void PublishPnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Publish-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("SkipFeatureDeployment", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id of the app + var identity = ""; + var skipFeatureDeployment = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + + var results = scope.ExecuteCommand("Publish-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("SkipFeatureDeployment", skipFeatureDeployment), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs b/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs index dcea6e4e6..e02b31c61 100644 --- a/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs +++ b/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class RegisterAppCatalogSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,38 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RegisterPnPAppCatalogSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Register-PnPAppCatalogSite",new CommandParameter("Url", "null"),new CommandParameter("Owner", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The full url of the app catalog site to be created, e.g. https://yourtenant.sharepoint.com/sites/appcatalog + var url = ""; + // This is a mandatory parameter + // From Cmdlet Help: The login account of the user designated to be the admin for the site, e.g. user@domain.com + var owner = ""; + // This is a mandatory parameter + // From Cmdlet Help: Use Get-PnPTimeZoneId to retrieve possible timezone values + var timeZoneId = ""; + // From Cmdlet Help: If specified, and an app catalog is already present, a new app catalog site will be created. If the same URL is used the existing/current app catalog site will be deleted first. + var force = ""; + + var results = scope.ExecuteCommand("Register-PnPAppCatalogSite", + new CommandParameter("Url", url), + new CommandParameter("Owner", owner), + new CommandParameter("TimeZoneId", timeZoneId), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/RemovePnPAppTests.cs b/Tests/Apps/RemovePnPAppTests.cs index 0353b06e5..53bd7ae85 100644 --- a/Tests/Apps/RemovePnPAppTests.cs +++ b/Tests/Apps/RemovePnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class RemoveAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id of the Addin Instance + var identity = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + + var results = scope.ExecuteCommand("Remove-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs b/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs index 3f101898f..a485f194a 100644 --- a/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs +++ b/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class RevokeTenantServicePrincipalTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RevokePnPTenantServicePrincipalPermissionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Revoke-PnPTenantServicePrincipalPermission",new CommandParameter("ObjectId", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + var objectId = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Revoke-PnPTenantServicePrincipalPermission", + new CommandParameter("ObjectId", objectId), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/SyncPnPAppToTeamsTests.cs b/Tests/Apps/SyncPnPAppToTeamsTests.cs index 01d714cea..f8bb0397d 100644 --- a/Tests/Apps/SyncPnPAppToTeamsTests.cs +++ b/Tests/Apps/SyncPnPAppToTeamsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class SyncAppToTeamsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SyncPnPAppToTeamsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Sync-PnPAppToTeams",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id of the Addin Instance + var identity = ""; + + var results = scope.ExecuteCommand("Sync-PnPAppToTeams", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/UninstallPnPAppInstanceTests.cs b/Tests/Apps/UninstallPnPAppInstanceTests.cs index 8a246f9d6..2e193de41 100644 --- a/Tests/Apps/UninstallPnPAppInstanceTests.cs +++ b/Tests/Apps/UninstallPnPAppInstanceTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class UninstallAppInstanceTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UninstallPnPAppInstanceTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Uninstall-PnPAppInstance",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Appinstance or Id of the addin to remove. + var identity = ""; + // From Cmdlet Help: Do not ask for confirmation. + var force = ""; + + var results = scope.ExecuteCommand("Uninstall-PnPAppInstance", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/UninstallPnPAppTests.cs b/Tests/Apps/UninstallPnPAppTests.cs index 0c3a75cbf..d09b51d94 100644 --- a/Tests/Apps/UninstallPnPAppTests.cs +++ b/Tests/Apps/UninstallPnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class UninstallAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UninstallPnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Uninstall-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id of the Addin Instance + var identity = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + + var results = scope.ExecuteCommand("Uninstall-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/UnpublishPnPAppTests.cs b/Tests/Apps/UnpublishPnPAppTests.cs index beacb7691..762cf5dd6 100644 --- a/Tests/Apps/UnpublishPnPAppTests.cs +++ b/Tests/Apps/UnpublishPnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class UnpublishAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UnpublishPnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Unpublish-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id of the Addin Instance + var identity = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + + var results = scope.ExecuteCommand("Unpublish-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Apps/UpdatePnPAppTests.cs b/Tests/Apps/UpdatePnPAppTests.cs index a88d2534e..aad5648a0 100644 --- a/Tests/Apps/UpdatePnPAppTests.cs +++ b/Tests/Apps/UpdatePnPAppTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Apps { - [TestClass] public class UpdateAppTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UpdatePnPAppTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Update-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the Id or an actual app metadata instance + var identity = ""; + // From Cmdlet Help: Defines which app catalog to use. Defaults to Tenant + var scopeVar = ""; + + var results = scope.ExecuteCommand("Update-PnPApp", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/AddPnPStoredCredentialTests.cs b/Tests/Base/AddPnPStoredCredentialTests.cs index e8fecb1ac..0de423be5 100644 --- a/Tests/Base/AddPnPStoredCredentialTests.cs +++ b/Tests/Base/AddPnPStoredCredentialTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class AddStoredCredentialTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPStoredCredentialTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPStoredCredential",new CommandParameter("Name", "null"),new CommandParameter("Username", "null"),new CommandParameter("Password", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The credential to set + var name = ""; + // This is a mandatory parameter + var username = ""; + // From Cmdlet Help: If not specified you will be prompted to enter your password. + // If you want to specify this value use ConvertTo-SecureString -String 'YourPassword' -AsPlainText -Force + var password = ""; + + var results = scope.ExecuteCommand("Add-PnPStoredCredential", + new CommandParameter("Name", name), + new CommandParameter("Username", username), + new CommandParameter("Password", password)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/ConnectPnPOnlineTests.cs b/Tests/Base/ConnectPnPOnlineTests.cs index 1d87891da..d52b0f2c6 100644 --- a/Tests/Base/ConnectPnPOnlineTests.cs +++ b/Tests/Base/ConnectPnPOnlineTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class ConnectOnlineTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,187 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ConnectPnPOnlineTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Connect-PnPOnline",new CommandParameter("ReturnConnection", "null"),new CommandParameter("Url", "null"),new CommandParameter("Credentials", "null"),new CommandParameter("CurrentCredentials", "null"),new CommandParameter("UseAdfs", "null"),new CommandParameter("UseAdfsCert", "null"),new CommandParameter("ClientCertificate", "null"),new CommandParameter("Kerberos", "null"),new CommandParameter("LoginProviderName", "null"),new CommandParameter("MinimalHealthScore", "null"),new CommandParameter("RetryCount", "null"),new CommandParameter("RetryWait", "null"),new CommandParameter("RequestTimeout", "null"),new CommandParameter("Realm", "null"),new CommandParameter("AppId", "null"),new CommandParameter("AppSecret", "null"),new CommandParameter("ClientSecret", "null"),new CommandParameter("UseWebLogin", "null"),new CommandParameter("AuthenticationMode", "null"),new CommandParameter("CreateDrive", "null"),new CommandParameter("DriveName", "null"),new CommandParameter("SPOManagementShell", "null"),new CommandParameter("PnPO365ManagementShell", "null"),new CommandParameter("LaunchBrowser", "null"),new CommandParameter("Graph", "null"),new CommandParameter("ClientId", "null"),new CommandParameter("RedirectUri", "null"),new CommandParameter("Tenant", "null"),new CommandParameter("CertificatePath", "null"),new CommandParameter("CertificateBase64Encoded", "null"),new CommandParameter("Certificate", "null"),new CommandParameter("CertificatePassword", "null"),new CommandParameter("PEMCertificate", "null"),new CommandParameter("PEMPrivateKey", "null"),new CommandParameter("Thumbprint", "null"),new CommandParameter("ClearTokenCache", "null"),new CommandParameter("AzureEnvironment", "null"),new CommandParameter("Scopes", "null"),new CommandParameter("AADDomain", "null"),new CommandParameter("AccessToken", "null"),new CommandParameter("TenantAdminUrl", "null"),new CommandParameter("SkipTenantAdminCheck", "null"),new CommandParameter("IgnoreSslErrors", "null"),new CommandParameter("NoTelemetry", "null")); + + // From Cmdlet Help: Returns the connection for use with the -Connection parameter on cmdlets. + var returnConnection = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Url of the site collection to connect to + var url = ""; + // From Cmdlet Help: Credentials of the user to connect with. Either specify a PSCredential object or a string. In case of a string value a lookup will be done to the Generic Credentials section of the Windows Credentials in the Windows Credential Manager for the correct credentials. + var credentials = ""; + // From Cmdlet Help: If you want to connect with the current user credentials + var currentCredentials = ""; + // From Cmdlet Help: If you want to connect to SharePoint using ADFS and credentials + var useAdfs = ""; + // From Cmdlet Help: If you want to connect to SharePoint farm using ADFS with a client certificate + var useAdfsCert = ""; + // From Cmdlet Help: The client certificate which you want to use for the ADFS authentication + var clientCertificate = ""; + // From Cmdlet Help: Authenticate using Kerberos to ADFS + var kerberos = ""; + // From Cmdlet Help: The name of the ADFS trusted login provider + var loginProviderName = ""; + // From Cmdlet Help: Specifies a minimal server healthscore before any requests are executed + var minimalHealthScore = ""; + // From Cmdlet Help: Defines how often a retry should be executed if the server healthscore is not sufficient. Default is 10 times. + var retryCount = ""; + // From Cmdlet Help: Defines how many seconds to wait before each retry. Default is 1 second. + var retryWait = ""; + // From Cmdlet Help: The request timeout. Default is 1800000 + var requestTimeoutVar = ""; + // From Cmdlet Help: Authentication realm. If not specified will be resolved from the url specified. + var realm = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Application Client ID to use. + var appId = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Application Client Secret to use. + var appSecret = ""; + // This is a mandatory parameter + // From Cmdlet Help: The client secret to use. + var clientSecret = ""; + // This is a mandatory parameter + // From Cmdlet Help: If you want to connect to SharePoint with browser based login. This is required when you have multi-factor authentication (MFA) enabled. + var useWebLogin = ""; + // From Cmdlet Help: Specify to use for instance use forms based authentication (FBA) + var authenticationMode = ""; + // From Cmdlet Help: If you want to create a PSDrive connected to the URL + var createDrive = ""; + // From Cmdlet Help: Name of the PSDrive to create (default: SPO) + var driveName = ""; + // This is a mandatory parameter + // From Cmdlet Help: Log in using the SharePoint Online Management Shell application + var sPOManagementShell = ""; + // This is a mandatory parameter + // From Cmdlet Help: Log in using the PnP O365 Management Shell application. You will be asked to consent to:* Read and write managed metadata + // * Have full control of all site collections + // * Read user profiles + // * Invite guest users to the organization + // * Read and write all groups + // * Read and write directory data + // * Read and write identity providers + // * Access the directory as you + var pnPO365ManagementShell = ""; + // From Cmdlet Help: Launch a browser automatically and copy the code to enter to the clipboard + var launchBrowser = ""; + // This is a mandatory parameter + // From Cmdlet Help: Log in using the PnP O365 Management Shell application towards the Graph. You will be asked to consent to:* Read and write managed metadata + // * Have full control of all site collections + // * Read user profiles + // * Invite guest users to the organization + // * Read and write all groups + // * Read and write directory data + // * Read and write identity providers + // * Access the directory as you + // + var graph = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Client ID of the Azure AD Application + var clientId = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Redirect URI of the Azure AD Application + var redirectUri = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Azure AD Tenant name,e.g. mycompany.onmicrosoft.com + var tenant = ""; + // From Cmdlet Help: Path to the certificate containing the private key (*.pfx) + var certificatePath = ""; + // From Cmdlet Help: Base64 Encoded X509Certificate2 certificate containing the private key to authenticate the requests to SharePoint Online such as retrieved in Azure Functions from Azure KeyVault + var certificateBase64Encoded = ""; + // From Cmdlet Help: X509Certificate2 reference containing the private key to authenticate the requests to SharePoint Online + var certificate = ""; + // From Cmdlet Help: Password to the certificate (*.pfx) + var certificatePassword = ""; + // This is a mandatory parameter + // From Cmdlet Help: PEM encoded certificate + var pEMCertificate = ""; + // This is a mandatory parameter + // From Cmdlet Help: PEM encoded private key for the certificate + var pEMPrivateKey = ""; + // This is a mandatory parameter + // From Cmdlet Help: Certificate thumbprint + var thumbprint = ""; + // From Cmdlet Help: Clears the token cache. + var clearTokenCache = ""; + // From Cmdlet Help: The Azure environment to use for authentication, the defaults to 'Production' which is the main Azure environment. + var azureEnvironment = ""; + // This is a mandatory parameter + // From Cmdlet Help: The array of permission scopes for the Microsoft Graph API. + var scopeVars = ""; + // This is a mandatory parameter + // From Cmdlet Help: The AAD where the O365 app is registered. Eg.: contoso.com, or contoso.onmicrosoft.com. + var aADDomain = ""; + // This is a mandatory parameter + // From Cmdlet Help: Connect with an existing Access Token + var accessToken = ""; + // From Cmdlet Help: The url to the Tenant Admin site. If not specified, the cmdlets will assume to connect automatically to https://-admin.sharepoint.com where appropriate. + var tenantAdminUrl = ""; + // From Cmdlet Help: Should we skip the check if this site is the Tenant admin site. Default is false + var skipTenantAdminCheck = ""; + // From Cmdlet Help: Ignores any SSL errors. To be used i.e. when connecting to a SharePoint farm using self signed certificates or using a certificate authority not trusted by this machine. + var ignoreSslErrors = ""; + // From Cmdlet Help: In order to help to make PnP PowerShell better, we can track anonymous telemetry. We track the version of the cmdlets you are using, which cmdlet you are executing and which version of SharePoint you are connecting to. Use Disable-PnPPowerShellTelemetry to turn this off in general or use the -NoTelemetry switch to turn it off for that session. + var noTelemetry = ""; + + var results = scope.ExecuteCommand("Connect-PnPOnline", + new CommandParameter("ReturnConnection", returnConnection), + new CommandParameter("Url", url), + new CommandParameter("Credentials", credentials), + new CommandParameter("CurrentCredentials", currentCredentials), + new CommandParameter("UseAdfs", useAdfs), + new CommandParameter("UseAdfsCert", useAdfsCert), + new CommandParameter("ClientCertificate", clientCertificate), + new CommandParameter("Kerberos", kerberos), + new CommandParameter("LoginProviderName", loginProviderName), + new CommandParameter("MinimalHealthScore", minimalHealthScore), + new CommandParameter("RetryCount", retryCount), + new CommandParameter("RetryWait", retryWait), + new CommandParameter("RequestTimeout", requestTimeoutVar), + new CommandParameter("Realm", realm), + new CommandParameter("AppId", appId), + new CommandParameter("AppSecret", appSecret), + new CommandParameter("ClientSecret", clientSecret), + new CommandParameter("UseWebLogin", useWebLogin), + new CommandParameter("AuthenticationMode", authenticationMode), + new CommandParameter("CreateDrive", createDrive), + new CommandParameter("DriveName", driveName), + new CommandParameter("SPOManagementShell", sPOManagementShell), + new CommandParameter("PnPO365ManagementShell", pnPO365ManagementShell), + new CommandParameter("LaunchBrowser", launchBrowser), + new CommandParameter("Graph", graph), + new CommandParameter("ClientId", clientId), + new CommandParameter("RedirectUri", redirectUri), + new CommandParameter("Tenant", tenant), + new CommandParameter("CertificatePath", certificatePath), + new CommandParameter("CertificateBase64Encoded", certificateBase64Encoded), + new CommandParameter("Certificate", certificate), + new CommandParameter("CertificatePassword", certificatePassword), + new CommandParameter("PEMCertificate", pEMCertificate), + new CommandParameter("PEMPrivateKey", pEMPrivateKey), + new CommandParameter("Thumbprint", thumbprint), + new CommandParameter("ClearTokenCache", clearTokenCache), + new CommandParameter("AzureEnvironment", azureEnvironment), + new CommandParameter("Scopes", scopeVars), + new CommandParameter("AADDomain", aADDomain), + new CommandParameter("AccessToken", accessToken), + new CommandParameter("TenantAdminUrl", tenantAdminUrl), + new CommandParameter("SkipTenantAdminCheck", skipTenantAdminCheck), + new CommandParameter("IgnoreSslErrors", ignoreSslErrors), + new CommandParameter("NoTelemetry", noTelemetry)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/DisablePnPPowerShellTelemetryTests.cs b/Tests/Base/DisablePnPPowerShellTelemetryTests.cs index e19398735..8c4f8be2b 100644 --- a/Tests/Base/DisablePnPPowerShellTelemetryTests.cs +++ b/Tests/Base/DisablePnPPowerShellTelemetryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class DisablePowerShellTelemetryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPPowerShellTelemetryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Disable-PnPPowerShellTelemetry",new CommandParameter("Force", "null")); + + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Disable-PnPPowerShellTelemetry", + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/DisconnectPnPOnlineTests.cs b/Tests/Base/DisconnectPnPOnlineTests.cs index d11eee57f..158a0fdf7 100644 --- a/Tests/Base/DisconnectPnPOnlineTests.cs +++ b/Tests/Base/DisconnectPnPOnlineTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class DisconnectOnlineTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisconnectPnPOnlineTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Disconnect-PnPOnline",new CommandParameter("Connection", "null")); + + // From Cmdlet Help: Connection to be used by cmdlet + var connection = ""; + + var results = scope.ExecuteCommand("Disconnect-PnPOnline", + new CommandParameter("Connection", connection)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/EnablePnPPowerShellTelemetryTests.cs b/Tests/Base/EnablePnPPowerShellTelemetryTests.cs index 068b09af7..3e5f39a05 100644 --- a/Tests/Base/EnablePnPPowerShellTelemetryTests.cs +++ b/Tests/Base/EnablePnPPowerShellTelemetryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class EnablePowerShellTelemetryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPPowerShellTelemetryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Enable-PnPPowerShellTelemetry",new CommandParameter("Force", "null")); + + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Enable-PnPPowerShellTelemetry", + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPAccessTokenTests.cs b/Tests/Base/GetPnPAccessTokenTests.cs index 92c75266c..01b6f0d07 100644 --- a/Tests/Base/GetPnPAccessTokenTests.cs +++ b/Tests/Base/GetPnPAccessTokenTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetPnPAccessTokenTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAccessTokenTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPAccessToken",new CommandParameter("Decoded", "null")); + + // From Cmdlet Help: Returns the details from the access token in a decoded manner + var decoded = ""; + + var results = scope.ExecuteCommand("Get-PnPAccessToken", + new CommandParameter("Decoded", decoded)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPAppAuthAccessTokenTests.cs b/Tests/Base/GetPnPAppAuthAccessTokenTests.cs index 8c22939c3..c10a481a7 100644 --- a/Tests/Base/GetPnPAppAuthAccessTokenTests.cs +++ b/Tests/Base/GetPnPAppAuthAccessTokenTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetPnPAppAuthAccessTokenTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAppAuthAccessTokenTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPAppAuthAccessToken"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPAzureCertificateTests.cs b/Tests/Base/GetPnPAzureCertificateTests.cs index dee4b0308..8bc3f4f75 100644 --- a/Tests/Base/GetPnPAzureCertificateTests.cs +++ b/Tests/Base/GetPnPAzureCertificateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetPnPAdalCertificateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAzureCertificateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPAzureCertificate",new CommandParameter("CertificatePath", "null"),new CommandParameter("CertificatePassword", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the certificate (*.pfx) + var certificatePath = ""; + // From Cmdlet Help: Password to the certificate (*.pfx) + var certificatePassword = ""; + + var results = scope.ExecuteCommand("Get-PnPAzureCertificate", + new CommandParameter("CertificatePath", certificatePath), + new CommandParameter("CertificatePassword", certificatePassword)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPConnectionTests.cs b/Tests/Base/GetPnPConnectionTests.cs index ed3f5fd90..af1b01d20 100644 --- a/Tests/Base/GetPnPConnectionTests.cs +++ b/Tests/Base/GetPnPConnectionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetPnPConnectionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPConnectionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPConnection"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPContextTests.cs b/Tests/Base/GetPnPContextTests.cs index ed58db961..acf1e4821 100644 --- a/Tests/Base/GetPnPContextTests.cs +++ b/Tests/Base/GetPnPContextTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetSPOContextTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPContextTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPContext"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPExceptionTests.cs b/Tests/Base/GetPnPExceptionTests.cs index f04d4e101..c7528f05a 100644 --- a/Tests/Base/GetPnPExceptionTests.cs +++ b/Tests/Base/GetPnPExceptionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetExceptionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPExceptionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPException",new CommandParameter("All", "null")); + + // From Cmdlet Help: Show all exceptions + var all = ""; + + var results = scope.ExecuteCommand("Get-PnPException", + new CommandParameter("All", all)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPGraphAccessTokenTests.cs b/Tests/Base/GetPnPGraphAccessTokenTests.cs index 3031b4006..d86bbb2ad 100644 --- a/Tests/Base/GetPnPGraphAccessTokenTests.cs +++ b/Tests/Base/GetPnPGraphAccessTokenTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetGraphAccessTokenTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPGraphAccessTokenTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPGraphAccessToken",new CommandParameter("Decoded", "null")); + + // From Cmdlet Help: Returns the access token in a decoded manner + var decoded = ""; + + var results = scope.ExecuteCommand("Get-PnPGraphAccessToken", + new CommandParameter("Decoded", decoded)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPHealthScoreTests.cs b/Tests/Base/GetPnPHealthScoreTests.cs index b6b41b5a9..4131e8199 100644 --- a/Tests/Base/GetPnPHealthScoreTests.cs +++ b/Tests/Base/GetPnPHealthScoreTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetHealthScoreTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPHealthScoreTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPHealthScore",new CommandParameter("Url", "null")); + + // From Cmdlet Help: The url of the WebApplication to retrieve the health score from + var url = ""; + + var results = scope.ExecuteCommand("Get-PnPHealthScore", + new CommandParameter("Url", url)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs b/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs index 5dc3eb330..0ce834b7b 100644 --- a/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs +++ b/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetPowerShellTelemetryEnabledTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPPowerShellTelemetryEnabledTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPPowerShellTelemetryEnabled"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPPropertyTests.cs b/Tests/Base/GetPnPPropertyTests.cs index 8b9e81661..f88a62a47 100644 --- a/Tests/Base/GetPnPPropertyTests.cs +++ b/Tests/Base/GetPnPPropertyTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class EnsurePropertyTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPPropertyTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPProperty",new CommandParameter("ClientObject", "null"),new CommandParameter("Property", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the object where the properties of should be retrieved + var clientObject = ""; + // This is a mandatory parameter + // From Cmdlet Help: The properties to load. If one property is specified its value will be returned to the output. + var property = ""; + + var results = scope.ExecuteCommand("Get-PnPProperty", + new CommandParameter("ClientObject", clientObject), + new CommandParameter("Property", property)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/GetPnPStoredCredentialTests.cs b/Tests/Base/GetPnPStoredCredentialTests.cs index cb825b7bf..7c2b18cc6 100644 --- a/Tests/Base/GetPnPStoredCredentialTests.cs +++ b/Tests/Base/GetPnPStoredCredentialTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class GetStoredCredentialTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPStoredCredentialTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPStoredCredential",new CommandParameter("Name", "null"),new CommandParameter("Type", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The credential to retrieve. + var name = ""; + // From Cmdlet Help: The object type of the credential to return from the Credential Manager. Possible values are 'O365', 'OnPrem' or 'PSCredential' + var type = ""; + + var results = scope.ExecuteCommand("Get-PnPStoredCredential", + new CommandParameter("Name", name), + new CommandParameter("Type", type)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs b/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs index 777209634..bd3098467 100644 --- a/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs +++ b/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class InitializePowerShellAuthenticationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,65 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void InitializePnPPowerShellAuthenticationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Initialize-PnPPowerShellAuthentication",new CommandParameter("ApplicationName", "null"),new CommandParameter("Tenant", "null"),new CommandParameter("CertificatePath", "null"),new CommandParameter("CommonName", "null"),new CommandParameter("Country", "null"),new CommandParameter("State", "null"),new CommandParameter("Locality", "null"),new CommandParameter("Organization", "null"),new CommandParameter("OrganizationUnit", "null"),new CommandParameter("ValidYears", "null"),new CommandParameter("CertificatePassword", "null"),new CommandParameter("OutPath", "null"),new CommandParameter("Store", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the Azure AD Application to create + var applicationName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The identifier of your tenant, e.g. mytenant.onmicrosoft.com + var tenant = ""; + // This is a mandatory parameter + // From Cmdlet Help: Password for the certificate being created + var certificatePath = ""; + // From Cmdlet Help: Common Name (e.g. server FQDN or YOUR name). defaults to 'pnp.contoso.com' + var commonName = ""; + // From Cmdlet Help: Country Name (2 letter code) + var country = ""; + // From Cmdlet Help: State or Province Name (full name) + var state = ""; + // From Cmdlet Help: Locality Name (eg, city) + var locality = ""; + // From Cmdlet Help: Organization Name (eg, company) + var organization = ""; + // From Cmdlet Help: Organizational Unit Name (eg, section) + var organizationUnit = ""; + // From Cmdlet Help: Number of years until expiration (default is 10, max is 30) + var validYears = ""; + // From Cmdlet Help: Optional certificate password + var certificatePassword = ""; + // From Cmdlet Help: Folder to create certificate files in (.CER and .PFX) + var outVarPath = ""; + // From Cmdlet Help: Local Certificate Store to add the certificate to + var store = ""; + + var results = scope.ExecuteCommand("Initialize-PnPPowerShellAuthentication", + new CommandParameter("ApplicationName", applicationName), + new CommandParameter("Tenant", tenant), + new CommandParameter("CertificatePath", certificatePath), + new CommandParameter("CommonName", commonName), + new CommandParameter("Country", country), + new CommandParameter("State", state), + new CommandParameter("Locality", locality), + new CommandParameter("Organization", organization), + new CommandParameter("OrganizationUnit", organizationUnit), + new CommandParameter("ValidYears", validYears), + new CommandParameter("CertificatePassword", certificatePassword), + new CommandParameter("OutPath", outVarPath), + new CommandParameter("Store", store)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/InvokePnPQueryTests.cs b/Tests/Base/InvokePnPQueryTests.cs index 96895f9d8..43a891fc1 100644 --- a/Tests/Base/InvokePnPQueryTests.cs +++ b/Tests/Base/InvokePnPQueryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class InvokeQueryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void InvokePnPQueryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Invoke-PnPQuery",new CommandParameter("RetryCount", "null"),new CommandParameter("RetryWait", "null")); + + // From Cmdlet Help: Number of times to retry in case of throttling. Defaults to 10. + var retryCount = ""; + // From Cmdlet Help: Delay in seconds. Defaults to 1. + var retryWait = ""; + + var results = scope.ExecuteCommand("Invoke-PnPQuery", + new CommandParameter("RetryCount", retryCount), + new CommandParameter("RetryWait", retryWait)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/NewPnPAzureCertificateTests.cs b/Tests/Base/NewPnPAzureCertificateTests.cs index 225edb3e8..adc693379 100644 --- a/Tests/Base/NewPnPAzureCertificateTests.cs +++ b/Tests/Base/NewPnPAzureCertificateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class NewPnPAdalCertificateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,56 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPAzureCertificateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPAzureCertificate",new CommandParameter("CommonName", "null"),new CommandParameter("Country", "null"),new CommandParameter("State", "null"),new CommandParameter("Locality", "null"),new CommandParameter("Organization", "null"),new CommandParameter("OrganizationUnit", "null"),new CommandParameter("Out", "null"),new CommandParameter("OutPfx", "null"),new CommandParameter("OutCert", "null"),new CommandParameter("ValidYears", "null"),new CommandParameter("CertificatePassword", "null")); + + // From Cmdlet Help: Common Name (e.g. server FQDN or YOUR name) [pnp.contoso.com] + var commonName = ""; + // From Cmdlet Help: Country Name (2 letter code) + var country = ""; + // From Cmdlet Help: State or Province Name (full name) + var state = ""; + // From Cmdlet Help: Locality Name (eg, city) + var locality = ""; + // From Cmdlet Help: Organization Name (eg, company) + var organization = ""; + // From Cmdlet Help: Organizational Unit Name (eg, section) + var organizationUnit = ""; + // From Cmdlet Help: Filename to write to, optionally including full path (.pfx) + var outVar = ""; + // From Cmdlet Help: Filename to write to, optionally including full path (.pfx) + var outVarPfx = ""; + // From Cmdlet Help: Filename to write to, optionally including full path (.cer) + var outVarCert = ""; + // From Cmdlet Help: Number of years until expiration (default is 10, max is 30) + var validYears = ""; + // From Cmdlet Help: Optional certificate password + var certificatePassword = ""; + + var results = scope.ExecuteCommand("New-PnPAzureCertificate", + new CommandParameter("CommonName", commonName), + new CommandParameter("Country", country), + new CommandParameter("State", state), + new CommandParameter("Locality", locality), + new CommandParameter("Organization", organization), + new CommandParameter("OrganizationUnit", organizationUnit), + new CommandParameter("Out", outVar), + new CommandParameter("OutPfx", outVarPfx), + new CommandParameter("OutCert", outVarCert), + new CommandParameter("ValidYears", validYears), + new CommandParameter("CertificatePassword", certificatePassword)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/RemovePnPStoredCredentialTests.cs b/Tests/Base/RemovePnPStoredCredentialTests.cs index 53504fff8..08c06a844 100644 --- a/Tests/Base/RemovePnPStoredCredentialTests.cs +++ b/Tests/Base/RemovePnPStoredCredentialTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class RemoveStoredCredentialTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPStoredCredentialTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPStoredCredential",new CommandParameter("Name", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The credential to remove + var name = ""; + // From Cmdlet Help: If specified you will not be asked for confirmation + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPStoredCredential", + new CommandParameter("Name", name), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/RequestPnPAccessTokenTests.cs b/Tests/Base/RequestPnPAccessTokenTests.cs index a0855ad12..b6ea5ef89 100644 --- a/Tests/Base/RequestPnPAccessTokenTests.cs +++ b/Tests/Base/RequestPnPAccessTokenTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class RequestAccessTokenTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,44 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RequestPnPAccessTokenTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Request-PnPAccessToken",new CommandParameter("ClientId", "null"),new CommandParameter("Resource", "null"),new CommandParameter("Scopes", "null"),new CommandParameter("Decoded", "null"),new CommandParameter("SetAsCurrent", "null"),new CommandParameter("Credentials", "null"),new CommandParameter("TenantUrl", "null")); + + // From Cmdlet Help: The Azure Application Client Id to use to retrieve the token. Defaults to the PnP Office 365 Management Shell + var clientId = ""; + // From Cmdlet Help: The scopes to retrieve the token for. Defaults to AllSites.FullControl + var resource = ""; + // From Cmdlet Help: The scopes to retrieve the token for. Defaults to AllSites.FullControl + var scopeVars = ""; + // From Cmdlet Help: Returns the token in a decoded / human readible manner + var decoded = ""; + // From Cmdlet Help: Set this token as the current token to use when performing Azure AD based authentication requests with PnP PowerShell + var setAsCurrent = ""; + // From Cmdlet Help: Optional credentials to use when retrieving the access token. If not present you need to connect first with Connect-PnPOnline. + var credentials = ""; + // From Cmdlet Help: Optional tenant URL to use when retrieving the access token. The Url should be in the shape of https://yourtenant.sharepoint.com. See examples for more info. + var tenantUrl = ""; + + var results = scope.ExecuteCommand("Request-PnPAccessToken", + new CommandParameter("ClientId", clientId), + new CommandParameter("Resource", resource), + new CommandParameter("Scopes", scopeVars), + new CommandParameter("Decoded", decoded), + new CommandParameter("SetAsCurrent", setAsCurrent), + new CommandParameter("Credentials", credentials), + new CommandParameter("TenantUrl", tenantUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/SetPnPContextTests.cs b/Tests/Base/SetPnPContextTests.cs index b683aae21..5c55cf714 100644 --- a/Tests/Base/SetPnPContextTests.cs +++ b/Tests/Base/SetPnPContextTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class SetContextTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPContextTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPContext",new CommandParameter("Context", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ClientContext to set + var context = ""; + + var results = scope.ExecuteCommand("Set-PnPContext", + new CommandParameter("Context", context)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Base/SetPnPTraceLogTests.cs b/Tests/Base/SetPnPTraceLogTests.cs index 69f449c1a..b13f5c352 100644 --- a/Tests/Base/SetPnPTraceLogTests.cs +++ b/Tests/Base/SetPnPTraceLogTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Base { - [TestClass] public class SetTraceLogTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,49 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPTraceLogTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPTraceLog",new CommandParameter("On", "null"),new CommandParameter("LogFile", "null"),new CommandParameter("WriteToConsole", "null"),new CommandParameter("Level", "null"),new CommandParameter("Delimiter", "null"),new CommandParameter("IndentSize", "null"),new CommandParameter("AutoFlush", "null"),new CommandParameter("Off", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Turn on tracing to log file + var on = ""; + // From Cmdlet Help: The path and filename of the file to write the trace log to. + var logFile = ""; + // From Cmdlet Help: Turn on console trace output. + var writeToConsole = ""; + // From Cmdlet Help: The level of events to capture. Possible values are 'Debug', 'Error', 'Warning', 'Information'. Defaults to 'Information'. + var level = ""; + // From Cmdlet Help: If specified the trace log entries will be delimited with this value. + var delimiter = ""; + // From Cmdlet Help: Indents in the tracelog will be with this amount of characters. Defaults to 4. + var indentSize = ""; + // From Cmdlet Help: Auto flush the trace log. Defaults to true. + var autoFlush = ""; + // This is a mandatory parameter + // From Cmdlet Help: Turn off tracing to log file. + var off = ""; + + var results = scope.ExecuteCommand("Set-PnPTraceLog", + new CommandParameter("On", on), + new CommandParameter("LogFile", logFile), + new CommandParameter("WriteToConsole", writeToConsole), + new CommandParameter("Level", level), + new CommandParameter("Delimiter", delimiter), + new CommandParameter("IndentSize", indentSize), + new CommandParameter("AutoFlush", autoFlush), + new CommandParameter("Off", off)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/AddPnPApplicationCustomizerTests.cs b/Tests/Branding/AddPnPApplicationCustomizerTests.cs index a408ee397..e71f924c1 100644 --- a/Tests/Branding/AddPnPApplicationCustomizerTests.cs +++ b/Tests/Branding/AddPnPApplicationCustomizerTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class AddApplicationCustomizerTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,45 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPApplicationCustomizerTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPApplicationCustomizer",new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("ClientSideComponentProperties", "null"),new CommandParameter("ClientSideHostProperties", "null")); + + // From Cmdlet Help: The title of the application customizer + var title = ""; + // From Cmdlet Help: The description of the application customizer + var description = ""; + // From Cmdlet Help: Sequence of this application customizer being injected. Use when you have a specific sequence with which to have multiple application customizers being added to the page. + var sequence = ""; + // From Cmdlet Help: The scope of the CustomAction to add to. Either Web or Site; defaults to Web. 'All' is not valid for this command. + var scopeVar = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Client Side Component Id of the SharePoint Framework client side extension application customizer found in the manifest + var clientSideComponentId = ""; + // From Cmdlet Help: The Client Side Component Properties of the application customizer. Specify values as a json string : "{Property1 : 'Value1', Property2: 'Value2'}" + var clientSideComponentProperties = ""; + // From Cmdlet Help: The Client Side Host Properties of the application customizer. Specify values as a json string : "{'preAllocatedApplicationCustomizerTopHeight': '50', 'preAllocatedApplicationCustomizerBottomHeight': '50'}" + var clientSideHostProperties = ""; + + var results = scope.ExecuteCommand("Add-PnPApplicationCustomizer", + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("Sequence", sequence), + new CommandParameter("Scope", scopeVar), + new CommandParameter("ClientSideComponentId", clientSideComponentId), + new CommandParameter("ClientSideComponentProperties", clientSideComponentProperties), + new CommandParameter("ClientSideHostProperties", clientSideHostProperties)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/AddPnPCustomActionTests.cs b/Tests/Branding/AddPnPCustomActionTests.cs index 8d8a728ba..e220c5530 100644 --- a/Tests/Branding/AddPnPCustomActionTests.cs +++ b/Tests/Branding/AddPnPCustomActionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class AddCustomActionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,77 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPCustomActionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPCustomAction",new CommandParameter("Name", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Group", "null"),new CommandParameter("Location", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("Url", "null"),new CommandParameter("ImageUrl", "null"),new CommandParameter("CommandUIExtension", "null"),new CommandParameter("RegistrationId", "null"),new CommandParameter("Rights", "null"),new CommandParameter("RegistrationType", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("ClientSideComponentProperties", "null"),new CommandParameter("ClientSideHostProperties", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the custom action + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The title of the custom action + var title = ""; + // This is a mandatory parameter + // From Cmdlet Help: The description of the custom action + var description = ""; + // This is a mandatory parameter + // From Cmdlet Help: The group where this custom action needs to be added like 'SiteActions' + var group = ""; + // This is a mandatory parameter + // From Cmdlet Help: The actual location where this custom action need to be added like 'CommandUI.Ribbon' + var location = ""; + // From Cmdlet Help: Sequence of this CustomAction being injected. Use when you have a specific sequence with which to have multiple CustomActions being added to the page. + var sequence = ""; + // From Cmdlet Help: The URL, URI or ECMAScript (JScript, JavaScript) function associated with the action + var url = ""; + // From Cmdlet Help: The URL of the image associated with the custom action + var imageUrl = ""; + // From Cmdlet Help: XML fragment that determines user interface properties of the custom action + var commandUIExtension = ""; + // From Cmdlet Help: The identifier of the object associated with the custom action. + var registrationId = ""; + // From Cmdlet Help: A string array that contain the permissions needed for the custom action + var rights = ""; + // From Cmdlet Help: Specifies the type of object associated with the custom action + var registrationType = ""; + // From Cmdlet Help: The scope of the CustomAction to add to. Either Web or Site; defaults to Web. 'All' is not valid for this command. + var scopeVar = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Client Side Component Id of the custom action + var clientSideComponentId = ""; + // From Cmdlet Help: The Client Side Component Properties of the custom action. Specify values as a json string : "{Property1 : 'Value1', Property2: 'Value2'}" + var clientSideComponentProperties = ""; + // From Cmdlet Help: The Client Side Host Properties of the custom action. Specify values as a json string : "{'preAllocatedApplicationCustomizerTopHeight': '50', 'preAllocatedApplicationCustomizerBottomHeight': '50'}" + var clientSideHostProperties = ""; + + var results = scope.ExecuteCommand("Add-PnPCustomAction", + new CommandParameter("Name", name), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("Group", group), + new CommandParameter("Location", location), + new CommandParameter("Sequence", sequence), + new CommandParameter("Url", url), + new CommandParameter("ImageUrl", imageUrl), + new CommandParameter("CommandUIExtension", commandUIExtension), + new CommandParameter("RegistrationId", registrationId), + new CommandParameter("Rights", rights), + new CommandParameter("RegistrationType", registrationType), + new CommandParameter("Scope", scopeVar), + new CommandParameter("ClientSideComponentId", clientSideComponentId), + new CommandParameter("ClientSideComponentProperties", clientSideComponentProperties), + new CommandParameter("ClientSideHostProperties", clientSideHostProperties)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/AddPnPJavaScriptBlockTests.cs b/Tests/Branding/AddPnPJavaScriptBlockTests.cs index e15b5093f..fe7180a1b 100644 --- a/Tests/Branding/AddPnPJavaScriptBlockTests.cs +++ b/Tests/Branding/AddPnPJavaScriptBlockTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class AddJavaScriptBlockTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPJavaScriptBlockTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPJavaScriptBlock",new CommandParameter("Name", "null"),new CommandParameter("Script", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("SiteScoped", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the script block. Can be used to identify the script with other cmdlets or coded solutions + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The javascript block to add to the specified scope + var script = ""; + // From Cmdlet Help: A sequence number that defines the order on the page + var sequence = ""; + var siteScoped = ""; + // From Cmdlet Help: The scope of the script to add to. Either Web or Site, defaults to Web. 'All' is not valid for this command. + var scopeVar = ""; + + var results = scope.ExecuteCommand("Add-PnPJavaScriptBlock", + new CommandParameter("Name", name), + new CommandParameter("Script", script), + new CommandParameter("Sequence", sequence), + new CommandParameter("SiteScoped", siteScoped), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/AddPnPJavaScriptLinkTests.cs b/Tests/Branding/AddPnPJavaScriptLinkTests.cs index 5be44914b..b272c2aff 100644 --- a/Tests/Branding/AddPnPJavaScriptLinkTests.cs +++ b/Tests/Branding/AddPnPJavaScriptLinkTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class AddJavaScriptLinkTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPJavaScriptLinkTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPJavaScriptLink",new CommandParameter("Name", "null"),new CommandParameter("Url", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("SiteScoped", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Name under which to register the JavaScriptLink + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: URL to the JavaScript file to inject + var url = ""; + // From Cmdlet Help: Sequence of this JavaScript being injected. Use when you have a specific sequence with which to have JavaScript files being added to the page. I.e. jQuery library first and then jQueryUI. + var sequence = ""; + var siteScoped = ""; + // From Cmdlet Help: Defines if this JavaScript file will be injected to every page within the current site collection or web. All is not allowed in for this command. Default is web. + var scopeVar = ""; + + var results = scope.ExecuteCommand("Add-PnPJavaScriptLink", + new CommandParameter("Name", name), + new CommandParameter("Url", url), + new CommandParameter("Sequence", sequence), + new CommandParameter("SiteScoped", siteScoped), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/AddPnPNavigationNodeTests.cs b/Tests/Branding/AddPnPNavigationNodeTests.cs index 34d55d2b0..f085c36a6 100644 --- a/Tests/Branding/AddPnPNavigationNodeTests.cs +++ b/Tests/Branding/AddPnPNavigationNodeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class AddNavigationNodeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,46 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPNavigationNodeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPNavigationNode",new CommandParameter("Location", "null"),new CommandParameter("Title", "null"),new CommandParameter("Url", "null"),new CommandParameter("Parent", "null"),new CommandParameter("Header", "null"),new CommandParameter("First", "null"),new CommandParameter("External", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The location where to add the navigation node to. Either TopNavigationBar, QuickLaunch, SearchNav or Footer. + var location = ""; + // This is a mandatory parameter + // From Cmdlet Help: The title of the node to add + var title = ""; + // From Cmdlet Help: The url to navigate to when clicking the new menu item. This can either be absolute or relative to the Web. Fragments are not supported. + var url = ""; + // From Cmdlet Help: The key of the parent. Leave empty to add to the top level + var parent = ""; + // From Cmdlet Help: Optional value of a header entry to add the menu item to + var header = ""; + // From Cmdlet Help: Add the new menu item to beginning of the collection + var first = ""; + // From Cmdlet Help: Indicates the destination URL is outside of the site collection + var external = ""; + + var results = scope.ExecuteCommand("Add-PnPNavigationNode", + new CommandParameter("Location", location), + new CommandParameter("Title", title), + new CommandParameter("Url", url), + new CommandParameter("Parent", parent), + new CommandParameter("Header", header), + new CommandParameter("First", first), + new CommandParameter("External", external)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/DisablePnPResponsiveUITests.cs b/Tests/Branding/DisablePnPResponsiveUITests.cs index 1d79492a7..69b9c4727 100644 --- a/Tests/Branding/DisablePnPResponsiveUITests.cs +++ b/Tests/Branding/DisablePnPResponsiveUITests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class DisableResponsiveUITests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPResponsiveUITest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Disable-PnPResponsiveUI"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/EnablePnPResponsiveUITests.cs b/Tests/Branding/EnablePnPResponsiveUITests.cs index 659604800..c87f5cfa6 100644 --- a/Tests/Branding/EnablePnPResponsiveUITests.cs +++ b/Tests/Branding/EnablePnPResponsiveUITests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class EnableResponsiveUITests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPResponsiveUITest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Enable-PnPResponsiveUI",new CommandParameter("InfrastructureSiteUrl", "null")); + + // From Cmdlet Help: A full URL pointing to an infrastructure site. If specified, it will add a custom action pointing to the responsive UI JS code in that site. + var infrastructureSiteUrl = ""; + + var results = scope.ExecuteCommand("Enable-PnPResponsiveUI", + new CommandParameter("InfrastructureSiteUrl", infrastructureSiteUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPApplicationCustomizerTests.cs b/Tests/Branding/GetPnPApplicationCustomizerTests.cs index b604ae5b7..598cf7c32 100644 --- a/Tests/Branding/GetPnPApplicationCustomizerTests.cs +++ b/Tests/Branding/GetPnPApplicationCustomizerTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GetApplicationCustomizerTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPApplicationCustomizerTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPApplicationCustomizer",new CommandParameter("Identity", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ThrowExceptionIfCustomActionNotFound", "null")); + + // From Cmdlet Help: Identity of the SharePoint Framework client side extension application customizer to return. Omit to return all SharePoint Frameworkclient side extension application customizer. + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Client Side Component Id of the SharePoint Framework client side extension application customizer found in the manifest for which existing custom action(s) should be removed + var clientSideComponentId = ""; + // From Cmdlet Help: Scope of the SharePoint Framework client side extension application customizer, either Web, Site or All to return both (all is the default) + var scopeVar = ""; + // From Cmdlet Help: Switch parameter if an exception should be thrown if the requested SharePoint Frameworkclient side extension application customizer does not exist (true) or if omitted, nothing will be returned in case the SharePoint Framework client side extension application customizer does not exist + var throwExceptionIfCustomActionNotFound = ""; + + var results = scope.ExecuteCommand("Get-PnPApplicationCustomizer", + new CommandParameter("Identity", identity), + new CommandParameter("ClientSideComponentId", clientSideComponentId), + new CommandParameter("Scope", scopeVar), + new CommandParameter("ThrowExceptionIfCustomActionNotFound", throwExceptionIfCustomActionNotFound)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPCustomActionTests.cs b/Tests/Branding/GetPnPCustomActionTests.cs index b0ff846dd..9fe7f60eb 100644 --- a/Tests/Branding/GetPnPCustomActionTests.cs +++ b/Tests/Branding/GetPnPCustomActionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GetCustomActionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPCustomActionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPCustomAction",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ThrowExceptionIfCustomActionNotFound", "null")); + + // From Cmdlet Help: Identity of the CustomAction to return. Omit to return all CustomActions. + var identity = ""; + // From Cmdlet Help: Scope of the CustomAction, either Web, Site or All to return both + var scopeVar = ""; + // From Cmdlet Help: Switch parameter if an exception should be thrown if the requested CustomAction does not exist (true) or if omitted, nothing will be returned in case the CustomAction does not exist + var throwExceptionIfCustomActionNotFound = ""; + + var results = scope.ExecuteCommand("Get-PnPCustomAction", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar), + new CommandParameter("ThrowExceptionIfCustomActionNotFound", throwExceptionIfCustomActionNotFound)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPFooterTests.cs b/Tests/Branding/GetPnPFooterTests.cs index 770118390..f31088c6c 100644 --- a/Tests/Branding/GetPnPFooterTests.cs +++ b/Tests/Branding/GetPnPFooterTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GettFooterTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPFooterTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPFooter"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPHomePageTests.cs b/Tests/Branding/GetPnPHomePageTests.cs index 2e86448a9..0e0b3f67b 100644 --- a/Tests/Branding/GetPnPHomePageTests.cs +++ b/Tests/Branding/GetPnPHomePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GetHomePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPHomePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPHomePage"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPJavaScriptLinkTests.cs b/Tests/Branding/GetPnPJavaScriptLinkTests.cs index 6968faa4f..38010f50c 100644 --- a/Tests/Branding/GetPnPJavaScriptLinkTests.cs +++ b/Tests/Branding/GetPnPJavaScriptLinkTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GetJavaScriptLinkTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPJavaScriptLinkTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPJavaScriptLink",new CommandParameter("Name", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ThrowExceptionIfJavaScriptLinkNotFound", "null")); + + // From Cmdlet Help: Name of the Javascript link. Omit this parameter to retrieve all script links + var name = ""; + // From Cmdlet Help: Scope of the action, either Web, Site or All to return both, defaults to Web + var scopeVar = ""; + // From Cmdlet Help: Switch parameter if an exception should be thrown if the requested JavaScriptLink does not exist (true) or if omitted, nothing will be returned in case the JavaScriptLink does not exist + var throwExceptionIfJavaScriptLinkNotFound = ""; + + var results = scope.ExecuteCommand("Get-PnPJavaScriptLink", + new CommandParameter("Name", name), + new CommandParameter("Scope", scopeVar), + new CommandParameter("ThrowExceptionIfJavaScriptLinkNotFound", throwExceptionIfJavaScriptLinkNotFound)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPNavigationNodeTests.cs b/Tests/Branding/GetPnPNavigationNodeTests.cs index 26acc2baf..f41089831 100644 --- a/Tests/Branding/GetPnPNavigationNodeTests.cs +++ b/Tests/Branding/GetPnPNavigationNodeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GetNavigationNodeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPNavigationNodeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPNavigationNode",new CommandParameter("Location", "null"),new CommandParameter("Id", "null"),new CommandParameter("Tree", "null")); + + // From Cmdlet Help: The location of the nodes to retrieve. Either TopNavigationBar, QuickLaunch, SearchNav or Footer. + var location = ""; + // From Cmdlet Help: The Id of the node to retrieve + var id = ""; + // From Cmdlet Help: Show a tree view of all navigation nodes + var tree = ""; + + var results = scope.ExecuteCommand("Get-PnPNavigationNode", + new CommandParameter("Location", location), + new CommandParameter("Id", id), + new CommandParameter("Tree", tree)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/GetPnPThemeTests.cs b/Tests/Branding/GetPnPThemeTests.cs index a3b4cbbf3..fc13bcd23 100644 --- a/Tests/Branding/GetPnPThemeTests.cs +++ b/Tests/Branding/GetPnPThemeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class GetThemeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPThemeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTheme",new CommandParameter("DetectCurrentComposedLook", "null")); + + // From Cmdlet Help: Specify this switch to not use the PnP Provisioning engine based composed look information but try to detect the current composed look as is. + var detectCurrentComposedLook = ""; + + var results = scope.ExecuteCommand("Get-PnPTheme", + new CommandParameter("DetectCurrentComposedLook", detectCurrentComposedLook)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/RemovePnPApplicationCustomizerTests.cs b/Tests/Branding/RemovePnPApplicationCustomizerTests.cs index 87db7904b..3fc8b1cff 100644 --- a/Tests/Branding/RemovePnPApplicationCustomizerTests.cs +++ b/Tests/Branding/RemovePnPApplicationCustomizerTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class RemoveApplicationCustomizerTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPApplicationCustomizerTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPApplicationCustomizer",new CommandParameter("Identity", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: The id or name of the CustomAction representing the client side extension registration that needs to be removed or a CustomAction instance itself + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Client Side Component Id of the SharePoint Framework client side extension application customizer found in the manifest for which existing custom action(s) should be removed + var clientSideComponentId = ""; + // From Cmdlet Help: Define if the CustomAction representing the client side extension registration is to be found at the web or site collection scope. Specify All to allow deletion from either web or site collection (default). + var scopeVar = ""; + // From Cmdlet Help: Use the -Force flag to bypass the confirmation question + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPApplicationCustomizer", + new CommandParameter("Identity", identity), + new CommandParameter("ClientSideComponentId", clientSideComponentId), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/RemovePnPCustomActionTests.cs b/Tests/Branding/RemovePnPCustomActionTests.cs index 8d44cc079..e14f0afef 100644 --- a/Tests/Branding/RemovePnPCustomActionTests.cs +++ b/Tests/Branding/RemovePnPCustomActionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class RemoveCustomActionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPCustomActionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPCustomAction",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: The id or name of the CustomAction that needs to be removed or a CustomAction instance itself + var identity = ""; + // From Cmdlet Help: Define if the CustomAction is to be found at the web or site collection scope. Specify All to allow deletion from either web or site collection. + var scopeVar = ""; + // From Cmdlet Help: Use the -Force flag to bypass the confirmation question + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPCustomAction", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/RemovePnPJavaScriptLinkTests.cs b/Tests/Branding/RemovePnPJavaScriptLinkTests.cs index b8cadc2fa..15fe3259d 100644 --- a/Tests/Branding/RemovePnPJavaScriptLinkTests.cs +++ b/Tests/Branding/RemovePnPJavaScriptLinkTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class RemoveJavaScriptLinkTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPJavaScriptLinkTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPJavaScriptLink",new CommandParameter("Identity", "null"),new CommandParameter("FromSite", "null"),new CommandParameter("Force", "null"),new CommandParameter("Scope", "null")); + + // From Cmdlet Help: Name or id of the JavaScriptLink to remove. Omit if you want to remove all JavaScript Links. + var identity = ""; + var fromSite = ""; + // From Cmdlet Help: Use the -Force flag to bypass the confirmation question + var force = ""; + // From Cmdlet Help: Define if the JavaScriptLink is to be found at the web or site collection scope. Specify All to allow deletion from either web or site collection. + var scopeVar = ""; + + var results = scope.ExecuteCommand("Remove-PnPJavaScriptLink", + new CommandParameter("Identity", identity), + new CommandParameter("FromSite", fromSite), + new CommandParameter("Force", force), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/RemovePnPNavigationNodeTests.cs b/Tests/Branding/RemovePnPNavigationNodeTests.cs index a6b2ca3f1..1dff956f1 100644 --- a/Tests/Branding/RemovePnPNavigationNodeTests.cs +++ b/Tests/Branding/RemovePnPNavigationNodeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class RemoveNavigationNodeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,45 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPNavigationNodeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPNavigationNode",new CommandParameter("Identity", "null"),new CommandParameter("Location", "null"),new CommandParameter("Title", "null"),new CommandParameter("Header", "null"),new CommandParameter("All", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Id or node object to delete + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: The location from where to remove the node. Either TopNavigationBar, QuickLaunch, SearchNav or Footer. + var location = ""; + // This is a mandatory parameter + // From Cmdlet Help: The title of the node that needs to be removed + var title = ""; + // From Cmdlet Help: The header where the node is located + var header = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifying the All parameter will remove all the nodes from specified Location. + var all = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPNavigationNode", + new CommandParameter("Identity", identity), + new CommandParameter("Location", location), + new CommandParameter("Title", title), + new CommandParameter("Header", header), + new CommandParameter("All", all), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPApplicationCustomizerTests.cs b/Tests/Branding/SetPnPApplicationCustomizerTests.cs index 3ccf6f4e1..12eb85ca9 100644 --- a/Tests/Branding/SetPnPApplicationCustomizerTests.cs +++ b/Tests/Branding/SetPnPApplicationCustomizerTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetApplicationCustomizerTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,44 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPApplicationCustomizerTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPApplicationCustomizer",new CommandParameter("Identity", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("ClientSideComponentProperties", "null")); + + // From Cmdlet Help: The id or name of the CustomAction representing the client side extension registration that needs to be updated or a CustomAction instance itself + var identity = ""; + // From Cmdlet Help: The Client Side Component Id of the SharePoint Framework client side extension application customizer found in the manifest for which existing custom action(s) should be updated + var clientSideComponentId = ""; + // From Cmdlet Help: Define if the CustomAction representing the client side extension registration is to be found at the web or site collection scope. Specify All to update the component on both web and site collection level. + var scopeVar = ""; + // From Cmdlet Help: The title of the application customizer. Omit to not update this property. + var title = ""; + // From Cmdlet Help: The description of the application customizer. Omit to not update this property. + var description = ""; + // From Cmdlet Help: Sequence of this application customizer being injected. Use when you have a specific sequence with which to have multiple application customizers being added to the page. Omit to not update this property. + var sequence = ""; + // From Cmdlet Help: The Client Side Component Properties of the application customizer to update. Specify values as a json string : "{Property1 : 'Value1', Property2: 'Value2'}". Omit to not update this property. + var clientSideComponentProperties = ""; + + var results = scope.ExecuteCommand("Set-PnPApplicationCustomizer", + new CommandParameter("Identity", identity), + new CommandParameter("ClientSideComponentId", clientSideComponentId), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("Sequence", sequence), + new CommandParameter("ClientSideComponentProperties", clientSideComponentProperties)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPFooterTests.cs b/Tests/Branding/SetPnPFooterTests.cs index 1e6245040..2a1493a69 100644 --- a/Tests/Branding/SetPnPFooterTests.cs +++ b/Tests/Branding/SetPnPFooterTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetFooterTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,38 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPFooterTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPFooter",new CommandParameter("Enabled", "null"),new CommandParameter("Layout", "null"),new CommandParameter("BackgroundTheme", "null"),new CommandParameter("Title", "null"),new CommandParameter("LogoUrl", "null")); + + // From Cmdlet Help: Indicates if the footer should be shown on the current web ($true) or if it should be hidden ($false) + var enabled = ""; + // From Cmdlet Help: Defines how the footer should look like + var layoutVar = ""; + // From Cmdlet Help: Defines the background emphasis of the content in the footer + var backgroundTheme = ""; + // From Cmdlet Help: Defines the title displayed in the footer + var title = ""; + // From Cmdlet Help: Defines the server relative URL to the logo to be displayed in the footer. Provide an empty string to remove the current logo. + var logoUrl = ""; + + var results = scope.ExecuteCommand("Set-PnPFooter", + new CommandParameter("Enabled", enabled), + new CommandParameter("Layout", layoutVar), + new CommandParameter("BackgroundTheme", backgroundTheme), + new CommandParameter("Title", title), + new CommandParameter("LogoUrl", logoUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPHomePageTests.cs b/Tests/Branding/SetPnPHomePageTests.cs index 5a52c20bd..898567059 100644 --- a/Tests/Branding/SetPnPHomePageTests.cs +++ b/Tests/Branding/SetPnPHomePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetHomePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPHomePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPHomePage",new CommandParameter("RootFolderRelativeUrl", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The root folder relative url of the homepage, e.g. 'sitepages/home.aspx' + var rootFolderRelativeUrl = ""; + + var results = scope.ExecuteCommand("Set-PnPHomePage", + new CommandParameter("RootFolderRelativeUrl", rootFolderRelativeUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPMasterPageTests.cs b/Tests/Branding/SetPnPMasterPageTests.cs index 24d836fa8..6af0052ec 100644 --- a/Tests/Branding/SetPnPMasterPageTests.cs +++ b/Tests/Branding/SetPnPMasterPageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetMasterPageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPMasterPageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPMasterPage",new CommandParameter("MasterPageServerRelativeUrl", "null"),new CommandParameter("CustomMasterPageServerRelativeUrl", "null"),new CommandParameter("MasterPageSiteRelativeUrl", "null"),new CommandParameter("CustomMasterPageSiteRelativeUrl", "null")); + + // From Cmdlet Help: Specifies the Master page URL based on the server relative URL + var masterPageServerRelativeUrl = ""; + // From Cmdlet Help: Specifies the custom Master page URL based on the server relative URL + var customMasterPageServerRelativeUrl = ""; + // From Cmdlet Help: Specifies the Master page URL based on the site relative URL + var masterPageSiteRelativeUrl = ""; + // From Cmdlet Help: Specifies the custom Master page URL based on the site relative URL + var customMasterPageSiteRelativeUrl = ""; + + var results = scope.ExecuteCommand("Set-PnPMasterPage", + new CommandParameter("MasterPageServerRelativeUrl", masterPageServerRelativeUrl), + new CommandParameter("CustomMasterPageServerRelativeUrl", customMasterPageServerRelativeUrl), + new CommandParameter("MasterPageSiteRelativeUrl", masterPageSiteRelativeUrl), + new CommandParameter("CustomMasterPageSiteRelativeUrl", customMasterPageSiteRelativeUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs b/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs index 22ad8cd61..6aa0c8479 100644 --- a/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs +++ b/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetMinimalDownloadStrategyTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPMinimalDownloadStrategyTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPMinimalDownloadStrategy",new CommandParameter("On", "null"),new CommandParameter("Off", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Turn minimal download strategy on + var on = ""; + // This is a mandatory parameter + // From Cmdlet Help: Turn minimal download strategy off + var off = ""; + // From Cmdlet Help: Specifies whether to overwrite (when activating) or continue (when deactivating) an existing feature with the same feature identifier. This parameter is ignored if there are no errors. + var force = ""; + + var results = scope.ExecuteCommand("Set-PnPMinimalDownloadStrategy", + new CommandParameter("On", on), + new CommandParameter("Off", off), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPThemeTests.cs b/Tests/Branding/SetPnPThemeTests.cs index 7529605cb..91e8e68d3 100644 --- a/Tests/Branding/SetPnPThemeTests.cs +++ b/Tests/Branding/SetPnPThemeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetThemeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,41 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPThemeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPTheme",new CommandParameter("ColorPaletteUrl", "null"),new CommandParameter("FontSchemeUrl", "null"),new CommandParameter("BackgroundImageUrl", "null"),new CommandParameter("ShareGenerated", "null"),new CommandParameter("ResetSubwebsToInherit", "null"),new CommandParameter("UpdateRootWebOnly", "null")); + + // From Cmdlet Help: Specifies the Color Palette Url based on the site or server relative url + var colorPaletteUrl = ""; + // From Cmdlet Help: Specifies the Font Scheme Url based on the site or server relative url + var fontSchemeUrl = ""; + // From Cmdlet Help: Specifies the Background Image Url based on the site or server relative url + var backgroundImageUrl = ""; + // From Cmdlet Help: true if the generated theme files should be placed in the root web, false to store them in this web. Default is false + var shareGenerated = ""; + // From Cmdlet Help: Resets subwebs to inherit the theme from the rootweb + var resetSubwebsToInherit = ""; + // From Cmdlet Help: Updates only the rootweb, even if subwebs are set to inherit the theme. + var updateRootWebOnly = ""; + + var results = scope.ExecuteCommand("Set-PnPTheme", + new CommandParameter("ColorPaletteUrl", colorPaletteUrl), + new CommandParameter("FontSchemeUrl", fontSchemeUrl), + new CommandParameter("BackgroundImageUrl", backgroundImageUrl), + new CommandParameter("ShareGenerated", shareGenerated), + new CommandParameter("ResetSubwebsToInherit", resetSubwebsToInherit), + new CommandParameter("UpdateRootWebOnly", updateRootWebOnly)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Branding/SetPnPWebThemeTests.cs b/Tests/Branding/SetPnPWebThemeTests.cs index 46f6d1263..17012bfca 100644 --- a/Tests/Branding/SetPnPWebThemeTests.cs +++ b/Tests/Branding/SetPnPWebThemeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Branding { - [TestClass] public class SetWebThemeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPWebThemeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPWebTheme",new CommandParameter("Theme", "null"),new CommandParameter("WebUrl", "null")); + + // From Cmdlet Help: Specifies the Color Palette Url based on the site or server relative url + var theme = ""; + // From Cmdlet Help: The URL of the web to apply the theme to. If not specified it will default to the current web based upon the URL specified with Connect-PnPOnline. + var webUrl = ""; + + var results = scope.ExecuteCommand("Set-PnPWebTheme", + new CommandParameter("Theme", theme), + new CommandParameter("WebUrl", webUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs b/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs index f425648fc..f1bbd3de8 100644 --- a/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs +++ b/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class AddClientSidePageSectionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPClientSidePageSectionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPClientSidePageSection",new CommandParameter("Page", "null"),new CommandParameter("SectionTemplate", "null"),new CommandParameter("Order", "null"),new CommandParameter("ZoneEmphasis", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var page = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifies the columns template to use for the section. + var sectionTemplate = ""; + // From Cmdlet Help: Sets the order of the section. (Default = 1) + var order = ""; + // From Cmdlet Help: Sets the background of the section (default = 0) + var zoneEmphasis = ""; + + var results = scope.ExecuteCommand("Add-PnPClientSidePageSection", + new CommandParameter("Page", page), + new CommandParameter("SectionTemplate", sectionTemplate), + new CommandParameter("Order", order), + new CommandParameter("ZoneEmphasis", zoneEmphasis)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/AddPnPClientSidePageTests.cs b/Tests/ClientSidePages/AddPnPClientSidePageTests.cs index 280360dc6..1c47f3a68 100644 --- a/Tests/ClientSidePages/AddPnPClientSidePageTests.cs +++ b/Tests/ClientSidePages/AddPnPClientSidePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class AddClientSidePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,48 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPClientSidePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPClientSidePage",new CommandParameter("Name", "null"),new CommandParameter("LayoutType", "null"),new CommandParameter("PromoteAs", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("CommentsEnabled", "null"),new CommandParameter("Publish", "null"),new CommandParameter("HeaderLayoutType", "null"),new CommandParameter("PublishMessage", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the name of the page. + var name = ""; + // From Cmdlet Help: Specifies the layout type of the page. + var layoutVarType = ""; + // From Cmdlet Help: Allows to promote the page for a specific purpose (HomePage | NewsPage) + var promoteAs = ""; + // From Cmdlet Help: Specify either the name, ID or an actual content type. + var contentType = ""; + // From Cmdlet Help: Enables or Disables the comments on the page + var commentsEnabled = ""; + // From Cmdlet Help: Publishes the page once it is saved. Applicable to libraries set to create major and minor versions. + var publish = ""; + // From Cmdlet Help: Type of layout used for the header + var headerLayoutVarType = ""; + // From Cmdlet Help: Sets the message for publishing the page. + var publishMessage = ""; + + var results = scope.ExecuteCommand("Add-PnPClientSidePage", + new CommandParameter("Name", name), + new CommandParameter("LayoutType", layoutVarType), + new CommandParameter("PromoteAs", promoteAs), + new CommandParameter("ContentType", contentType), + new CommandParameter("CommentsEnabled", commentsEnabled), + new CommandParameter("Publish", publish), + new CommandParameter("HeaderLayoutType", headerLayoutVarType), + new CommandParameter("PublishMessage", publishMessage)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/AddPnPClientSideTextTests.cs b/Tests/ClientSidePages/AddPnPClientSideTextTests.cs index 9ec820f6d..a2c0fb79f 100644 --- a/Tests/ClientSidePages/AddPnPClientSideTextTests.cs +++ b/Tests/ClientSidePages/AddPnPClientSideTextTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class AddClientSideTextTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPClientSideTextTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPClientSideText",new CommandParameter("Page", "null"),new CommandParameter("Text", "null"),new CommandParameter("Order", "null"),new CommandParameter("Section", "null"),new CommandParameter("Column", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page. + var page = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifies the text to display in the text area. + var text = ""; + // From Cmdlet Help: Sets the order of the text control. (Default = 1) + var order = ""; + // This is a mandatory parameter + // From Cmdlet Help: Sets the section where to insert the text control. + var section = ""; + // This is a mandatory parameter + // From Cmdlet Help: Sets the column where to insert the text control. + var column = ""; + + var results = scope.ExecuteCommand("Add-PnPClientSideText", + new CommandParameter("Page", page), + new CommandParameter("Text", text), + new CommandParameter("Order", order), + new CommandParameter("Section", section), + new CommandParameter("Column", column)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/ConvertToPnPClientSidePageTests.cs b/Tests/ClientSidePages/ConvertToPnPClientSidePageTests.cs new file mode 100644 index 000000000..08e5d0189 --- /dev/null +++ b/Tests/ClientSidePages/ConvertToPnPClientSidePageTests.cs @@ -0,0 +1,204 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + [TestClass] + public class ConvertToClientSidePageTests + { + #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + // Do Test Setup - Note, this runs PER test + } + catch (Exception) + { + // Describe Exception + } + } + } + #endregion + + #region Scaffolded Cmdlet Tests + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ConvertToPnPClientSidePageTest() + { + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page to convert + var identity = ""; + // From Cmdlet Help: The name of the library containing the page. If SitePages then please omit this parameter + var library = ""; + // From Cmdlet Help: The folder to load the provided page from. If not provided all folders are searched + var folder = ""; + // From Cmdlet Help: Path and name of the web part mapping file driving the transformation + var webPartMappingFile = ""; + // From Cmdlet Help: Overwrites page if already existing + var overwrite = ""; + // From Cmdlet Help: Created client side page takes name from previous classic page. Classic page gets renamed to previous_.aspx + var takeSourcePageName = ""; + // From Cmdlet Help: Replaces a home page with a default stock modern home page + var replaceHomePageWithDefault = ""; + // From Cmdlet Help: Adds the page accept banner web part. The actual web part is specified in webpartmapping.xml file + var addPageAcceptBanner = ""; + // From Cmdlet Help: By default the item level permissions on a page are copied to the created client side page. Use this switch to prevent the copy + var skipItemLevelPermissionCopyToClientSidePage = ""; + // From Cmdlet Help: If transforming cross site then by default urls in html and summarylinks are rewritten for the target site. Set this flag to prevent that + var skipUrlRewriting = ""; + // From Cmdlet Help: Set this flag to prevent the default URL rewriting while you still want to do URL rewriting using a custom URL mapping file + var skipDefaultUrlRewriting = ""; + // From Cmdlet Help: File holding custom URL mapping definitions + var urlMappingFile = ""; + // From Cmdlet Help: Clears the cache. Can be needed if you've installed a new web part to the site and want to use that in a custom webpartmapping file. Restarting your PS session has the same effect + var clearCache = ""; + // From Cmdlet Help: Copies the page metadata to the created modern page + var copyPageMetadata = ""; + // From Cmdlet Help: When an image lives inside a table/list then it's also created as separate image web part underneath that table/list by default. Use this switch set to $false to change that + var addTableListImageAsImageWebPart = ""; + // From Cmdlet Help: Uses the community script editor (https://github.com/SharePoint/sp-dev-fx-webparts/tree/master/samples/react-script-editor) as replacement for the classic script editor web part + var useCommunityScriptEditor = ""; + // From Cmdlet Help: By default summarylinks web parts are replaced by QuickLinks, but you can transform to plain html by setting this switch + var summaryLinksToHtml = ""; + // From Cmdlet Help: Url of the target web that will receive the modern page. Defaults to null which means in-place transformation + var targetWebUrl = ""; + // From Cmdlet Help: Allows to generate a transformation log (File | SharePoint) + var logType = ""; + // From Cmdlet Help: Folder in where the log file will be created (if LogType==File) + var logFolder = ""; + // From Cmdlet Help: By default each cmdlet invocation will result in a log file, use the -SkipLogFlush to delay the log flushing. The first call without -SkipLogFlush will then write all log entries to a single log + var logSkipFlush = ""; + // From Cmdlet Help: Configure logging to include verbose log entries + var logVerbose = ""; + // From Cmdlet Help: Don't publish the created modern page + var dontPublish = ""; + // From Cmdlet Help: Keep the author, editor, created and modified information from the source page (when source page lives in SPO) + var keepPageCreationModificationInformation = ""; + // From Cmdlet Help: Set's the author of the source page as author in the modern page header (when source page lives in SPO) + var setAuthorInPageHeader = ""; + // From Cmdlet Help: Post the created, and published, modern page as news + var postAsNews = ""; + // From Cmdlet Help: Disable comments for the created modern page + var disablePageComments = ""; + // From Cmdlet Help: I'm transforming a publishing page + var publishingPage = ""; + // From Cmdlet Help: I'm transforming a blog page + var blogPage = ""; + // From Cmdlet Help: I'm transforming a Delve blog page + var delveBlogPage = ""; + // From Cmdlet Help: Transform the possible sub title as topic header on the modern page + var delveKeepSubTitle = ""; + // From Cmdlet Help: Path and name of the page layout mapping file driving the publishing page transformation + var pageLayoutVarMapping = ""; + // From Cmdlet Help: Name for the target page (only applies to publishing page transformation) + var publishingTargetPageName = ""; + // From Cmdlet Help: Name for the target page (only applies when doing cross site page transformation) + var targetPageName = ""; + // From Cmdlet Help: Folder to create the target page in (will be used in conjunction with auto-generated folders that ensure page name uniqueness) + var targetPageFolder = ""; + // From Cmdlet Help: When setting a target page folder then the target page folder overrides possibly default folder path (e.g. in the source page lived in a folder) instead of being appended to it + var targetPageFolderOverridesDefaultFolder = ""; + // From Cmdlet Help: Remove empty sections and columns after transformation of the page + var removeEmptySectionsAndColumns = ""; + // From Cmdlet Help: Optional connection to be used by the cmdlet. Retrieve the value for this parameter by either specifying -ReturnConnection on Connect-PnPOnline or by executing Get-PnPConnection. + var targetConnection = ""; + // From Cmdlet Help: Disables user mapping during transformation + var skipUserMapping = ""; + // From Cmdlet Help: Specifies a user mapping file + var userMappingFile = ""; + // From Cmdlet Help: Specifies a taxonomy term mapping file + var termMappingFile = ""; + // From Cmdlet Help: Disables term mapping during transformation + var skipTermStoreMapping = ""; + // From Cmdlet Help: Specifies a LDAP connection string e.g. LDAP://OU=Users,DC=Contoso,DC=local + var lDAPConnectionString = ""; + + var results = scope.ExecuteCommand("ConvertTo-PnPClientSidePage", + new CommandParameter("Identity", identity), + new CommandParameter("Library", library), + new CommandParameter("Folder", folder), + new CommandParameter("WebPartMappingFile", webPartMappingFile), + new CommandParameter("Overwrite", overwrite), + new CommandParameter("TakeSourcePageName", takeSourcePageName), + new CommandParameter("ReplaceHomePageWithDefault", replaceHomePageWithDefault), + new CommandParameter("AddPageAcceptBanner", addPageAcceptBanner), + new CommandParameter("SkipItemLevelPermissionCopyToClientSidePage", skipItemLevelPermissionCopyToClientSidePage), + new CommandParameter("SkipUrlRewriting", skipUrlRewriting), + new CommandParameter("SkipDefaultUrlRewriting", skipDefaultUrlRewriting), + new CommandParameter("UrlMappingFile", urlMappingFile), + new CommandParameter("ClearCache", clearCache), + new CommandParameter("CopyPageMetadata", copyPageMetadata), + new CommandParameter("AddTableListImageAsImageWebPart", addTableListImageAsImageWebPart), + new CommandParameter("UseCommunityScriptEditor", useCommunityScriptEditor), + new CommandParameter("SummaryLinksToHtml", summaryLinksToHtml), + new CommandParameter("TargetWebUrl", targetWebUrl), + new CommandParameter("LogType", logType), + new CommandParameter("LogFolder", logFolder), + new CommandParameter("LogSkipFlush", logSkipFlush), + new CommandParameter("LogVerbose", logVerbose), + new CommandParameter("DontPublish", dontPublish), + new CommandParameter("KeepPageCreationModificationInformation", keepPageCreationModificationInformation), + new CommandParameter("SetAuthorInPageHeader", setAuthorInPageHeader), + new CommandParameter("PostAsNews", postAsNews), + new CommandParameter("DisablePageComments", disablePageComments), + new CommandParameter("PublishingPage", publishingPage), + new CommandParameter("BlogPage", blogPage), + new CommandParameter("DelveBlogPage", delveBlogPage), + new CommandParameter("DelveKeepSubTitle", delveKeepSubTitle), + new CommandParameter("PageLayoutMapping", pageLayoutVarMapping), + new CommandParameter("PublishingTargetPageName", publishingTargetPageName), + new CommandParameter("TargetPageName", targetPageName), + new CommandParameter("TargetPageFolder", targetPageFolder), + new CommandParameter("TargetPageFolderOverridesDefaultFolder", targetPageFolderOverridesDefaultFolder), + new CommandParameter("RemoveEmptySectionsAndColumns", removeEmptySectionsAndColumns), + new CommandParameter("TargetConnection", targetConnection), + new CommandParameter("SkipUserMapping", skipUserMapping), + new CommandParameter("UserMappingFile", userMappingFile), + new CommandParameter("TermMappingFile", termMappingFile), + new CommandParameter("SkipTermStoreMapping", skipTermStoreMapping), + new CommandParameter("LDAPConnectionString", lDAPConnectionString)); + + Assert.IsNotNull(results); + } + } + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/ExportPnPClientSidePageMappingTests.cs b/Tests/ClientSidePages/ExportPnPClientSidePageMappingTests.cs new file mode 100644 index 000000000..b8940dfa2 --- /dev/null +++ b/Tests/ClientSidePages/ExportPnPClientSidePageMappingTests.cs @@ -0,0 +1,98 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + [TestClass] + public class ExportClientSidePageMappingTests + { + #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + // Do Test Setup - Note, this runs PER test + } + catch (Exception) + { + // Describe Exception + } + } + } + #endregion + + #region Scaffolded Cmdlet Tests + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ExportPnPClientSidePageMappingTest() + { + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + + // From Cmdlet Help: Exports the builtin web part mapping file + var builtInWebPartMapping = ""; + // From Cmdlet Help: Exports the builtin pagelayout mapping file (only needed for publishing page transformation) + var builtInPageLayoutVarMapping = ""; + // From Cmdlet Help: Analyzes the pagelayouts in the current publishing portal and exports them as a pagelayout mapping file + var customPageLayoutVarMapping = ""; + // From Cmdlet Help: The name of the publishing page to export a page layout mapping file for + var publishingPage = ""; + // From Cmdlet Help: Set this flag if you also want to analyze the OOB page layouts...typically these are covered via the default mapping, but if you've updated these page layouts you might want to analyze them again + var analyzeOOBPageLayoutVars = ""; + // From Cmdlet Help: The folder to created the mapping file(s) in + var folder = ""; + // From Cmdlet Help: Overwrites existing mapping files + var overwrite = ""; + // From Cmdlet Help: Outputs analyser logging to the console + var logging = ""; + + var results = scope.ExecuteCommand("Export-PnPClientSidePageMapping", + new CommandParameter("BuiltInWebPartMapping", builtInWebPartMapping), + new CommandParameter("BuiltInPageLayoutMapping", builtInPageLayoutVarMapping), + new CommandParameter("CustomPageLayoutMapping", customPageLayoutVarMapping), + new CommandParameter("PublishingPage", publishingPage), + new CommandParameter("AnalyzeOOBPageLayouts", analyzeOOBPageLayoutVars), + new CommandParameter("Folder", folder), + new CommandParameter("Overwrite", overwrite), + new CommandParameter("Logging", logging)); + + Assert.IsNotNull(results); + } + } + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs b/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs index 148dd2aba..86b76c6d4 100644 --- a/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs +++ b/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class GetAvailableClientSideComponentsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAvailableClientSideComponentsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPAvailableClientSideComponents",new CommandParameter("Page", "null"),new CommandParameter("Component", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page. + var page = ""; + // From Cmdlet Help: Specifies the component instance or Id to look for. + var component = ""; + + var results = scope.ExecuteCommand("Get-PnPAvailableClientSideComponents", + new CommandParameter("Page", page), + new CommandParameter("Component", component)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs b/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs index 760fc5dc8..7bf2903f7 100644 --- a/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs +++ b/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class GetClientSideControlTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPClientSideComponentTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPClientSideComponent",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var page = ""; + // From Cmdlet Help: The instance id of the component + var instanceId = ""; + + var results = scope.ExecuteCommand("Get-PnPClientSideComponent", + new CommandParameter("Page", page), + new CommandParameter("InstanceId", instanceId)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/GetPnPClientSidePageTests.cs b/Tests/ClientSidePages/GetPnPClientSidePageTests.cs index 9ffc06cb8..acb6af13c 100644 --- a/Tests/ClientSidePages/GetPnPClientSidePageTests.cs +++ b/Tests/ClientSidePages/GetPnPClientSidePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class GetClientSidePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPClientSidePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPClientSidePage",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPClientSidePage", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs b/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs index 8a6b482ab..ce160e252 100644 --- a/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs +++ b/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class MoveClientSideWebPartTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MovePnPClientSideComponentTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Move-PnPClientSideComponent",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null"),new CommandParameter("Section", "null"),new CommandParameter("Column", "null"),new CommandParameter("Position", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var page = ""; + // This is a mandatory parameter + // From Cmdlet Help: The instance id of the control. Use Get-PnPClientSideControl retrieve the instance ids. + var instanceId = ""; + // This is a mandatory parameter + // From Cmdlet Help: The section to move the web part to + var section = ""; + // This is a mandatory parameter + // From Cmdlet Help: The column to move the web part to + var column = ""; + // From Cmdlet Help: Change to order of the web part in the column + var position = ""; + + var results = scope.ExecuteCommand("Move-PnPClientSideComponent", + new CommandParameter("Page", page), + new CommandParameter("InstanceId", instanceId), + new CommandParameter("Section", section), + new CommandParameter("Column", column), + new CommandParameter("Position", position)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs b/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs index b2e08b76b..d18c6cfd8 100644 --- a/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs +++ b/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class RemoveClientSideComponentTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPClientSideComponentTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPClientSideComponent",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var page = ""; + // This is a mandatory parameter + // From Cmdlet Help: The instance id of the component + var instanceId = ""; + // From Cmdlet Help: If specified you will not receive the confirmation question + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPClientSideComponent", + new CommandParameter("Page", page), + new CommandParameter("InstanceId", instanceId), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs b/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs index d79f6de67..3785b8605 100644 --- a/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs +++ b/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class RemoveClientSidePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPClientSidePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPClientSidePage",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var identity = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPClientSidePage", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/SavePnPClientSidePageConversionLogTests.cs b/Tests/ClientSidePages/SavePnPClientSidePageConversionLogTests.cs new file mode 100644 index 000000000..601bd291f --- /dev/null +++ b/Tests/ClientSidePages/SavePnPClientSidePageConversionLogTests.cs @@ -0,0 +1,74 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + [TestClass] + public class SaveClientSidePageConversionLogTests + { + #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + // Do Test Setup - Note, this runs PER test + } + catch (Exception) + { + // Describe Exception + } + } + } + #endregion + + #region Scaffolded Cmdlet Tests + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SavePnPClientSidePageConversionLogTest() + { + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + + + var results = scope.ExecuteCommand("Save-PnPClientSidePageConversionLog"); + + Assert.IsNotNull(results); + } + } + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/SetPnPClientSidePageTests.cs b/Tests/ClientSidePages/SetPnPClientSidePageTests.cs index 81af2cb5d..07007dc89 100644 --- a/Tests/ClientSidePages/SetPnPClientSidePageTests.cs +++ b/Tests/ClientSidePages/SetPnPClientSidePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class SetClientSidePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,57 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPClientSidePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPClientSidePage",new CommandParameter("Identity", "null"),new CommandParameter("Name", "null"),new CommandParameter("Title", "null"),new CommandParameter("LayoutType", "null"),new CommandParameter("PromoteAs", "null"),new CommandParameter("CommentsEnabled", "null"),new CommandParameter("Publish", "null"),new CommandParameter("HeaderType", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("ThumbnailUrl", "null"),new CommandParameter("PublishMessage", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name/identity of the page + var identity = ""; + // From Cmdlet Help: Sets the name of the page. + var name = ""; + // From Cmdlet Help: Sets the title of the page. + var title = ""; + // From Cmdlet Help: Sets the layout type of the page. (Default = Article) + var layoutVarType = ""; + // From Cmdlet Help: Allows to promote the page for a specific purpose (None | HomePage | NewsArticle | Template) + var promoteAs = ""; + // From Cmdlet Help: Enables or Disables the comments on the page + var commentsEnabled = ""; + // From Cmdlet Help: Publishes the page once it is saved. + var publish = ""; + // From Cmdlet Help: Sets the page header type + var headerType = ""; + // From Cmdlet Help: Specify either the name, ID or an actual content type. + var contentType = ""; + // From Cmdlet Help: Thumbnail Url + var thumbnailUrl = ""; + // From Cmdlet Help: Sets the message for publishing the page. + var publishMessage = ""; + + var results = scope.ExecuteCommand("Set-PnPClientSidePage", + new CommandParameter("Identity", identity), + new CommandParameter("Name", name), + new CommandParameter("Title", title), + new CommandParameter("LayoutType", layoutVarType), + new CommandParameter("PromoteAs", promoteAs), + new CommandParameter("CommentsEnabled", commentsEnabled), + new CommandParameter("Publish", publish), + new CommandParameter("HeaderType", headerType), + new CommandParameter("ContentType", contentType), + new CommandParameter("ThumbnailUrl", thumbnailUrl), + new CommandParameter("PublishMessage", publishMessage)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/SetPnPClientSideTextTests.cs b/Tests/ClientSidePages/SetPnPClientSideTextTests.cs index cb067fa95..4cf532f55 100644 --- a/Tests/ClientSidePages/SetPnPClientSideTextTests.cs +++ b/Tests/ClientSidePages/SetPnPClientSideTextTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class SetClientSideTextTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPClientSideTextTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPClientSideText",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null"),new CommandParameter("Text", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var page = ""; + // This is a mandatory parameter + // From Cmdlet Help: The instance id of the text component + var instanceId = ""; + // This is a mandatory parameter + // From Cmdlet Help: Text to set + var text = ""; + + var results = scope.ExecuteCommand("Set-PnPClientSideText", + new CommandParameter("Page", page), + new CommandParameter("InstanceId", instanceId), + new CommandParameter("Text", text)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs b/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs index 4d1abcfe5..5a49210d6 100644 --- a/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs +++ b/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ClientSidePages { - [TestClass] public class SetClientSideWebPartTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPClientSideWebPartTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPClientSideWebPart",new CommandParameter("Page", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Title", "null"),new CommandParameter("PropertiesJson", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var page = ""; + // This is a mandatory parameter + // From Cmdlet Help: The identity of the web part. This can be the web part instance id or the title of a web part + var identity = ""; + // From Cmdlet Help: Sets the internal title of the web part. Notice that this will NOT set a visible title. + var title = ""; + // From Cmdlet Help: Sets the properties as a JSON string. + var propertiesJson = ""; + + var results = scope.ExecuteCommand("Set-PnPClientSideWebPart", + new CommandParameter("Page", page), + new CommandParameter("Identity", identity), + new CommandParameter("Title", title), + new CommandParameter("PropertiesJson", propertiesJson)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/AddPnPContentTypeTests.cs b/Tests/ContentTypes/AddPnPContentTypeTests.cs index c9c7fc81f..744ccf8b9 100644 --- a/Tests/ContentTypes/AddPnPContentTypeTests.cs +++ b/Tests/ContentTypes/AddPnPContentTypeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class AddContentTypeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPContentTypeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPContentType",new CommandParameter("Name", "null"),new CommandParameter("ContentTypeId", "null"),new CommandParameter("Description", "null"),new CommandParameter("Group", "null"),new CommandParameter("ParentContentType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specify the name of the new content type + var name = ""; + // From Cmdlet Help: If specified, in the format of 0x0100233af432334r434343f32f3, will create a content type with the specific ID + var contentTypeId = ""; + // From Cmdlet Help: Specifies the description of the new content type + var description = ""; + // From Cmdlet Help: Specifies the group of the new content type + var group = ""; + // From Cmdlet Help: Specifies the parent of the new content type + var parentContentType = ""; + + var results = scope.ExecuteCommand("Add-PnPContentType", + new CommandParameter("Name", name), + new CommandParameter("ContentTypeId", contentTypeId), + new CommandParameter("Description", description), + new CommandParameter("Group", group), + new CommandParameter("ParentContentType", parentContentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/AddPnPContentTypeToListTests.cs b/Tests/ContentTypes/AddPnPContentTypeToListTests.cs index 75b735c01..97c92ffc7 100644 --- a/Tests/ContentTypes/AddPnPContentTypeToListTests.cs +++ b/Tests/ContentTypes/AddPnPContentTypeToListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class AddContentTypeToListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPContentTypeToListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPContentTypeToList",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("DefaultContentType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the list to which the content type needs to be added + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifies the content type that needs to be added to the list + var contentType = ""; + // From Cmdlet Help: Specify if the content type needs to be the default content type or not + var defaultContentType = ""; + + var results = scope.ExecuteCommand("Add-PnPContentTypeToList", + new CommandParameter("List", list), + new CommandParameter("ContentType", contentType), + new CommandParameter("DefaultContentType", defaultContentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs b/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs index 2d10fcbb4..47c94d0b3 100644 --- a/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs +++ b/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class AddFieldToContentTypeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPFieldToContentTypeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPFieldToContentType",new CommandParameter("Field", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("Required", "null"),new CommandParameter("Hidden", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the field that needs to be added to the content type + var field = ""; + // This is a mandatory parameter + // From Cmdlet Help: Specifies which content type a field needs to be added to + var contentType = ""; + // From Cmdlet Help: Specifies whether the field is required or not + var required = ""; + // From Cmdlet Help: Specifies whether the field should be hidden or not + var hidden = ""; + + var results = scope.ExecuteCommand("Add-PnPFieldToContentType", + new CommandParameter("Field", field), + new CommandParameter("ContentType", contentType), + new CommandParameter("Required", required), + new CommandParameter("Hidden", hidden)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs b/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs index e5e5e42f7..89b772299 100644 --- a/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs +++ b/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class GetContentTypePublishingHubTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPContentTypePublishingHubUrlTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPContentTypePublishingHubUrl"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/GetPnPContentTypeTests.cs b/Tests/ContentTypes/GetPnPContentTypeTests.cs index f50e08610..520d33b38 100644 --- a/Tests/ContentTypes/GetPnPContentTypeTests.cs +++ b/Tests/ContentTypes/GetPnPContentTypeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class GetContentTypeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPContentTypeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPContentType",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("InSiteHierarchy", "null")); + + // From Cmdlet Help: Name or ID of the content type to retrieve + var identity = ""; + // From Cmdlet Help: List to query + var list = ""; + // From Cmdlet Help: Search site hierarchy for content types + var inSiteHierarchy = ""; + + var results = scope.ExecuteCommand("Get-PnPContentType", + new CommandParameter("Identity", identity), + new CommandParameter("List", list), + new CommandParameter("InSiteHierarchy", inSiteHierarchy)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs b/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs index 836711332..ab53945ce 100644 --- a/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs +++ b/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class RemoveContentTypeFromListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPContentTypeFromListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPContentTypeFromList",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the list, its ID or an actual list object from where the content type needs to be removed from + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of a content type, its ID or an actual content type object that needs to be removed from the specified list. + var contentType = ""; + + var results = scope.ExecuteCommand("Remove-PnPContentTypeFromList", + new CommandParameter("List", list), + new CommandParameter("ContentType", contentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/RemovePnPContentTypeTests.cs b/Tests/ContentTypes/RemovePnPContentTypeTests.cs index cc14c2af7..4f2605e35 100644 --- a/Tests/ContentTypes/RemovePnPContentTypeTests.cs +++ b/Tests/ContentTypes/RemovePnPContentTypeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class RemoveContentTypeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPContentTypeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPContentType",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name or ID of the content type to remove + var identity = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPContentType", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs b/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs index 4729d612e..846ad967e 100644 --- a/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs +++ b/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class RemoveFieldFromContentTypeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPFieldFromContentTypeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPFieldFromContentType",new CommandParameter("Field", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("DoNotUpdateChildren", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The field to remove + var field = ""; + // This is a mandatory parameter + // From Cmdlet Help: The content type where the field is to be removed from + var contentType = ""; + // From Cmdlet Help: If specified, inherited content types will not be updated + var doNotUpdateChildren = ""; + + var results = scope.ExecuteCommand("Remove-PnPFieldFromContentType", + new CommandParameter("Field", field), + new CommandParameter("ContentType", contentType), + new CommandParameter("DoNotUpdateChildren", doNotUpdateChildren)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs b/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs index b0abe2617..ac0bea809 100644 --- a/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs +++ b/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ContentTypes { - [TestClass] public class SetDefaultContentTypeToListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPDefaultContentTypeToListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPDefaultContentTypeToList",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of a list, an ID or the actual list object to update + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The content type object that needs to be set as the default content type on the list. Content Type needs to be present on the list. + var contentType = ""; + + var results = scope.ExecuteCommand("Set-PnPDefaultContentTypeToList", + new CommandParameter("List", list), + new CommandParameter("ContentType", contentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Diagnostic/MeasurePnPListTests.cs b/Tests/Diagnostic/MeasurePnPListTests.cs index e0a169e13..2560f75f4 100644 --- a/Tests/Diagnostic/MeasurePnPListTests.cs +++ b/Tests/Diagnostic/MeasurePnPListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Diagnostic { - [TestClass] public class MeasurePnPListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MeasurePnPListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Measure-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("ItemLevel", "null"),new CommandParameter("BrokenPermissions", "null")); + + // This is a mandatory parameter + var identity = ""; + // From Cmdlet Help: Show item level statistics + var itemLevel = ""; + // From Cmdlet Help: Show items with broken permissions + var brokenPermissions = ""; + + var results = scope.ExecuteCommand("Measure-PnPList", + new CommandParameter("Identity", identity), + new CommandParameter("ItemLevel", itemLevel), + new CommandParameter("BrokenPermissions", brokenPermissions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs b/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs index d0fb29148..059a53df0 100644 --- a/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs +++ b/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Diagnostic { - [TestClass] public class MeasureResponseTimeTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,40 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MeasurePnPResponseTimeTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Measure-PnPResponseTime",new CommandParameter("Url", "null"),new CommandParameter("Count", "null"),new CommandParameter("WarmUp", "null"),new CommandParameter("Timeout", "null"),new CommandParameter("Histogram", "null"),new CommandParameter("Mode", "null")); + + var url = ""; + // From Cmdlet Help: Number of probe requests to send + var count = ""; + // From Cmdlet Help: Number of warm up requests to send before start calculating statistics + var warmUp = ""; + // From Cmdlet Help: Idle timeout between requests to avoid request throttling + var timeoutVar = ""; + // From Cmdlet Help: Number of buckets in histogram in output statistics + var histogram = ""; + // From Cmdlet Help: Response time measurement mode. RoundTrip - measures full request round trip. SPRequestDuration - measures server processing time only, based on SPRequestDuration HTTP header. Latency - difference between RoundTrip and SPRequestDuration + var mode = ""; + + var results = scope.ExecuteCommand("Measure-PnPResponseTime", + new CommandParameter("Url", url), + new CommandParameter("Count", count), + new CommandParameter("WarmUp", warmUp), + new CommandParameter("Timeout", timeoutVar), + new CommandParameter("Histogram", histogram), + new CommandParameter("Mode", mode)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Diagnostic/MeasurePnPWebTests.cs b/Tests/Diagnostic/MeasurePnPWebTests.cs index 4fcace84a..8785a53f9 100644 --- a/Tests/Diagnostic/MeasurePnPWebTests.cs +++ b/Tests/Diagnostic/MeasurePnPWebTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Diagnostic { - [TestClass] public class MeasurePnPWebTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MeasurePnPWebTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Measure-PnPWeb",new CommandParameter("Identity", "null"),new CommandParameter("Recursive", "null"),new CommandParameter("IncludeHiddenList", "null")); + + var identity = ""; + // From Cmdlet Help: Iterate all sub webs recursively + var recursive = ""; + // From Cmdlet Help: Include hidden lists in statistics calculation + var includeHiddenList = ""; + + var results = scope.ExecuteCommand("Measure-PnPWeb", + new CommandParameter("Identity", identity), + new CommandParameter("Recursive", recursive), + new CommandParameter("IncludeHiddenList", includeHiddenList)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs b/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs index 75136fd19..01aa134a4 100644 --- a/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs +++ b/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.DocumentSets { - [TestClass] public class AddContentTypeToDocumentSetTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPContentTypeToDocumentSetTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPContentTypeToDocumentSet",new CommandParameter("ContentType", "null"),new CommandParameter("DocumentSet", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The content type object, name or id to add. Either specify name, an id, or a content type object. + var contentType = ""; + // This is a mandatory parameter + // From Cmdlet Help: The document set object or id to add the content type to. Either specify a name, a document set template object, an id, or a content type object + var documentSet = ""; + + var results = scope.ExecuteCommand("Add-PnPContentTypeToDocumentSet", + new CommandParameter("ContentType", contentType), + new CommandParameter("DocumentSet", documentSet)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/DocumentSets/AddPnPDocumentSetTests.cs b/Tests/DocumentSets/AddPnPDocumentSetTests.cs index fdaf5a323..2d569a991 100644 --- a/Tests/DocumentSets/AddPnPDocumentSetTests.cs +++ b/Tests/DocumentSets/AddPnPDocumentSetTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.DocumentSets { - [TestClass] public class AddDocumentSetTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPDocumentSetTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPDocumentSet",new CommandParameter("List", "null"),new CommandParameter("Name", "null"),new CommandParameter("ContentType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the list, its ID or an actual list object from where the document set needs to be added + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the document set + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the content type, its ID or an actual content object referencing to the document set + var contentType = ""; + + var results = scope.ExecuteCommand("Add-PnPDocumentSet", + new CommandParameter("List", list), + new CommandParameter("Name", name), + new CommandParameter("ContentType", contentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs b/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs index 534f3192a..087fc2b15 100644 --- a/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs +++ b/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.DocumentSets { - [TestClass] public class GetDocumentSetTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPDocumentSetTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPDocumentSetTemplate",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Either specify a name, an id, a document set template object or a content type object + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPDocumentSetTemplate", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs b/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs index 6ebc1d4d0..2f1e38f11 100644 --- a/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs +++ b/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.DocumentSets { - [TestClass] public class RemoveContentTypeFromDocumentSetTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPContentTypeFromDocumentSetTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPContentTypeFromDocumentSet",new CommandParameter("ContentType", "null"),new CommandParameter("DocumentSet", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The content type to remove. Either specify name, an id, or a content type object. + var contentType = ""; + // This is a mandatory parameter + // From Cmdlet Help: The document set to remove the content type from. Either specify a name, a document set template object, an id, or a content type object + var documentSet = ""; + + var results = scope.ExecuteCommand("Remove-PnPContentTypeFromDocumentSet", + new CommandParameter("ContentType", contentType), + new CommandParameter("DocumentSet", documentSet)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs b/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs index ef77761fa..dd9dd473f 100644 --- a/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs +++ b/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.DocumentSets { - [TestClass] public class SetFieldInDocumentSetTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,43 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPDocumentSetFieldTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPDocumentSetField",new CommandParameter("DocumentSet", "null"),new CommandParameter("Field", "null"),new CommandParameter("SetSharedField", "null"),new CommandParameter("SetWelcomePageField", "null"),new CommandParameter("RemoveSharedField", "null"),new CommandParameter("RemoveWelcomePageField", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The document set in which to set the field. Either specify a name, a document set template object, an id, or a content type object + var documentSet = ""; + // This is a mandatory parameter + // From Cmdlet Help: The field to set. The field needs to be available in one of the available content types. Either specify a name, an id or a field object + var field = ""; + // From Cmdlet Help: Set the field as a Shared Field + var setSharedField = ""; + // From Cmdlet Help: Set the field as a Welcome Page field + var setWelcomePageField = ""; + // From Cmdlet Help: Removes the field as a Shared Field + var removeSharedField = ""; + // From Cmdlet Help: Removes the field as a Welcome Page Field + var removeWelcomePageField = ""; + + var results = scope.ExecuteCommand("Set-PnPDocumentSetField", + new CommandParameter("DocumentSet", documentSet), + new CommandParameter("Field", field), + new CommandParameter("SetSharedField", setSharedField), + new CommandParameter("SetWelcomePageField", setWelcomePageField), + new CommandParameter("RemoveSharedField", removeSharedField), + new CommandParameter("RemoveWelcomePageField", removeWelcomePageField)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Events/AddPnPEventReceiverTests.cs b/Tests/Events/AddPnPEventReceiverTests.cs index 7f55d2e6c..b8f4dc7d3 100644 --- a/Tests/Events/AddPnPEventReceiverTests.cs +++ b/Tests/Events/AddPnPEventReceiverTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Events { - [TestClass] public class AddEventReceiverTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,48 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPEventReceiverTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPEventReceiver",new CommandParameter("List", "null"),new CommandParameter("Name", "null"),new CommandParameter("Url", "null"),new CommandParameter("EventReceiverType", "null"),new CommandParameter("Synchronization", "null"),new CommandParameter("SequenceNumber", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: The list object or name where the remote event receiver needs to be added. If omitted, the remote event receiver will be added to the web. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the remote event receiver + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The URL of the remote event receiver web service + var url = ""; + // This is a mandatory parameter + // From Cmdlet Help: The type of the event receiver like ItemAdded, ItemAdding. See https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.eventreceivertype.aspx for the full list of available types. + var eventReceiverType = ""; + // This is a mandatory parameter + // From Cmdlet Help: The synchronization type: Asynchronous or Synchronous + var synchronization = ""; + // From Cmdlet Help: The sequence number where this remote event receiver should be placed + var sequenceNumber = ""; + // From Cmdlet Help: Overwrites the output file if it exists. + var force = ""; + + var results = scope.ExecuteCommand("Add-PnPEventReceiver", + new CommandParameter("List", list), + new CommandParameter("Name", name), + new CommandParameter("Url", url), + new CommandParameter("EventReceiverType", eventReceiverType), + new CommandParameter("Synchronization", synchronization), + new CommandParameter("SequenceNumber", sequenceNumber), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Events/GetPnPEventReceiverTests.cs b/Tests/Events/GetPnPEventReceiverTests.cs index 8df56a8fa..95978c25c 100644 --- a/Tests/Events/GetPnPEventReceiverTests.cs +++ b/Tests/Events/GetPnPEventReceiverTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Events { - [TestClass] public class GetEventReceiverTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPEventReceiverTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPEventReceiver",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + + // From Cmdlet Help: The list object from which to get the event receiver object + var list = ""; + // From Cmdlet Help: The Guid of the event receiver + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPEventReceiver", + new CommandParameter("List", list), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Events/RemovePnPEventReceiverTests.cs b/Tests/Events/RemovePnPEventReceiverTests.cs index d01f5ea9e..cfaf29dc0 100644 --- a/Tests/Events/RemovePnPEventReceiverTests.cs +++ b/Tests/Events/RemovePnPEventReceiverTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Events { - [TestClass] public class RemoveEventReceiverTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPEventReceiverTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPEventReceiver",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Guid of the event receiver on the list + var identity = ""; + // From Cmdlet Help: The list object from where to remove the event receiver object + var list = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPEventReceiver", + new CommandParameter("Identity", identity), + new CommandParameter("List", list), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs b/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs index 9af9906f1..2e89f1f79 100644 --- a/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs +++ b/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Extensibility { - [TestClass] public class NewExtensibilityHandlerObjectTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPExtensibilityHandlerObjectTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPExtensibilityHandlerObject",new CommandParameter("Assembly", "null"),new CommandParameter("Type", "null"),new CommandParameter("Configuration", "null"),new CommandParameter("Disabled", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The full assembly name of the handler + var assembly = ""; + // This is a mandatory parameter + // From Cmdlet Help: The type of the handler + var type = ""; + // From Cmdlet Help: Any configuration data you want to send to the handler + var configuration = ""; + // From Cmdlet Help: If set, the handler will be disabled + var disabled = ""; + + var results = scope.ExecuteCommand("New-PnPExtensibilityHandlerObject", + new CommandParameter("Assembly", assembly), + new CommandParameter("Type", type), + new CommandParameter("Configuration", configuration), + new CommandParameter("Disabled", disabled)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Features/DisablePnPFeatureTests.cs b/Tests/Features/DisablePnPFeatureTests.cs index 9e9bcff63..aa9a6ad3a 100644 --- a/Tests/Features/DisablePnPFeatureTests.cs +++ b/Tests/Features/DisablePnPFeatureTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Features { - [TestClass] public class DisableFeatureTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPFeatureTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Disable-PnPFeature",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The id of the feature to disable. + var identity = ""; + // From Cmdlet Help: Specifies whether to continue if an error occurs when deactivating the feature. + var force = ""; + // From Cmdlet Help: Specify the scope of the feature to deactivate, either Web or Site. Defaults to Web. + var scopeVar = ""; + + var results = scope.ExecuteCommand("Disable-PnPFeature", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Features/EnablePnPFeatureTests.cs b/Tests/Features/EnablePnPFeatureTests.cs index c32de2769..b22df9a54 100644 --- a/Tests/Features/EnablePnPFeatureTests.cs +++ b/Tests/Features/EnablePnPFeatureTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Features { - [TestClass] public class EnableFeatureTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPFeatureTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Enable-PnPFeature",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Sandboxed", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The id of the feature to enable. + var identity = ""; + // From Cmdlet Help: Specifies whether to overwrite an existing feature with the same feature identifier. This parameter is ignored if there are no errors. + var force = ""; + // From Cmdlet Help: Specify the scope of the feature to activate, either Web or Site. Defaults to Web. + var scopeVar = ""; + // From Cmdlet Help: Specify this parameter if the feature you're trying to activate is part of a sandboxed solution. + var sandboxed = ""; + + var results = scope.ExecuteCommand("Enable-PnPFeature", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Sandboxed", sandboxed)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Features/GetPnPFeatureTests.cs b/Tests/Features/GetPnPFeatureTests.cs index c6d7fc6a5..7d4613db9 100644 --- a/Tests/Features/GetPnPFeatureTests.cs +++ b/Tests/Features/GetPnPFeatureTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Features { - [TestClass] public class GetFeatureTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPFeatureTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPFeature",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + + // From Cmdlet Help: The feature ID or name to query for, Querying by name is not supported in version 15 of the Client Side Object Model + var identity = ""; + // From Cmdlet Help: The scope of the feature. Defaults to Web. + var scopeVar = ""; + + var results = scope.ExecuteCommand("Get-PnPFeature", + new CommandParameter("Identity", identity), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/AddPnPFieldFromXmlTests.cs b/Tests/Fields/AddPnPFieldFromXmlTests.cs index 713bfc4af..969ab2577 100644 --- a/Tests/Fields/AddPnPFieldFromXmlTests.cs +++ b/Tests/Fields/AddPnPFieldFromXmlTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class AddFieldFromXmlTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPFieldFromXmlTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPFieldFromXml",new CommandParameter("List", "null"),new CommandParameter("FieldXml", "null")); + + // From Cmdlet Help: The name of the list, its ID or an actual list object where this field needs to be added + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: CAML snippet containing the field definition. See http://msdn.microsoft.com/en-us/library/office/ms437580(v=office.15).aspx + var fieldXml = ""; + + var results = scope.ExecuteCommand("Add-PnPFieldFromXml", + new CommandParameter("List", list), + new CommandParameter("FieldXml", fieldXml)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/AddPnPFieldTests.cs b/Tests/Fields/AddPnPFieldTests.cs index bb6328830..ebc9d7ea0 100644 --- a/Tests/Fields/AddPnPFieldTests.cs +++ b/Tests/Fields/AddPnPFieldTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class AddFieldTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,60 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPFieldTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPField",new CommandParameter("List", "null"),new CommandParameter("Field", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("InternalName", "null"),new CommandParameter("Type", "null"),new CommandParameter("Id", "null"),new CommandParameter("AddToDefaultView", "null"),new CommandParameter("Required", "null"),new CommandParameter("Group", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("ClientSideComponentProperties", "null")); + + // From Cmdlet Help: The name of the list, its ID or an actual list object where this field needs to be added + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the field, its ID or an actual field object that needs to be added + var field = ""; + // This is a mandatory parameter + // From Cmdlet Help: The display name of the field + var displayName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The internal name of the field + var internalName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The type of the field like Choice, Note, MultiChoice. For a complete list of field types visit https://docs.microsoft.com/dotnet/api/microsoft.sharepoint.client.fieldtype + var type = ""; + // From Cmdlet Help: The ID of the field, must be unique + var id = ""; + // From Cmdlet Help: Switch Parameter if this field must be added to the default view + var addToDefaultView = ""; + // From Cmdlet Help: Switch Parameter if the field is a required field + var required = ""; + // From Cmdlet Help: The group name to where this field belongs to + var group = ""; + // From Cmdlet Help: The Client Side Component Id to set to the field + var clientSideComponentId = ""; + // From Cmdlet Help: The Client Side Component Properties to set to the field + var clientSideComponentProperties = ""; + + var results = scope.ExecuteCommand("Add-PnPField", + new CommandParameter("List", list), + new CommandParameter("Field", field), + new CommandParameter("DisplayName", displayName), + new CommandParameter("InternalName", internalName), + new CommandParameter("Type", type), + new CommandParameter("Id", id), + new CommandParameter("AddToDefaultView", addToDefaultView), + new CommandParameter("Required", required), + new CommandParameter("Group", group), + new CommandParameter("ClientSideComponentId", clientSideComponentId), + new CommandParameter("ClientSideComponentProperties", clientSideComponentProperties)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/AddPnPTaxonomyFieldTests.cs b/Tests/Fields/AddPnPTaxonomyFieldTests.cs index 0a7b18557..10e3aa8cc 100644 --- a/Tests/Fields/AddPnPTaxonomyFieldTests.cs +++ b/Tests/Fields/AddPnPTaxonomyFieldTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class AddTaxonomyFieldTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,62 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTaxonomyFieldTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPTaxonomyField",new CommandParameter("List", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("InternalName", "null"),new CommandParameter("TermSetPath", "null"),new CommandParameter("TaxonomyItemId", "null"),new CommandParameter("TermPathDelimiter", "null"),new CommandParameter("Group", "null"),new CommandParameter("Id", "null"),new CommandParameter("AddToDefaultView", "null"),new CommandParameter("MultiValue", "null"),new CommandParameter("Required", "null"),new CommandParameter("FieldOptions", "null")); + + // From Cmdlet Help: The list object or name where this field needs to be added + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The display name of the field + var displayName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The internal name of the field + var internalName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The path to the term that this needs to be bound + var termSetPath = ""; + // From Cmdlet Help: The ID of the Taxonomy item + var taxonomyItemId = ""; + // From Cmdlet Help: The path delimiter to be used, by default this is '|' + var termPathDelimiter = ""; + // From Cmdlet Help: The group name to where this field belongs to + var group = ""; + // From Cmdlet Help: The ID for the field, must be unique + var id = ""; + // From Cmdlet Help: Switch Parameter if this field must be added to the default view + var addToDefaultView = ""; + // From Cmdlet Help: Switch Parameter if this Taxonomy field can hold multiple values + var multiValue = ""; + // From Cmdlet Help: Switch Parameter if the field is a required field + var required = ""; + // From Cmdlet Help: Specifies the control settings while adding a field. See https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.addfieldoptions.aspx for details + var fieldOptions = ""; + + var results = scope.ExecuteCommand("Add-PnPTaxonomyField", + new CommandParameter("List", list), + new CommandParameter("DisplayName", displayName), + new CommandParameter("InternalName", internalName), + new CommandParameter("TermSetPath", termSetPath), + new CommandParameter("TaxonomyItemId", taxonomyItemId), + new CommandParameter("TermPathDelimiter", termPathDelimiter), + new CommandParameter("Group", group), + new CommandParameter("Id", id), + new CommandParameter("AddToDefaultView", addToDefaultView), + new CommandParameter("MultiValue", multiValue), + new CommandParameter("Required", required), + new CommandParameter("FieldOptions", fieldOptions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/GetPnPFieldTests.cs b/Tests/Fields/GetPnPFieldTests.cs index 0022f2cdf..8d2875fd0 100644 --- a/Tests/Fields/GetPnPFieldTests.cs +++ b/Tests/Fields/GetPnPFieldTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class GetFieldTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPFieldTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPField",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("InSiteHierarchy", "null")); + + // From Cmdlet Help: The list object or name where to get the field from + var list = ""; + // From Cmdlet Help: The field object or name to get + var identity = ""; + // From Cmdlet Help: Filter to the specified group + var group = ""; + // From Cmdlet Help: Search site hierarchy for fields + var inSiteHierarchy = ""; + + var results = scope.ExecuteCommand("Get-PnPField", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Group", group), + new CommandParameter("InSiteHierarchy", inSiteHierarchy)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/RemovePnPFieldTests.cs b/Tests/Fields/RemovePnPFieldTests.cs index 5f012458f..40fcc5dd8 100644 --- a/Tests/Fields/RemovePnPFieldTests.cs +++ b/Tests/Fields/RemovePnPFieldTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class RemoveFieldTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPFieldTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPField",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The field object or name to remove + var identity = ""; + // From Cmdlet Help: The list object or name where to remove the field from + var list = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPField", + new CommandParameter("Identity", identity), + new CommandParameter("List", list), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/SetPnPFieldTests.cs b/Tests/Fields/SetPnPFieldTests.cs index 894522ce4..0ce8f84fa 100644 --- a/Tests/Fields/SetPnPFieldTests.cs +++ b/Tests/Fields/SetPnPFieldTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class SetFieldTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPFieldTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPField",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Values", "null"),new CommandParameter("UpdateExistingLists", "null")); + + // From Cmdlet Help: The list object, name or id where to update the field. If omitted the field will be updated on the web. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The field object, internal field name (case sensitive) or field id to update + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: Hashtable of properties to update on the field. Use the syntax @{property1="value";property2="value"}. + var values = ""; + // From Cmdlet Help: If provided, the field will be updated on existing lists that use it as well. If not provided or set to $false, existing lists using the field will remain unchanged but new lists will get the updated field. + var updateExistingLists = ""; + + var results = scope.ExecuteCommand("Set-PnPField", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Values", values), + new CommandParameter("UpdateExistingLists", updateExistingLists)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Fields/SetPnPViewTests.cs b/Tests/Fields/SetPnPViewTests.cs index 957a00350..649921f33 100644 --- a/Tests/Fields/SetPnPViewTests.cs +++ b/Tests/Fields/SetPnPViewTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Fields { - [TestClass] public class SetViewTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPViewTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPView",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Values", "null"),new CommandParameter("Fields", "null"),new CommandParameter("Aggregations", "null")); + + // From Cmdlet Help: The Id, Title or Url of the list + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Id, Title or instance of the view + var identity = ""; + // From Cmdlet Help: Hashtable of properties to update on the view. Use the syntax @{property1="value";property2="value"}. + var values = ""; + // From Cmdlet Help: An array of fields to use in the view. Notice that specifying this value will remove the existing fields + var fields = ""; + // From Cmdlet Help: A valid XML fragment containing one or more Aggregations + var aggregations = ""; + + var results = scope.ExecuteCommand("Set-PnPView", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Values", values), + new CommandParameter("Fields", fields), + new CommandParameter("Aggregations", aggregations)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/AddPnPFileTests.cs b/Tests/Files/AddPnPFileTests.cs index 7d708cf75..2074ea8a2 100644 --- a/Tests/Files/AddPnPFileTests.cs +++ b/Tests/Files/AddPnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class AddFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,87 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPFile",new CommandParameter("Path", "null"),new CommandParameter("Folder", "null"),new CommandParameter("FileName", "null"),new CommandParameter("NewFileName", "null"),new CommandParameter("Stream", "null"),new CommandParameter("Checkout", "null"),new CommandParameter("CheckInComment", "null"),new CommandParameter("Approve", "null"),new CommandParameter("ApproveComment", "null"),new CommandParameter("Publish", "null"),new CommandParameter("PublishComment", "null"),new CommandParameter("UseWebDav", "null"),new CommandParameter("Values", "null"),new CommandParameter("ContentType", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The local file path + var path = ""; + // This is a mandatory parameter + // From Cmdlet Help: The destination folder in the site + var folder = ""; + // This is a mandatory parameter + // From Cmdlet Help: Name for file + var fileName = ""; + // From Cmdlet Help: Filename to give the file on SharePoint + var newFileName = ""; + // This is a mandatory parameter + // From Cmdlet Help: Stream with the file contents + var stream = ""; + // From Cmdlet Help: If versioning is enabled, this will check out the file first if it exists, upload the file, then check it in again + var checkoutVar = ""; + // From Cmdlet Help: The comment added to the checkin + var checkInComment = ""; + // From Cmdlet Help: Will auto approve the uploaded file + var approve = ""; + // From Cmdlet Help: The comment added to the approval + var approveComment = ""; + // From Cmdlet Help: Will auto publish the file + var publish = ""; + // From Cmdlet Help: The comment added to the publish action + var publishComment = ""; + var useWebDav = ""; + // From Cmdlet Help: Use the internal names of the fields when specifying field names. + // Single line of text: -Values @{"Title" = "Title New"} + // Multiple lines of text: -Values @{"MultiText" = "New text\n\nMore text"} + // Rich text: -Values @{"MultiText" = "New text"} + // Choice: -Values @{"Choice" = "Value 1"} + // Number: -Values @{"Number" = "10"} + // Currency: -Values @{"Number" = "10"} + // Currency: -Values @{"Currency" = "10"} + // Date and Time: -Values @{"DateAndTime" = "03/10/2015 14:16"} + // Lookup (id of lookup value): -Values @{"Lookup" = "2"} + // Multi value lookup (id of lookup values as array 1): -Values @{"MultiLookupField" = "1","2"} + // Multi value lookup (id of lookup values as array 2): -Values @{"MultiLookupField" = 1,2} + // Multi value lookup (id of lookup values as string): -Values @{"MultiLookupField" = "1,2"} + // Yes/No: -Values @{"YesNo" = $false} + // Person/Group (id of user/group in Site User Info List or email of the user, separate multiple values with a comma): -Values @{"Person" = "user1@domain.com","21"} + // Managed Metadata (single value with path to term): -Values @{"MetadataField" = "CORPORATE|DEPARTMENTS|FINANCE"} + // Managed Metadata (single value with id of term): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818"} with Id of term + // Managed Metadata (multiple values with paths to terms): -Values @{"MetadataField" = "CORPORATE|DEPARTMENTS|FINANCE","CORPORATE|DEPARTMENTS|HR"} + // Managed Metadata (multiple values with ids of terms): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818","52d88107-c2a8-4bf0-adfa-04bc2305b593"} + // Hyperlink or Picture: -Values @{"Hyperlink" = "https://github.com/OfficeDev/, OfficePnp"} + var values = ""; + // From Cmdlet Help: Use to assign a ContentType to the file + var contentType = ""; + + var results = scope.ExecuteCommand("Add-PnPFile", + new CommandParameter("Path", path), + new CommandParameter("Folder", folder), + new CommandParameter("FileName", fileName), + new CommandParameter("NewFileName", newFileName), + new CommandParameter("Stream", stream), + new CommandParameter("Checkout", checkoutVar), + new CommandParameter("CheckInComment", checkInComment), + new CommandParameter("Approve", approve), + new CommandParameter("ApproveComment", approveComment), + new CommandParameter("Publish", publish), + new CommandParameter("PublishComment", publishComment), + new CommandParameter("UseWebDav", useWebDav), + new CommandParameter("Values", values), + new CommandParameter("ContentType", contentType)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/AddPnPFolderTests.cs b/Tests/Files/AddPnPFolderTests.cs index 9b6bd7a25..3a7ff2aaa 100644 --- a/Tests/Files/AddPnPFolderTests.cs +++ b/Tests/Files/AddPnPFolderTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class AddFolderTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPFolderTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPFolder",new CommandParameter("Name", "null"),new CommandParameter("Folder", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The folder name + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The parent folder in the site + var folder = ""; + + var results = scope.ExecuteCommand("Add-PnPFolder", + new CommandParameter("Name", name), + new CommandParameter("Folder", folder)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/CopyPnPFileTests.cs b/Tests/Files/CopyPnPFileTests.cs index 7cf6aae21..04ced9266 100644 --- a/Tests/Files/CopyPnPFileTests.cs +++ b/Tests/Files/CopyPnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class CopyFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,44 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void CopyPnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Copy-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SourceUrl", "null"),new CommandParameter("TargetUrl", "null"),new CommandParameter("OverwriteIfAlreadyExists", "null"),new CommandParameter("Force", "null"),new CommandParameter("SkipSourceFolderName", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Server relative Url specifying the file or folder to copy. + var serverRelativeUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Site relative Url specifying the file or folder to copy. + var sourceUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Server relative Url where to copy the file or folder to. + var targetUrl = ""; + // From Cmdlet Help: If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location. + var overwriteIfAlreadyExists = ""; + // From Cmdlet Help: If provided, no confirmation will be requested and the action will be performed + var force = ""; + // From Cmdlet Help: If the source is a folder, the source folder name will not be created, only the contents within it. + var skipSourceFolderName = ""; + + var results = scope.ExecuteCommand("Copy-PnPFile", + new CommandParameter("ServerRelativeUrl", serverRelativeUrl), + new CommandParameter("SourceUrl", sourceUrl), + new CommandParameter("TargetUrl", targetUrl), + new CommandParameter("OverwriteIfAlreadyExists", overwriteIfAlreadyExists), + new CommandParameter("Force", force), + new CommandParameter("SkipSourceFolderName", skipSourceFolderName)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/FindPnPFileTests.cs b/Tests/Files/FindPnPFileTests.cs index 2492fa6e0..cf0abc525 100644 --- a/Tests/Files/FindPnPFileTests.cs +++ b/Tests/Files/FindPnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class FindFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void FindPnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Find-PnPFile",new CommandParameter("Match", "null"),new CommandParameter("List", "null"),new CommandParameter("Folder", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Wildcard query + var match = ""; + // This is a mandatory parameter + // From Cmdlet Help: List title, url or an actual List object to query + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: Folder object or relative url of a folder to query + var folder = ""; + + var results = scope.ExecuteCommand("Find-PnPFile", + new CommandParameter("Match", match), + new CommandParameter("List", list), + new CommandParameter("Folder", folder)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/GetPnPFileTests.cs b/Tests/Files/GetPnPFileTests.cs index 64fb43936..1f7c92731 100644 --- a/Tests/Files/GetPnPFileTests.cs +++ b/Tests/Files/GetPnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class GetFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,51 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPFile",new CommandParameter("Url", "null"),new CommandParameter("Path", "null"),new CommandParameter("Filename", "null"),new CommandParameter("AsFile", "null"),new CommandParameter("AsListItem", "null"),new CommandParameter("ThrowExceptionIfFileNotFound", "null"),new CommandParameter("AsString", "null"),new CommandParameter("Force", "null"),new CommandParameter("AsFileObject", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The URL (server or site relative) to the file + var url = ""; + // From Cmdlet Help: Local path where the file should be saved + var path = ""; + // From Cmdlet Help: Name for the local file + var filename = ""; + // This is a mandatory parameter + var asFile = ""; + // From Cmdlet Help: Returns the file as a listitem showing all its properties + var asListItem = ""; + // From Cmdlet Help: If provided in combination with -AsListItem, a System.ArgumentException will be thrown if the file specified in the -Url argument does not exist. Otherwise it will return nothing instead. + var throwExceptionIfFileNotFound = ""; + // From Cmdlet Help: Retrieve the file contents as a string + var asString = ""; + // From Cmdlet Help: Overwrites the file if it exists. + var force = ""; + // From Cmdlet Help: Retrieve the file contents as a file object. + var asFileObject = ""; + + var results = scope.ExecuteCommand("Get-PnPFile", + new CommandParameter("Url", url), + new CommandParameter("Path", path), + new CommandParameter("Filename", filename), + new CommandParameter("AsFile", asFile), + new CommandParameter("AsListItem", asListItem), + new CommandParameter("ThrowExceptionIfFileNotFound", throwExceptionIfFileNotFound), + new CommandParameter("AsString", asString), + new CommandParameter("Force", force), + new CommandParameter("AsFileObject", asFileObject)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/GetPnPFolderItemTests.cs b/Tests/Files/GetPnPFolderItemTests.cs index a5f40b79b..fdfb0e70d 100644 --- a/Tests/Files/GetPnPFolderItemTests.cs +++ b/Tests/Files/GetPnPFolderItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class GetFolderItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,38 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPFolderItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPFolderItem",new CommandParameter("FolderSiteRelativeUrl", "null"),new CommandParameter("Identity", "null"),new CommandParameter("ItemType", "null"),new CommandParameter("ItemName", "null"),new CommandParameter("Recursive", "null")); + + // From Cmdlet Help: The site relative URL of the folder to retrieve + var folderSiteRelativeUrl = ""; + // From Cmdlet Help: A folder instance to the folder to retrieve + var identity = ""; + // From Cmdlet Help: The type of contents to retrieve, either File, Folder or All (default) + var itemType = ""; + // From Cmdlet Help: Optional name of the item to retrieve + var itemName = ""; + // From Cmdlet Help: A switch parameter to include contents of all subfolders in the specified folder + var recursive = ""; + + var results = scope.ExecuteCommand("Get-PnPFolderItem", + new CommandParameter("FolderSiteRelativeUrl", folderSiteRelativeUrl), + new CommandParameter("Identity", identity), + new CommandParameter("ItemType", itemType), + new CommandParameter("ItemName", itemName), + new CommandParameter("Recursive", recursive)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/GetPnPFolderTests.cs b/Tests/Files/GetPnPFolderTests.cs index bd1d80a9b..c3db98937 100644 --- a/Tests/Files/GetPnPFolderTests.cs +++ b/Tests/Files/GetPnPFolderTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class GetFolderTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPFolderTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPFolder",new CommandParameter("Url", "null"),new CommandParameter("List", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Site or server relative URL of the folder to retrieve. In the case of a server relative url, make sure that the url starts with the managed path as the current web. + var url = ""; + // This is a mandatory parameter + // From Cmdlet Help: Name, ID or instance of a list or document library to retrieve the folders residing in it for. + var list = ""; + + var results = scope.ExecuteCommand("Get-PnPFolder", + new CommandParameter("Url", url), + new CommandParameter("List", list)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/MovePnPFileTests.cs b/Tests/Files/MovePnPFileTests.cs index fa8ddf6bc..8a91c7162 100644 --- a/Tests/Files/MovePnPFileTests.cs +++ b/Tests/Files/MovePnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class MoveFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,54 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MovePnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Move-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SiteRelativeUrl", "null"),new CommandParameter("TargetUrl", "null"),new CommandParameter("TargetServerRelativeLibrary", "null"),new CommandParameter("OverwriteIfAlreadyExists", "null"),new CommandParameter("AllowSchemaMismatch", "null"),new CommandParameter("AllowSmallerVersionLimitOnDestination", "null"),new CommandParameter("IgnoreVersionHistory", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Server relative Url specifying the file to move. Must include the file name. + var serverRelativeUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Site relative Url specifying the file to move. Must include the file name. + var siteRelativeUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Server relative Url where to move the file to. Must include the file name. + var targetUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Server relative url of a document library where to move the file to. Must not include the file name. + var targetServerRelativeLibrary = ""; + // From Cmdlet Help: If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the move operation will be canceled if the file already exists at the TargetUrl location. + var overwriteIfAlreadyExists = ""; + // From Cmdlet Help: If provided and the target document library specified using TargetServerRelativeLibrary has different fields than the document library where the document is being moved from, the move will succeed. If not provided, it will fail to protect against data loss of metadata stored in fields that cannot be moved along. + var allowSchemaMismatch = ""; + // From Cmdlet Help: If provided and the target document library specified using TargetServerRelativeLibrary is configured to keep less historical versions of documents than the document library where the document is being moved from, the move will succeed. If not provided, it will fail to protect against data loss of historical versions that cannot be moved along. + var allowSmallerVersionLimitOnDestination = ""; + // From Cmdlet Help: If provided, only the latest version of the document will be moved and its history will be discared. If not provided, all historical versions will be moved along. + var ignoreVersionHistory = ""; + // From Cmdlet Help: If provided, no confirmation will be requested and the action will be performed + var force = ""; + + var results = scope.ExecuteCommand("Move-PnPFile", + new CommandParameter("ServerRelativeUrl", serverRelativeUrl), + new CommandParameter("SiteRelativeUrl", siteRelativeUrl), + new CommandParameter("TargetUrl", targetUrl), + new CommandParameter("TargetServerRelativeLibrary", targetServerRelativeLibrary), + new CommandParameter("OverwriteIfAlreadyExists", overwriteIfAlreadyExists), + new CommandParameter("AllowSchemaMismatch", allowSchemaMismatch), + new CommandParameter("AllowSmallerVersionLimitOnDestination", allowSmallerVersionLimitOnDestination), + new CommandParameter("IgnoreVersionHistory", ignoreVersionHistory), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/MovePnPFolderTests.cs b/Tests/Files/MovePnPFolderTests.cs index cc459f367..dd765d158 100644 --- a/Tests/Files/MovePnPFolderTests.cs +++ b/Tests/Files/MovePnPFolderTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class MoveFolderTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MovePnPFolderTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Move-PnPFolder",new CommandParameter("Folder", "null"),new CommandParameter("TargetFolder", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The folder to move + var folder = ""; + // This is a mandatory parameter + // From Cmdlet Help: The new parent location to which the folder should be moved to + var targetFolder = ""; + + var results = scope.ExecuteCommand("Move-PnPFolder", + new CommandParameter("Folder", folder), + new CommandParameter("TargetFolder", targetFolder)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/RemovePnPFileTests.cs b/Tests/Files/RemovePnPFileTests.cs index 8f58b9291..967e9c6d9 100644 --- a/Tests/Files/RemovePnPFileTests.cs +++ b/Tests/Files/RemovePnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class RemoveFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SiteRelativeUrl", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Server relative URL to the file + var serverRelativeUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Site relative URL to the file + var siteRelativeUrl = ""; + var recycle = ""; + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPFile", + new CommandParameter("ServerRelativeUrl", serverRelativeUrl), + new CommandParameter("SiteRelativeUrl", siteRelativeUrl), + new CommandParameter("Recycle", recycle), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/RemovePnPFolderTests.cs b/Tests/Files/RemovePnPFolderTests.cs index b5617f69b..756e2b646 100644 --- a/Tests/Files/RemovePnPFolderTests.cs +++ b/Tests/Files/RemovePnPFolderTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class RemoveFolderTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPFolderTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPFolder",new CommandParameter("Name", "null"),new CommandParameter("Folder", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The folder name + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The parent folder in the site + var folder = ""; + var recycle = ""; + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPFolder", + new CommandParameter("Name", name), + new CommandParameter("Folder", folder), + new CommandParameter("Recycle", recycle), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/RenamePnPFileTests.cs b/Tests/Files/RenamePnPFileTests.cs index 0a60d2059..8a86fdbb7 100644 --- a/Tests/Files/RenamePnPFileTests.cs +++ b/Tests/Files/RenamePnPFileTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class RenameFileTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,41 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RenamePnPFileTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Rename-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SiteRelativeUrl", "null"),new CommandParameter("TargetFileName", "null"),new CommandParameter("OverwriteIfAlreadyExists", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Server relative Url specifying the file to rename. Must include the file name. + var serverRelativeUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Site relative Url specifying the file to rename. Must include the file name. + var siteRelativeUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: File name to rename the file to. Should only be the file name and not include the path to its location. Use Move-PnPFile to move the file to another location. + var targetFileName = ""; + // From Cmdlet Help: If provided, if a file already exist with the provided TargetFileName, it will be overwritten. If omitted, the rename operation will be canceled if a file already exists with the TargetFileName file name. + var overwriteIfAlreadyExists = ""; + // From Cmdlet Help: If provided, no confirmation will be requested and the action will be performed + var force = ""; + + var results = scope.ExecuteCommand("Rename-PnPFile", + new CommandParameter("ServerRelativeUrl", serverRelativeUrl), + new CommandParameter("SiteRelativeUrl", siteRelativeUrl), + new CommandParameter("TargetFileName", targetFileName), + new CommandParameter("OverwriteIfAlreadyExists", overwriteIfAlreadyExists), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/RenamePnPFolderTests.cs b/Tests/Files/RenamePnPFolderTests.cs index e8dc9b127..34da4abc1 100644 --- a/Tests/Files/RenamePnPFolderTests.cs +++ b/Tests/Files/RenamePnPFolderTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class RenameFolderTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RenamePnPFolderTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Rename-PnPFolder",new CommandParameter("Folder", "null"),new CommandParameter("TargetFolderName", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The folder to rename + var folder = ""; + // This is a mandatory parameter + // From Cmdlet Help: The new folder name + var targetFolderName = ""; + + var results = scope.ExecuteCommand("Rename-PnPFolder", + new CommandParameter("Folder", folder), + new CommandParameter("TargetFolderName", targetFolderName)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/ResetPnPFileVersionTests.cs b/Tests/Files/ResetPnPFileVersionTests.cs index 241d2bd3b..d9f28eea6 100644 --- a/Tests/Files/ResetPnPFileVersionTests.cs +++ b/Tests/Files/ResetPnPFileVersionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class ResetFileVersionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ResetPnPFileVersionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Reset-PnPFileVersion",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("CheckinType", "null"),new CommandParameter("CheckInComment", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The server relative URL of the file. + var serverRelativeUrl = ""; + // From Cmdlet Help: The check in type to use. Defaults to Major. + var checkinType = ""; + // From Cmdlet Help: The comment added to the checkin. Defaults to 'Restored to previous version'. + var checkInComment = ""; + + var results = scope.ExecuteCommand("Reset-PnPFileVersion", + new CommandParameter("ServerRelativeUrl", serverRelativeUrl), + new CommandParameter("CheckinType", checkinType), + new CommandParameter("CheckInComment", checkInComment)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/ResolvePnPFolderTests.cs b/Tests/Files/ResolvePnPFolderTests.cs index 27c8aa875..80b2c2b9c 100644 --- a/Tests/Files/ResolvePnPFolderTests.cs +++ b/Tests/Files/ResolvePnPFolderTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class ResolveFolderTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ResolvePnPFolderTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Resolve-PnPFolder",new CommandParameter("SiteRelativePath", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Site Relative Folder Path + var siteRelativePath = ""; + + var results = scope.ExecuteCommand("Resolve-PnPFolder", + new CommandParameter("SiteRelativePath", siteRelativePath)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/SetPnPFileCheckedInTests.cs b/Tests/Files/SetPnPFileCheckedInTests.cs index ac6f90634..dd98f5fcb 100644 --- a/Tests/Files/SetPnPFileCheckedInTests.cs +++ b/Tests/Files/SetPnPFileCheckedInTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class SetFileCheckedInTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPFileCheckedInTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPFileCheckedIn",new CommandParameter("Url", "null"),new CommandParameter("CheckinType", "null"),new CommandParameter("Comment", "null"),new CommandParameter("Approve", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The server relative url of the file to check in + var url = ""; + // From Cmdlet Help: The check in type to use. Defaults to Major + var checkinType = ""; + // From Cmdlet Help: The check in comment + var comment = ""; + // From Cmdlet Help: Approve file + var approve = ""; + + var results = scope.ExecuteCommand("Set-PnPFileCheckedIn", + new CommandParameter("Url", url), + new CommandParameter("CheckinType", checkinType), + new CommandParameter("Comment", comment), + new CommandParameter("Approve", approve)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/SetPnPFileCheckedOutTests.cs b/Tests/Files/SetPnPFileCheckedOutTests.cs index 9b9f14a9f..4d5ebf96c 100644 --- a/Tests/Files/SetPnPFileCheckedOutTests.cs +++ b/Tests/Files/SetPnPFileCheckedOutTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class SetFileCheckedOutTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPFileCheckedOutTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPFileCheckedOut",new CommandParameter("Url", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The server relative url of the file to check out + var url = ""; + + var results = scope.ExecuteCommand("Set-PnPFileCheckedOut", + new CommandParameter("Url", url)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Files/SetPnPFolderPermissionTests.cs b/Tests/Files/SetPnPFolderPermissionTests.cs index 3e7f48f84..03995b05b 100644 --- a/Tests/Files/SetPnPFolderPermissionTests.cs +++ b/Tests/Files/SetPnPFolderPermissionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Files { - [TestClass] public class SetFolderPermissionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,52 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPFolderPermissionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPFolderPermission",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("User", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null"),new CommandParameter("ClearExisting", "null"),new CommandParameter("InheritPermissions", "null"),new CommandParameter("SystemUpdate", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list the folder is part of + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the folder, the server relative URL to the folder or actual Folder object + var identity = ""; + // This is a mandatory parameter + var group = ""; + // This is a mandatory parameter + var user = ""; + // From Cmdlet Help: The role that must be assigned to the group or user + var addRole = ""; + // From Cmdlet Help: The role that must be removed from the group or user + var removeRole = ""; + // From Cmdlet Help: Clear all existing permissions + var clearExisting = ""; + // From Cmdlet Help: Inherit permissions from the parent, removing unique permissions + var inheritPermissions = ""; + // From Cmdlet Help: Update the folder permissions without creating a new version or triggering MS Flow. + var systemUpdate = ""; + + var results = scope.ExecuteCommand("Set-PnPFolderPermission", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Group", group), + new CommandParameter("User", user), + new CommandParameter("AddRole", addRole), + new CommandParameter("RemoveRole", removeRole), + new CommandParameter("ClearExisting", clearExisting), + new CommandParameter("InheritPermissions", inheritPermissions), + new CommandParameter("SystemUpdate", systemUpdate)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/AddPnPSiteClassificationTests.cs b/Tests/Graph/AddPnPSiteClassificationTests.cs index 6533840e7..627fa2a6b 100644 --- a/Tests/Graph/AddPnPSiteClassificationTests.cs +++ b/Tests/Graph/AddPnPSiteClassificationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class AddSiteClassificationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPSiteClassificationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPSiteClassification",new CommandParameter("Classifications", "null")); + + // This is a mandatory parameter + var classifications = ""; + + var results = scope.ExecuteCommand("Add-PnPSiteClassification", + new CommandParameter("Classifications", classifications)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/DisablePnPSiteClassificationTests.cs b/Tests/Graph/DisablePnPSiteClassificationTests.cs index aec5b4443..46b799260 100644 --- a/Tests/Graph/DisablePnPSiteClassificationTests.cs +++ b/Tests/Graph/DisablePnPSiteClassificationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class DisableSiteClassificationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPSiteClassificationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Disable-PnPSiteClassification"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/EnablePnPSiteClassificationTests.cs b/Tests/Graph/EnablePnPSiteClassificationTests.cs index ee69f6f58..69b8e3ce2 100644 --- a/Tests/Graph/EnablePnPSiteClassificationTests.cs +++ b/Tests/Graph/EnablePnPSiteClassificationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class EnableSiteClassificationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPSiteClassificationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Enable-PnPSiteClassification",new CommandParameter("Classifications", "null"),new CommandParameter("DefaultClassification", "null"),new CommandParameter("UsageGuidelinesUrl", "null")); + + // This is a mandatory parameter + var classifications = ""; + // This is a mandatory parameter + var defaultClassification = ""; + var usageGuidelinesUrl = ""; + + var results = scope.ExecuteCommand("Enable-PnPSiteClassification", + new CommandParameter("Classifications", classifications), + new CommandParameter("DefaultClassification", defaultClassification), + new CommandParameter("UsageGuidelinesUrl", usageGuidelinesUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPAADUserTests.cs b/Tests/Graph/GetPnPAADUserTests.cs index fee671b61..1e66a919f 100644 --- a/Tests/Graph/GetPnPAADUserTests.cs +++ b/Tests/Graph/GetPnPAADUserTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetAADUserTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAADUserTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPAADUser",new CommandParameter("Identity", "null"),new CommandParameter("Filter", "null"),new CommandParameter("OrderBy", "null"),new CommandParameter("Select", "null"),new CommandParameter("Delta", "null"),new CommandParameter("DeltaToken", "null")); + + // From Cmdlet Help: Returns the user with the provided user id + var identity = ""; + // From Cmdlet Help: Includes a filter to the retrieval of the users. Use OData instructions to construct the filter, i.e. "startswith(DisplayName, 'John')". + var filter = ""; + // From Cmdlet Help: Includes a custom sorting instruction to the retrieval of the users. Use OData syntax to construct the orderby, i.e. "DisplayName desc". + var orderBy = ""; + // From Cmdlet Help: Allows providing an array with the property names of specific properties to return. If not provided, the default properties will be returned. + var select = ""; + // This is a mandatory parameter + // From Cmdlet Help: Retrieves all users and provides a SkipToken delta token to allow to query for changes since this run when querying again by adding -DeltaToken to the command + var delta = ""; + // From Cmdlet Help: The change token provided during the previous run with -Delta to query for the changes to user objects made in Azure Active Directory since that run + var deltaToken = ""; + + var results = scope.ExecuteCommand("Get-PnPAADUser", + new CommandParameter("Identity", identity), + new CommandParameter("Filter", filter), + new CommandParameter("OrderBy", orderBy), + new CommandParameter("Select", select), + new CommandParameter("Delta", delta), + new CommandParameter("DeltaToken", deltaToken)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs b/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs index 1e56bc4d4..289be366f 100644 --- a/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs +++ b/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetDeletedUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPDeletedUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPDeletedUnifiedGroup",new CommandParameter("Identity", "null")); + + // From Cmdlet Help: The Identity of the Microsoft 365 Group + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPDeletedUnifiedGroup", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPGraphSubscriptionTests.cs b/Tests/Graph/GetPnPGraphSubscriptionTests.cs index 4f5b739a2..660baa330 100644 --- a/Tests/Graph/GetPnPGraphSubscriptionTests.cs +++ b/Tests/Graph/GetPnPGraphSubscriptionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetGraphSubscriptionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPGraphSubscriptionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPGraphSubscription",new CommandParameter("Identity", "null")); + + // From Cmdlet Help: Returns the subscription with the provided subscription id + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPGraphSubscription", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPSiteClassificationTests.cs b/Tests/Graph/GetPnPSiteClassificationTests.cs index c95633192..6aef7851f 100644 --- a/Tests/Graph/GetPnPSiteClassificationTests.cs +++ b/Tests/Graph/GetPnPSiteClassificationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetSiteClassificationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteClassificationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPSiteClassification"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs b/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs index 08eed24b5..5e3bfde1a 100644 --- a/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs +++ b/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetUnifiedGroupMembersTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPUnifiedGroupMembersTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPUnifiedGroupMembers",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the Microsoft 365 Group + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPUnifiedGroupMembers", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs b/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs index 7eb13ef5a..f8a39c1c2 100644 --- a/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs +++ b/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetUnifiedGroupOwnersTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPUnifiedGroupOwnersTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPUnifiedGroupOwners",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the Microsoft 365 Group. + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPUnifiedGroupOwners", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/GetPnPUnifiedGroupTests.cs b/Tests/Graph/GetPnPUnifiedGroupTests.cs index e2405b048..75323cc15 100644 --- a/Tests/Graph/GetPnPUnifiedGroupTests.cs +++ b/Tests/Graph/GetPnPUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class GetUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPUnifiedGroup",new CommandParameter("Identity", "null"),new CommandParameter("ExcludeSiteUrl", "null"),new CommandParameter("IncludeClassification", "null"),new CommandParameter("IncludeHasTeam", "null")); + + // From Cmdlet Help: The Identity of the Microsoft 365 Group + var identity = ""; + // From Cmdlet Help: Exclude fetching the site URL for Microsoft 365 Groups. This speeds up large listings. + var excludeSiteUrl = ""; + // From Cmdlet Help: Include Classification value of Microsoft 365 Groups + var includeClassification = ""; + // From Cmdlet Help: Include a flag for every Microsoft 365 Group if it has a Microsoft Team provisioned for it. This will slow down the retrieval of Microsoft 365 Groups so only use it if you need it. + var includeHasTeam = ""; + + var results = scope.ExecuteCommand("Get-PnPUnifiedGroup", + new CommandParameter("Identity", identity), + new CommandParameter("ExcludeSiteUrl", excludeSiteUrl), + new CommandParameter("IncludeClassification", includeClassification), + new CommandParameter("IncludeHasTeam", includeHasTeam)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/NewPnPGraphSubscriptionTests.cs b/Tests/Graph/NewPnPGraphSubscriptionTests.cs index 0adf52f49..9029bf20e 100644 --- a/Tests/Graph/NewPnPGraphSubscriptionTests.cs +++ b/Tests/Graph/NewPnPGraphSubscriptionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class NewGraphSubscriptionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,44 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPGraphSubscriptionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPGraphSubscription",new CommandParameter("ChangeType", "null"),new CommandParameter("NotificationUrl", "null"),new CommandParameter("Resource", "null"),new CommandParameter("ExpirationDateTime", "null"),new CommandParameter("ClientState", "null"),new CommandParameter("LatestSupportedTlsVersion", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The event(s) the subscription should trigger on + var changeType = ""; + // This is a mandatory parameter + // From Cmdlet Help: The URL that should be called when an event matching this subscription occurs + var notificationUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: The resource to monitor for changes. See https://docs.microsoft.com/graph/api/subscription-post-subscriptions#resources-examples for the list with supported options. + var resource = ""; + // From Cmdlet Help: The datetime defining how long this subscription should stay alive before which it needs to get extended to stay alive. See https://docs.microsoft.com/graph/api/resources/subscription#maximum-length-of-subscription-per-resource-type for the supported maximum lifetime of the subscriber endpoints. + var expirationDateTime = ""; + // From Cmdlet Help: Specifies the value of the clientState property sent by the service in each notification. The maximum length is 128 characters. The client can check that the notification came from the service by comparing the value of the clientState property sent with the subscription with the value of the clientState property received with each notification. + var clientState = ""; + // From Cmdlet Help: Specifies the latest version of Transport Layer Security (TLS) that the notification endpoint, specified by NotificationUrl, supports. If not provided, TLS 1.2 will be assumed. + var latestSupportedTlsVersion = ""; + + var results = scope.ExecuteCommand("New-PnPGraphSubscription", + new CommandParameter("ChangeType", changeType), + new CommandParameter("NotificationUrl", notificationUrl), + new CommandParameter("Resource", resource), + new CommandParameter("ExpirationDateTime", expirationDateTime), + new CommandParameter("ClientState", clientState), + new CommandParameter("LatestSupportedTlsVersion", latestSupportedTlsVersion)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/NewPnPUnifiedGroupTests.cs b/Tests/Graph/NewPnPUnifiedGroupTests.cs index 266a5892d..0312f647b 100644 --- a/Tests/Graph/NewPnPUnifiedGroupTests.cs +++ b/Tests/Graph/NewPnPUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class NewPnPUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,53 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPUnifiedGroup",new CommandParameter("DisplayName", "null"),new CommandParameter("Description", "null"),new CommandParameter("MailNickname", "null"),new CommandParameter("Owners", "null"),new CommandParameter("Members", "null"),new CommandParameter("IsPrivate", "null"),new CommandParameter("GroupLogoPath", "null"),new CommandParameter("CreateTeam", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Display Name of the Microsoft 365 Group + var displayName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Description of the Microsoft 365 Group + var description = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Mail Nickname of the Microsoft 365 Group. Cannot contain spaces. + var mailNickname = ""; + // From Cmdlet Help: The array UPN values of the group's owners + var owners = ""; + // From Cmdlet Help: The array UPN values of the group's members + var members = ""; + // From Cmdlet Help: Makes the group private when selected + var isPrivate = ""; + // From Cmdlet Help: The path to the logo file of to set + var groupLogoPath = ""; + // From Cmdlet Help: Creates a Microsoft Teams team associated with created group + var createTeam = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("New-PnPUnifiedGroup", + new CommandParameter("DisplayName", displayName), + new CommandParameter("Description", description), + new CommandParameter("MailNickname", mailNickname), + new CommandParameter("Owners", owners), + new CommandParameter("Members", members), + new CommandParameter("IsPrivate", isPrivate), + new CommandParameter("GroupLogoPath", groupLogoPath), + new CommandParameter("CreateTeam", createTeam), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs b/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs index 6647ebc9e..bb7aeeaa1 100644 --- a/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs +++ b/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class RemoveDeletedUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPDeletedUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPDeletedUnifiedGroup",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the deleted Microsoft 365 Group + var identity = ""; + + var results = scope.ExecuteCommand("Remove-PnPDeletedUnifiedGroup", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/RemovePnPGraphSubscriptionTests.cs b/Tests/Graph/RemovePnPGraphSubscriptionTests.cs index 413d8fab1..e24a6d48e 100644 --- a/Tests/Graph/RemovePnPGraphSubscriptionTests.cs +++ b/Tests/Graph/RemovePnPGraphSubscriptionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class RemoveGraphSubscriptionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPGraphSubscriptionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPGraphSubscription",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The unique id or an instance of a Microsoft Graph Subscription + var identity = ""; + + var results = scope.ExecuteCommand("Remove-PnPGraphSubscription", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/RemovePnPSiteClassificationTests.cs b/Tests/Graph/RemovePnPSiteClassificationTests.cs index a71fc8167..f57669ac1 100644 --- a/Tests/Graph/RemovePnPSiteClassificationTests.cs +++ b/Tests/Graph/RemovePnPSiteClassificationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class RemoveSiteClassificationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPSiteClassificationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPSiteClassification",new CommandParameter("Classifications", "null"),new CommandParameter("Confirm", "null")); + + // This is a mandatory parameter + var classifications = ""; + // From Cmdlet Help: Specifying the Confirm parameter will allow the confirmation question to be skipped + var confirm = ""; + + var results = scope.ExecuteCommand("Remove-PnPSiteClassification", + new CommandParameter("Classifications", classifications), + new CommandParameter("Confirm", confirm)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/RemovePnPUnifiedGroupTests.cs b/Tests/Graph/RemovePnPUnifiedGroupTests.cs index 9cb32e752..d472a1689 100644 --- a/Tests/Graph/RemovePnPUnifiedGroupTests.cs +++ b/Tests/Graph/RemovePnPUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class RemoveUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPUnifiedGroup",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the Microsoft 365 Group + var identity = ""; + + var results = scope.ExecuteCommand("Remove-PnPUnifiedGroup", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs b/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs index 1e506108c..30fd3643c 100644 --- a/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs +++ b/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class ResetUnifiedGroupExpirationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ResetPnPUnifiedGroupExpirationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Reset-PnPUnifiedGroupExpiration",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the Office 365 Group + var identity = ""; + + var results = scope.ExecuteCommand("Reset-PnPUnifiedGroupExpiration", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs b/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs index 1f3652567..8ec2ff5d0 100644 --- a/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs +++ b/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class RestoreDeletedUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RestorePnPDeletedUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Restore-PnPDeletedUnifiedGroup",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the deleted Microsoft 365 Group + var identity = ""; + + var results = scope.ExecuteCommand("Restore-PnPDeletedUnifiedGroup", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/SetPnPGraphSubscriptionTests.cs b/Tests/Graph/SetPnPGraphSubscriptionTests.cs index ba437fbff..98238a7ea 100644 --- a/Tests/Graph/SetPnPGraphSubscriptionTests.cs +++ b/Tests/Graph/SetPnPGraphSubscriptionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class SetGraphSubscriptionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPGraphSubscriptionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPGraphSubscription",new CommandParameter("Identity", "null"),new CommandParameter("ExpirationDate", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The unique id or an instance of a Microsoft Graph Subscription + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: Date and time to set the expiration to. Take notice of the maximum allowed lifetime of the subscription endponts as documented at https://docs.microsoft.com/graph/api/resources/subscription#maximum-length-of-subscription-per-resource-type + var expirationDate = ""; + + var results = scope.ExecuteCommand("Set-PnPGraphSubscription", + new CommandParameter("Identity", identity), + new CommandParameter("ExpirationDate", expirationDate)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/SetPnPUnifiedGroupTests.cs b/Tests/Graph/SetPnPUnifiedGroupTests.cs index 77d5cbfd8..b363c938d 100644 --- a/Tests/Graph/SetPnPUnifiedGroupTests.cs +++ b/Tests/Graph/SetPnPUnifiedGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class SetUnifiedGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,48 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPUnifiedGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPUnifiedGroup",new CommandParameter("Identity", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Description", "null"),new CommandParameter("Owners", "null"),new CommandParameter("Members", "null"),new CommandParameter("IsPrivate", "null"),new CommandParameter("GroupLogoPath", "null"),new CommandParameter("CreateTeam", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Identity of the Microsoft 365 Group + var identity = ""; + // From Cmdlet Help: The DisplayName of the group to set + var displayName = ""; + // From Cmdlet Help: The Description of the group to set + var description = ""; + // From Cmdlet Help: The array UPN values of owners to set to the group. Note: Will replace owners. + var owners = ""; + // From Cmdlet Help: The array UPN values of members to set to the group. Note: Will replace members. + var members = ""; + // From Cmdlet Help: Makes the group private when selected + var isPrivate = ""; + // From Cmdlet Help: The path to the logo file of to set + var groupLogoPath = ""; + // From Cmdlet Help: Creates a Microsoft Teams team associated with created group + var createTeam = ""; + + var results = scope.ExecuteCommand("Set-PnPUnifiedGroup", + new CommandParameter("Identity", identity), + new CommandParameter("DisplayName", displayName), + new CommandParameter("Description", description), + new CommandParameter("Owners", owners), + new CommandParameter("Members", members), + new CommandParameter("IsPrivate", isPrivate), + new CommandParameter("GroupLogoPath", groupLogoPath), + new CommandParameter("CreateTeam", createTeam)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Graph/UpdatePnPSiteClassificationTests.cs b/Tests/Graph/UpdatePnPSiteClassificationTests.cs index 3e2e0a034..2fe82cba3 100644 --- a/Tests/Graph/UpdatePnPSiteClassificationTests.cs +++ b/Tests/Graph/UpdatePnPSiteClassificationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Graph { - [TestClass] public class UpdateSiteClassificationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UpdatePnPSiteClassificationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Update-PnPSiteClassification",new CommandParameter("Settings", "null"),new CommandParameter("Classifications", "null"),new CommandParameter("DefaultClassification", "null"),new CommandParameter("UsageGuidelinesUrl", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: A settings object retrieved by Get-PnPSiteClassification + var settings = ""; + // From Cmdlet Help: A list of classifications, separated by commas. E.g. "HBI","LBI","Top Secret" + var classifications = ""; + // From Cmdlet Help: The default classification to be used. The value needs to be present in the list of possible classifications + var defaultClassification = ""; + // From Cmdlet Help: The UsageGuidelinesUrl. Set to "" to clear. + var usageGuidelinesUrl = ""; + + var results = scope.ExecuteCommand("Update-PnPSiteClassification", + new CommandParameter("Settings", settings), + new CommandParameter("Classifications", classifications), + new CommandParameter("DefaultClassification", defaultClassification), + new CommandParameter("UsageGuidelinesUrl", usageGuidelinesUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/GetPnPLabelTests.cs b/Tests/InformationManagement/GetPnPLabelTests.cs index 74f4a583a..e8d64ebe7 100644 --- a/Tests/InformationManagement/GetPnPLabelTests.cs +++ b/Tests/InformationManagement/GetPnPLabelTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class GetLabelTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPLabelTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPLabel",new CommandParameter("List", "null"),new CommandParameter("ValuesOnly", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Url of the list + var list = ""; + // From Cmdlet Help: If provided, the results will be returned as values instead of in written text and will include more detailed information + var valuesOnly = ""; + + var results = scope.ExecuteCommand("Get-PnPLabel", + new CommandParameter("List", list), + new CommandParameter("ValuesOnly", valuesOnly)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs b/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs index ba6035bd6..edd8810de 100644 --- a/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs +++ b/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class GetListInformationRightsManagementTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPListInformationRightsManagementTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPListInformationRightsManagement",new CommandParameter("List", "null")); + + // This is a mandatory parameter + var list = ""; + + var results = scope.ExecuteCommand("Get-PnPListInformationRightsManagement", + new CommandParameter("List", list)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/GetPnPSiteClosureTests.cs b/Tests/InformationManagement/GetPnPSiteClosureTests.cs index 2bdaee520..59c64b4a7 100644 --- a/Tests/InformationManagement/GetPnPSiteClosureTests.cs +++ b/Tests/InformationManagement/GetPnPSiteClosureTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class GetSiteClosureTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteClosureTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPSiteClosure"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/GetPnPSitePolicyTests.cs b/Tests/InformationManagement/GetPnPSitePolicyTests.cs index ad747b59c..83c814d33 100644 --- a/Tests/InformationManagement/GetPnPSitePolicyTests.cs +++ b/Tests/InformationManagement/GetPnPSitePolicyTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class GetSitePolicyTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSitePolicyTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSitePolicy",new CommandParameter("AllAvailable", "null"),new CommandParameter("Name", "null")); + + // From Cmdlet Help: Retrieve all available site policies + var allAvailable = ""; + // From Cmdlet Help: Retrieves a site policy with a specific name + var name = ""; + + var results = scope.ExecuteCommand("Get-PnPSitePolicy", + new CommandParameter("AllAvailable", allAvailable), + new CommandParameter("Name", name)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/ResetPnPLabelTests.cs b/Tests/InformationManagement/ResetPnPLabelTests.cs index 666279f83..3999c9c02 100644 --- a/Tests/InformationManagement/ResetPnPLabelTests.cs +++ b/Tests/InformationManagement/ResetPnPLabelTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class ResetLabelTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ResetPnPLabelTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Reset-PnPLabel",new CommandParameter("List", "null"),new CommandParameter("SyncToItems", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Url of the list + var list = ""; + // From Cmdlet Help: Reset label on existing items in the library + var syncToItems = ""; + + var results = scope.ExecuteCommand("Reset-PnPLabel", + new CommandParameter("List", list), + new CommandParameter("SyncToItems", syncToItems)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/SetPnPLabelTests.cs b/Tests/InformationManagement/SetPnPLabelTests.cs index 2707486a8..758d0a084 100644 --- a/Tests/InformationManagement/SetPnPLabelTests.cs +++ b/Tests/InformationManagement/SetPnPLabelTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class SetLabelTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,40 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPLabelTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPLabel",new CommandParameter("List", "null"),new CommandParameter("Label", "null"),new CommandParameter("SyncToItems", "null"),new CommandParameter("BlockDeletion", "null"),new CommandParameter("BlockEdit", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the retention label + var label = ""; + // From Cmdlet Help: Apply label to existing items in the library + var syncToItems = ""; + // From Cmdlet Help: Block deletion of items in the library + var blockDeletion = ""; + // From Cmdlet Help: Block editing of items in the library + var blockEdit = ""; + + var results = scope.ExecuteCommand("Set-PnPLabel", + new CommandParameter("List", list), + new CommandParameter("Label", label), + new CommandParameter("SyncToItems", syncToItems), + new CommandParameter("BlockDeletion", blockDeletion), + new CommandParameter("BlockEdit", blockEdit)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs b/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs index 8d321bd76..d1385e5ce 100644 --- a/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs +++ b/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class SetListInformationRightsManagementTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,80 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListInformationRightsManagementTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPListInformationRightsManagement",new CommandParameter("List", "null"),new CommandParameter("Enable", "null"),new CommandParameter("EnableExpiration", "null"),new CommandParameter("EnableRejection", "null"),new CommandParameter("AllowPrint", "null"),new CommandParameter("AllowScript", "null"),new CommandParameter("AllowWriteCopy", "null"),new CommandParameter("DisableDocumentBrowserView", "null"),new CommandParameter("DocumentAccessExpireDays", "null"),new CommandParameter("DocumentLibraryProtectionExpireDate", "null"),new CommandParameter("EnableDocumentAccessExpire", "null"),new CommandParameter("EnableDocumentBrowserPublishingView", "null"),new CommandParameter("EnableGroupProtection", "null"),new CommandParameter("EnableLicenseCacheExpire", "null"),new CommandParameter("LicenseCacheExpireDays", "null"),new CommandParameter("GroupName", "null"),new CommandParameter("PolicyDescription", "null"),new CommandParameter("PolicyTitle", "null"),new CommandParameter("TemplateId", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The list to set Information Rights Management (IRM) settings for. + var list = ""; + // From Cmdlet Help: Specifies whether Information Rights Management (IRM) is enabled for the list. + var enable = ""; + // From Cmdlet Help: Specifies whether Information Rights Management (IRM) expiration is enabled for the list. + var enableExpiration = ""; + // From Cmdlet Help: Specifies whether Information Rights Management (IRM) rejection is enabled for the list. + var enableRejection = ""; + // From Cmdlet Help: Sets a value indicating whether the viewer can print the downloaded document. + var allowPrint = ""; + // From Cmdlet Help: Sets a value indicating whether the viewer can run a script on the downloaded document. + var allowScript = ""; + // From Cmdlet Help: Sets a value indicating whether the viewer can write on a copy of the downloaded document. + var allowWriteCopy = ""; + // From Cmdlet Help: Sets a value indicating whether to block Office Web Application Companion applications (WACs) from showing this document. + var disableDocumentBrowserView = ""; + // From Cmdlet Help: Sets the number of days after which the downloaded document will expire. + var documentAccessExpireDays = ""; + // From Cmdlet Help: Sets the date after which the Information Rights Management (IRM) protection of this document library will stop. + var documentLibraryProtectionExpireDate = ""; + // From Cmdlet Help: Sets a value indicating whether the downloaded document will expire. + var enableDocumentAccessExpire = ""; + // From Cmdlet Help: Sets a value indicating whether to enable Office Web Application Companion applications (WACs) to publishing view. + var enableDocumentBrowserPublishingView = ""; + // From Cmdlet Help: Sets a value indicating whether the permission of the downloaded document is applicable to a group. + var enableGroupProtection = ""; + // From Cmdlet Help: Sets whether a user must verify their credentials after some interval. + var enableLicenseCacheExpire = ""; + // From Cmdlet Help: Sets the number of days that the application that opens the document caches the IRM license. When these elapse, the application will connect to the IRM server to validate the license. + var licenseCacheExpireDays = ""; + // From Cmdlet Help: Sets the group name (email address) that the permission is also applicable to. + var groupName = ""; + // From Cmdlet Help: Sets the permission policy description. + var policyDescription = ""; + // From Cmdlet Help: Sets the permission policy title. + var policyTitle = ""; + var templateId = ""; + + var results = scope.ExecuteCommand("Set-PnPListInformationRightsManagement", + new CommandParameter("List", list), + new CommandParameter("Enable", enable), + new CommandParameter("EnableExpiration", enableExpiration), + new CommandParameter("EnableRejection", enableRejection), + new CommandParameter("AllowPrint", allowPrint), + new CommandParameter("AllowScript", allowScript), + new CommandParameter("AllowWriteCopy", allowWriteCopy), + new CommandParameter("DisableDocumentBrowserView", disableDocumentBrowserView), + new CommandParameter("DocumentAccessExpireDays", documentAccessExpireDays), + new CommandParameter("DocumentLibraryProtectionExpireDate", documentLibraryProtectionExpireDate), + new CommandParameter("EnableDocumentAccessExpire", enableDocumentAccessExpire), + new CommandParameter("EnableDocumentBrowserPublishingView", enableDocumentBrowserPublishingView), + new CommandParameter("EnableGroupProtection", enableGroupProtection), + new CommandParameter("EnableLicenseCacheExpire", enableLicenseCacheExpire), + new CommandParameter("LicenseCacheExpireDays", licenseCacheExpireDays), + new CommandParameter("GroupName", groupName), + new CommandParameter("PolicyDescription", policyDescription), + new CommandParameter("PolicyTitle", policyTitle), + new CommandParameter("TemplateId", templateId)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/SetPnPSiteClosureTests.cs b/Tests/InformationManagement/SetPnPSiteClosureTests.cs index e24e5131c..51f969134 100644 --- a/Tests/InformationManagement/SetPnPSiteClosureTests.cs +++ b/Tests/InformationManagement/SetPnPSiteClosureTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class SetSiteClosureTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPSiteClosureTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPSiteClosure",new CommandParameter("State", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The state of the site + var state = ""; + + var results = scope.ExecuteCommand("Set-PnPSiteClosure", + new CommandParameter("State", state)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/InformationManagement/SetPnPSitePolicyTests.cs b/Tests/InformationManagement/SetPnPSitePolicyTests.cs index fc5082c7b..c18b0f269 100644 --- a/Tests/InformationManagement/SetPnPSitePolicyTests.cs +++ b/Tests/InformationManagement/SetPnPSitePolicyTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.InformationManagement { - [TestClass] public class ApplySitePolicyTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPSitePolicyTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPSitePolicy",new CommandParameter("Name", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the site policy to apply + var name = ""; + + var results = scope.ExecuteCommand("Set-PnPSitePolicy", + new CommandParameter("Name", name)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/AddPnPListItemTests.cs b/Tests/Lists/AddPnPListItemTests.cs index 279b66895..912ec40db 100644 --- a/Tests/Lists/AddPnPListItemTests.cs +++ b/Tests/Lists/AddPnPListItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class AddListItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,58 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPListItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("Values", "null"),new CommandParameter("Folder", "null"),new CommandParameter("Label", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // From Cmdlet Help: Specify either the name, ID or an actual content type. + var contentType = ""; + // From Cmdlet Help: Use the internal names of the fields when specifying field names. + // Single line of text: -Values @{"Title" = "Title New"} + // Multiple lines of text: -Values @{"MultiText" = "New text\n\nMore text"} + // Rich text: -Values @{"MultiText" = "New text"} + // Choice: -Values @{"Choice" = "Value 1"} + // Number: -Values @{"Number" = "10"} + // Currency: -Values @{"Number" = "10"} + // Currency: -Values @{"Currency" = "10"} + // Date and Time: -Values @{"DateAndTime" = "03/13/2015 14:16"} + // Lookup (id of lookup value): -Values @{"Lookup" = "2"} + // Multi value lookup (id of lookup values as array 1): -Values @{"MultiLookupField" = "1","2"} + // Multi value lookup (id of lookup values as array 2): -Values @{"MultiLookupField" = 1,2} + // Multi value lookup (id of lookup values as string): -Values @{"MultiLookupField" = "1,2"} + // Yes/No: -Values @{"YesNo" = $false} + // Person/Group (id of user/group in Site User Info List or email of the user, separate multiple values with a comma): -Values @{"Person" = "user1@domain.com","21"} + // Managed Metadata (single value with path to term): -Values @{"MetadataField" = "CORPORATE|DEPARTMENTS|FINANCE"} + // Managed Metadata (single value with id of term): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818"} with Id of term + // Managed Metadata (multiple values with paths to terms): -Values @{"MetadataField" = "CORPORATE|DEPARTMENTS|FINANCE","CORPORATE|DEPARTMENTS|HR"} + // Managed Metadata (multiple values with ids of terms): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818","52d88107-c2a8-4bf0-adfa-04bc2305b593"} + // Hyperlink or Picture: -Values @{"Hyperlink" = "https://github.com/OfficeDev/, OfficePnp"} + var values = ""; + // From Cmdlet Help: The list relative URL of a folder. E.g. "MyFolder" for a folder located in the root of the list, or "MyFolder/SubFolder" for a folder located in the MyFolder folder which is located in the root of the list. + var folder = ""; + // From Cmdlet Help: The name of the retention label. + var label = ""; + + var results = scope.ExecuteCommand("Add-PnPListItem", + new CommandParameter("List", list), + new CommandParameter("ContentType", contentType), + new CommandParameter("Values", values), + new CommandParameter("Folder", folder), + new CommandParameter("Label", label)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/AddPnPViewTests.cs b/Tests/Lists/AddPnPViewTests.cs index 8d3de16e9..1c3971d29 100644 --- a/Tests/Lists/AddPnPViewTests.cs +++ b/Tests/Lists/AddPnPViewTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class AddViewTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,56 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPViewTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPView",new CommandParameter("List", "null"),new CommandParameter("Title", "null"),new CommandParameter("Query", "null"),new CommandParameter("Fields", "null"),new CommandParameter("ViewType", "null"),new CommandParameter("RowLimit", "null"),new CommandParameter("Personal", "null"),new CommandParameter("SetAsDefault", "null"),new CommandParameter("Paged", "null"),new CommandParameter("Aggregations", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The title of the view. + var title = ""; + // From Cmdlet Help: A valid CAML Query. + var query = ""; + // This is a mandatory parameter + // From Cmdlet Help: A list of fields to add. + var fields = ""; + // From Cmdlet Help: The type of view to add. + var viewType = ""; + // From Cmdlet Help: The row limit for the view. Defaults to 30. + var rowLimit = ""; + // From Cmdlet Help: If specified, a personal view will be created. + var personal = ""; + // From Cmdlet Help: If specified, the view will be set as the default view for the list. + var setAsDefault = ""; + // From Cmdlet Help: If specified, the view will have paging. + var paged = ""; + // From Cmdlet Help: A valid XML fragment containing one or more Aggregations + var aggregations = ""; + + var results = scope.ExecuteCommand("Add-PnPView", + new CommandParameter("List", list), + new CommandParameter("Title", title), + new CommandParameter("Query", query), + new CommandParameter("Fields", fields), + new CommandParameter("ViewType", viewType), + new CommandParameter("RowLimit", rowLimit), + new CommandParameter("Personal", personal), + new CommandParameter("SetAsDefault", setAsDefault), + new CommandParameter("Paged", paged), + new CommandParameter("Aggregations", aggregations)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs b/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs index a602e48b6..729565d4e 100644 --- a/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs +++ b/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class ClearDefaultColumnValuesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ClearPnPDefaultColumnValuesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Clear-PnPDefaultColumnValues",new CommandParameter("List", "null"),new CommandParameter("Field", "null"),new CommandParameter("Folder", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Name or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The internal name, id or a reference to a field + var field = ""; + // From Cmdlet Help: A library relative folder path, if not specified it will set the default column values on the root folder of the library ('/') + var folder = ""; + + var results = scope.ExecuteCommand("Clear-PnPDefaultColumnValues", + new CommandParameter("List", list), + new CommandParameter("Field", field), + new CommandParameter("Folder", folder)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/GetPnPDefaultColumnValuesTests.cs b/Tests/Lists/GetPnPDefaultColumnValuesTests.cs index c77448ab8..061c1e753 100644 --- a/Tests/Lists/GetPnPDefaultColumnValuesTests.cs +++ b/Tests/Lists/GetPnPDefaultColumnValuesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class GetDefaultColumnValuesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPDefaultColumnValuesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPDefaultColumnValues",new CommandParameter("List", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Name or Url of the list. + var list = ""; + + var results = scope.ExecuteCommand("Get-PnPDefaultColumnValues", + new CommandParameter("List", list)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/GetPnPListItemTests.cs b/Tests/Lists/GetPnPListItemTests.cs index 8c7934fab..405a2b773 100644 --- a/Tests/Lists/GetPnPListItemTests.cs +++ b/Tests/Lists/GetPnPListItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class GetListItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,48 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPListItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("Id", "null"),new CommandParameter("UniqueId", "null"),new CommandParameter("Query", "null"),new CommandParameter("FolderServerRelativeUrl", "null"),new CommandParameter("Fields", "null"),new CommandParameter("PageSize", "null"),new CommandParameter("ScriptBlock", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The list to query + var list = ""; + // From Cmdlet Help: The ID of the item to retrieve + var id = ""; + // From Cmdlet Help: The unique id (GUID) of the item to retrieve + var uniqueId = ""; + // From Cmdlet Help: The CAML query to execute against the list + var query = ""; + // From Cmdlet Help: The server relative URL of a list folder from which results will be returned. + var folderServerRelativeUrl = ""; + // From Cmdlet Help: The fields to retrieve. If not specified all fields will be loaded in the returned list object. + var fields = ""; + // From Cmdlet Help: The number of items to retrieve per page request. + var pageSize = ""; + // From Cmdlet Help: The script block to run after every page request. + var scriptBlock = ""; + + var results = scope.ExecuteCommand("Get-PnPListItem", + new CommandParameter("List", list), + new CommandParameter("Id", id), + new CommandParameter("UniqueId", uniqueId), + new CommandParameter("Query", query), + new CommandParameter("FolderServerRelativeUrl", folderServerRelativeUrl), + new CommandParameter("Fields", fields), + new CommandParameter("PageSize", pageSize), + new CommandParameter("ScriptBlock", scriptBlock)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/GetPnPListTests.cs b/Tests/Lists/GetPnPListTests.cs index 5811feb9a..3c7461310 100644 --- a/Tests/Lists/GetPnPListTests.cs +++ b/Tests/Lists/GetPnPListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class GetListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("ThrowExceptionIfListNotFound", "null")); + + // From Cmdlet Help: The ID, name or Url (Lists/MyList) of the list + var identity = ""; + // From Cmdlet Help: Switch parameter if an exception should be thrown if the requested list does not exist (true) or if omitted, nothing will be returned in case the list does not exist + var throwExceptionIfListNotFound = ""; + + var results = scope.ExecuteCommand("Get-PnPList", + new CommandParameter("Identity", identity), + new CommandParameter("ThrowExceptionIfListNotFound", throwExceptionIfListNotFound)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/GetPnPViewTests.cs b/Tests/Lists/GetPnPViewTests.cs index 5efbfb7bc..1e32b50bb 100644 --- a/Tests/Lists/GetPnPViewTests.cs +++ b/Tests/Lists/GetPnPViewTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class GetViewTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPViewTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPView",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Url of the list. + var list = ""; + // From Cmdlet Help: The ID or name of the view + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPView", + new CommandParameter("List", list), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/MovePnPListItemToRecycleBinTests.cs b/Tests/Lists/MovePnPListItemToRecycleBinTests.cs index 7036f7214..d54d211e0 100644 --- a/Tests/Lists/MovePnPListItemToRecycleBinTests.cs +++ b/Tests/Lists/MovePnPListItemToRecycleBinTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class MoveListItemToRecycleBinTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MovePnPListItemToRecycleBinTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Move-PnPListItemToRecycleBin",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Move-PnPListItemToRecycleBin", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/NewPnPListTests.cs b/Tests/Lists/NewPnPListTests.cs index dd6a887d5..b5a7920cc 100644 --- a/Tests/Lists/NewPnPListTests.cs +++ b/Tests/Lists/NewPnPListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class NewListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,49 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPList",new CommandParameter("Title", "null"),new CommandParameter("Template", "null"),new CommandParameter("Url", "null"),new CommandParameter("Hidden", "null"),new CommandParameter("EnableVersioning", "null"),new CommandParameter("QuickLaunchOptions", "null"),new CommandParameter("EnableContentTypes", "null"),new CommandParameter("OnQuickLaunch", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Title of the list + var title = ""; + // This is a mandatory parameter + // From Cmdlet Help: The type of list to create. + var template = ""; + // From Cmdlet Help: If set, will override the url of the list. + var url = ""; + // From Cmdlet Help: Switch parameter if list should be hidden from the SharePoint UI + var hidden = ""; + // From Cmdlet Help: Switch parameter if versioning should be enabled + var enableVersioning = ""; + // From Cmdlet Help: Obsolete + var quickLaunchOptions = ""; + // From Cmdlet Help: Switch parameter if content types should be enabled on this list + var enableContentTypes = ""; + // From Cmdlet Help: Switch parameter if this list should be visible on the QuickLaunch + var onQuickLaunch = ""; + + var results = scope.ExecuteCommand("New-PnPList", + new CommandParameter("Title", title), + new CommandParameter("Template", template), + new CommandParameter("Url", url), + new CommandParameter("Hidden", hidden), + new CommandParameter("EnableVersioning", enableVersioning), + new CommandParameter("QuickLaunchOptions", quickLaunchOptions), + new CommandParameter("EnableContentTypes", enableContentTypes), + new CommandParameter("OnQuickLaunch", onQuickLaunch)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/RemovePnPListItemTests.cs b/Tests/Lists/RemovePnPListItemTests.cs index 0336a476b..378c23201 100644 --- a/Tests/Lists/RemovePnPListItemTests.cs +++ b/Tests/Lists/RemovePnPListItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class RemoveListItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPListItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + var recycle = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPListItem", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Recycle", recycle), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/RemovePnPListTests.cs b/Tests/Lists/RemovePnPListTests.cs index 4e3899f0a..eb51d6d48 100644 --- a/Tests/Lists/RemovePnPListTests.cs +++ b/Tests/Lists/RemovePnPListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class RemoveListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Title of the list. + var identity = ""; + // From Cmdlet Help: Defines if the list should be moved to recycle bin or directly deleted. + var recycle = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPList", + new CommandParameter("Identity", identity), + new CommandParameter("Recycle", recycle), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/RemovePnPViewTests.cs b/Tests/Lists/RemovePnPViewTests.cs index 9859b2cd8..bf72ea488 100644 --- a/Tests/Lists/RemovePnPViewTests.cs +++ b/Tests/Lists/RemovePnPViewTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class RemoveViewTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPViewTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPView",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Title of the view. + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID or Url of the list. + var list = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPView", + new CommandParameter("Identity", identity), + new CommandParameter("List", list), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/RequestPnPReIndexListTests.cs b/Tests/Lists/RequestPnPReIndexListTests.cs index f311a455c..31620fdae 100644 --- a/Tests/Lists/RequestPnPReIndexListTests.cs +++ b/Tests/Lists/RequestPnPReIndexListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class RequestReIndexListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RequestPnPReIndexListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Request-PnPReIndexList",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var identity = ""; + + var results = scope.ExecuteCommand("Request-PnPReIndexList", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/SetPnPDefaultColumnValuesTests.cs b/Tests/Lists/SetPnPDefaultColumnValuesTests.cs index 0c00f54f4..50887f675 100644 --- a/Tests/Lists/SetPnPDefaultColumnValuesTests.cs +++ b/Tests/Lists/SetPnPDefaultColumnValuesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class SetDefaultColumnValuesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,38 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPDefaultColumnValuesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPDefaultColumnValues",new CommandParameter("List", "null"),new CommandParameter("Field", "null"),new CommandParameter("Value", "null"),new CommandParameter("Folder", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Name or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The internal name, id or a reference to a field + var field = ""; + // This is a mandatory parameter + // From Cmdlet Help: A list of values. In case of a text field the values will be concatenated, separated by a semi-colon. In case of a taxonomy field multiple values will added. In case of people field multiple values will be added. + var value = ""; + // From Cmdlet Help: A library relative folder path, if not specified it will set the default column values on the root folder of the library ('/') + var folder = ""; + + var results = scope.ExecuteCommand("Set-PnPDefaultColumnValues", + new CommandParameter("List", list), + new CommandParameter("Field", field), + new CommandParameter("Value", value), + new CommandParameter("Folder", folder)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/SetPnPListItemPermissionTests.cs b/Tests/Lists/SetPnPListItemPermissionTests.cs index 3d5d350d8..085dcf52c 100644 --- a/Tests/Lists/SetPnPListItemPermissionTests.cs +++ b/Tests/Lists/SetPnPListItemPermissionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class SetListItemPermissionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,52 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListItemPermissionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPListItemPermission",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("User", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null"),new CommandParameter("ClearExisting", "null"),new CommandParameter("InheritPermissions", "null"),new CommandParameter("SystemUpdate", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + // This is a mandatory parameter + var group = ""; + // This is a mandatory parameter + var user = ""; + // From Cmdlet Help: The role that must be assigned to the group or user + var addRole = ""; + // From Cmdlet Help: The role that must be removed from the group or user + var removeRole = ""; + // From Cmdlet Help: Clear all existing permissions + var clearExisting = ""; + // From Cmdlet Help: Inherit permissions from the list, removing unique permissions + var inheritPermissions = ""; + // From Cmdlet Help: Update the item permissions without creating a new version or triggering MS Flow. + var systemUpdate = ""; + + var results = scope.ExecuteCommand("Set-PnPListItemPermission", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("Group", group), + new CommandParameter("User", user), + new CommandParameter("AddRole", addRole), + new CommandParameter("RemoveRole", removeRole), + new CommandParameter("ClearExisting", clearExisting), + new CommandParameter("InheritPermissions", inheritPermissions), + new CommandParameter("SystemUpdate", systemUpdate)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/SetPnPListItemTests.cs b/Tests/Lists/SetPnPListItemTests.cs index 98daa012b..9213ed169 100644 --- a/Tests/Lists/SetPnPListItemTests.cs +++ b/Tests/Lists/SetPnPListItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class SetListItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,62 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("Values", "null"),new CommandParameter("SystemUpdate", "null"),new CommandParameter("Label", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + // From Cmdlet Help: Specify either the name, ID or an actual content type + var contentType = ""; + // From Cmdlet Help: Use the internal names of the fields when specifying field names. + // Single line of text: -Values @{"TextField" = "Title New"} + // Multiple lines of text: -Values @{"MultiTextField" = "New text\n\nMore text"} + // Rich text: -Values @{"MultiTextField" = "New text"} + // Choice: -Values @{"ChoiceField" = "Value 1"} + // Number: -Values @{"NumberField" = "10"} + // Currency: -Values @{"NumberField" = "10"} + // Currency: -Values @{"CurrencyField" = "10"} + // Date and Time: -Values @{"DateAndTimeField" = "03/13/2015 14:16"} + // Lookup (id of lookup value): -Values @{"LookupField" = "2"} + // Multi value lookup (id of lookup values as array 1): -Values @{"MultiLookupField" = "1","2"} + // Multi value lookup (id of lookup values as array 2): -Values @{"MultiLookupField" = 1,2} + // Multi value lookup (id of lookup values as string): -Values @{"MultiLookupField" = "1,2"} + // Yes/No: -Values @{"YesNoField" = $false} + // Person/Group (id of user/group in Site User Info List or email of the user, separate multiple values with a comma): -Values @{"PersonField" = "user1@domain.com","21"} + // Managed Metadata (single value with path to term): -Values @{"MetadataField" = "CORPORATE|DEPARTMENTS|FINANCE"} + // Managed Metadata (single value with id of term): -Values @{"MetadataField" = "fe40a95b-2144-4fa2-b82a-0b3d0299d818"} with Id of term + // Managed Metadata (multiple values with paths to terms): -Values @{"MetadataField" = ("CORPORATE|DEPARTMENTS|FINANCE","CORPORATE|DEPARTMENTS|HR")} + // Managed Metadata (multiple values with ids of terms): -Values @{"MetadataField" = ("fe40a95b-2144-4fa2-b82a-0b3d0299d818","52d88107-c2a8-4bf0-adfa-04bc2305b593")} + // Hyperlink or Picture: -Values @{"HyperlinkField" = "https://github.com/OfficeDev/, OfficePnp"} + var values = ""; + // From Cmdlet Help: Update the item without creating a new version. + var systemUpdate = ""; + // From Cmdlet Help: The name of the retention label. + var label = ""; + + var results = scope.ExecuteCommand("Set-PnPListItem", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("ContentType", contentType), + new CommandParameter("Values", values), + new CommandParameter("SystemUpdate", systemUpdate), + new CommandParameter("Label", label)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/SetPnPListPermissionTests.cs b/Tests/Lists/SetPnPListPermissionTests.cs index b2f0ad044..7c96ff1d1 100644 --- a/Tests/Lists/SetPnPListPermissionTests.cs +++ b/Tests/Lists/SetPnPListPermissionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class SetListPermissionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListPermissionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPListPermission",new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("User", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID or Title of the list. + var identity = ""; + // This is a mandatory parameter + var group = ""; + // This is a mandatory parameter + var user = ""; + // From Cmdlet Help: The role that must be assigned to the group or user + var addRole = ""; + // From Cmdlet Help: The role that must be removed from the group or user + var removeRole = ""; + + var results = scope.ExecuteCommand("Set-PnPListPermission", + new CommandParameter("Identity", identity), + new CommandParameter("Group", group), + new CommandParameter("User", user), + new CommandParameter("AddRole", addRole), + new CommandParameter("RemoveRole", removeRole)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Lists/SetPnPListTests.cs b/Tests/Lists/SetPnPListTests.cs index 1db990fc2..17a1bded0 100644 --- a/Tests/Lists/SetPnPListTests.cs +++ b/Tests/Lists/SetPnPListTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Lists { - [TestClass] public class SetListTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,78 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("EnableContentTypes", "null"),new CommandParameter("BreakRoleInheritance", "null"),new CommandParameter("ResetRoleInheritance", "null"),new CommandParameter("CopyRoleAssignments", "null"),new CommandParameter("ClearSubscopes", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Hidden", "null"),new CommandParameter("ForceCheckout", "null"),new CommandParameter("ListExperience", "null"),new CommandParameter("EnableAttachments", "null"),new CommandParameter("EnableFolderCreation", "null"),new CommandParameter("EnableVersioning", "null"),new CommandParameter("EnableMinorVersions", "null"),new CommandParameter("MajorVersions", "null"),new CommandParameter("MinorVersions", "null"),new CommandParameter("EnableModeration", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var identity = ""; + // From Cmdlet Help: Set to $true to enable content types, set to $false to disable content types + var enableContentTypes = ""; + // From Cmdlet Help: If used the security inheritance is broken for this list + var breakRoleInheritance = ""; + // From Cmdlet Help: If used the security inheritance is reset for this list (inherited from parent) + var resetRoleInheritance = ""; + // From Cmdlet Help: If used the roles are copied from the parent web + var copyRoleAssignments = ""; + // From Cmdlet Help: If used the unique permissions are cleared from child objects and they can inherit role assignments from this object + var clearSubscopeVars = ""; + // From Cmdlet Help: The title of the list + var title = ""; + // From Cmdlet Help: The description of the list + var description = ""; + // From Cmdlet Help: Hide the list from the SharePoint UI. Set to $true to hide, $false to show. + var hidden = ""; + // From Cmdlet Help: Enable or disable force checkout. Set to $true to enable, $false to disable. + var forceCheckoutVar = ""; + // From Cmdlet Help: Set the list experience: Auto, NewExperience or ClassicExperience + var listExperience = ""; + // From Cmdlet Help: Enable or disable attachments. Set to $true to enable, $false to disable. + var enableAttachments = ""; + // From Cmdlet Help: Enable or disable folder creation. Set to $true to enable, $false to disable. + var enableFolderCreation = ""; + // From Cmdlet Help: Enable or disable versioning. Set to $true to enable, $false to disable. + var enableVersioning = ""; + // From Cmdlet Help: Enable or disable minor versions versioning. Set to $true to enable, $false to disable. + var enableMinorVersions = ""; + // From Cmdlet Help: Maximum major versions to keep + var majorVersions = ""; + // From Cmdlet Help: Maximum minor versions to keep + var minorVersions = ""; + // From Cmdlet Help: Enable or disable whether content approval is enabled for the list. Set to $true to enable, $false to disable. + var enableModeration = ""; + + var results = scope.ExecuteCommand("Set-PnPList", + new CommandParameter("Identity", identity), + new CommandParameter("EnableContentTypes", enableContentTypes), + new CommandParameter("BreakRoleInheritance", breakRoleInheritance), + new CommandParameter("ResetRoleInheritance", resetRoleInheritance), + new CommandParameter("CopyRoleAssignments", copyRoleAssignments), + new CommandParameter("ClearSubscopes", clearSubscopeVars), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("Hidden", hidden), + new CommandParameter("ForceCheckout", forceCheckoutVar), + new CommandParameter("ListExperience", listExperience), + new CommandParameter("EnableAttachments", enableAttachments), + new CommandParameter("EnableFolderCreation", enableFolderCreation), + new CommandParameter("EnableVersioning", enableVersioning), + new CommandParameter("EnableMinorVersions", enableMinorVersions), + new CommandParameter("MajorVersions", majorVersions), + new CommandParameter("MinorVersions", minorVersions), + new CommandParameter("EnableModeration", enableModeration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs b/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs index 041437831..54e6c6490 100644 --- a/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs +++ b/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetManagementApiAccessTokenTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPManagementApiAccessTokenTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPManagementApiAccessToken",new CommandParameter("TenantId", "null"),new CommandParameter("ClientId", "null"),new CommandParameter("ClientSecret", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Tenant ID to connect to the Office 365 Management API + var tenantId = ""; + // This is a mandatory parameter + // From Cmdlet Help: The App\Client ID of the app which gives you access to the Office 365 Management API + var clientId = ""; + // This is a mandatory parameter + // From Cmdlet Help: The Client Secret of the app which gives you access to the Office 365 Management API + var clientSecret = ""; + + var results = scope.ExecuteCommand("Get-PnPManagementApiAccessToken", + new CommandParameter("TenantId", tenantId), + new CommandParameter("ClientId", clientId), + new CommandParameter("ClientSecret", clientSecret)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs b/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs index 3ce3f6684..db998bf6b 100644 --- a/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs +++ b/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetOffice365CurrentServiceStatusTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOffice365CurrentServiceStatusTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPOffice365CurrentServiceStatus",new CommandParameter("Workload", "null")); + + // From Cmdlet Help: Allows retrieval of the current service status of only one particular service. If not provided, the current service status of all services will be returned. + var workload = ""; + + var results = scope.ExecuteCommand("Get-PnPOffice365CurrentServiceStatus", + new CommandParameter("Workload", workload)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs b/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs index a2f91b195..8771152f5 100644 --- a/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs +++ b/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetOffice365HistoricalServiceStatusTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOffice365HistoricalServiceStatusTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPOffice365HistoricalServiceStatus",new CommandParameter("Workload", "null")); + + // From Cmdlet Help: Allows retrieval of the historical service status of only one particular service. If not provided, the historical service status of all services will be returned. + var workload = ""; + + var results = scope.ExecuteCommand("Get-PnPOffice365HistoricalServiceStatus", + new CommandParameter("Workload", workload)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs b/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs index fdbd1b606..1ce98f798 100644 --- a/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs +++ b/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetOffice365ServiceMessageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOffice365ServiceMessageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPOffice365ServiceMessage",new CommandParameter("Workload", "null")); + + // From Cmdlet Help: Allows retrieval of the service messages for only one particular service. If not provided, the service messages of all services will be returned. + var workload = ""; + + var results = scope.ExecuteCommand("Get-PnPOffice365ServiceMessage", + new CommandParameter("Workload", workload)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs b/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs index ea539ccd6..977f1ff9a 100644 --- a/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs +++ b/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetOffice365ServicesTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOffice365ServicesTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPOffice365Services"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs b/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs index f541b1f6f..8b30bdb59 100644 --- a/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs +++ b/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetOfficeManagementApiAccessTokenTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPOfficeManagementApiAccessTokenTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPOfficeManagementApiAccessToken",new CommandParameter("Decoded", "null")); + + // From Cmdlet Help: Returns the access token in a decoded manner + var decoded = ""; + + var results = scope.ExecuteCommand("Get-PnPOfficeManagementApiAccessToken", + new CommandParameter("Decoded", decoded)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs b/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs index 6b3ecf2fa..d5ebaf952 100644 --- a/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs +++ b/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.ManagementApi { - [TestClass] public class GetUnifiedAuditLogTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPUnifiedAuditLogTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPUnifiedAuditLog",new CommandParameter("ContentType", "null"),new CommandParameter("StartTime", "null"),new CommandParameter("EndTime", "null")); + + // From Cmdlet Help: Content type of logs to be retrieved, should be one of the following: AzureActiveDirectory, Exchange, SharePoint, General, DLP. + var contentType = ""; + // From Cmdlet Help: Start time of logs to be retrieved. Start time and end time must both be specified (or both omitted) and must be less than or equal to 24 hours apart, with the start time prior to end time and start time no more than 7 days in the past. + var startTime = ""; + // From Cmdlet Help: End time of logs to be retrieved. Start time and end time must both be specified (or both omitted) and must be less than or equal to 24 hours apart. + var endTime = ""; + + var results = scope.ExecuteCommand("Get-PnPUnifiedAuditLog", + new CommandParameter("ContentType", contentType), + new CommandParameter("StartTime", startTime), + new CommandParameter("EndTime", endTime)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/AddPnPAlertTests.cs b/Tests/Principals/AddPnPAlertTests.cs index a0718e8d7..abf5917f4 100644 --- a/Tests/Principals/AddPnPAlertTests.cs +++ b/Tests/Principals/AddPnPAlertTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class AddAlertTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,48 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPAlertTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPAlert",new CommandParameter("List", "null"),new CommandParameter("Title", "null"),new CommandParameter("User", "null"),new CommandParameter("DeliveryMethod", "null"),new CommandParameter("ChangeType", "null"),new CommandParameter("Frequency", "null"),new CommandParameter("Filter", "null"),new CommandParameter("Time", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // From Cmdlet Help: Alert title + var title = ""; + // From Cmdlet Help: User to create the alert for (User ID, login name or actual User object). Skip this parameter to create an alert for the current user. Note: Only site owners can create alerts for other users. + var user = ""; + // From Cmdlet Help: Alert delivery method + var deliveryMethod = ""; + // From Cmdlet Help: Alert change type + var changeType = ""; + // From Cmdlet Help: Alert frequency + var frequency = ""; + // From Cmdlet Help: Alert filter + var filter = ""; + // From Cmdlet Help: Alert time (if frequency is not immediate) + var time = ""; + + var results = scope.ExecuteCommand("Add-PnPAlert", + new CommandParameter("List", list), + new CommandParameter("Title", title), + new CommandParameter("User", user), + new CommandParameter("DeliveryMethod", deliveryMethod), + new CommandParameter("ChangeType", changeType), + new CommandParameter("Frequency", frequency), + new CommandParameter("Filter", filter), + new CommandParameter("Time", time)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/AddPnPUserToGroupTests.cs b/Tests/Principals/AddPnPUserToGroupTests.cs index 5a41bc301..c279b1f7f 100644 --- a/Tests/Principals/AddPnPUserToGroupTests.cs +++ b/Tests/Principals/AddPnPUserToGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class AddUserToGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPUserToGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPUserToGroup",new CommandParameter("LoginName", "null"),new CommandParameter("Identity", "null"),new CommandParameter("EmailAddress", "null"),new CommandParameter("SendEmail", "null"),new CommandParameter("EmailBody", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The login name of the user + var loginName = ""; + // This is a mandatory parameter + // From Cmdlet Help: The group id, group name or group object to add the user to. + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: The email address of the user + var emailAddress = ""; + var sendEmail = ""; + var emailBody = ""; + + var results = scope.ExecuteCommand("Add-PnPUserToGroup", + new CommandParameter("LoginName", loginName), + new CommandParameter("Identity", identity), + new CommandParameter("EmailAddress", emailAddress), + new CommandParameter("SendEmail", sendEmail), + new CommandParameter("EmailBody", emailBody)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/GetPnPAlertTests.cs b/Tests/Principals/GetPnPAlertTests.cs index ccd82308c..7e6ccf825 100644 --- a/Tests/Principals/GetPnPAlertTests.cs +++ b/Tests/Principals/GetPnPAlertTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class GetAlertTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAlertTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPAlert",new CommandParameter("List", "null"),new CommandParameter("User", "null"),new CommandParameter("Title", "null")); + + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // From Cmdlet Help: User to retrieve the alerts for (User ID, login name or actual User object). Skip this parameter to retrieve the alerts for the current user. Note: Only site owners can retrieve alerts for other users. + var user = ""; + // From Cmdlet Help: Retrieve alerts with this title. Title comparison is case sensitive. + var title = ""; + + var results = scope.ExecuteCommand("Get-PnPAlert", + new CommandParameter("List", list), + new CommandParameter("User", user), + new CommandParameter("Title", title)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/GetPnPGroupMembersTests.cs b/Tests/Principals/GetPnPGroupMembersTests.cs index f84a55a67..15ae17d41 100644 --- a/Tests/Principals/GetPnPGroupMembersTests.cs +++ b/Tests/Principals/GetPnPGroupMembersTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class GetGroupMembersTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPGroupMembersTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPGroupMembers",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: A group object, an ID or a name of a group + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPGroupMembers", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/GetPnPGroupPermissionsTests.cs b/Tests/Principals/GetPnPGroupPermissionsTests.cs index 01abcda82..7525a995e 100644 --- a/Tests/Principals/GetPnPGroupPermissionsTests.cs +++ b/Tests/Principals/GetPnPGroupPermissionsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class GetGroupPermissionsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPGroupPermissionsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPGroupPermissions",new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Get the permissions of a specific group by name + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPGroupPermissions", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/GetPnPGroupTests.cs b/Tests/Principals/GetPnPGroupTests.cs index 1c171da75..d5b0c2988 100644 --- a/Tests/Principals/GetPnPGroupTests.cs +++ b/Tests/Principals/GetPnPGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class GetGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPGroup",new CommandParameter("Identity", "null"),new CommandParameter("AssociatedMemberGroup", "null"),new CommandParameter("AssociatedVisitorGroup", "null"),new CommandParameter("AssociatedOwnerGroup", "null")); + + // From Cmdlet Help: Get a specific group by name + var identity = ""; + // From Cmdlet Help: Retrieve the associated member group + var associatedMemberGroup = ""; + // From Cmdlet Help: Retrieve the associated visitor group + var associatedVisitorGroup = ""; + // From Cmdlet Help: Retrieve the associated owner group + var associatedOwnerGroup = ""; + + var results = scope.ExecuteCommand("Get-PnPGroup", + new CommandParameter("Identity", identity), + new CommandParameter("AssociatedMemberGroup", associatedMemberGroup), + new CommandParameter("AssociatedVisitorGroup", associatedVisitorGroup), + new CommandParameter("AssociatedOwnerGroup", associatedOwnerGroup)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/GetPnPUserTests.cs b/Tests/Principals/GetPnPUserTests.cs index e7bf20c77..e4cf05e80 100644 --- a/Tests/Principals/GetPnPUserTests.cs +++ b/Tests/Principals/GetPnPUserTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class GetUserTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPUserTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPUser",new CommandParameter("Identity", "null"),new CommandParameter("WithRightsAssigned", "null")); + + // From Cmdlet Help: User ID or login name + var identity = ""; + // From Cmdlet Help: If provided, only users that currently have any kinds of access rights assigned to the current site collection will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity. + var withRightsAssigned = ""; + + var results = scope.ExecuteCommand("Get-PnPUser", + new CommandParameter("Identity", identity), + new CommandParameter("WithRightsAssigned", withRightsAssigned)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/NewPnPGroupTests.cs b/Tests/Principals/NewPnPGroupTests.cs index 49d550988..90ad8852f 100644 --- a/Tests/Principals/NewPnPGroupTests.cs +++ b/Tests/Principals/NewPnPGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class NewGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,53 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPGroup",new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Owner", "null"),new CommandParameter("AllowRequestToJoinLeave", "null"),new CommandParameter("AutoAcceptRequestToJoinLeave", "null"),new CommandParameter("AllowMembersEditMembership", "null"),new CommandParameter("OnlyAllowMembersViewMembership", "null"),new CommandParameter("DisallowMembersViewMembership", "null"),new CommandParameter("RequestToJoinEmail", "null"),new CommandParameter("SetAssociatedGroup", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The Title of the group + var title = ""; + // From Cmdlet Help: The description for the group + var description = ""; + // From Cmdlet Help: The owner for the group, which can be a user or another group + var owner = ""; + // From Cmdlet Help: A switch parameter that specifies whether to allow users to request membership in the group and to allow users to request to leave the group + var allowRequestToJoinLeave = ""; + // From Cmdlet Help: A switch parameter that specifies whether users are automatically added or removed when they make a request + var autoAcceptRequestToJoinLeave = ""; + // From Cmdlet Help: A switch parameter that specifies whether group members can modify membership in the group + var allowMembersEditMembership = ""; + // From Cmdlet Help: A switch parameter that specifies whether only group members are allowed to view the list of members in the group + var onlyAllowMembersViewMembership = ""; + // From Cmdlet Help: A switch parameter that disallows group members to view membership. + var disallowMembersViewMembership = ""; + // From Cmdlet Help: The e-mail address to which membership requests are sent + var requestToJoinEmail = ""; + var setAssociatedGroup = ""; + + var results = scope.ExecuteCommand("New-PnPGroup", + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("Owner", owner), + new CommandParameter("AllowRequestToJoinLeave", allowRequestToJoinLeave), + new CommandParameter("AutoAcceptRequestToJoinLeave", autoAcceptRequestToJoinLeave), + new CommandParameter("AllowMembersEditMembership", allowMembersEditMembership), + new CommandParameter("OnlyAllowMembersViewMembership", onlyAllowMembersViewMembership), + new CommandParameter("DisallowMembersViewMembership", disallowMembersViewMembership), + new CommandParameter("RequestToJoinEmail", requestToJoinEmail), + new CommandParameter("SetAssociatedGroup", setAssociatedGroup)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/NewPnPUserTests.cs b/Tests/Principals/NewPnPUserTests.cs index e714a4b9d..f5fe7406f 100644 --- a/Tests/Principals/NewPnPUserTests.cs +++ b/Tests/Principals/NewPnPUserTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class NewUserTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPUserTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPUser",new CommandParameter("LoginName", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The users login name (user@company.com) + var loginName = ""; + + var results = scope.ExecuteCommand("New-PnPUser", + new CommandParameter("LoginName", loginName)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/RemovePnPAlertTests.cs b/Tests/Principals/RemovePnPAlertTests.cs index 76002e906..6d63a2811 100644 --- a/Tests/Principals/RemovePnPAlertTests.cs +++ b/Tests/Principals/RemovePnPAlertTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class RemoveAlertTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPAlertTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPAlert",new CommandParameter("User", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: User to remove the alert for (User ID, login name or actual User object). Skip this parameter to use the current user. Note: Only site owners can remove alerts for other users. + var user = ""; + // This is a mandatory parameter + // From Cmdlet Help: The alert id, or the actual alert object to remove. + var identity = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPAlert", + new CommandParameter("User", user), + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/RemovePnPGroupTests.cs b/Tests/Principals/RemovePnPGroupTests.cs index e08ced6bd..cf0a9f539 100644 --- a/Tests/Principals/RemovePnPGroupTests.cs +++ b/Tests/Principals/RemovePnPGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class RemoveGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPGroup",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: A group object, an ID or a name of a group to remove + var identity = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPGroup", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/RemovePnPUserFromGroupTests.cs b/Tests/Principals/RemovePnPUserFromGroupTests.cs index c6a45699d..2ffd2a762 100644 --- a/Tests/Principals/RemovePnPUserFromGroupTests.cs +++ b/Tests/Principals/RemovePnPUserFromGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class RemoveUserFromGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPUserFromGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPUserFromGroup",new CommandParameter("LoginName", "null"),new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: A valid login name of a user (user@company.com) + var loginName = ""; + // This is a mandatory parameter + // From Cmdlet Help: A group object, an ID or a name of a group + var identity = ""; + + var results = scope.ExecuteCommand("Remove-PnPUserFromGroup", + new CommandParameter("LoginName", loginName), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/RemovePnPUserTests.cs b/Tests/Principals/RemovePnPUserTests.cs index f03275b7f..9109166fc 100644 --- a/Tests/Principals/RemovePnPUserTests.cs +++ b/Tests/Principals/RemovePnPUserTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class RemoveUserTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPUserTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPUser",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null"),new CommandParameter("Confirm", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: User ID or login name + var identity = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question + var force = ""; + // From Cmdlet Help: Specifying the Confirm parameter will allow the confirmation question to be skipped + var confirm = ""; + + var results = scope.ExecuteCommand("Remove-PnPUser", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force), + new CommandParameter("Confirm", confirm)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/SetPnPGroupPermissionsTests.cs b/Tests/Principals/SetPnPGroupPermissionsTests.cs index b089d3128..89737119c 100644 --- a/Tests/Principals/SetPnPGroupPermissionsTests.cs +++ b/Tests/Principals/SetPnPGroupPermissionsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class SetGroupPermissionsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPGroupPermissionsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPGroupPermissions",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Get the permissions of a specific group by name + var identity = ""; + // From Cmdlet Help: The list to apply the command to. + var list = ""; + // From Cmdlet Help: Name of the permission set to add to this SharePoint group + var addRole = ""; + // From Cmdlet Help: Name of the permission set to remove from this SharePoint group + var removeRole = ""; + + var results = scope.ExecuteCommand("Set-PnPGroupPermissions", + new CommandParameter("Identity", identity), + new CommandParameter("List", list), + new CommandParameter("AddRole", addRole), + new CommandParameter("RemoveRole", removeRole)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Principals/SetPnPGroupTests.cs b/Tests/Principals/SetPnPGroupTests.cs index 2027f4ab4..e0183c61a 100644 --- a/Tests/Principals/SetPnPGroupTests.cs +++ b/Tests/Principals/SetPnPGroupTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Principals { - [TestClass] public class SetGroupTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,60 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPGroupTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPGroup",new CommandParameter("Identity", "null"),new CommandParameter("SetAssociatedGroup", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null"),new CommandParameter("Title", "null"),new CommandParameter("Owner", "null"),new CommandParameter("Description", "null"),new CommandParameter("AllowRequestToJoinLeave", "null"),new CommandParameter("AutoAcceptRequestToJoinLeave", "null"),new CommandParameter("AllowMembersEditMembership", "null"),new CommandParameter("OnlyAllowMembersViewMembership", "null"),new CommandParameter("RequestToJoinEmail", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: A group object, an ID or a name of a group + var identity = ""; + // From Cmdlet Help: One of the associated group types (Visitors, Members, Owners + var setAssociatedGroup = ""; + // From Cmdlet Help: Name of the permission set to add to this SharePoint group + var addRole = ""; + // From Cmdlet Help: Name of the permission set to remove from this SharePoint group + var removeRole = ""; + // From Cmdlet Help: The title for the group + var title = ""; + // From Cmdlet Help: The owner for the group, which can be a user or another group + var owner = ""; + // From Cmdlet Help: The description for the group + var description = ""; + // From Cmdlet Help: A switch parameter that specifies whether to allow users to request membership in the group and to allow users to request to leave the group + var allowRequestToJoinLeave = ""; + // From Cmdlet Help: A switch parameter that specifies whether users are automatically added or removed when they make a request + var autoAcceptRequestToJoinLeave = ""; + // From Cmdlet Help: A switch parameter that specifies whether group members can modify membership in the group + var allowMembersEditMembership = ""; + // From Cmdlet Help: A switch parameter that specifies whether only group members are allowed to view the list of members in the group + var onlyAllowMembersViewMembership = ""; + // From Cmdlet Help: The e-mail address to which membership requests are sent + var requestToJoinEmail = ""; + + var results = scope.ExecuteCommand("Set-PnPGroup", + new CommandParameter("Identity", identity), + new CommandParameter("SetAssociatedGroup", setAssociatedGroup), + new CommandParameter("AddRole", addRole), + new CommandParameter("RemoveRole", removeRole), + new CommandParameter("Title", title), + new CommandParameter("Owner", owner), + new CommandParameter("Description", description), + new CommandParameter("AllowRequestToJoinLeave", allowRequestToJoinLeave), + new CommandParameter("AutoAcceptRequestToJoinLeave", autoAcceptRequestToJoinLeave), + new CommandParameter("AllowMembersEditMembership", allowMembersEditMembership), + new CommandParameter("OnlyAllowMembersViewMembership", onlyAllowMembersViewMembership), + new CommandParameter("RequestToJoinEmail", requestToJoinEmail)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs index 68434ff34..faf0f716c 100644 --- a/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class AddDataRowsToProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,46 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPDataRowsToProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPDataRowsToProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("List", "null"),new CommandParameter("Query", "null"),new CommandParameter("Fields", "null"),new CommandParameter("IncludeSecurity", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("TokenizeUrls", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Filename of the .PNP Open XML site template to read from, optionally including full path. + var path = ""; + // This is a mandatory parameter + // From Cmdlet Help: The list to query + var list = ""; + // From Cmdlet Help: The CAML query to execute against the list. Defaults to all items. + var query = ""; + // From Cmdlet Help: The fields to retrieve. If not specified all fields will be loaded in the returned list object. + var fields = ""; + // From Cmdlet Help: A switch to include ObjectSecurity information. + var includeSecurity = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while loading the template. + var templateProviderExtensions = ""; + // From Cmdlet Help: If set, this switch will try to tokenize the values with web and site related tokens + var tokenizeUrls = ""; + + var results = scope.ExecuteCommand("Add-PnPDataRowsToProvisioningTemplate", + new CommandParameter("Path", path), + new CommandParameter("List", list), + new CommandParameter("Query", query), + new CommandParameter("Fields", fields), + new CommandParameter("IncludeSecurity", includeSecurity), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions), + new CommandParameter("TokenizeUrls", tokenizeUrls)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs index ca1921e1c..8f23a2570 100644 --- a/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class AddFileToProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,51 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPFileToProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPFileToProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("Source", "null"),new CommandParameter("SourceUrl", "null"),new CommandParameter("Folder", "null"),new CommandParameter("Container", "null"),new CommandParameter("FileLevel", "null"),new CommandParameter("FileOverwrite", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Filename of the .PNP Open XML site template to read from, optionally including full path. + var path = ""; + // This is a mandatory parameter + // From Cmdlet Help: The file to add to the in-memory template, optionally including full path. + var source = ""; + // This is a mandatory parameter + // From Cmdlet Help: The file to add to the in-memory template, specifying its url in the current connected Web. + var sourceUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: The target Folder for the file to add to the in-memory template. + var folder = ""; + // From Cmdlet Help: The target Container for the file to add to the in-memory template, optional argument. + var container = ""; + // From Cmdlet Help: The level of the files to add. Defaults to Published + var fileLevel = ""; + // From Cmdlet Help: Set to overwrite in site, Defaults to true + var fileOverwrite = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while loading the template. + var templateProviderExtensions = ""; + + var results = scope.ExecuteCommand("Add-PnPFileToProvisioningTemplate", + new CommandParameter("Path", path), + new CommandParameter("Source", source), + new CommandParameter("SourceUrl", sourceUrl), + new CommandParameter("Folder", folder), + new CommandParameter("Container", container), + new CommandParameter("FileLevel", fileLevel), + new CommandParameter("FileOverwrite", fileOverwrite), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs index 4136a4435..ea1a2d20e 100644 --- a/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class AddListFoldersToProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,40 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPListFoldersToProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPListFoldersToProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("List", "null"),new CommandParameter("Recursive", "null"),new CommandParameter("IncludeSecurity", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Filename of the .PNP Open XML site template to read from, optionally including full path. + var path = ""; + // This is a mandatory parameter + // From Cmdlet Help: The list to query + var list = ""; + // From Cmdlet Help: A switch parameter to include all folders in the list, or just top level folders. + var recursive = ""; + // From Cmdlet Help: A switch to include ObjectSecurity information. + var includeSecurity = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while loading the template. + var templateProviderExtensions = ""; + + var results = scope.ExecuteCommand("Add-PnPListFoldersToProvisioningTemplate", + new CommandParameter("Path", path), + new CommandParameter("List", list), + new CommandParameter("Recursive", recursive), + new CommandParameter("IncludeSecurity", includeSecurity), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs b/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs index 893f97fb0..37aed0a5e 100644 --- a/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class ApplyProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,66 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ApplyPnPProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Apply-PnPProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("TemplateId", "null"),new CommandParameter("ResourceFolder", "null"),new CommandParameter("OverwriteSystemPropertyBagValues", "null"),new CommandParameter("IgnoreDuplicateDataRowErrors", "null"),new CommandParameter("ProvisionContentTypesToSubWebs", "null"),new CommandParameter("ProvisionFieldsToSubWebs", "null"),new CommandParameter("ClearNavigation", "null"),new CommandParameter("Parameters", "null"),new CommandParameter("Handlers", "null"),new CommandParameter("ExcludeHandlers", "null"),new CommandParameter("ExtensibilityHandlers", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("InputInstance", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the xml or pnp file containing the provisioning template. + var path = ""; + // From Cmdlet Help: ID of the template to use from the xml file containing the provisioning template. If not specified and multiple ProvisioningTemplate elements exist, the last one will be used. + var templateId = ""; + // From Cmdlet Help: Root folder where resources/files that are being referenced in the template are located. If not specified the same folder as where the provisioning template is located will be used. + var resourceFolder = ""; + // From Cmdlet Help: Specify this parameter if you want to overwrite and/or create properties that are known to be system entries (starting with vti_, dlc_, etc.) + var overwriteSystemPropertyBagValues = ""; + // From Cmdlet Help: Ignore duplicate data row errors when the data row in the template already exists. + var ignoreDuplicateDataRowErrors = ""; + // From Cmdlet Help: If set content types will be provisioned if the target web is a subweb. + var provisionContentTypesToSubWebs = ""; + // From Cmdlet Help: If set fields will be provisioned if the target web is a subweb. + var provisionFieldsToSubWebs = ""; + // From Cmdlet Help: Override the RemoveExistingNodes attribute in the Navigation elements of the template. If you specify this value the navigation nodes will always be removed before adding the nodes in the template + var clearNavigation = ""; + // From Cmdlet Help: Allows you to specify parameters that can be referred to in the template by means of the {parameter:} token. See examples on how to use this parameter. + var parameters = ""; + // From Cmdlet Help: Allows you to only process a specific part of the template. Notice that this might fail, as some of the handlers require other artifacts in place if they are not part of what your applying. Visit https://docs.microsoft.com/dotnet/api/officedevpnp.core.framework.provisioning.model.handlers for possible values. + var handlers = ""; + // From Cmdlet Help: Allows you to run all handlers, excluding the ones specified. + var excludeHandlers = ""; + // From Cmdlet Help: Allows you to specify ExtensbilityHandlers to execute while applying a template + var extensibilityHandlers = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while applying a template. + var templateProviderExtensions = ""; + // From Cmdlet Help: Allows you to provide an in-memory instance of the ProvisioningTemplate type of the PnP Core Component. When using this parameter, the -Path parameter refers to the path of any supporting file for the template. + var inputInstance = ""; + + var results = scope.ExecuteCommand("Apply-PnPProvisioningTemplate", + new CommandParameter("Path", path), + new CommandParameter("TemplateId", templateId), + new CommandParameter("ResourceFolder", resourceFolder), + new CommandParameter("OverwriteSystemPropertyBagValues", overwriteSystemPropertyBagValues), + new CommandParameter("IgnoreDuplicateDataRowErrors", ignoreDuplicateDataRowErrors), + new CommandParameter("ProvisionContentTypesToSubWebs", provisionContentTypesToSubWebs), + new CommandParameter("ProvisionFieldsToSubWebs", provisionFieldsToSubWebs), + new CommandParameter("ClearNavigation", clearNavigation), + new CommandParameter("Parameters", parameters), + new CommandParameter("Handlers", handlers), + new CommandParameter("ExcludeHandlers", excludeHandlers), + new CommandParameter("ExtensibilityHandlers", extensibilityHandlers), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions), + new CommandParameter("InputInstance", inputInstance)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs index 90ebad459..70dec9037 100644 --- a/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class ExportListToProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ExportPnPListToProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Export-PnPListToProvisioningTemplate",new CommandParameter("List", "null"),new CommandParameter("Out", "null"),new CommandParameter("Schema", "null"),new CommandParameter("Force", "null"),new CommandParameter("OutputInstance", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specify the lists to extract, either providing their ID or their Title. + var list = ""; + // From Cmdlet Help: Filename to write to, optionally including full path + var outVar = ""; + // From Cmdlet Help: The schema of the output to use, defaults to the latest schema + var schema = ""; + // From Cmdlet Help: Overwrites the output file if it exists. + var force = ""; + // From Cmdlet Help: Returns the template as an in-memory object, which is an instance of the ProvisioningTemplate type of the PnP Core Component. It cannot be used together with the -Out parameter. + var outVarputInstance = ""; + + var results = scope.ExecuteCommand("Export-PnPListToProvisioningTemplate", + new CommandParameter("List", list), + new CommandParameter("Out", outVar), + new CommandParameter("Schema", schema), + new CommandParameter("Force", force), + new CommandParameter("OutputInstance", outVarputInstance)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs b/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs index 09926cc4b..91c068a9f 100644 --- a/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class GetProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,116 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPProvisioningTemplate",new CommandParameter("Out", "null"),new CommandParameter("Schema", "null"),new CommandParameter("IncludeAllTermGroups", "null"),new CommandParameter("IncludeSiteCollectionTermGroup", "null"),new CommandParameter("IncludeSiteGroups", "null"),new CommandParameter("IncludeTermGroupsSecurity", "null"),new CommandParameter("IncludeSearchConfiguration", "null"),new CommandParameter("PersistBrandingFiles", "null"),new CommandParameter("PersistComposedLookFiles", "null"),new CommandParameter("PersistPublishingFiles", "null"),new CommandParameter("IncludeNativePublishingFiles", "null"),new CommandParameter("IncludeHiddenLists", "null"),new CommandParameter("IncludeAllClientSidePages", "null"),new CommandParameter("SkipVersionCheck", "null"),new CommandParameter("PersistMultiLanguageResources", "null"),new CommandParameter("ResourceFilePrefix", "null"),new CommandParameter("Handlers", "null"),new CommandParameter("ExcludeHandlers", "null"),new CommandParameter("ExtensibilityHandlers", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("ContentTypeGroups", "null"),new CommandParameter("Force", "null"),new CommandParameter("NoBaseTemplate", "null"),new CommandParameter("Encoding", "null"),new CommandParameter("TemplateDisplayName", "null"),new CommandParameter("TemplateImagePreviewUrl", "null"),new CommandParameter("TemplateProperties", "null"),new CommandParameter("OutputInstance", "null"),new CommandParameter("ExcludeContentTypesFromSyndication", "null"),new CommandParameter("ListsToExtract", "null"),new CommandParameter("Configuration", "null")); + + // From Cmdlet Help: Filename to write to, optionally including full path + var outVar = ""; + // From Cmdlet Help: The schema of the output to use, defaults to the latest schema + var schema = ""; + // From Cmdlet Help: If specified, all term groups will be included. Overrides IncludeSiteCollectionTermGroup. + var includeAllTermGroups = ""; + // From Cmdlet Help: If specified, all the site collection term groups will be included. Overridden by IncludeAllTermGroups. + var includeSiteCollectionTermGroup = ""; + // From Cmdlet Help: If specified all site groups will be included. + var includeSiteGroups = ""; + // From Cmdlet Help: If specified all the managers and contributors of term groups will be included. + var includeTermGroupsSecurity = ""; + // From Cmdlet Help: If specified the template will contain the current search configuration of the site. + var includeSearchConfiguration = ""; + // From Cmdlet Help: If specified the files used for masterpages, sitelogo, alternate CSS and the files that make up the composed look will be saved. + var persistBrandingFiles = ""; + // From Cmdlet Help: If specified the files making up the composed look (background image, font file and color file) will be saved. + var persistComposedLookFiles = ""; + // From Cmdlet Help: If specified the files used for the publishing feature will be saved. + var persistPublishingFiles = ""; + // From Cmdlet Help: If specified, out of the box / native publishing files will be saved. + var includeNativePublishingFiles = ""; + // From Cmdlet Help: If specified hidden lists will be included in the template + var includeHiddenLists = ""; + // From Cmdlet Help: If specified all client side pages will be included + var includeAllClientSidePages = ""; + // From Cmdlet Help: During extraction the version of the server will be checked for certain actions. If you specify this switch, this check will be skipped. + var skipVersionCheck = ""; + // From Cmdlet Help: If specified, resource values for applicable artifacts will be persisted to a resource file + var persistMultiLanguageResources = ""; + // From Cmdlet Help: If specified, resource files will be saved with the specified prefix instead of using the template name specified. If no template name is specified the files will be called PnP-Resources..resx. See examples for more info. + var resourceFilePrefix = ""; + // From Cmdlet Help: Allows you to only process a specific type of artifact in the site. Notice that this might result in a non-working template, as some of the handlers require other artifacts in place if they are not part of what your extracting. For possible values for this parameter visit https://docs.microsoft.com/dotnet/api/officedevpnp.core.framework.provisioning.model.handlers + var handlers = ""; + // From Cmdlet Help: Allows you to run all handlers, excluding the ones specified. + var excludeHandlers = ""; + // From Cmdlet Help: Allows you to specify ExtensibilityHandlers to execute while extracting a template. + var extensibilityHandlers = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while extracting a template. + var templateProviderExtensions = ""; + // From Cmdlet Help: Allows you to specify from which content type group(s) the content types should be included into the template. + var contentTypeGroups = ""; + // From Cmdlet Help: Overwrites the output file if it exists. + var force = ""; + // From Cmdlet Help: Exports the template without the use of a base template, causing all OOTB artifacts to be included. Using this switch is generally not required/recommended. + var noBaseTemplate = ""; + // From Cmdlet Help: The encoding type of the XML file, Unicode is default + var encoding = ""; + // From Cmdlet Help: It can be used to specify the DisplayName of the template file that will be extracted. + var templateDisplayName = ""; + // From Cmdlet Help: It can be used to specify the ImagePreviewUrl of the template file that will be extracted. + var templateImagePreviewUrl = ""; + // From Cmdlet Help: It can be used to specify custom Properties for the template file that will be extracted. + var templateProperties = ""; + // From Cmdlet Help: Returns the template as an in-memory object, which is an instance of the ProvisioningTemplate type of the PnP Core Component. It cannot be used together with the -Out parameter. + var outVarputInstance = ""; + // From Cmdlet Help: Specify whether or not content types issued from a content hub should be exported. By default, these content types are included. + var excludeContentTypesFromSyndication = ""; + // From Cmdlet Help: Specify the lists to extract, either providing their ID or their Title. + var listsToExtract = ""; + // From Cmdlet Help: Specify a JSON configuration file to configure the extraction progress. + var configuration = ""; + + var results = scope.ExecuteCommand("Get-PnPProvisioningTemplate", + new CommandParameter("Out", outVar), + new CommandParameter("Schema", schema), + new CommandParameter("IncludeAllTermGroups", includeAllTermGroups), + new CommandParameter("IncludeSiteCollectionTermGroup", includeSiteCollectionTermGroup), + new CommandParameter("IncludeSiteGroups", includeSiteGroups), + new CommandParameter("IncludeTermGroupsSecurity", includeTermGroupsSecurity), + new CommandParameter("IncludeSearchConfiguration", includeSearchConfiguration), + new CommandParameter("PersistBrandingFiles", persistBrandingFiles), + new CommandParameter("PersistComposedLookFiles", persistComposedLookFiles), + new CommandParameter("PersistPublishingFiles", persistPublishingFiles), + new CommandParameter("IncludeNativePublishingFiles", includeNativePublishingFiles), + new CommandParameter("IncludeHiddenLists", includeHiddenLists), + new CommandParameter("IncludeAllClientSidePages", includeAllClientSidePages), + new CommandParameter("SkipVersionCheck", skipVersionCheck), + new CommandParameter("PersistMultiLanguageResources", persistMultiLanguageResources), + new CommandParameter("ResourceFilePrefix", resourceFilePrefix), + new CommandParameter("Handlers", handlers), + new CommandParameter("ExcludeHandlers", excludeHandlers), + new CommandParameter("ExtensibilityHandlers", extensibilityHandlers), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions), + new CommandParameter("ContentTypeGroups", contentTypeGroups), + new CommandParameter("Force", force), + new CommandParameter("NoBaseTemplate", noBaseTemplate), + new CommandParameter("Encoding", encoding), + new CommandParameter("TemplateDisplayName", templateDisplayName), + new CommandParameter("TemplateImagePreviewUrl", templateImagePreviewUrl), + new CommandParameter("TemplateProperties", templateProperties), + new CommandParameter("OutputInstance", outVarputInstance), + new CommandParameter("ExcludeContentTypesFromSyndication", excludeContentTypesFromSyndication), + new CommandParameter("ListsToExtract", listsToExtract), + new CommandParameter("Configuration", configuration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs b/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs index e2988b4d4..e8ed92c71 100644 --- a/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs +++ b/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class GetTenantTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantTemplate",new CommandParameter("SiteUrl", "null"),new CommandParameter("Out", "null"),new CommandParameter("Force", "null"),new CommandParameter("AsInstance", "null"),new CommandParameter("Configuration", "null")); + + var siteUrl = ""; + // This is a mandatory parameter + // From Cmdlet Help: Filename to write to, optionally including full path + var outVar = ""; + // From Cmdlet Help: Overwrites the output file if it exists. + var force = ""; + // This is a mandatory parameter + // From Cmdlet Help: Returns the template as an in-memory object, which is an instance of the ProvisioningHierarchy type of the PnP Core Component. It cannot be used together with the -Out parameter. + var asInstance = ""; + // From Cmdlet Help: Specify a JSON configuration file to configure the extraction progress. + var configuration = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantTemplate", + new CommandParameter("SiteUrl", siteUrl), + new CommandParameter("Out", outVar), + new CommandParameter("Force", force), + new CommandParameter("AsInstance", asInstance), + new CommandParameter("Configuration", configuration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs b/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs index 14dd6db6b..f923a754b 100644 --- a/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class RemoveFileFromProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPFileFromProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPFileFromProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("FilePath", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Filename to read the template from, optionally including full path. + var path = ""; + // This is a mandatory parameter + // From Cmdlet Help: The relative File Path of the file to remove from the in-memory template + var filePath = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while saving the template. + var templateProviderExtensions = ""; + + var results = scope.ExecuteCommand("Remove-PnPFileFromProvisioningTemplate", + new CommandParameter("Path", path), + new CommandParameter("FilePath", filePath), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs b/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs index 95f13aa13..8f7c5ec1f 100644 --- a/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs +++ b/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Site { - [TestClass] public class SetProvisioningTemplateMetadataTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPProvisioningTemplateMetadataTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPProvisioningTemplateMetadata",new CommandParameter("Path", "null"),new CommandParameter("TemplateDisplayName", "null"),new CommandParameter("TemplateImagePreviewUrl", "null"),new CommandParameter("TemplateProperties", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the xml or pnp file containing the site template. + var path = ""; + // From Cmdlet Help: It can be used to specify the DisplayName of the template file that will be updated. + var templateDisplayName = ""; + // From Cmdlet Help: It can be used to specify the ImagePreviewUrl of the template file that will be updated. + var templateImagePreviewUrl = ""; + // From Cmdlet Help: It can be used to specify custom Properties for the template file that will be updated. + var templateProperties = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while extracting a template. + var templateProviderExtensions = ""; + + var results = scope.ExecuteCommand("Set-PnPProvisioningTemplateMetadata", + new CommandParameter("Path", path), + new CommandParameter("TemplateDisplayName", templateDisplayName), + new CommandParameter("TemplateImagePreviewUrl", templateImagePreviewUrl), + new CommandParameter("TemplateProperties", templateProperties), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs b/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs index d39fd49dd..dbb49a7e5 100644 --- a/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs +++ b/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class AddProvisioningTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPProvisioningTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPProvisioningTemplate",new CommandParameter("SiteTemplate", "null"),new CommandParameter("TenantTemplate", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The template to add to the tenant template + var siteTemplate = ""; + // This is a mandatory parameter + // From Cmdlet Help: The tenant template to add the template to + var tenantTemplate = ""; + + var results = scope.ExecuteCommand("Add-PnPProvisioningTemplate", + new CommandParameter("SiteTemplate", siteTemplate), + new CommandParameter("TenantTemplate", tenantTemplate)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs index 47a118a2d..882b521a3 100644 --- a/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs +++ b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class AddTenantSequenceSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTenantSequenceSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPTenantSequenceSite",new CommandParameter("Site", "null"),new CommandParameter("Sequence", "null")); + + // This is a mandatory parameter + var site = ""; + // This is a mandatory parameter + // From Cmdlet Help: The sequence to add the site to + var sequence = ""; + + var results = scope.ExecuteCommand("Add-PnPTenantSequenceSite", + new CommandParameter("Site", site), + new CommandParameter("Sequence", sequence)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs index dd3a5c258..085646385 100644 --- a/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs +++ b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class AddTenantSequenceSubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTenantSequenceSubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPTenantSequenceSubSite",new CommandParameter("SubSite", "null"),new CommandParameter("Site", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The subsite to add + var subSite = ""; + // This is a mandatory parameter + // From Cmdlet Help: The site to add the subsite to + var site = ""; + + var results = scope.ExecuteCommand("Add-PnPTenantSequenceSubSite", + new CommandParameter("SubSite", subSite), + new CommandParameter("Site", site)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs b/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs index 97ee32f52..003d17ef7 100644 --- a/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs +++ b/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class AddTenantSequenceTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTenantSequenceTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPTenantSequence",new CommandParameter("Template", "null"),new CommandParameter("Sequence", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The template to add the sequence to + var template = ""; + // This is a mandatory parameter + // From Cmdlet Help: Optional Id of the sequence + var sequence = ""; + + var results = scope.ExecuteCommand("Add-PnPTenantSequence", + new CommandParameter("Template", template), + new CommandParameter("Sequence", sequence)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs index edc49aa17..812a1b42a 100644 --- a/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs +++ b/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class ApplyTenantTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,68 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ApplyPnPTenantTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Apply-PnPTenantTemplate",new CommandParameter("Path", "null"),new CommandParameter("Template", "null"),new CommandParameter("SequenceId", "null"),new CommandParameter("ResourceFolder", "null"),new CommandParameter("Handlers", "null"),new CommandParameter("ExcludeHandlers", "null"),new CommandParameter("ExtensibilityHandlers", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("Parameters", "null"),new CommandParameter("OverwriteSystemPropertyBagValues", "null"),new CommandParameter("IgnoreDuplicateDataRowErrors", "null"),new CommandParameter("ProvisionContentTypesToSubWebs", "null"),new CommandParameter("ProvisionFieldsToSubWebs", "null"),new CommandParameter("ClearNavigation", "null"),new CommandParameter("Configuration", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the xml or pnp file containing the tenant template. + var path = ""; + // This is a mandatory parameter + var template = ""; + var sequenceId = ""; + // From Cmdlet Help: Root folder where resources/files that are being referenced in the template are located. If not specified the same folder as where the tenant template is located will be used. + var resourceFolder = ""; + // From Cmdlet Help: Allows you to only process a specific part of the template. Notice that this might fail, as some of the handlers require other artifacts in place if they are not part of what your applying. + var handlers = ""; + // From Cmdlet Help: Allows you to run all handlers, excluding the ones specified. + var excludeHandlers = ""; + // From Cmdlet Help: Allows you to specify ExtensbilityHandlers to execute while applying a template + var extensibilityHandlers = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while applying a template. + var templateProviderExtensions = ""; + // From Cmdlet Help: Allows you to specify parameters that can be referred to in the tenant template by means of the {parameter:} token. See examples on how to use this parameter. + var parameters = ""; + // From Cmdlet Help: Specify this parameter if you want to overwrite and/or create properties that are known to be system entries (starting with vti_, dlc_, etc.) + var overwriteSystemPropertyBagValues = ""; + // From Cmdlet Help: Ignore duplicate data row errors when the data row in the template already exists. + var ignoreDuplicateDataRowErrors = ""; + // From Cmdlet Help: If set content types will be provisioned if the target web is a subweb. + var provisionContentTypesToSubWebs = ""; + // From Cmdlet Help: If set fields will be provisioned if the target web is a subweb. + var provisionFieldsToSubWebs = ""; + // From Cmdlet Help: Override the RemoveExistingNodes attribute in the Navigation elements of the template. If you specify this value the navigation nodes will always be removed before adding the nodes in the template + var clearNavigation = ""; + // From Cmdlet Help: Specify a JSON configuration file to configure the extraction progress. + var configuration = ""; + + var results = scope.ExecuteCommand("Apply-PnPTenantTemplate", + new CommandParameter("Path", path), + new CommandParameter("Template", template), + new CommandParameter("SequenceId", sequenceId), + new CommandParameter("ResourceFolder", resourceFolder), + new CommandParameter("Handlers", handlers), + new CommandParameter("ExcludeHandlers", excludeHandlers), + new CommandParameter("ExtensibilityHandlers", extensibilityHandlers), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions), + new CommandParameter("Parameters", parameters), + new CommandParameter("OverwriteSystemPropertyBagValues", overwriteSystemPropertyBagValues), + new CommandParameter("IgnoreDuplicateDataRowErrors", ignoreDuplicateDataRowErrors), + new CommandParameter("ProvisionContentTypesToSubWebs", provisionContentTypesToSubWebs), + new CommandParameter("ProvisionFieldsToSubWebs", provisionFieldsToSubWebs), + new CommandParameter("ClearNavigation", clearNavigation), + new CommandParameter("Configuration", configuration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs b/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs index 05e3245b1..5dacd48ae 100644 --- a/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs +++ b/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class ExportClientSidePageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ExportPnPClientSidePageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Export-PnPClientSidePage",new CommandParameter("Identity", "null"),new CommandParameter("PersistBrandingFiles", "null"),new CommandParameter("Out", "null"),new CommandParameter("Force", "null"),new CommandParameter("Configuration", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page + var identity = ""; + // From Cmdlet Help: If specified referenced files will be exported to the current folder. + var persistBrandingFiles = ""; + // From Cmdlet Help: If specified the template will be saved to the file specified with this parameter. + var outVar = ""; + // From Cmdlet Help: Specify to override the question to overwrite a file if it already exists. + var force = ""; + // From Cmdlet Help: Specify a JSON configuration file to configure the extraction progress. + var configuration = ""; + + var results = scope.ExecuteCommand("Export-PnPClientSidePage", + new CommandParameter("Identity", identity), + new CommandParameter("PersistBrandingFiles", persistBrandingFiles), + new CommandParameter("Out", outVar), + new CommandParameter("Force", force), + new CommandParameter("Configuration", configuration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs b/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs index 856e964dc..f8df3b170 100644 --- a/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs +++ b/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class GetTenantSequenceSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantSequenceSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantSequenceSite",new CommandParameter("Sequence", "null"),new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The sequence to retrieve the site from + var sequence = ""; + // From Cmdlet Help: Optional Id of the site + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantSequenceSite", + new CommandParameter("Sequence", sequence), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs b/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs index b9db8d840..c17256bfd 100644 --- a/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs +++ b/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class GetTenantSequenceTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantSequenceTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPTenantSequence",new CommandParameter("Template", "null"),new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The template to retrieve the sequence from + var template = ""; + // From Cmdlet Help: Optional Id of the sequence + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPTenantSequence", + new CommandParameter("Template", template), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs index 2353c3d4a..996ac4356 100644 --- a/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class NewTenantSequenceCommunicationSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,45 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPTenantSequenceCommunicationSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPTenantSequenceCommunicationSite",new CommandParameter("Url", "null"),new CommandParameter("Title", "null"),new CommandParameter("Language", "null"),new CommandParameter("Owner", "null"),new CommandParameter("Description", "null"),new CommandParameter("Classification", "null"),new CommandParameter("SiteDesignId", "null"),new CommandParameter("HubSite", "null"),new CommandParameter("AllowFileSharingForGuestUsers", "null"),new CommandParameter("TemplateIds", "null")); + + // This is a mandatory parameter + var url = ""; + // This is a mandatory parameter + var title = ""; + var language = ""; + var owner = ""; + var description = ""; + var classification = ""; + var siteDesignId = ""; + var hubSite = ""; + var allowFileSharingForGuestUsers = ""; + var templateIds = ""; + + var results = scope.ExecuteCommand("New-PnPTenantSequenceCommunicationSite", + new CommandParameter("Url", url), + new CommandParameter("Title", title), + new CommandParameter("Language", language), + new CommandParameter("Owner", owner), + new CommandParameter("Description", description), + new CommandParameter("Classification", classification), + new CommandParameter("SiteDesignId", siteDesignId), + new CommandParameter("HubSite", hubSite), + new CommandParameter("AllowFileSharingForGuestUsers", allowFileSharingForGuestUsers), + new CommandParameter("TemplateIds", templateIds)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs index 65b061729..89d4b738f 100644 --- a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class NewTenantSequenceTeamNoGroupSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPTenantSequenceTeamNoGroupSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamNoGroupSite",new CommandParameter("Url", "null"),new CommandParameter("Title", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("Language", "null"),new CommandParameter("Owner", "null"),new CommandParameter("Description", "null"),new CommandParameter("HubSite", "null"),new CommandParameter("TemplateIds", "null")); + + // This is a mandatory parameter + var url = ""; + // This is a mandatory parameter + var title = ""; + // This is a mandatory parameter + var timeZoneId = ""; + var language = ""; + var owner = ""; + var description = ""; + var hubSite = ""; + var templateIds = ""; + + var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamNoGroupSite", + new CommandParameter("Url", url), + new CommandParameter("Title", title), + new CommandParameter("TimeZoneId", timeZoneId), + new CommandParameter("Language", language), + new CommandParameter("Owner", owner), + new CommandParameter("Description", description), + new CommandParameter("HubSite", hubSite), + new CommandParameter("TemplateIds", templateIds)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs index 0e3e902c9..c056b4cb3 100644 --- a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class NewTenantSequenceTeamNoGroupSubSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPTenantSequenceTeamNoGroupSubSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamNoGroupSubSite",new CommandParameter("Url", "null"),new CommandParameter("Title", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("Language", "null"),new CommandParameter("Description", "null"),new CommandParameter("TemplateIds", "null"),new CommandParameter("QuickLaunchDisabled", "null"),new CommandParameter("UseDifferentPermissionsFromParentSite", "null")); + + // This is a mandatory parameter + var url = ""; + // This is a mandatory parameter + var title = ""; + // This is a mandatory parameter + var timeZoneId = ""; + var language = ""; + var description = ""; + var templateIds = ""; + var quickLaunchDisabled = ""; + var useDifferentPermissionsFromParentSite = ""; + + var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamNoGroupSubSite", + new CommandParameter("Url", url), + new CommandParameter("Title", title), + new CommandParameter("TimeZoneId", timeZoneId), + new CommandParameter("Language", language), + new CommandParameter("Description", description), + new CommandParameter("TemplateIds", templateIds), + new CommandParameter("QuickLaunchDisabled", quickLaunchDisabled), + new CommandParameter("UseDifferentPermissionsFromParentSite", useDifferentPermissionsFromParentSite)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs index 653a6e3b4..5499ed7eb 100644 --- a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class NewTenantSequenceTeamSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,41 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPTenantSequenceTeamSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamSite",new CommandParameter("Alias", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Classification", "null"),new CommandParameter("Public", "null"),new CommandParameter("HubSite", "null"),new CommandParameter("TemplateIds", "null")); + + // This is a mandatory parameter + var alias = ""; + // This is a mandatory parameter + var title = ""; + var description = ""; + var displayName = ""; + var classification = ""; + var publicVar = ""; + var hubSite = ""; + var templateIds = ""; + + var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamSite", + new CommandParameter("Alias", alias), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("DisplayName", displayName), + new CommandParameter("Classification", classification), + new CommandParameter("Public", publicVar), + new CommandParameter("HubSite", hubSite), + new CommandParameter("TemplateIds", templateIds)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs index c7377e0d5..b1c2f8eb0 100644 --- a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class NewTenantSequenceTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPTenantSequenceTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPTenantSequence",new CommandParameter("Id", "null")); + + // From Cmdlet Help: Optional Id of the sequence + var id = ""; + + var results = scope.ExecuteCommand("New-PnPTenantSequence", + new CommandParameter("Id", id)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs index 56d4d0b8b..7d3b34a16 100644 --- a/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs +++ b/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class NewTenantTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void NewPnPTenantTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("New-PnPTenantTemplate",new CommandParameter("Author", "null"),new CommandParameter("Description", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Generator", "null")); + + var author = ""; + var description = ""; + var displayName = ""; + var generator = ""; + + var results = scope.ExecuteCommand("New-PnPTenantTemplate", + new CommandParameter("Author", author), + new CommandParameter("Description", description), + new CommandParameter("DisplayName", displayName), + new CommandParameter("Generator", generator)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs index a3a4f5afa..6f810a3e9 100644 --- a/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs +++ b/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class ReadTenantTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ReadPnPTenantTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Read-PnPTenantTemplate",new CommandParameter("Path", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Filename to read from, optionally including full path. + var path = ""; + // From Cmdlet Help: Allows you to specify ITemplateProviderExtension to execute while loading the template. + var templateProviderExtensions = ""; + + var results = scope.ExecuteCommand("Read-PnPTenantTemplate", + new CommandParameter("Path", path), + new CommandParameter("TemplateProviderExtensions", templateProviderExtensions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs index 8972a8352..9e918e2eb 100644 --- a/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs +++ b/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class SaveTenantTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SavePnPTenantTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Save-PnPTenantTemplate",new CommandParameter("Template", "null"),new CommandParameter("Out", "null"),new CommandParameter("Schema", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Allows you to provide an in-memory instance of a Tenant Template or a filename of a template file in XML format. When using this parameter, the -Out parameter refers to the path for saving the template and storing any supporting file for the template. + var template = ""; + // This is a mandatory parameter + // From Cmdlet Help: Filename to write to, optionally including full path. + var outVar = ""; + // From Cmdlet Help: The optional schema to use when creating the PnP file. Always defaults to the latest schema. + var schema = ""; + // From Cmdlet Help: Specifying the Force parameter will skip the confirmation question. + var force = ""; + + var results = scope.ExecuteCommand("Save-PnPTenantTemplate", + new CommandParameter("Template", template), + new CommandParameter("Out", outVar), + new CommandParameter("Schema", schema), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs index 7fdfd07de..5508eadc3 100644 --- a/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs +++ b/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant { - [TestClass] public class TestTenantTemplateTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void TestPnPTenantTemplateTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Test-PnPTenantTemplate",new CommandParameter("Template", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The in-memory template to test + var template = ""; + + var results = scope.ExecuteCommand("Test-PnPTenantTemplate", + new CommandParameter("Template", template)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs b/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs index b6664974b..5ed11885b 100644 --- a/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs +++ b/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class AddHtmlPublishingPageLayoutTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPHtmlPublishingPageLayoutTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPHtmlPublishingPageLayout",new CommandParameter("SourceFilePath", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("AssociatedContentTypeID", "null"),new CommandParameter("DestinationFolderHierarchy", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the file which will be uploaded + var sourceFilePath = ""; + // This is a mandatory parameter + // From Cmdlet Help: Title for the page layout + var title = ""; + // This is a mandatory parameter + // From Cmdlet Help: Description for the page layout + var description = ""; + // This is a mandatory parameter + // From Cmdlet Help: Associated content type ID + var associatedContentTypeID = ""; + // From Cmdlet Help: Folder hierarchy where the HTML page layouts will be deployed + var destinationFolderHierarchy = ""; + + var results = scope.ExecuteCommand("Add-PnPHtmlPublishingPageLayout", + new CommandParameter("SourceFilePath", sourceFilePath), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("AssociatedContentTypeID", associatedContentTypeID), + new CommandParameter("DestinationFolderHierarchy", destinationFolderHierarchy)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/AddPnPMasterPageTests.cs b/Tests/Publishing/AddPnPMasterPageTests.cs index 126090e7e..75473a56d 100644 --- a/Tests/Publishing/AddPnPMasterPageTests.cs +++ b/Tests/Publishing/AddPnPMasterPageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class AddMasterPageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,44 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPMasterPageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPMasterPage",new CommandParameter("SourceFilePath", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("DestinationFolderHierarchy", "null"),new CommandParameter("UIVersion", "null"),new CommandParameter("DefaultCssFile", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the file which will be uploaded + var sourceFilePath = ""; + // This is a mandatory parameter + // From Cmdlet Help: Title for the Masterpage + var title = ""; + // This is a mandatory parameter + // From Cmdlet Help: Description for the Masterpage + var description = ""; + // From Cmdlet Help: Folder hierarchy where the MasterPage will be deployed + var destinationFolderHierarchy = ""; + // From Cmdlet Help: UIVersion of the Masterpage. Default = 15 + var uIVersion = ""; + // From Cmdlet Help: Default CSS file for the MasterPage, this Url is SiteRelative + var defaultCssFile = ""; + + var results = scope.ExecuteCommand("Add-PnPMasterPage", + new CommandParameter("SourceFilePath", sourceFilePath), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("DestinationFolderHierarchy", destinationFolderHierarchy), + new CommandParameter("UIVersion", uIVersion), + new CommandParameter("DefaultCssFile", defaultCssFile)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs b/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs index b5da9a1ba..dea31846a 100644 --- a/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs +++ b/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class AddPublishingImageRenditionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPPublishingImageRenditionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPPublishingImageRendition",new CommandParameter("Name", "null"),new CommandParameter("Width", "null"),new CommandParameter("Height", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The display name of the Image Rendition. + var name = ""; + // This is a mandatory parameter + // From Cmdlet Help: The width of the Image Rendition. + var width = ""; + // This is a mandatory parameter + // From Cmdlet Help: The height of the Image Rendition. + var height = ""; + + var results = scope.ExecuteCommand("Add-PnPPublishingImageRendition", + new CommandParameter("Name", name), + new CommandParameter("Width", width), + new CommandParameter("Height", height)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs b/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs index 9de85945d..47d9066e4 100644 --- a/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs +++ b/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class AddPublishingPageLayoutTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,42 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPPublishingPageLayoutTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPPublishingPageLayout",new CommandParameter("SourceFilePath", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("AssociatedContentTypeID", "null"),new CommandParameter("DestinationFolderHierarchy", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Path to the file which will be uploaded + var sourceFilePath = ""; + // This is a mandatory parameter + // From Cmdlet Help: Title for the page layout + var title = ""; + // This is a mandatory parameter + // From Cmdlet Help: Description for the page layout + var description = ""; + // This is a mandatory parameter + // From Cmdlet Help: Associated content type ID + var associatedContentTypeID = ""; + // From Cmdlet Help: Folder hierarchy where the html page layouts will be deployed + var destinationFolderHierarchy = ""; + + var results = scope.ExecuteCommand("Add-PnPPublishingPageLayout", + new CommandParameter("SourceFilePath", sourceFilePath), + new CommandParameter("Title", title), + new CommandParameter("Description", description), + new CommandParameter("AssociatedContentTypeID", associatedContentTypeID), + new CommandParameter("DestinationFolderHierarchy", destinationFolderHierarchy)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/AddPnPPublishingPageTests.cs b/Tests/Publishing/AddPnPPublishingPageTests.cs index 40d426792..495c34565 100644 --- a/Tests/Publishing/AddPnPPublishingPageTests.cs +++ b/Tests/Publishing/AddPnPPublishingPageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class AddPublishingPageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,40 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPPublishingPageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPPublishingPage",new CommandParameter("PageName", "null"),new CommandParameter("FolderPath", "null"),new CommandParameter("PageTemplateName", "null"),new CommandParameter("Title", "null"),new CommandParameter("Publish", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The name of the page to be added as an aspx file + var pageName = ""; + // From Cmdlet Help: The site relative folder path of the page to be added + var folderPath = ""; + // This is a mandatory parameter + // From Cmdlet Help: The name of the page layout you want to use. Specify without the .aspx extension. So 'ArticleLeft' or 'BlankWebPartPage' + var pageTemplateName = ""; + // From Cmdlet Help: The title of the page + var title = ""; + // From Cmdlet Help: Publishes the page. Also Approves it if moderation is enabled on the Pages library. + var publish = ""; + + var results = scope.ExecuteCommand("Add-PnPPublishingPage", + new CommandParameter("PageName", pageName), + new CommandParameter("FolderPath", folderPath), + new CommandParameter("PageTemplateName", pageTemplateName), + new CommandParameter("Title", title), + new CommandParameter("Publish", publish)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/AddPnPWikiPageTests.cs b/Tests/Publishing/AddPnPWikiPageTests.cs index 5609b6efe..1227d2ec8 100644 --- a/Tests/Publishing/AddPnPWikiPageTests.cs +++ b/Tests/Publishing/AddPnPWikiPageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class AddWikiPageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPWikiPageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPWikiPage",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Content", "null"),new CommandParameter("Layout", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The server relative page URL + var serverRelativePageUrl = ""; + // This is a mandatory parameter + var content = ""; + // This is a mandatory parameter + var layoutVar = ""; + + var results = scope.ExecuteCommand("Add-PnPWikiPage", + new CommandParameter("ServerRelativePageUrl", serverRelativePageUrl), + new CommandParameter("Content", content), + new CommandParameter("Layout", layoutVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs b/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs index d51dad560..4e90380aa 100644 --- a/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs +++ b/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class GetPublishingImageRenditionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPPublishingImageRenditionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPPublishingImageRendition",new CommandParameter("Identity", "null")); + + // From Cmdlet Help: Id or name of an existing image rendition + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPPublishingImageRendition", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/GetPnPWikiPageContentTests.cs b/Tests/Publishing/GetPnPWikiPageContentTests.cs index c505d6f1e..534af35f3 100644 --- a/Tests/Publishing/GetPnPWikiPageContentTests.cs +++ b/Tests/Publishing/GetPnPWikiPageContentTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class GetWikiPageContentTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPWikiPageContentTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPWikiPageContent",new CommandParameter("ServerRelativePageUrl", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The server relative URL for the wiki page + var serverRelativePageUrl = ""; + + var results = scope.ExecuteCommand("Get-PnPWikiPageContent", + new CommandParameter("ServerRelativePageUrl", serverRelativePageUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs b/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs index 79b6da251..6403434a1 100644 --- a/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs +++ b/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class RemovePublishingImageRenditionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPPublishingImageRenditionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPPublishingImageRendition",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The display name or id of the Image Rendition. + var identity = ""; + // From Cmdlet Help: If provided, no confirmation will be asked to remove the Image Rendition. + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPPublishingImageRendition", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/RemovePnPWikiPageTests.cs b/Tests/Publishing/RemovePnPWikiPageTests.cs index a0b903169..8f9649248 100644 --- a/Tests/Publishing/RemovePnPWikiPageTests.cs +++ b/Tests/Publishing/RemovePnPWikiPageTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class RemoveWikiPageTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPWikiPageTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPWikiPage",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("SiteRelativePageUrl", "null")); + + // This is a mandatory parameter + var serverRelativePageUrl = ""; + // This is a mandatory parameter + var siteRelativePageUrl = ""; + + var results = scope.ExecuteCommand("Remove-PnPWikiPage", + new CommandParameter("ServerRelativePageUrl", serverRelativePageUrl), + new CommandParameter("SiteRelativePageUrl", siteRelativePageUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs b/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs index c1eabbf4e..25a0391b0 100644 --- a/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs +++ b/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class SetAvailablePageLayoutsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPAvailablePageLayoutsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPAvailablePageLayouts",new CommandParameter("PageLayouts", "null"),new CommandParameter("AllowAllPageLayouts", "null"),new CommandParameter("InheritPageLayouts", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: An array of page layout files to set as available page layouts for the site. + var pageLayoutVars = ""; + // This is a mandatory parameter + // From Cmdlet Help: An array of page layout files to set as available page layouts for the site. + var allowAllPageLayoutVars = ""; + // This is a mandatory parameter + // From Cmdlet Help: Set the available page layouts to inherit from the parent site. + var inheritPageLayoutVars = ""; + + var results = scope.ExecuteCommand("Set-PnPAvailablePageLayouts", + new CommandParameter("PageLayouts", pageLayoutVars), + new CommandParameter("AllowAllPageLayouts", allowAllPageLayoutVars), + new CommandParameter("InheritPageLayouts", inheritPageLayoutVars)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs b/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs index c1c8dee2e..5c10de9d5 100644 --- a/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs +++ b/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class SetDefaultPageLayoutTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPDefaultPageLayoutTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPDefaultPageLayout",new CommandParameter("Title", "null"),new CommandParameter("InheritFromParentSite", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Title of the page layout + var title = ""; + // This is a mandatory parameter + // From Cmdlet Help: Set the default page layout to be inherited from the parent site. + var inheritFromParentSite = ""; + + var results = scope.ExecuteCommand("Set-PnPDefaultPageLayout", + new CommandParameter("Title", title), + new CommandParameter("InheritFromParentSite", inheritFromParentSite)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Publishing/SetPnPWikiPageContentTests.cs b/Tests/Publishing/SetPnPWikiPageContentTests.cs index e64d3c50a..d54f8d10c 100644 --- a/Tests/Publishing/SetPnPWikiPageContentTests.cs +++ b/Tests/Publishing/SetPnPWikiPageContentTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Publishing { - [TestClass] public class SetWikiPageContentTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPWikiPageContentTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPWikiPageContent",new CommandParameter("Content", "null"),new CommandParameter("Path", "null"),new CommandParameter("ServerRelativePageUrl", "null")); + + // This is a mandatory parameter + var content = ""; + // This is a mandatory parameter + var path = ""; + // This is a mandatory parameter + // From Cmdlet Help: Site Relative Page Url + var serverRelativePageUrl = ""; + + var results = scope.ExecuteCommand("Set-PnPWikiPageContent", + new CommandParameter("Content", content), + new CommandParameter("Path", path), + new CommandParameter("ServerRelativePageUrl", serverRelativePageUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs b/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs index cfedacb3e..13b2cf5bf 100644 --- a/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs +++ b/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class ClearListItemAsRecordTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ClearPnPListItemAsRecordTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Clear-PnPListItemAsRecord",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + + var results = scope.ExecuteCommand("Clear-PnPListItemAsRecord", + new CommandParameter("List", list), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs b/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs index 59e9b5854..4843bd63d 100644 --- a/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs +++ b/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class DisableInPlaceRecordsManagementForSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPInPlaceRecordsManagementForSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Disable-PnPInPlaceRecordsManagementForSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs b/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs index aaefc9650..0e124e8da 100644 --- a/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs +++ b/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class EnableInPlaceRecordsManagementForSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPInPlaceRecordsManagementForSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Enable-PnPInPlaceRecordsManagementForSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs b/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs index 3c0aecd94..1b5aff160 100644 --- a/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs +++ b/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class GetInPlaceRecordsManagementTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPInPlaceRecordsManagementTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPInPlaceRecordsManagement"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs b/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs index 4b5fa9d41..6442fc5df 100644 --- a/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs +++ b/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class GetListRecordDeclarationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPListRecordDeclarationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPListRecordDeclaration",new CommandParameter("List", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The list to retrieve the record declaration settings for + var list = ""; + + var results = scope.ExecuteCommand("Get-PnPListRecordDeclaration", + new CommandParameter("List", list)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs b/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs index 073d25c43..62aebfa17 100644 --- a/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs +++ b/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class SetInPlaceRecordsManagementTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPInPlaceRecordsManagementTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPInPlaceRecordsManagement",new CommandParameter("Enabled", "null"),new CommandParameter("On", "null"),new CommandParameter("Off", "null")); + + // This is a mandatory parameter + var enabled = ""; + // This is a mandatory parameter + // From Cmdlet Help: Turn records management on + var on = ""; + // This is a mandatory parameter + // From Cmdlet Help: Turn records management off + var off = ""; + + var results = scope.ExecuteCommand("Set-PnPInPlaceRecordsManagement", + new CommandParameter("Enabled", enabled), + new CommandParameter("On", on), + new CommandParameter("Off", off)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs b/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs index 3097b843f..2534e6ec6 100644 --- a/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs +++ b/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class SetListItemAsRecordTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListItemAsRecordTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPListItemAsRecord",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("DeclarationDate", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + // From Cmdlet Help: The declaration date + var declarationDate = ""; + + var results = scope.ExecuteCommand("Set-PnPListItemAsRecord", + new CommandParameter("List", list), + new CommandParameter("Identity", identity), + new CommandParameter("DeclarationDate", declarationDate)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs b/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs index 5e0a9b9e0..7b344ddcf 100644 --- a/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs +++ b/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class SetListRecordDeclarationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPListRecordDeclarationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPListRecordDeclaration",new CommandParameter("List", "null"),new CommandParameter("ManualRecordDeclaration", "null"),new CommandParameter("AutoRecordDeclaration", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The List to set the manual record declaration settings for + var list = ""; + // From Cmdlet Help: Defines the manual record declaration setting for the lists + var manualRecordDeclaration = ""; + // From Cmdlet Help: Defines if you want to set auto record declaration on the list + var autoRecordDeclaration = ""; + + var results = scope.ExecuteCommand("Set-PnPListRecordDeclaration", + new CommandParameter("List", list), + new CommandParameter("ManualRecordDeclaration", manualRecordDeclaration), + new CommandParameter("AutoRecordDeclaration", autoRecordDeclaration)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs b/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs index 539c00510..fa466ae5d 100644 --- a/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs +++ b/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecordsManagement { - [TestClass] public class TestListItemIsRecordTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,31 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void TestPnPListItemIsRecordTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Test-PnPListItemIsRecord",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID, Title or Url of the list. + var list = ""; + // This is a mandatory parameter + // From Cmdlet Help: The ID of the listitem, or actual ListItem object + var identity = ""; + + var results = scope.ExecuteCommand("Test-PnPListItemIsRecord", + new CommandParameter("List", list), + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs b/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs index 996568d3e..f795ebfcd 100644 --- a/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs +++ b/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class ClearRecycleBinItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,36 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ClearPnPRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Clear-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("All", "null"),new CommandParameter("SecondStageOnly", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Id of the recycle bin item or the recycle bin item itself to permanently delete + var identity = ""; + // From Cmdlet Help: Clears all items + var all = ""; + // From Cmdlet Help: If provided, only all the items in the second stage recycle bin will be cleared + var secondStageOnly = ""; + // From Cmdlet Help: If provided, no confirmation will be asked to permanently delete the recycle bin item + var force = ""; + + var results = scope.ExecuteCommand("Clear-PnPRecycleBinItem", + new CommandParameter("Identity", identity), + new CommandParameter("All", all), + new CommandParameter("SecondStageOnly", secondStageOnly), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs b/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs index ab8a984c6..76ba6c248 100644 --- a/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs +++ b/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class ClearTenantRecycleBinItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ClearPnPTenantRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Clear-PnPTenantRecycleBinItem",new CommandParameter("Url", "null"),new CommandParameter("Wait", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Url of the site collection to permanently delete from the tenant recycle bin + var url = ""; + // From Cmdlet Help: If provided, the PowerShell execution will halt until the operation has completed + var wait = ""; + // From Cmdlet Help: If provided, no confirmation will be asked to permanently delete the site collection from the tenant recycle bin + var force = ""; + + var results = scope.ExecuteCommand("Clear-PnPTenantRecycleBinItem", + new CommandParameter("Url", url), + new CommandParameter("Wait", wait), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs b/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs index 9725e2f3a..1753a64a1 100644 --- a/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs +++ b/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class GetRecycleBinItemsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("FirstStage", "null"),new CommandParameter("SecondStage", "null"),new CommandParameter("RowLimit", "null")); + + // From Cmdlet Help: Returns a recycle bin item with a specific identity + var identity = ""; + // From Cmdlet Help: Return all items in the first stage recycle bin + var firstStage = ""; + // From Cmdlet Help: Return all items in the second stage recycle bin + var secondStage = ""; + // From Cmdlet Help: Limits return results to specified amount + var rowLimit = ""; + + var results = scope.ExecuteCommand("Get-PnPRecycleBinItem", + new CommandParameter("Identity", identity), + new CommandParameter("FirstStage", firstStage), + new CommandParameter("SecondStage", secondStage), + new CommandParameter("RowLimit", rowLimit)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs b/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs index 2246615d4..20092ff61 100644 --- a/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs +++ b/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class GetTenantRecycleBinItemsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPTenantRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPTenantRecycleBinItem"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs b/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs index 7cf874658..43adf281d 100644 --- a/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs +++ b/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class MoveRecycleBinItemsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void MovePnPRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Move-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: If provided, moves the item with the specific ID to the second stage recycle bin + var identity = ""; + // From Cmdlet Help: If provided, no confirmation will be asked to move the first stage recycle bin items to the second stage + var force = ""; + + var results = scope.ExecuteCommand("Move-PnPRecycleBinItem", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs b/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs index 46f54b75c..7f21dc438 100644 --- a/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs +++ b/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class RestoreRecycleBinItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,34 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RestorePnPRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Restore-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("All", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Id of the recycle bin item or the recycle bin item object itself to restore + var identity = ""; + // This is a mandatory parameter + // From Cmdlet Help: If provided all items will be stored + var all = ""; + // From Cmdlet Help: If provided, no confirmation will be asked to restore the recycle bin item + var force = ""; + + var results = scope.ExecuteCommand("Restore-PnPRecycleBinItem", + new CommandParameter("Identity", identity), + new CommandParameter("All", all), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs b/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs index 40ab83372..77067c681 100644 --- a/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs +++ b/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.RecycleBin { - [TestClass] public class RestoreTenantRecycleBinItemTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RestorePnPTenantRecycleBinItemTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Restore-PnPTenantRecycleBinItem",new CommandParameter("Url", "null"),new CommandParameter("Wait", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Url of the site collection to restore from the tenant recycle bin + var url = ""; + // From Cmdlet Help: If provided, the PowerShell execution will halt until the site restore process has completed + var wait = ""; + // From Cmdlet Help: If provided, no confirmation will be asked to restore the site collection from the tenant recycle bin + var force = ""; + + var results = scope.ExecuteCommand("Restore-PnPTenantRecycleBinItem", + new CommandParameter("Url", url), + new CommandParameter("Wait", wait), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/GetPnPSearchConfigurationTests.cs b/Tests/Search/GetPnPSearchConfigurationTests.cs index f5e583234..6bd7df2d2 100644 --- a/Tests/Search/GetPnPSearchConfigurationTests.cs +++ b/Tests/Search/GetPnPSearchConfigurationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class GetSearchConfigurationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,32 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSearchConfigurationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSearchConfiguration",new CommandParameter("Scope", "null"),new CommandParameter("Path", "null"),new CommandParameter("OutputFormat", "null")); + + // From Cmdlet Help: Scope to use. Either Web, Site, or Subscription. Defaults to Web + var scopeVar = ""; + // From Cmdlet Help: Local path where the search configuration will be saved + var path = ""; + // From Cmdlet Help: Output format for of the configuration. Defaults to complete XML + var outVarputFormat = ""; + + var results = scope.ExecuteCommand("Get-PnPSearchConfiguration", + new CommandParameter("Scope", scopeVar), + new CommandParameter("Path", path), + new CommandParameter("OutputFormat", outVarputFormat)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/GetPnPSearchCrawlLogTests.cs b/Tests/Search/GetPnPSearchCrawlLogTests.cs index 925326da4..5e6ed921b 100644 --- a/Tests/Search/GetPnPSearchCrawlLogTests.cs +++ b/Tests/Search/GetPnPSearchCrawlLogTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class GetSearchCrawlLogTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,44 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSearchCrawlLogTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSearchCrawlLog",new CommandParameter("LogLevel", "null"),new CommandParameter("RowLimit", "null"),new CommandParameter("Filter", "null"),new CommandParameter("ContentSource", "null"),new CommandParameter("StartDate", "null"),new CommandParameter("EndDate", "null"),new CommandParameter("RawFormat", "null")); + + // From Cmdlet Help: Filter what log entries to return (All, Success, Warning, Error). Defaults to All + var logLevel = ""; + // From Cmdlet Help: Number of entries to return. Defaults to 100. + var rowLimit = ""; + // From Cmdlet Help: Filter to limit what is being returned. Has to be a URL prefix for SharePoint content, and part of a user principal name for user profiles. Wildcard characters are not supported. + var filter = ""; + // From Cmdlet Help: Content to retrieve (Sites, User Profiles). Defaults to Sites. + var contentSource = ""; + // From Cmdlet Help: Start date to start getting entries from. Defaults to start of time. + var startDate = ""; + // From Cmdlet Help: End date to stop getting entries from. Default to current time. + var endDate = ""; + // From Cmdlet Help: Show raw crawl log data + var rawFormat = ""; + + var results = scope.ExecuteCommand("Get-PnPSearchCrawlLog", + new CommandParameter("LogLevel", logLevel), + new CommandParameter("RowLimit", rowLimit), + new CommandParameter("Filter", filter), + new CommandParameter("ContentSource", contentSource), + new CommandParameter("StartDate", startDate), + new CommandParameter("EndDate", endDate), + new CommandParameter("RawFormat", rawFormat)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/GetPnPSearchSettingsTests.cs b/Tests/Search/GetPnPSearchSettingsTests.cs index 32cc7d945..da8bc5185 100644 --- a/Tests/Search/GetPnPSearchSettingsTests.cs +++ b/Tests/Search/GetPnPSearchSettingsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class GetSearchSettingsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSearchSettingsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPSearchSettings"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs b/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs index 66a318f22..cc45c80e9 100644 --- a/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs +++ b/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class GetSiteSearchQueryResultsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,35 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteSearchQueryResultsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSiteSearchQueryResults",new CommandParameter("Query", "null"),new CommandParameter("StartRow", "null"),new CommandParameter("MaxResults", "null"),new CommandParameter("All", "null")); + + // From Cmdlet Help: Search query in Keyword Query Language (KQL) to execute to refine the returned sites. If omitted, all indexed sites will be returned. + var query = ""; + // From Cmdlet Help: Search result item to start returning the results from. Useful for paging. Leave at 0 to return all results. + var startRow = ""; + // From Cmdlet Help: Maximum amount of search results to return. Default and max is 500 search results. + var maxResults = ""; + // From Cmdlet Help: Automatically page results until the end to get more than 500 sites. Use with caution! + var all = ""; + + var results = scope.ExecuteCommand("Get-PnPSiteSearchQueryResults", + new CommandParameter("Query", query), + new CommandParameter("StartRow", startRow), + new CommandParameter("MaxResults", maxResults), + new CommandParameter("All", all)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/RemovePnPSearchConfigurationTests.cs b/Tests/Search/RemovePnPSearchConfigurationTests.cs index a7a83ea53..616403ad0 100644 --- a/Tests/Search/RemovePnPSearchConfigurationTests.cs +++ b/Tests/Search/RemovePnPSearchConfigurationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class RemoveSearchConfigurationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPSearchConfigurationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPSearchConfiguration",new CommandParameter("Configuration", "null"),new CommandParameter("Path", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Search configuration string + var configuration = ""; + // This is a mandatory parameter + // From Cmdlet Help: Path to a search configuration + var path = ""; + var scopeVar = ""; + + var results = scope.ExecuteCommand("Remove-PnPSearchConfiguration", + new CommandParameter("Configuration", configuration), + new CommandParameter("Path", path), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/SetPnPSearchConfigurationTests.cs b/Tests/Search/SetPnPSearchConfigurationTests.cs index 5cb94d0ce..825df151d 100644 --- a/Tests/Search/SetPnPSearchConfigurationTests.cs +++ b/Tests/Search/SetPnPSearchConfigurationTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class SetSearchConfigurationTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,33 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPSearchConfigurationTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPSearchConfiguration",new CommandParameter("Configuration", "null"),new CommandParameter("Path", "null"),new CommandParameter("Scope", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Search configuration string + var configuration = ""; + // This is a mandatory parameter + // From Cmdlet Help: Path to a search configuration + var path = ""; + var scopeVar = ""; + + var results = scope.ExecuteCommand("Set-PnPSearchConfiguration", + new CommandParameter("Configuration", configuration), + new CommandParameter("Path", path), + new CommandParameter("Scope", scopeVar)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/SetPnPSearchSettingsTests.cs b/Tests/Search/SetPnPSearchSettingsTests.cs index bc8abdf63..76017e7c9 100644 --- a/Tests/Search/SetPnPSearchSettingsTests.cs +++ b/Tests/Search/SetPnPSearchSettingsTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class SetSearchSettingsTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,38 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPSearchSettingsTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPSearchSettings",new CommandParameter("SearchBoxInNavBar", "null"),new CommandParameter("SearchPageUrl", "null"),new CommandParameter("SearchScope", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Force", "null")); + + // From Cmdlet Help: Set the scope of which the suite bar search box shows. Possible values: Inherit, AllPages, ModernOnly, Hidden + var searchBoxInNavBar = ""; + // From Cmdlet Help: Set the URL where the search box should redirect to. + var searchPageUrl = ""; + // From Cmdlet Help: Set the search scope of the suite bar search box. Possible values: DefaultScope, Tenant, Hub, Site + var searchScope = ""; + // From Cmdlet Help: Scope to apply the setting to. Possible values: Web (default), Site\r\n\r\nFor a root site, the scope does not matter. + var scopeVar = ""; + // From Cmdlet Help: Do not ask for confirmation. + var force = ""; + + var results = scope.ExecuteCommand("Set-PnPSearchSettings", + new CommandParameter("SearchBoxInNavBar", searchBoxInNavBar), + new CommandParameter("SearchPageUrl", searchPageUrl), + new CommandParameter("SearchScope", searchScope), + new CommandParameter("Scope", scopeVar), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Search/SubmitPnPSearchQueryTests.cs b/Tests/Search/SubmitPnPSearchQueryTests.cs index 793ec41bf..ef168f906 100644 --- a/Tests/Search/SubmitPnPSearchQueryTests.cs +++ b/Tests/Search/SubmitPnPSearchQueryTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Search { - [TestClass] public class SubmitSearchQueryTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,96 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SubmitPnPSearchQueryTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Submit-PnPSearchQuery",new CommandParameter("Query", "null"),new CommandParameter("StartRow", "null"),new CommandParameter("MaxResults", "null"),new CommandParameter("All", "null"),new CommandParameter("TrimDuplicates", "null"),new CommandParameter("Properties", "null"),new CommandParameter("Refiners", "null"),new CommandParameter("Culture", "null"),new CommandParameter("QueryTemplate", "null"),new CommandParameter("SelectProperties", "null"),new CommandParameter("RefinementFilters", "null"),new CommandParameter("SortList", "null"),new CommandParameter("RankingModelId", "null"),new CommandParameter("ClientType", "null"),new CommandParameter("CollapseSpecification", "null"),new CommandParameter("HiddenConstraints", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("EnablePhonetic", "null"),new CommandParameter("EnableStemming", "null"),new CommandParameter("EnableQueryRules", "null"),new CommandParameter("SourceId", "null"),new CommandParameter("ProcessBestBets", "null"),new CommandParameter("ProcessPersonalFavorites", "null"),new CommandParameter("RelevantResults", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Search query in Keyword Query Language (KQL). + var query = ""; + // From Cmdlet Help: Search result item to start returning the results from. Useful for paging. Leave at 0 to return all results. + var startRow = ""; + // From Cmdlet Help: Maximum amount of search results to return. Default and max per page is 500 search results. + var maxResults = ""; + // From Cmdlet Help: Automatically page results until the end to get more than 500. Use with caution! + var all = ""; + // From Cmdlet Help: Specifies whether near duplicate items should be removed from the search results. + var trimDuplicates = ""; + // From Cmdlet Help: Extra query properties. Can for example be used for Office Graph queries. + var properties = ""; + // From Cmdlet Help: The list of refiners to be returned in a search result. + var refiners = ""; + // From Cmdlet Help: The locale for the query. + var culture = ""; + // From Cmdlet Help: Specifies the query template that is used at run time to transform the query based on user input. + var queryTemplate = ""; + // From Cmdlet Help: The list of properties to return in the search results. + var selectProperties = ""; + // From Cmdlet Help: The set of refinement filters used. + var refinementFilters = ""; + // From Cmdlet Help: The list of properties by which the search results are ordered. + var sortList = ""; + // From Cmdlet Help: The identifier (ID) of the ranking model to use for the query. + var rankingModelId = ""; + // From Cmdlet Help: Specifies the name of the client which issued the query. + var clientType = ""; + // From Cmdlet Help: Limit the number of items per the collapse specification. See https://docs.microsoft.com/en-us/sharepoint/dev/general-development/customizing-search-results-in-sharepoint#collapse-similar-search-results-using-the-collapsespecification-property for more information. + var collapseSpecification = ""; + // From Cmdlet Help: The keyword query’s hidden constraints. + var hiddenConstraints = ""; + // From Cmdlet Help: The identifier for the search query time zone. + var timeZoneId = ""; + // From Cmdlet Help: Specifies whether the phonetic forms of the query terms are used to find matches. + var enablePhonetic = ""; + // From Cmdlet Help: Specifies whether stemming is enabled. + var enableStemming = ""; + // From Cmdlet Help: Specifies whether Query Rules are enabled for this query. + var enableQueryRules = ""; + // From Cmdlet Help: Specifies the identifier (ID or name) of the result source to be used to run the query. + var sourceId = ""; + // From Cmdlet Help: Determines whether Best Bets are enabled. + var processBestBets = ""; + // From Cmdlet Help: Determines whether personal favorites data is processed or not. + var processPersonalFavorites = ""; + // From Cmdlet Help: Specifies whether only relevant results are returned + var relevantResults = ""; + + var results = scope.ExecuteCommand("Submit-PnPSearchQuery", + new CommandParameter("Query", query), + new CommandParameter("StartRow", startRow), + new CommandParameter("MaxResults", maxResults), + new CommandParameter("All", all), + new CommandParameter("TrimDuplicates", trimDuplicates), + new CommandParameter("Properties", properties), + new CommandParameter("Refiners", refiners), + new CommandParameter("Culture", culture), + new CommandParameter("QueryTemplate", queryTemplate), + new CommandParameter("SelectProperties", selectProperties), + new CommandParameter("RefinementFilters", refinementFilters), + new CommandParameter("SortList", sortList), + new CommandParameter("RankingModelId", rankingModelId), + new CommandParameter("ClientType", clientType), + new CommandParameter("CollapseSpecification", collapseSpecification), + new CommandParameter("HiddenConstraints", hiddenConstraints), + new CommandParameter("TimeZoneId", timeZoneId), + new CommandParameter("EnablePhonetic", enablePhonetic), + new CommandParameter("EnableStemming", enableStemming), + new CommandParameter("EnableQueryRules", enableQueryRules), + new CommandParameter("SourceId", sourceId), + new CommandParameter("ProcessBestBets", processBestBets), + new CommandParameter("ProcessPersonalFavorites", processPersonalFavorites), + new CommandParameter("RelevantResults", relevantResults)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/AddPnPRoleDefinitionTests.cs b/Tests/Site/AddPnPRoleDefinitionTests.cs index b6791fc13..63576f05b 100644 --- a/Tests/Site/AddPnPRoleDefinitionTests.cs +++ b/Tests/Site/AddPnPRoleDefinitionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class AddRoleDefinitionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,39 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPRoleDefinitionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPRoleDefinition",new CommandParameter("RoleName", "null"),new CommandParameter("Clone", "null"),new CommandParameter("Include", "null"),new CommandParameter("Exclude", "null"),new CommandParameter("Description", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Name of new permission level. + var roleName = ""; + // From Cmdlet Help: An existing permission level or the name of an permission level to clone as base template. + var clone = ""; + // From Cmdlet Help: Specifies permission flags(s) to enable. Please visit https://docs.microsoft.com/previous-versions/office/sharepoint-csom/ee536458(v%3Doffice.15) for the PermissionKind enum + var include = ""; + // From Cmdlet Help: Specifies permission flags(s) to disable. Please visit https://docs.microsoft.com/previous-versions/office/sharepoint-csom/ee536458(v%3Doffice.15) for the PermissionKind enum + var exclude = ""; + // From Cmdlet Help: Optional description for the new permission level. + var description = ""; + + var results = scope.ExecuteCommand("Add-PnPRoleDefinition", + new CommandParameter("RoleName", roleName), + new CommandParameter("Clone", clone), + new CommandParameter("Include", include), + new CommandParameter("Exclude", exclude), + new CommandParameter("Description", description)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/AddPnPSiteCollectionAdminTests.cs b/Tests/Site/AddPnPSiteCollectionAdminTests.cs index 80193ecc9..ea6a6717b 100644 --- a/Tests/Site/AddPnPSiteCollectionAdminTests.cs +++ b/Tests/Site/AddPnPSiteCollectionAdminTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class AddSiteCollectionAdminTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPSiteCollectionAdminTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPSiteCollectionAdmin",new CommandParameter("Owners", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies owner(s) to add as site collection administrators. They will be added as additional site collection administrators to the site in the current context. Existing administrators will stay. Can be both users and groups. + var owners = ""; + + var results = scope.ExecuteCommand("Add-PnPSiteCollectionAdmin", + new CommandParameter("Owners", owners)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/AddPnPTeamsTeamTests.cs b/Tests/Site/AddPnPTeamsTeamTests.cs index d3ca0887d..4a709e78a 100644 --- a/Tests/Site/AddPnPTeamsTeamTests.cs +++ b/Tests/Site/AddPnPTeamsTeamTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class AddTeamsTeamTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPTeamsTeamTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Add-PnPTeamsTeam"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs b/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs index 31fcd87a5..5af28a9f5 100644 --- a/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs +++ b/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class DisableSharingForNonOwnersOfSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,25 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void DisablePnPSharingForNonOwnersOfSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Disable-PnPSharingForNonOwnersOfSite",new CommandParameter("Identity", "null")); + + var identity = ""; + + var results = scope.ExecuteCommand("Disable-PnPSharingForNonOwnersOfSite", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/EnablePnPCommSiteTests.cs b/Tests/Site/EnablePnPCommSiteTests.cs index 898d4d7f8..152b44f64 100644 --- a/Tests/Site/EnablePnPCommSiteTests.cs +++ b/Tests/Site/EnablePnPCommSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class EnableCommSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void EnablePnPCommSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Enable-PnPCommSite",new CommandParameter("DesignPackageId", "null")); + + // From Cmdlet Help: The id (guid) of the design package to apply: 96c933ac-3698-44c7-9f4a-5fd17d71af9e (Topic = default), 6142d2a0-63a5-4ba0-aede-d9fefca2c767 (Showcase) or f6cc5403-0d63-442e-96c0-285923709ffc (Blank) + var designPackageId = ""; + + var results = scope.ExecuteCommand("Enable-PnPCommSite", + new CommandParameter("DesignPackageId", designPackageId)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/GetPnPAuditingTests.cs b/Tests/Site/GetPnPAuditingTests.cs index f64c1f6b3..20470d8a3 100644 --- a/Tests/Site/GetPnPAuditingTests.cs +++ b/Tests/Site/GetPnPAuditingTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class GetAuditingTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPAuditingTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPAuditing"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/GetPnPRoleDefinitionTests.cs b/Tests/Site/GetPnPRoleDefinitionTests.cs index a73784d7b..982282e40 100644 --- a/Tests/Site/GetPnPRoleDefinitionTests.cs +++ b/Tests/Site/GetPnPRoleDefinitionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class GetRoleDefinitionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,26 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPRoleDefinitionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPRoleDefinition",new CommandParameter("Identity", "null")); + + // From Cmdlet Help: The name of a role definition to retrieve. + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPRoleDefinition", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs b/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs index 177cd1e8c..cef0d0204 100644 --- a/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs +++ b/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class GetSharingForNonOwnersOfSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,25 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSharingForNonOwnersOfSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSharingForNonOwnersOfSite",new CommandParameter("Identity", "null")); + + var identity = ""; + + var results = scope.ExecuteCommand("Get-PnPSharingForNonOwnersOfSite", + new CommandParameter("Identity", identity)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/GetPnPSiteCollectionAdminTests.cs b/Tests/Site/GetPnPSiteCollectionAdminTests.cs index 077ffd73d..a2895baf2 100644 --- a/Tests/Site/GetPnPSiteCollectionAdminTests.cs +++ b/Tests/Site/GetPnPSiteCollectionAdminTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class GetSiteCollectionAdminTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteCollectionAdminTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPSiteCollectionAdmin"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/GetPnPSiteTests.cs b/Tests/Site/GetPnPSiteTests.cs index 1c2664980..e74fb3ffa 100644 --- a/Tests/Site/GetPnPSiteTests.cs +++ b/Tests/Site/GetPnPSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class GetSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,23 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters + + var results = scope.ExecuteCommand("Get-PnPSite"); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/InstallPnPSolutionTests.cs b/Tests/Site/InstallPnPSolutionTests.cs index f22150ae2..2b47f4d4e 100644 --- a/Tests/Site/InstallPnPSolutionTests.cs +++ b/Tests/Site/InstallPnPSolutionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class InstallSolutionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void InstallPnPSolutionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Install-PnPSolution",new CommandParameter("PackageId", "null"),new CommandParameter("SourceFilePath", "null"),new CommandParameter("MajorVersion", "null"),new CommandParameter("MinorVersion", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: ID of the solution, from the solution manifest + var packageId = ""; + // This is a mandatory parameter + // From Cmdlet Help: Path to the sandbox solution package (.WSP) file + var sourceFilePath = ""; + // From Cmdlet Help: Optional major version of the solution, defaults to 1 + var majorVersion = ""; + // From Cmdlet Help: Optional minor version of the solution, defaults to 0 + var minorVersion = ""; + + var results = scope.ExecuteCommand("Install-PnPSolution", + new CommandParameter("PackageId", packageId), + new CommandParameter("SourceFilePath", sourceFilePath), + new CommandParameter("MajorVersion", majorVersion), + new CommandParameter("MinorVersion", minorVersion)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/RemovePnPRoleDefinitionTests.cs b/Tests/Site/RemovePnPRoleDefinitionTests.cs index 66a6906fb..0bc0680bd 100644 --- a/Tests/Site/RemovePnPRoleDefinitionTests.cs +++ b/Tests/Site/RemovePnPRoleDefinitionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class RemoveRoleDefinitionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPRoleDefinitionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPRoleDefinition",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The identity of the role definition, either a RoleDefinition object or a the name of roledefinition + var identity = ""; + // From Cmdlet Help: Do not ask for confirmation to delete the role definition + var force = ""; + + var results = scope.ExecuteCommand("Remove-PnPRoleDefinition", + new CommandParameter("Identity", identity), + new CommandParameter("Force", force)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/RemovePnPSiteCollectionAdminTests.cs b/Tests/Site/RemovePnPSiteCollectionAdminTests.cs index 98b53ec28..ca220cd3a 100644 --- a/Tests/Site/RemovePnPSiteCollectionAdminTests.cs +++ b/Tests/Site/RemovePnPSiteCollectionAdminTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class RemoveSiteCollectionAdminTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void RemovePnPSiteCollectionAdminTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Remove-PnPSiteCollectionAdmin",new CommandParameter("Owners", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies owner(s) to remove as site collection administrators. Can be both users and groups. + var owners = ""; + + var results = scope.ExecuteCommand("Remove-PnPSiteCollectionAdmin", + new CommandParameter("Owners", owners)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/SetPnPAppSideLoadingTests.cs b/Tests/Site/SetPnPAppSideLoadingTests.cs index b99bd2516..92c81727d 100644 --- a/Tests/Site/SetPnPAppSideLoadingTests.cs +++ b/Tests/Site/SetPnPAppSideLoadingTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class SetAppSideLoadingTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPAppSideLoadingTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPAppSideLoading",new CommandParameter("On", "null"),new CommandParameter("Off", "null")); + + // This is a mandatory parameter + var on = ""; + // This is a mandatory parameter + var off = ""; + + var results = scope.ExecuteCommand("Set-PnPAppSideLoading", + new CommandParameter("On", on), + new CommandParameter("Off", off)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/SetPnPAuditingTests.cs b/Tests/Site/SetPnPAuditingTests.cs index 30fbbeaa1..2f59af239 100644 --- a/Tests/Site/SetPnPAuditingTests.cs +++ b/Tests/Site/SetPnPAuditingTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class SetAuditingTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,58 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPAuditingTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPAuditing",new CommandParameter("EnableAll", "null"),new CommandParameter("DisableAll", "null"),new CommandParameter("RetentionTime", "null"),new CommandParameter("TrimAuditLog", "null"),new CommandParameter("EditItems", "null"),new CommandParameter("CheckOutCheckInItems", "null"),new CommandParameter("MoveCopyItems", "null"),new CommandParameter("DeleteRestoreItems", "null"),new CommandParameter("EditContentTypesColumns", "null"),new CommandParameter("SearchContent", "null"),new CommandParameter("EditUsersPermissions", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Enable all audit flags + var enableAll = ""; + // This is a mandatory parameter + // From Cmdlet Help: Disable all audit flags + var disableAll = ""; + // From Cmdlet Help: Set the retention time + var retentionTime = ""; + // From Cmdlet Help: Trim the audit log + var trimAuditLog = ""; + // From Cmdlet Help: Audit editing items + var editItems = ""; + // From Cmdlet Help: Audit checking out or checking in items + var checkOutCheckInItems = ""; + // From Cmdlet Help: Audit moving or copying items to another location in the site. + var moveCopyItems = ""; + // From Cmdlet Help: Audit deleting or restoring items + var deleteRestoreItems = ""; + // From Cmdlet Help: Audit editing content types and columns + var editContentTypesColumns = ""; + // From Cmdlet Help: Audit searching site content + var searchContent = ""; + // From Cmdlet Help: Audit editing users and permissions + var editUsersPermissions = ""; + + var results = scope.ExecuteCommand("Set-PnPAuditing", + new CommandParameter("EnableAll", enableAll), + new CommandParameter("DisableAll", disableAll), + new CommandParameter("RetentionTime", retentionTime), + new CommandParameter("TrimAuditLog", trimAuditLog), + new CommandParameter("EditItems", editItems), + new CommandParameter("CheckOutCheckInItems", checkOutCheckInItems), + new CommandParameter("MoveCopyItems", moveCopyItems), + new CommandParameter("DeleteRestoreItems", deleteRestoreItems), + new CommandParameter("EditContentTypesColumns", editContentTypesColumns), + new CommandParameter("SearchContent", searchContent), + new CommandParameter("EditUsersPermissions", editUsersPermissions)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/SetPnPSiteTests.cs b/Tests/Site/SetPnPSiteTests.cs index 81670305d..5df308810 100644 --- a/Tests/Site/SetPnPSiteTests.cs +++ b/Tests/Site/SetPnPSiteTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class SetSiteTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,92 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void SetPnPSiteTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Set-PnPSite",new CommandParameter("Identity", "null"),new CommandParameter("Classification", "null"),new CommandParameter("DisableFlows", "null"),new CommandParameter("LogoFilePath", "null"),new CommandParameter("Sharing", "null"),new CommandParameter("StorageMaximumLevel", "null"),new CommandParameter("StorageWarningLevel", "null"),new CommandParameter("UserCodeMaximumLevel", "null"),new CommandParameter("UserCodeWarningLevel", "null"),new CommandParameter("LockState", "null"),new CommandParameter("AllowSelfServiceUpgrade", "null"),new CommandParameter("NoScriptSite", "null"),new CommandParameter("Owners", "null"),new CommandParameter("CommentsOnSitePagesDisabled", "null"),new CommandParameter("DefaultLinkPermission", "null"),new CommandParameter("DefaultSharingLinkType", "null"),new CommandParameter("DisableAppViews", "null"),new CommandParameter("DisableCompanyWideSharingLinks", "null"),new CommandParameter("DisableSharingForNonOwners", "null"),new CommandParameter("LocaleId", "null"),new CommandParameter("NewUrl", "null"),new CommandParameter("RestrictedToGeo", "null"),new CommandParameter("SocialBarOnSitePagesDisabled", "null"),new CommandParameter("Wait", "null")); + + var identity = ""; + // From Cmdlet Help: The classification to set + var classification = ""; + // From Cmdlet Help: Disables Microsoft Flow for this site + var disableFlows = ""; + // From Cmdlet Help: Sets the logo of the site if it concerns a modern team site. Provide a full path to a local image file on your disk which you want to use as the site logo. The logo will be uploaded automatically to SharePoint. If you want to set the logo for a classic site, use Set-PnPWeb -SiteLogoUrl. + var logoFilePath = ""; + // From Cmdlet Help: Specifies what the sharing capabilities are for the site. Possible values: Disabled, ExternalUserSharingOnly, ExternalUserAndGuestSharing, ExistingExternalUserSharingOnly + var sharing = ""; + // From Cmdlet Help: Specifies the storage quota for this site collection in megabytes. This value must not exceed the company's available quota. + var storageMaximumLevel = ""; + // From Cmdlet Help: Specifies the warning level for the storage quota in megabytes. This value must not exceed the values set for the StorageMaximumLevel parameter + var storageWarningLevel = ""; + // From Cmdlet Help: Specifies the quota for this site collection in Sandboxed Solutions units. This value must not exceed the company's aggregate available Sandboxed Solutions quota. The default value is 0. For more information, see Resource Usage Limits on Sandboxed Solutions in SharePoint 2010 : http://msdn.microsoft.com/en-us/library/gg615462.aspx. + var userCodeMaximumLevel = ""; + // From Cmdlet Help: Specifies the warning level for the resource quota. This value must not exceed the value set for the UserCodeMaximumLevel parameter + var userCodeWarningLevel = ""; + // From Cmdlet Help: Sets the lockstate of a site + var lockState = ""; + // From Cmdlet Help: Specifies if the site administrator can upgrade the site collection + var allowSelfServiceUpgrade = ""; + // From Cmdlet Help: Specifies if a site allows custom script or not. See https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f for more information. + var noScriptSite = ""; + // From Cmdlet Help: Specifies owner(s) to add as site collection administrators. They will be added as additional site collection administrators. Existing administrators will stay. Can be both users and groups. + var owners = ""; + // From Cmdlet Help: Specifies if comments on site pages are enabled or disabled + var commentsOnSitePagesDisabled = ""; + // From Cmdlet Help: Specifies the default link permission for the site collection. None - Respect the organization default link permission. View - Sets the default link permission for the site to "view" permissions. Edit - Sets the default link permission for the site to "edit" permissions + var defaultLinkPermission = ""; + // From Cmdlet Help: Specifies the default link type for the site collection. None - Respect the organization default sharing link type. AnonymousAccess - Sets the default sharing link for this site to an Anonymous Access or Anyone link. Internal - Sets the default sharing link for this site to the "organization" link or company shareable link. Direct - Sets the default sharing link for this site to the "Specific people" link + var defaultSharingLinkType = ""; + var disableAppViews = ""; + var disableCompanyWideSharingLinks = ""; + // From Cmdlet Help: Specifies to prevent non-owners from inviting new users to the site + var disableSharingForNonOwners = ""; + // From Cmdlet Help: Specifies the language of this site collection. + var localeId = ""; + // From Cmdlet Help: Specifies the new URL for this site collection. + var newUrl = ""; + // From Cmdlet Help: Specifies the Geo/Region restrictions of this site. + var restrictedToGeo = ""; + // From Cmdlet Help: Disables or enables the Social Bar for Site Collection. + var socialBarOnSitePagesDisabled = ""; + // From Cmdlet Help: Wait for the operation to complete + var wait = ""; + + var results = scope.ExecuteCommand("Set-PnPSite", + new CommandParameter("Identity", identity), + new CommandParameter("Classification", classification), + new CommandParameter("DisableFlows", disableFlows), + new CommandParameter("LogoFilePath", logoFilePath), + new CommandParameter("Sharing", sharing), + new CommandParameter("StorageMaximumLevel", storageMaximumLevel), + new CommandParameter("StorageWarningLevel", storageWarningLevel), + new CommandParameter("UserCodeMaximumLevel", userCodeMaximumLevel), + new CommandParameter("UserCodeWarningLevel", userCodeWarningLevel), + new CommandParameter("LockState", lockState), + new CommandParameter("AllowSelfServiceUpgrade", allowSelfServiceUpgrade), + new CommandParameter("NoScriptSite", noScriptSite), + new CommandParameter("Owners", owners), + new CommandParameter("CommentsOnSitePagesDisabled", commentsOnSitePagesDisabled), + new CommandParameter("DefaultLinkPermission", defaultLinkPermission), + new CommandParameter("DefaultSharingLinkType", defaultSharingLinkType), + new CommandParameter("DisableAppViews", disableAppViews), + new CommandParameter("DisableCompanyWideSharingLinks", disableCompanyWideSharingLinks), + new CommandParameter("DisableSharingForNonOwners", disableSharingForNonOwners), + new CommandParameter("LocaleId", localeId), + new CommandParameter("NewUrl", newUrl), + new CommandParameter("RestrictedToGeo", restrictedToGeo), + new CommandParameter("SocialBarOnSitePagesDisabled", socialBarOnSitePagesDisabled), + new CommandParameter("Wait", wait)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs b/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs index 09d7b3c63..84609536f 100644 --- a/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs +++ b/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class AddOffice365GroupAliasIsUsedTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void TestPnPOffice365GroupAliasIsUsedTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Test-PnPOffice365GroupAliasIsUsed",new CommandParameter("Alias", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: Specifies the alias of the group. Cannot contain spaces. + var alias = ""; + + var results = scope.ExecuteCommand("Test-PnPOffice365GroupAliasIsUsed", + new CommandParameter("Alias", alias)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Site/UninstallPnPSolutionTests.cs b/Tests/Site/UninstallPnPSolutionTests.cs index 09f410141..0249df147 100644 --- a/Tests/Site/UninstallPnPSolutionTests.cs +++ b/Tests/Site/UninstallPnPSolutionTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Site { - [TestClass] public class UninstallSolutionTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,37 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void UninstallPnPSolutionTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Uninstall-PnPSolution",new CommandParameter("PackageId", "null"),new CommandParameter("PackageName", "null"),new CommandParameter("MajorVersion", "null"),new CommandParameter("MinorVersion", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: ID of the solution, from the solution manifest + var packageId = ""; + // This is a mandatory parameter + // From Cmdlet Help: Filename of the WSP file to uninstall + var packageName = ""; + // From Cmdlet Help: Optional major version of the solution, defaults to 1 + var majorVersion = ""; + // From Cmdlet Help: Optional minor version of the solution, defaults to 0 + var minorVersion = ""; + + var results = scope.ExecuteCommand("Uninstall-PnPSolution", + new CommandParameter("PackageId", packageId), + new CommandParameter("PackageName", packageName), + new CommandParameter("MajorVersion", majorVersion), + new CommandParameter("MinorVersion", minorVersion)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs b/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs index 73a627cab..9f89db071 100644 --- a/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs +++ b/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.SiteDesigns { - [TestClass] public class AddSiteDesignTaskTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,30 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void AddPnPSiteDesignTaskTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Add-PnPSiteDesignTask",new CommandParameter("SiteDesignId", "null"),new CommandParameter("WebUrl", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The ID of the site design to apply. + var siteDesignId = ""; + // From Cmdlet Help: The URL of the site collection where the site design will be applied. If not specified the design will be applied to the site you connected to with Connect-PnPOnline. + var webUrl = ""; + + var results = scope.ExecuteCommand("Add-PnPSiteDesignTask", + new CommandParameter("SiteDesignId", siteDesignId), + new CommandParameter("WebUrl", webUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs b/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs index 4c833ecc5..a0e802670 100644 --- a/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs +++ b/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.SiteDesigns { - [TestClass] public class GetSiteDesignRunStatusTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,27 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteDesignRunStatusTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSiteDesignRunStatus",new CommandParameter("Run", "null")); + + // This is a mandatory parameter + // From Cmdlet Help: The site design run for the desired set of script action details. + var run = ""; + + var results = scope.ExecuteCommand("Get-PnPSiteDesignRunStatus", + new CommandParameter("Run", run)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs b/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs index d786bf9c4..f6dff257a 100644 --- a/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs +++ b/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.SiteDesigns { - [TestClass] public class GetSiteDesignRunTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteDesignRunTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSiteDesignRun",new CommandParameter("SiteDesignId", "null"),new CommandParameter("WebUrl", "null")); + + // From Cmdlet Help: The ID of the site design to apply. + var siteDesignId = ""; + // From Cmdlet Help: The URL of the site collection where the site design will be applied. If not specified the design will be applied to the site you connected to with Connect-PnPOnline. + var webUrl = ""; + + var results = scope.ExecuteCommand("Get-PnPSiteDesignRun", + new CommandParameter("SiteDesignId", siteDesignId), + new CommandParameter("WebUrl", webUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs b/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs index da9864f6d..6b55e89d2 100644 --- a/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs +++ b/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.SiteDesigns { - [TestClass] public class GetSiteDesignTaskTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,29 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void GetPnPSiteDesignTaskTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Get-PnPSiteDesignTask",new CommandParameter("Identity", "null"),new CommandParameter("WebUrl", "null")); + + // From Cmdlet Help: The ID of the site design task to retrieve. + var identity = ""; + // From Cmdlet Help: The URL of the site collection where the site design will be applied. If not specified the site design tasks will be returned for the site you connected to with Connect-PnPOnline. + var webUrl = ""; + + var results = scope.ExecuteCommand("Get-PnPSiteDesignTask", + new CommandParameter("Identity", identity), + new CommandParameter("WebUrl", webUrl)); + Assert.IsNotNull(results); } - } - - #endregion } } diff --git a/Tests/Taxonomy/ExportPnPTaxonomyTests.cs b/Tests/Taxonomy/ExportPnPTaxonomyTests.cs index 6243fd86d..3addbe7c4 100644 --- a/Tests/Taxonomy/ExportPnPTaxonomyTests.cs +++ b/Tests/Taxonomy/ExportPnPTaxonomyTests.cs @@ -4,11 +4,27 @@ namespace SharePointPnP.PowerShell.Tests.Taxonomy { - [TestClass] public class ExportTaxonomyTests { #region Test Setup/CleanUp + [ClassInitialize] + public static void Initialize(TestContext testContext) + { + // This runs on class level once before all tests run + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } + + [ClassCleanup] + public static void Cleanup(TestContext testContext) + { + // This runs on class level once + //using (var ctx = TestCommon.CreateClientContext()) + //{ + //} + } [TestInitialize] public void Initialize() @@ -27,7 +43,7 @@ public void Cleanup() { try { - + // Do Test Setup - Note, this runs PER test } catch (Exception) { @@ -35,28 +51,47 @@ public void Cleanup() } } } - #endregion #region Scaffolded Cmdlet Tests - - - //TODO: This is a scaffold of the cmdlet - complete the unit test //[TestMethod] public void ExportPnPTaxonomyTest() { - using (var scope = new PSTestScope(true)) { // Complete writing cmd parameters - var results = scope.ExecuteCommand("Export-PnPTaxonomy",new CommandParameter("TermSetId", "null"),new CommandParameter("IncludeID", "null"),new CommandParameter("Path", "null"),new CommandParameter("TermStoreName", "null"),new CommandParameter("Force", "null"),new CommandParameter("Delimiter", "null"),new CommandParameter("Lcid", "null"),new CommandParameter("Encoding", "null")); + + // From Cmdlet Help: If specified, will export the specified termset only + var termSetId = ""; + // From Cmdlet Help: If specified will include the ids of the taxonomy items in the output. Format: internal string UserAgent { get; set; } + internal ConnectionMethod ConnectionMethod { get; set; } /// @@ -60,11 +63,19 @@ public HttpClient HttpClient public static PnPConnection CurrentConnection { get; internal set; } public ConnectionType ConnectionType { get; protected set; } + public IPublicClientApplication PublicClientApp { get; internal set; } + public IConfidentialClientApplication ConfidentialClientApp { get; internal set; } + /// /// Indication for telemetry through which method a connection has been established /// public InitializationType InitializationType { get; protected set; } + /// + /// used to retrieve a new token in case the current token expires + /// + public string[] Scopes { get; internal set; } + /// /// If provided, it defines the minimal health score the SharePoint server should return back before executing requests on it. Use scale 0 - 10 where 0 is most health and 10 is least healthy. If set to NULL, no health score check will take place. /// @@ -141,24 +152,24 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles { GenericToken token = null; - // Validate if we have a token already - if (AccessTokens.ContainsKey(tokenAudience)) - { - // We have a token already, ensure it is still valid - token = AccessTokens[tokenAudience]; - - if (token.ExpiresOn > DateTime.Now) - { - var validationResults = ValidateTokenForPermissions(token, tokenAudience, orRoles, andRoles, tokenType); - if (validationResults.valid) - { - return token; - } - throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {validationResults.message}"); - } - - // Token was no longer valid, proceed with trying to create a new token - } + //Validate if we have a token already + //if (AccessTokens.ContainsKey(tokenAudience)) + //{ + // // We have a token already, ensure it is still valid + // token = AccessTokens[tokenAudience]; + + // if (token.ExpiresOn > DateTime.Now) + // { + // var validationResults = ValidateTokenForPermissions(token, tokenAudience, orRoles, andRoles, tokenType); + // if (validationResults.valid) + // { + // return token; + // } + // throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {validationResults.message}"); + // } + + // // Token was no longer valid, proceed with trying to create a new token + //} // We do not have a token for the requested audience yet or it was no longer valid, try to create (a new) one switch (tokenAudience) @@ -174,6 +185,10 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles { token = GraphToken.AcquireApplicationToken(Tenant, ClientId, ClientSecret); } + else if (Scopes != null) + { + token = PSCredential == null ? GraphToken.AcquireApplicationTokenInteractive(MSALPnPPowerShellClientId, Scopes) : GraphToken.AcquireDelegatedTokenWithCredentials(MSALPnPPowerShellClientId, Scopes, PSCredential.UserName, PSCredential.Password); + } } break; @@ -204,7 +219,7 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles throw new PSSecurityException($"Access to {tokenAudience} failed because the app registration {ClientId} in tenant {Tenant} is not granted {validationResults.message}"); } // Managed to create a token for the requested audience, add it to our collection with tokens - AccessTokens[tokenAudience] = token; + //AccessTokens[tokenAudience] = token; return token; } @@ -466,6 +481,7 @@ public static PnPConnection GetConnectionWithToken(GenericToken token, TokenAudience tokenAudience, PSHost host, InitializationType initializationType, + PSCredential credentials, string url = null, ClientContext clientContext = null, int? minimalHealthScore = null, @@ -478,7 +494,7 @@ public static PnPConnection GetConnectionWithToken(GenericToken token, Tenant = token.ParsedToken.Claims.FirstOrDefault(c => c.Type.Equals("tid", StringComparison.InvariantCultureIgnoreCase))?.Value, ClientId = token.ParsedToken.Claims.FirstOrDefault(c => c.Type.Equals("appid", StringComparison.InvariantCultureIgnoreCase))?.Value }; - + connection.PSCredential = credentials; return connection; } diff --git a/Commands/Base/PnPConnectionHelper.cs b/Commands/Base/PnPConnectionHelper.cs index a9be2c679..b4cd5bffe 100644 --- a/Commands/Base/PnPConnectionHelper.cs +++ b/Commands/Base/PnPConnectionHelper.cs @@ -207,7 +207,7 @@ internal static PnPConnection InstantiateDeviceLoginConnection(string url, bool if (tokenResult != null) { progressCallback("Token received"); - spoConnection = PnPConnection.GetConnectionWithToken(tokenResult, TokenAudience.SharePointOnline, host, InitializationType.DeviceLogin, url, context, minimalHealthScore, PnPPSVersionTag, disableTelemetry); + spoConnection = PnPConnection.GetConnectionWithToken(tokenResult, TokenAudience.SharePointOnline, host, InitializationType.DeviceLogin, null, url, context, minimalHealthScore, PnPPSVersionTag, disableTelemetry); } else { diff --git a/Commands/Model/GraphToken.cs b/Commands/Model/GraphToken.cs index 8f629af0b..6171526a7 100644 --- a/Commands/Model/GraphToken.cs +++ b/Commands/Model/GraphToken.cs @@ -1,5 +1,9 @@ using Microsoft.Identity.Client; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Utilities; using System; +using System.Collections.Generic; +using System.IO; using System.Linq; using System.Security; using System.Security.Cryptography.X509Certificates; @@ -11,6 +15,8 @@ namespace SharePointPnP.PowerShell.Commands.Model /// public class GraphToken : GenericToken { + private static IPublicClientApplication publicClientApplication; + private static IConfidentialClientApplication confidentialClientApplication; /// /// The resource identifier for Microsoft Graph API tokens /// @@ -56,9 +62,23 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI { throw new ArgumentNullException(nameof(certificate)); } + AuthenticationResult tokenResult = null; - var app = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithCertificate(certificate).Build(); - var tokenResult = app.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + if (confidentialClientApplication == null) + { + confidentialClientApplication = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithCertificate(certificate).Build(); + } + + var account = confidentialClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + try + { + tokenResult = confidentialClientApplication.AcquireTokenSilent(new[] { $"{ResourceIdentifier}/{DefaultScope}" }, account.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = confidentialClientApplication.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + } return new GraphToken(tokenResult.AccessToken); } @@ -85,8 +105,23 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI throw new ArgumentNullException(nameof(clientSecret)); } - var app = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithClientSecret(clientSecret).Build(); - var tokenResult = app.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + AuthenticationResult tokenResult = null; + + if (confidentialClientApplication == null) + { + confidentialClientApplication = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithClientSecret(clientSecret).Build(); + } + + var account = confidentialClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + try + { + tokenResult = confidentialClientApplication.AcquireTokenSilent(new[] { $"{ResourceIdentifier}/{DefaultScope}" }, account.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = confidentialClientApplication.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + } return new GraphToken(tokenResult.AccessToken); } @@ -108,8 +143,29 @@ public static GenericToken AcquireApplicationTokenInteractive(string clientId, s throw new ArgumentNullException(nameof(scopes)); } - var app = PublicClientApplicationBuilder.Create(clientId).Build(); - var tokenResult = app.AcquireTokenInteractive(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray()).ExecuteAsync().GetAwaiter().GetResult(); + + if (publicClientApplication == null) + { + publicClientApplication = PublicClientApplicationBuilder.Create(clientId).Build(); + } + + AuthenticationResult tokenResult = null; + + if (publicClientApplication == null) + { + publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}organizations/").Build(); + + } + var account = publicClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + try + { + tokenResult = publicClientApplication.AcquireTokenSilent(scopes, account.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = publicClientApplication.AcquireTokenInteractive(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray()).ExecuteAsync().GetAwaiter().GetResult(); + } return new GraphToken(tokenResult.AccessToken); } @@ -141,12 +197,22 @@ public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId, throw new ArgumentNullException(nameof(securePassword)); } - var app = PublicClientApplicationBuilder.Create(clientId) - // Delegated Graph token using credentials is only possible against organizational tenants - .WithAuthority($"{OAuthBaseUrl}organizations/") - .Build(); + AuthenticationResult tokenResult = null; - var tokenResult = app.AcquireTokenByUsernamePassword(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray(), username, securePassword).ExecuteAsync().GetAwaiter().GetResult(); + if (publicClientApplication == null) + { + publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}organizations/").Build(); + + } + var account = publicClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + try + { + tokenResult = publicClientApplication.AcquireTokenSilent(scopes, account.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = publicClientApplication.AcquireTokenByUsernamePassword(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray(), username, securePassword).ExecuteAsync().GetAwaiter().GetResult(); + } return new GraphToken(tokenResult.AccessToken); } diff --git a/Commands/Model/OfficeManagementApiToken.cs b/Commands/Model/OfficeManagementApiToken.cs index 77ecb74f8..7869cddb1 100644 --- a/Commands/Model/OfficeManagementApiToken.cs +++ b/Commands/Model/OfficeManagementApiToken.cs @@ -11,6 +11,9 @@ namespace SharePointPnP.PowerShell.Commands.Model /// public class OfficeManagementApiToken : GenericToken { + private static IPublicClientApplication publicClientApplication; + private static IConfidentialClientApplication confidentialClientApplication; + /// /// The resource identifier for Microsoft Office 365 Management API tokens /// @@ -57,8 +60,22 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI throw new ArgumentNullException(nameof(certificate)); } - var app = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithCertificate(certificate).Build(); - var tokenResult = app.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + if (confidentialClientApplication == null) + { + confidentialClientApplication = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithCertificate(certificate).Build(); + } + var accounts = confidentialClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + AuthenticationResult tokenResult = null; + + try + { + tokenResult = confidentialClientApplication.AcquireTokenSilent(new[] { $"{ResourceIdentifier}/{DefaultScope}" }, accounts.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = confidentialClientApplication.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + } return new OfficeManagementApiToken(tokenResult.AccessToken); } @@ -85,8 +102,23 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI throw new ArgumentNullException(nameof(clientSecret)); } - var app = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithClientSecret(clientSecret).Build(); - var tokenResult = app.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + if (confidentialClientApplication == null) + { + confidentialClientApplication = ConfidentialClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}{tenant}").WithClientSecret(clientSecret).Build(); + } + + var accounts = confidentialClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + AuthenticationResult tokenResult = null; + + try + { + tokenResult = confidentialClientApplication.AcquireTokenSilent(new[] { $"{ResourceIdentifier}/{DefaultScope}" }, accounts.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = confidentialClientApplication.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); + } return new OfficeManagementApiToken(tokenResult.AccessToken); } @@ -108,8 +140,23 @@ public static GenericToken AcquireApplicationTokenInteractive(string clientId, s throw new ArgumentNullException(nameof(scopes)); } - var app = PublicClientApplicationBuilder.Create(clientId).Build(); - var tokenResult = app.AcquireTokenInteractive(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray()).ExecuteAsync().GetAwaiter().GetResult(); + if (publicClientApplication == null) + { + publicClientApplication = PublicClientApplicationBuilder.Create(clientId).Build(); + } + + var accounts = confidentialClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + AuthenticationResult tokenResult = null; + + try + { + tokenResult = publicClientApplication.AcquireTokenSilent(new[] { $"{ResourceIdentifier}/{DefaultScope}" }, accounts.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = publicClientApplication.AcquireTokenInteractive(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray()).ExecuteAsync().GetAwaiter().GetResult(); + } return new OfficeManagementApiToken(tokenResult.AccessToken); } @@ -141,13 +188,27 @@ public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId, throw new ArgumentNullException(nameof(securePassword)); } - var app = PublicClientApplicationBuilder.Create(clientId) + + if (publicClientApplication == null) + { + publicClientApplication = PublicClientApplicationBuilder.Create(clientId) // Delegated Graph token using credentials is only possible against organizational tenants .WithAuthority($"{OAuthBaseUrl}organizations/") .Build(); + } + + var accounts = confidentialClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); - var tokenResult = app.AcquireTokenByUsernamePassword(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray(), username, securePassword).ExecuteAsync().GetAwaiter().GetResult(); + AuthenticationResult tokenResult = null; + try + { + tokenResult = publicClientApplication.AcquireTokenSilent(new[] { $"{ResourceIdentifier}/{DefaultScope}" }, accounts.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = publicClientApplication.AcquireTokenByUsernamePassword(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray(), username, securePassword).ExecuteAsync().GetAwaiter().GetResult(); + } return new GraphToken(tokenResult.AccessToken); } } From b442e667dccb8186226d20ce35d9a3143340f20e Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Fri, 3 Jul 2020 23:37:49 +0200 Subject: [PATCH 109/130] Added Teams cmdlets --- Commands/Model/Teams/TeamChannelMessage.cs | 51 ++++++++++++++++++- Commands/Model/Teams/User.cs | 2 + .../PnP.PowerShell.Core.Format.ps1xml | 36 +++++++++++++ ...P.PowerShell.Online.Commands.Format.ps1xml | 36 +++++++++++++ Commands/PnPPowerShell.csproj | 3 +- .../SharePointPnP.PowerShell.Commands.csproj | 1 + Commands/Teams/GetTeamsChannel.cs | 2 +- Commands/Teams/GetTeamsChannelMessage.cs | 45 ++++++++++++++++ Commands/Teams/SubmitTeamsChannelMessage.cs | 18 ++++++- Commands/Utilities/REST/GraphHelper.cs | 7 +-- Commands/Utilities/TeamsUtility.cs | 33 ++++++++++-- 11 files changed, 223 insertions(+), 11 deletions(-) create mode 100644 Commands/Teams/GetTeamsChannelMessage.cs diff --git a/Commands/Model/Teams/TeamChannelMessage.cs b/Commands/Model/Teams/TeamChannelMessage.cs index fb1e1c3f4..075ea9bc3 100644 --- a/Commands/Model/Teams/TeamChannelMessage.cs +++ b/Commands/Model/Teams/TeamChannelMessage.cs @@ -1,4 +1,5 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,11 +9,57 @@ namespace SharePointPnP.PowerShell.Commands.Model.Teams { public partial class TeamChannelMessage { - public TeamChannelMessageBody Body { get; set; } + public string Id { get; set; } + + public DateTime? CreatedDateTime { get; set; } + + public DateTime? DeletedDateTime { get; set; } + + public DateTime? LastModifiedDateTime { get; set; } + public string Importance { get; set; } = "normal"; + public TeamChannelMessageBody Body { get; set; } = new TeamChannelMessageBody(); + + public TeamChannelMessageFrom From { get; set; } = new TeamChannelMessageFrom(); + } + + public class TeamChannelMessageFrom + { + public User User { get; set; } = new User(); } public class TeamChannelMessageBody { + + [JsonProperty("contentType")] + private string contentType { get; set; } + + [JsonIgnore] + public TeamChannelMessageContentType ContentType + { + get + { + if (Enum.TryParse(contentType, out TeamChannelMessageContentType ct)) + { + return ct; + } + else + { + return TeamChannelMessageContentType.Text; + } + } + set + { + contentType = value.ToString().ToLower(); + } + } + public string Content { get; set; } + + } + + public enum TeamChannelMessageContentType + { + Text, + Html } } diff --git a/Commands/Model/Teams/User.cs b/Commands/Model/Teams/User.cs index 8b1560424..868ebeb51 100644 --- a/Commands/Model/Teams/User.cs +++ b/Commands/Model/Teams/User.cs @@ -7,5 +7,7 @@ namespace SharePointPnP.PowerShell.Commands.Model.Teams public class User { public string Id { get; set; } + public string DisplayName { get; set; } + public string UserIdentityType { get; set; } } } diff --git a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml index c9776ee87..66c44a376 100644 --- a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml +++ b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml @@ -1965,5 +1965,41 @@ + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.TeamChannelMessage + + + + + + + + + + + + + + + + + + ID + + + + $_.Body.Content + + + + CreatedDateTime + + + + + + \ No newline at end of file diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index 45dfefc3f..83fb387a7 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2168,5 +2168,41 @@ + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.TeamChannelMessage + + + + + + + + + + + + + + + + + + ID + + + + $_.Body.Content + + + + CreatedDateTime + + + + + + diff --git a/Commands/PnPPowerShell.csproj b/Commands/PnPPowerShell.csproj index fc6ccd91a..3099189c9 100644 --- a/Commands/PnPPowerShell.csproj +++ b/Commands/PnPPowerShell.csproj @@ -37,11 +37,12 @@ - + + diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 89521fae5..70d63dc81 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -921,6 +921,7 @@ + diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs index 5aa90087c..346e0e2c3 100644 --- a/Commands/Teams/GetTeamsChannel.cs +++ b/Commands/Teams/GetTeamsChannel.cs @@ -34,7 +34,7 @@ public class GetTeamsChannel : PnPGraphCmdlet [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] public TeamsTeamPipeBind Team; - [Parameter(Mandatory = false, HelpMessage = "")] + [Parameter(Mandatory = false, HelpMessage = "The identity of the channel to retrieve.")] public TeamsChannelPipeBind Identity; protected override void ExecuteCmdlet() diff --git a/Commands/Teams/GetTeamsChannelMessage.cs b/Commands/Teams/GetTeamsChannelMessage.cs new file mode 100644 index 000000000..1f9cd1f67 --- /dev/null +++ b/Commands/Teams/GetTeamsChannelMessage.cs @@ -0,0 +1,45 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Get, "PnPTeamsChannelMessage")] + [CmdletHelp("Sends a message to a Microsoft Teams Channel.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A new message\"", + Remarks = "Sends \"A new message\" to the specified channel", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class GetTeamsChannelMessage : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsChannelPipeBind Channel; + + [Parameter(Mandatory = false, HelpMessage = "Specify to include deleted messages")] + public SwitchParameter IncludeDeleted; + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + var channel = Channel.GetChannel(HttpClient, AccessToken, groupId); + if (channel != null) + { + WriteObject(TeamsUtility.GetMessages(HttpClient, AccessToken, groupId, channel.Id, IncludeDeleted), true); + } + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SubmitTeamsChannelMessage.cs b/Commands/Teams/SubmitTeamsChannelMessage.cs index e41b1cd30..8557cdd11 100644 --- a/Commands/Teams/SubmitTeamsChannelMessage.cs +++ b/Commands/Teams/SubmitTeamsChannelMessage.cs @@ -2,6 +2,7 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; using System.Management.Automation; @@ -15,6 +16,10 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A new message\"", Remarks = "Sends \"A new message\" to the specified channel", SortOrder = 1)] + [CmdletExample( + Code = "PS:> Submit-PnPTeamsChannelMessage -Team MyTestTeam -Channel \"My Channel\" -Message \"A bold new message\" -ContentType Html", + Remarks = "Sends the message, formatted as html to the specified channel", + SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class SubmitTeamsChannelMessage : PnPGraphCmdlet { @@ -27,6 +32,12 @@ public class SubmitTeamsChannelMessage : PnPGraphCmdlet [Parameter(Mandatory = true, HelpMessage = "The message to send to the channel.")] public string Message; + [Parameter(Mandatory = false, HelpMessage = "Specify to set the content type of the message, either Text or Html.")] + public TeamChannelMessageContentType ContentType; + + [Parameter(Mandatory = false, HelpMessage = "Specify to make this an important message.")] + public SwitchParameter Important; + protected override void ExecuteCmdlet() { var groupId = Team.GetGroupId(HttpClient, AccessToken); @@ -35,7 +46,12 @@ protected override void ExecuteCmdlet() var channel = Channel.GetChannel(HttpClient, AccessToken, groupId); if (channel != null) { - TeamsUtility.PostMessage(HttpClient, AccessToken, groupId, channel.Id, Message); + var channelMessage = new TeamChannelMessage(); + channelMessage.Importance = Important ? "high" : "normal"; + channelMessage.Body.Content = Message; + channelMessage.Body.ContentType = ContentType; + + TeamsUtility.PostMessage(HttpClient, AccessToken, groupId, channel.Id, channelMessage); } } diff --git a/Commands/Utilities/REST/GraphHelper.cs b/Commands/Utilities/REST/GraphHelper.cs index cdc1ebeda..f4b942b1f 100644 --- a/Commands/Utilities/REST/GraphHelper.cs +++ b/Commands/Utilities/REST/GraphHelper.cs @@ -24,7 +24,7 @@ private static HttpRequestMessage GetMessage(string url, HttpMethod method, stri var message = new HttpRequestMessage(); message.Method = method; - message.RequestUri = new Uri($"https://graph.microsoft.com/{url}"); + message.RequestUri = !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ? new Uri($"https://graph.microsoft.com/{url}") : new Uri(url); message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); if (method == HttpMethod.Post || method == HttpMethod.Put) { @@ -87,10 +87,11 @@ public static async Task PostAsync(HttpClient httpClient, string url, T co requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); var message = GetMessage(url, HttpMethod.Post, accessToken, requestContent); var returnValue = await SendMessageAsync(httpClient, message); - if(!string.IsNullOrEmpty(returnValue)) + if (!string.IsNullOrEmpty(returnValue)) { return JsonConvert.DeserializeObject(returnValue); - } else + } + else { return default; } diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index d8d3f3a04..84432385e 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -5,6 +5,9 @@ using System.Linq; using System.Management.Automation; using System.Net.Http; +#if !NETSTANDARD2_1 +using System.Web; +#endif namespace SharePointPnP.PowerShell.Commands.Utilities { @@ -269,10 +272,34 @@ public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels", channel, accessToken).GetAwaiter().GetResult(); } - public static void PostMessage(HttpClient httpClient, string accessToken, string groupId, string channelId, string message) + public static void PostMessage(HttpClient httpClient, string accessToken, string groupId, string channelId, TeamChannelMessage message) + { + GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/messages", message, accessToken).GetAwaiter().GetResult(); + } + + public static List GetMessages(HttpClient httpClient, string accessToken, string groupId, string channelId, bool includeDeleted = false) { - var channelMessage = new TeamChannelMessage() { Body = new TeamChannelMessageBody() { Content = message } }; - GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/messages", channelMessage, accessToken).GetAwaiter().GetResult(); + List messages = new List(); + var collection = GraphHelper.GetAsync>(httpClient, $"beta/teams/{groupId}/channels/{channelId}/messages", accessToken).GetAwaiter().GetResult(); + if(collection != null) + { + messages.AddRange(collection.Items); + while(collection != null && !string.IsNullOrEmpty(collection.NextLink)) + { + collection = GraphHelper.GetAsync>(httpClient, collection.NextLink, accessToken).GetAwaiter().GetResult(); + if (collection != null) + { + messages.AddRange(collection.Items); + } + } + } + if (includeDeleted) + { + return messages; + } else + { + return messages.Where(m => !m.DeletedDateTime.HasValue).ToList(); + } } #endregion From 499e686b971de2bf0e3b272fa80d7aa221cfb119 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Mon, 6 Jul 2020 00:02:03 +0200 Subject: [PATCH 110/130] Removed custom build MSAL, upgraded NuGet reference to v4.15. Awaiting v4.16 release. --- Binaries/Microsoft.Identity.Client.dll | Bin 1338368 -> 0 bytes .../SharePointPnP.PowerShell.Commands.csproj | 5 ++--- Commands/packages.config | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 Binaries/Microsoft.Identity.Client.dll diff --git a/Binaries/Microsoft.Identity.Client.dll b/Binaries/Microsoft.Identity.Client.dll deleted file mode 100644 index a62395208521ce4fb49ed98368dadf964031c386..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1338368 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 z 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 z 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 KelhrbKvid%r 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 z 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%0AUP*^KEaOd;sUS3=~*u2qv;Y9k?kRhTEArNPSX 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∓wODiEN=~k&>j0t;VOYk=0yb#_$5AU<# z{gT7#3sH26U^U+wtW;2=j)gs!*>jbiRkY*Y70U3`WinWS53DrKq2-c{D3}u)@;6I3j@8R8^!qPRwUO{3F7^n zgy9#ZvI+AmIbnXqQeMlYyk;rqaw+F5<>!`Cg=T1os%eOy+lM!ES>H6Z_EuDDZ>bZl zVoQHJroU|k-?f4r4za@^zH1-O=OCW9l=pKf?;ETO5!MBZUX0O;7QGasmsI?SD@#*r zM-ofv%m5zgRFNZS7t_T@sut~u(H_g+XZgjOw7y@s9_h0W^kh3_iKW0T?UZE(3mxE~ z`z^zuWpHc;EyIeKVTDCk#^_4R590yQ^RKcDYhs2q7F`>oYc2n}90KbsWqmGX{S|8M z21^mImAkW`wQGa4$dOH!ie^<)H(52CV>O%W%CWUwPRb)6u`*jN)An5YL_X7mW!i3; zcH}b6^B;n)GhUNOt%+qkV@)kaDdbn@yP(RTcuK+R@Qb?x1jo;Fknn>b3(ru!D*^ zI%-5aIu^*1#Ka?9U0wMEOm+$-%?Q)0N4?pJuHwx|l1u9*-V5&CwW?ZBt1|SF)PcU{ z<$s>k4FbL0HaJbmB&23=Fh@rH|aSIkGn{{S{A^9~)(m;l|14%s0Qg`s3;4`knE;~^r#0D) zDM5C5A_Q6!dVSRF&I1OvJ;$D`4$A27bGJk`5uPm0eRHtLX_?9JAXe&Tx{R!DE7&DXQtNKa|sI+CdycglM zg&B`jGa2e`yZ^Io=^h2rv3cXupZ>(-poP^w)4pGwiG$8KOM>MjX;5yimo*VkTY!CvW`UQLGe zDD|2~n&Jb0Xz6Yl$TifgLGnH#xu#@I57n4%vqx1=nfYM4&IIX&`jHnb@KThhmr%u3 zdOoVE)A7S;8wIFvrkCM=f&szQUo%+u^&@9u&NBw_Y>b|@=qoY$%C{`^Ud4qjd#HP$lGvr1rB*!^1zz}^AtR;bTcED zCp~nv=b(^H?%(st{d={AgZLZXvmtwsc?ssO4b99E(UVDi^cu!Bb$NHvRUN=1qnsK8 z-i_$IOC_V%Qm1Cu9ttTXk?y<+Ox+N`p|)63$E&n>uv5~IOR3eQG&WlPpb_=8Tiown z*zi4<1g|El~W z52~_xUwRNfsuJt1n-?&bBuS!#hW3DEg5BxV-TZmOp?44|)rfQ$ECD2|6nok{ z$c)k_SOl@-`aAF5LIf0c9Qd8&tPYNI(jqnRx))DQp6*Wb#x=vhh{tJLFl8# zEaiPdLxj^Hq*iHotuJkkEQFpiePv>YQ1|awmU`NvMer30(UmD?s3PubQ7HE@n6rzj zgIy$7%Q(v9q>*78{Vg+{So$*%1Lf9-ikIomsA34sMz05=+6Rp;`0~=x+sxH{9ID~J z?G|CWWpJTNn^QEoTfm!MDYJ;?GEDs@wKT~^kEonIk1xQm2SNFi>^rH-B8BLA=p$*} zg@X%}kN@a)!SPq`6-gKP!(+j_Gb=tJJdVSE!p;HOcq*I%zKtf8!xx5=Wikpe>NTy6 zLe$%bSt-kR!e#(Y;p09$Q&xW{36!aiN5_H6C~>?yxS5VuQIDo;tCa=b62wV!r7~r@ zD|lr24|$i)>o=7tv79kw`LxCLC4^+TAfSjY(ixVKh@vp#f)+v?Z4^}2B6&l@QWwge z^{{&LyJjSR7Yk+Ro$RYTT>Un&Z+@2wk6g5>Qz@k_WeT;y2(j?B#v)9FPL}$dytVE^ z(LO^ztm}xS80L>$=u}Am>dtNPdwFq3_dpxIi1JH>4AFaokSU236f#mhfTy=W{V3w~qb2QvLbrfKUnr!v3VlBo z`hK6r%gH6AhXSBI|IDjd8NTbS?=Qw` zUd*b|3Y%c)tvo-y0?SE+_^I;n*PE0HS+BJ#UK0xGtwKMHfPbh$nvB@`#pr(pL(J$l8#S0SHs8?Pjweed%{Q1=q@%YJ!005{ z)UadUU++e+XiY+Ji~8R2SX@ewKaWU+%~(WF%>57-WX7ITiYwL@$3 zq&@`cfU}n=TmKg;ePDcFy~WBe3oh6K*kjm<1W9ZE=}Yr*qEef!E(Vs-2Q)75vh{Y} zHfoJNz*lSjZdo**14~j;#22fcI^u`c!fMFUPHH}Gy}3J;z{^feNB040pg#JLkd|4g z)d#TgK9W5;xz3DBIm6qK>*Q`NRqkpSFXZfl&XHwb7t2O=6m!*wZmZGXxxNiwTi5he zs-RHg|3&is*K5qw+=gjwhhqll11i=B5QZ)TFs1tguGhFF&%yPz1#mepE$+1q)^lI`}7n!*~xk+J{szqg!s7;bXCd-Q;0<|nEV>vD| zGkN`@YD!vWY_+xna3SNOS68c4tu-u!mKWJdFrg~0A{n%02IsEwvWgl^lij@P!2ZGv zWSm}L1|i0#T!D*{1vn6EObT18RipV2%)GN2nT^ZveFsh!aYxMzmQs1gIQStZ4&l49 ze5FzsH}Ve^FL9XMED>lv?o5dsn8@iF1wFo10KXCiCO502C$%>~Qa`!5BAG@Hh<}*s zOm6Ox#6AjpsUnN)qz*-{$O*jS64TK;z1je;`HtYA3akdNGe8C@%kSR}MN=6|DxEOt zR=Q7Z1=BE@wWN*(%-g^agbrGDkE^=YHnUVjlw4vR?-E1WXj7m}H^1XcX(kr9Y4}3r z7GtT;=q?Zj@rK0}s>-FQA_KmY))NkWMefH<%Z{j+<90W10Pn>*LSkj94D|QlxS>ZV z`8Zpc64s*n%1l7ex01|OZ;kcxIK4qEtUbzXQU$fy_5`?rek~xUlRM0TM4uoqAyQs$ zTW#Y#D49+J!@GM%1!}Nl$I+j`Az!`1nCS5Uv((>HquN%yP zU#sHim(|-*LnJ%8E1d%@6|yCP%^~Ib( z3OXKi)VjL|**4<;Noh_Vas%Npu#(=?TjTg|^w^E!LW2(Ud!9zf6W_z0x7DkH;~`R4 zWRi&H>5FYA+T=7*4C!9{com-1%Txw9`UVf-3LtUy1v+dB|BHZ8iqbI|vF{>Gyi;_5qDtlTW3SCp7n>Rs40MjL9Rt zY`)TMomhPbrF&o%Bn0(`788!Gn*-}KcRP>lhQV!YHGNDG3d-Ll2a6TBT_kPwYE7qg zJMO`qTBs36n~S~9C(_r7ZKQ`<+h`AFecHNHyXAsqsS$KCl zb$6E9yf3E8AStU9q_)9`0m}y9S`E2DgnWcD7NT?Hjge_dsfsL1-ooqP(n0pM^@(erua~FeZ;pM~ zTd%-!tzOG8`AjvPd^VD~*KLGe(O;`17GTtCNodl^=M0!w`)1p>afw+u4jSAQnujOa zP)NtH%gJWmRlFJU1=I%mectmz#v_taMHfm{ZDCT&K(E=l^fdr*p?Bam{resUh{mh+ z$>*yqJ-Vw(Q&MQmOY>8V3r%*zzEDKE9Z{1`*lgM6?5e{&n5}*7#1Oo~$B%#r9u--X zx0^L^Bdc64aW$C*WMM>y1rjxG;l~z?4?D64q zH(~$;NN-4r*fMN(D`1IuLSv9*DPsLItBrlZHmln$^P{yUm(G@9)1a%?;)86hGGAW3 z@tTA=gikA6Ut!P2EB-p;uQ!cjwn-sxg7`vq)92}O>xAZ|4}Q07;jDSdNS!dOEY%J_ zNC5?Me`U0j*`AM!E1UPxMs+dl=h}AT&~gvG ziG1SPT4_WW#2=ov`uVifOdJ_wttFJ6{JDMKglP_fn-po{QmmwdP}31Ho`8ZW7I{pG zI%ZYX*Xu^Vm#G7~DmP@T(w2p^d0rLJ3%6EMW7k>n z{kOt~f%`?=(eE3HAJ_0c`6k3f0kxXizE1ot>al5)>14A2)~2luqVjpx^n4eeLN#no zjLtsvmZ2VWKjb7DrZ`B^!6lWd+@Uwxpmie>b|Y?Zml_7D8#S|Ty>1*$1QTHN2WU~C ze5$et1rC7Fzh;(&N|r+D*7164h8_87>uLTl)84R2I^K^ibii>&lo|G5BrE|#NVZy82_3`9&$r9ujr^rKcIR`l><8!1xJ#IwbcxQbdajPrAGhmA$<;W#gn4<+o1V5y|_ zBI6$n$2e)v87%K!{w?5NH~%{M*TcUG{}!&)vb@$;Ujttea20=+vLa|4*E=gPT{Zkk z#M3K8;m=?578=22#`&t84{6w-hK_x3vlrM|JQI#$h3{ z_6fIn>Wv_K@g+uTzEaaf=AcG2sg(zS(1+h#mMckHS?X!LY=U(@ZCx_Zm&kIS5uHU{ zZKOQ~{p!t&0=6~Xy1KFiDImuMN}_#Q{d`0ER}foCW}u^?W~g`>FA+j!3;SvT$A6zj zj#{q)f7TyD$!6|Gqf%jeZmrh;`AB+p4XOv`yco76&mezgg$=^iG%DSfHZIUe{;JHg zi5{%hC7z%*g_fY(DbZb7zU(IXI4u+;49ky+uv_GOWUOo!|fBi;ifw6iR)^w0$tfNq}+ zcrJI{d_9dHm-}OPAO{+UT0hdRo*FX=Vx2lgxdZ=;@ z8pbu)&c6*KqfDw{Iyo~*C*e{DJt4ezR#b9R)lY=ulc@cV}FkV{*BP@ ztenv8EOIF8b8^1>%8?KHUFkW#DYgHty# z8k=0TR)Ja-W9yXULNrh_m)2W9(Kuyjv#8@ie+HkjNpd?(#%uaIwAPFdp|o6fOqink z7)aa#8~K9+Qp}dbN>w$n=FLgQg~$yburt^G$^bdq0WVt zWVwew7Hva(v6PIfw>G9yq^%WKR@h_HxWJMt-P*zI~b<4E&Oa@s-@&d-9FIVO=I$Y_KT%Ej3*Ew zS(Q6vW6SuDi4yKDxOmMCJ!NObY;JH+J{)GhOl}XNfaUDd)R1?jVxGU&Hk&H8wt=E- zqo3OIRksXU+Zbo?r(>V!^$UN!W4-cv&dj%(gXA&R%bt1zM+yoZD)g5bZFpZ%S%7P< z@haT<_iTh>SBzNr?;#8OUX`Q{YP@O#0*4*gD=K+mi$N>zE z8;3d*5SE9iR{K(gJzOO5L9QOWMXo=Li3N6U0LH8hbYN8Cx9+HqvYex>1=Y9$tU{k#`+zLrms8HxOLZREHmZ)Q=mMBW&h|*>L9DUCwVD;8B{}Sn&S|;-wRbzu800LU3 zBg*M|c#K5E?;vVUq2~H37Q^|#&QnWl;;{beIGHqUEDkU@4Yuf=w$O?J&FxVV`L<`( zNyqY~5vOHSOSBHx-p~p^8TV=aZUK?`P&mfq6VKL34Idf+p3o*k%oajwzGd}dtzU%l zW)(hhRhS`1#>kjc<8aW^VkIAz+u20g))S%2REq?GT2-AUlC3Acpn2pZa{Cj>(i5>{ zKA_2~6$*Vv1g;DP+G*JiT7cV(qV+`BnI^+D^a2=~C-IP6jtragP8>=8htl#=XE$;x zjHd=^SsMVyqB=wW1e(PyucCb>4EdP%rR0@GCK!yk!y~|~RwN|keLz6mwh~?6hjKz2 z+de#X=y|P+@rCv0uvkhOCkicBaD$M79|V=mo6M^KW2M59_|%%15SF{A*2V;_Ycpk{ zLR5p{l(x=QwXTQNd(JeOM&1M%p?PA)YaaI}D<2hMn3KOYD*mPTduwcjY$i z8f~y{F#&$1qC+JX9*7N@*K=rLh}AJtAhEQmxX0dX6=HVi;kXM>SR>ytnJ9mPQ6K$P zwaS22AN_SdhY+Q}4T$I9xsXjs`iSvl!W*lSke~PQ_t!GR`*jG>?ID@M=LebQtV>&G z>2f0=eSd~NLO6-D>(y<$Uy*Y~1wAsf)F@jY5(pB_o)(f202t6bWC^=U#TekK&7#VEb6(DnW&ejU2rQf^3x z^k*qISbu5{uQ%v3noRm6IqIHl__Hi$d!3R#XOLZ}X7MQ+;n3y0iHQORp5tWBfDrGs zB6FN`1{nQ~zsK0M0KE4gNib_6bcO(13gofpS^##EwtmS%*3f_+*GN^Yfby@gv4z>% z8%9)3<&87r3fh#NJDGYcGU{VSy+)wkxkx?9c73WLjM%Dqx6ua7ZR9c&=e+dLojPkF zCC$lvx^S%5WZsI%yk*D?8wE!=eVw-6 zf~IVRw(OH3yJXqq{=8+MG_s#v9wuIObgy`jDzPc*jDs3a4`J}?2(K$H^x4?|dfQ~g+LWrVWRq7yZ_sF^oI0e0zo;*2 zD`a6f2cowa?dWIU1?P%&Du9VR7ZfBVW)g}nP?Wb8sg%rYOuJt@{VTgwXCYTDLS9ge zR*KQCVzd*b?6jCDe&{Yndvs8k`OmDX7pfHt9kGRTzAjRsMM{<%V2BgWBrXq;)i(1wrJrnLc)Z;S;ncu!bHffX6L?y)o}t7`Ofh-UCJ@aFm|%z* zE|9Z>Q#Rxm?ON47;oe^96N>xG)~$QjRhDurhPsTr zOnj)4Ki~dpRjD@ZvbH~Yko=Dsd$rq6+Sw%wx^V*7O@Ha+HL)jAAY=7X&5j)qK>6d% zm*dgDAJ>7w0NF9@wzFuhi{4mjR%Nu(n%&z|Y^*w|@$1kVL+lUL6oWC>P7gP=pd@2+ zXr<0|uoap!h@1y1mvv3VstS9l5Ms~c`>aEPQhm>_?J>}Le!_V|$(DbIg6e!)&uXWlkDe0jtP-dWutv-P=h+5$5p)KOyq4VkRAlYqq z=Fl$Q^gm<%LEF#sd^&Wmtcam)SP`1Uk1aJMZddxyHnQ^6{u{lubkTg?vhTF#od}7S z8c^9GE+YcM)ntbg?i7m*ZDX@~I<&J!oOv2B)O$Ds_t`$ep`BL4oz$SaI1YM6clv85 zevWkNHU1>c>C`#?Lg!AM!!y$AWql@{`nhmAXc^BbV|#6N>a{R|m^x?v!>MzFmF{%v zO+jj%9?(u9Is((1?+o>HOfPN^X_fYpzrdncr~wDlL0lCmF?=y@9Kv>-TLQ%0B`IeD zOp^O+N=5Zp1hJ4Cg&u=4Jb@*@hr`Z#MeaQvt3@cVC^p(N?7xTkM7{gj8#b`lDbM7&rCXmr9hOI6&PZP zR8gE!#-f}!hAU5M&)5+BsGU3Yp@+otNI~QKk)Jn4EuxDSvJ4an41b%!(M2OFWpD@x ztblyq<`t$2>}HmsM|CvAFzwW<#xR|Z-7XCEM#(8AOciy}c+zTk!DZo5)C(QRSU5Dp zUw7DoN)SY)Up!#nt(`M?#M8!)(xE5Qp{aCeA{}a`LnG!H_F%nt1Iz6OT|6sRbYLp2L2PC zE;y>%HW=xHIC*MFHYM`m=kG; zv(^DsFkrbXpk-@18f$%=)v!uUY{v#oLl+hf zc4@yarzh=V0uJhRv1zKS#v++l-Y!h-Q2J7}SalEPtE!My+l)UEZR%}hX-?4@<*r`X zhuzH}DlEFuwGh+Cu+&{;){Ay&nQ``o z*sm8%3tZHAueQkzt(4)FSO)YLo1`&s5AQI?`8&OGQE@~y9fnzLL-gSt-05aBRm4CV zuzu|4dXC+NXmFjG9lJO@sfc`0f;Fwkx)6Cnl^tFojd2*?o}2|kFOpz_aCn*qaJ5=G zydJMXaG9B!Jv{9ho`@MXcziO(HyOlsbaPDK8Ux!!)!}!{?E5kF@p^W|z^)j$D+caW z$4X!v}s%*i7_48N-~^-$Ex)3xj?iDbtlz=+eL0VX*dz^7Un23efcha0uBcI6EH z45NR*=+=1JhJeP?zH$D^8Y2U;JbFVXyG5P1X@&ZKxMEh^@PYQJdS6I+n(dHQq7R_T zIb|F)brCuZy+Of~7?xsasCASH8Z&xClL2J-j5aN0F%9%b6L|oRiWh&S9PNO8groV0 z>auHS2xKQ+4I~pW7L$IV6Zzz0)xdx}AAvk?K>ApqhK`M=%XEt=i-~82_SiXj%5W5dDbDS5j4Ef-a2DRBqfvnp%7+G6zq zk{#~xj-Y2^g7w1+>!g+5Nur?j*2G2oxKh1vbk(Q1F~YEn+yCTN3~S$Zd4zJUvAk=| z29)x|64Z*Q4R9Rx6zPrk)(5<-(HHZ)7b;zE7;Sb$4lfB99oAw|{pe<0&U19D!;sWk z>Q;m7Ze=Iuu(_0v?ywKLa#bE)lCLsA-DTPC%4G|<++`o`&3!oBQz+kK_1|mR_T;in zT*_yg&<4T!(LE+O_ea6Ge>2{NqkEl~=wdJrY%bzlKiE5$Txh_xjQ4h=LWE*5Ed}SCS8^_2B{E?ysqQM>?|K|Hw%|DWiMSkr((wO+gv1 zNwj(Yu2K&&meQ%^d-bvJdwo9;7Q+v*4UcDi?1%kwW|0rmi4prD*69ZrKz#w8 zf$*1TkoxdJfgXENs1D1aC~M4;eyr)`vidPP;pOszWjcPnj3+A`H>#fIh#gNJj;D8q z{q#;Q?%McqhAh0eIG!4>V$*RvF&%pq`tjrv7`z)bAY=DeHH&*a9s8NO@Hcc6_l<&{ z9C183MMtCVw7$4g+)yRfvB2(?do6j%v?cdh{9lJYG^{KK!yUAHPZ< z#;;mt@YvWw<>LeXlBbK;9c%-eC`O@RpYK&j+`EK;r&HmcR)TDl_N0;|< zanP|nx`#DArqfYZ4l0hMu|XO38VfaVsX?!mF<8 zO5nJIorB30oQWuvt|%e3ix!|om$6ZtBP1i{v>U$9x_;zpWK|>{xu!mHEk&snGgV6i z_3>@iz}u;Xy$O8ATP0P1aFgA>?KD#DG*II^)A5~39kB)2ksHL*wfe~QmQ&8XYC3X* zwB^W+(ny%p_TnBEl2%K@jGTcu>Bz-pHF~$UOkKPTpA(DNYDpiGh39FQ^8mw~=|Qs| zd&+pluHQTMl(^^EiNHPmQA^tZ*KxosGw($##21bm8*Dee)Y8#i>Btr)G%i;|-__VKvL$T}q~j0JH$G?P zJDnV0Yxk3rVq}|5bw;+WZo4aJs`hv1$)(KfH}f>PykHw>zR!9HUyF5LGzv$}C_MI@ zeUxkISL$2qzUM9Ng^=bv@B-%uxv7vnVcdQ=*a3@cb{;1Cy@S2xrG}`>(Y{lcC9AME!aghCWQI|D9%$sXu?%)j^=!c*vj25kN_$rb{=Zs7FP!i~EMkAa3AA6}nIkw7kYYtkAZT9F8t$d~TGNI%(vNIjIQ$uY!^aFeo zYHzm=an+BVM!y&_wCTg6+K(rT%5Hkr&H$~19oGgD4oPYx)#P{RmpGa!0cmY_ivsL7 z(S|RBDGD4r8;rVRXC=Po_~0r_xs_K-ggF<%{6S5$ehr?o@NzRZ7m17WHm@D}8CzFX zOvJ(zlF*IrwZ45N^sQN8$6i@p;rMwq9lex}{yZJq0Opv1>F6uz=xga%l?iueeRQ}! zI$o=>eiVc0$R-(&BP-I8H3M?xYcv~MLw(5Jn5H?1%NRCCA{}Vof-qW&fBixQCEy?X zedH_@T_f}j9Le+_$Jgk0bqakQS{7c=0yynRE`!=VwgX5i9csHDYn3QB#;0TVV?6sO zJ*!u;f?~-rD>-WY+WusC-VY<%mI5wJjY(cUjQC_XeKvM~K)9+N_g=8gi4KMo=tD(T zSD?%>wu*#w0-Vdh$F~^A2W+z#7$hjby^H7>_386ScsjCMH;0S#CIKo)JC-M0`A1?q zowFJ^G4$*&b1PrDAMXK#9JvqaiJE%!tnE@I&338k+l`f8^$bWy+N}!vCPvSO3I6EW zbo6X@H;0}jf$c5>5o_wIxR(Ox?Gk}D-Ji!I_I#sfDd3EE)`$@JI=rAn%*VmK7zDNY z2(1MH{!jz7gbNiFx2@rP^X*(QmkGgXwOn+raW7&8JDhFMqX;5Sb(RHsh-7 z{e=sh&BP+Du_&G{YA2pg?MCRSPd`$y06Z2LJ8JkHTc@4L>Da1%Rs|M?&NMNzPW4SN zW9vfKjIE;px@=Zw#y%Wd7yEE*9SRE?jICq1)3~;Ql|t>od(HWS7Rsy7OTK(v)#lz zSt6$SEY)I`_VR_Taf%NlbkR9Q-x>lWEwI@*!s_ave(cR4cnYaeObX>0$L}LU0+mdO z8q*#ij2x5_L)^<4xJ#Mm>BkdZjTXSz4nD?uc3c@3R*PdK^M2~!<{EB5R!CD&JJhOO z}m{`rOnL7&VUostuZMjP1VMrt(9cFw zxs!fHZA>Xbz|5$N_VJRZjlCZ}j=gUmFPUjEofJ$9i)!M0frq(7Mz}vN9Um?)@S9*Q z1KV*z?=b+d`G)=&S&JJ6tHXvmRRF5^XviiV$LiOU!ezQM;vy8LJ3p@-+<5`C{4Nub zsYA?)7g{h~Eo_x!D>B=C(T?MrQ69B)e1mWq-%Jv50!msAN@gid1cRvVm#qraqF$5#cO9AE3sT*S`OWG#5WQk;Xw*Sc+`6~&Yr?BIKl8(ACK)RCR; zi(ERs0c16?v%muVP)mP*d!s(7=Bf3KMaQoVmrH2ei+YAEPB;tLs7Pp5j;KhfO7=0} zbWdO)6%nx-bQ2!3vo>k$VQUU*!FVuj4AYAG_zpvKmwKOmAKyhWEq7|JIKG!@imlj; z+Z87AEZcl(T1I_3y-a6@#?FDbOhhq?xI}iuuVif~u_qrfwpqg@ZRANz)u%)LwR5tp z$)*C+`wMCNIb_37GGAW|+qT^41BLwNr=E^}>S>)Ts82su zsM?DShhnz2Fg0{AB^?WsaO^JYw+D5RMaWBO#F ztobgcPZiQm8N6pa&DS`lpRu%O3-F$`wC6l6bn0`~1lEylb#MB47F>dC!R)`Z(_4B) z)wP-JgwhEvCv-gwt`VM>+&YZ#BWn=-pu?Q)UMe8_66f;;q0Kj^3!hI*T*fcdhaVGS z!;kSN#W$fd4>nRypRrb)^->d<*v6w1RpZgK$~=8W^N8s){DsMaHS(3%$X6`-T8wJT zdVTs_jGnXTn=$&P7&$P~TcIwzb6%-==ceB>jNUG!y=`gl7Si6emhb}@UFpQ;{2y%- zJxEdr+7dEzsw!*C4V2B+viGCDHvm@0g+d({J`>$O6Ptm>&|*0WGOStxBMFLhf;NQD z3NZ3acyF~W1EZ%I1k;y773O!GzC?$kwQYaVc+=ck<0B+Y0LTNvYbFVW_C{ja%zY-Y zkDc+OYMJS@v|_%hrMWIoC%kOWGI(t0MZ>o^=3C~z0?S)_q36?lr&;XNi+SQGpkt)oWsPZ8AbsQFSgxVaeVc(`kWH9P%{Dl{5h;-xpL%k zk0Z0MwOK9?4s>ZHF04amOLL(jPY4H#ZQX9A92Rhue=+#q7yOvQ(hIA5eARN8R*SXR zr*O<*{Gv4vKIu6#D1huToH*f&iYMCfT3Aw>IKj%cpPwF|`rz}^3pqbMaRLfCeZg6W)ki8|2?Yv&^hgzzwpA6QKfi zfEOtDhNF!hh0ZLC=15Nhrd&QD7`C1t*k6kK3nreT_ClZJiiKH@m3k_oLqOgL5`RB> z3qAx0?B)e1vxz-OGq|#f_<2iNR940u0=XcpC-amkP2*)rP$6IF*uzU~#f(=t3+kP~ zDz;3_7%`yO5SZESsix+9hrrBsDfgKjLAlTD_(}zZO7oovv!13EHT$!k z^d+ z5Ofz&n=Ij1BN%^zBh>JTIZ6IuDKeB(IRP@FFsuIc99NsTKpBkOLsm!{Qc2Q57r)Q6)T(WRDi|SpM>O?_gAtLz`+C-z~v~DJ@ z9I@B+nSYHD-Pa`7SN_lE*5Y_Cs(@zOAQVy*@RTrcNf10mgx64JJ>Yq;0W9UP`_@A& zcMK0AT2AX8FRYFVbrSO8>Znj_J53$sWz{{Q;+SUL6RM5}cI2XB4IV$J`G}ZbqTcZl zjoUKA49^ZORMGrWL{V>G-5$3Y{)C%6T(H5!_J>;9XYu8Sn(gAy(hQha{qO-MJnGu< zVN+E5T~YbeWoEyn9q=^Ylrm$}yqQCVd^R7Md909TCh%e3q-o>uVVi2qGzz&IR>N>1 z%`q7-q>Wp?Nly!yIK1gXKAXDCJW)uqsmsh$g*2PG%$z8soe&*nPNMU|l9T3zO0sp< z8Iz2eXD#J9dp@7b>Pz-BFW85d?0MRrXIKMRh%1v*wGG0x9^7|00>&r9Y7kOff*!=t&jU*=*Hzt(9U{cA$ud$_lPQ7iIu{bo+>2xb`&fENyrd=5tIaI0Z z=YPOP{>z}6rC9yt0ycz3zGbVz>o8CzMjv{?-uP%NkB=lrI8U97(3RT>p zvt=1}bL&*irBcV7mQwRu5grx3Uu2M(Lz%TQ?717L>dOMJaLlnxdr*mj5 z2;_G|9xb6{h!$yZ{@MzcanIl5mw^oa??;s0&sF#S%1XCD<%`YFN4Y{5Vi>3wBGe0k zV?MYvB`(Gi7xkMS)ZHd_{BSAK;PQ0h_cq&ddZg3kzR-vq#rQF%>O9T#Y76KV3-tti zj`YO3s`Vp10XMCAU8WED3C|3-CAsjj2#~YN(hrF2?6w~nj69O>e)8sI;K+)g6fTE5 zXs#^iji3{XP*#1)k;u2BjZO~hH4*DIxx}?GaqTK@W1=Yt*>ibFp=FjdSCHwFbrHh4 z2$mlYYKO_NK4w^-%dq})UY+LdNK3IwQ$)>c^BMy<8zP(yU-YtUXqr{fn{Bw7V%KjT z<%k84O%cc@Oa%0)_G(Fb{oTd8C-gbcv)r56w=U|qtD$)rYS8elg^UxI&$zviapv+F zcYHFdnk~ri>fCOi;$69Hu5#whc30phxiKyS>0TG-lWiV~B-?`n9U_De;^p||{utOB z1N&p(Knxs;fyZK?5d*_9FdhSwF)$qiPsG4eF>oRVPR78g7Nj;f2w<4G zcj3hN(?t9b(G^-)37!xx>$F?bo8R>-p>Ndno#ALANPE=Hd41q3&qeH`YQFA&HTGA< zFoF2%Gp}<`uH~@b`ym|T&DX(~ANp9#9lIQ#=6`+xl^YH8lLr33UEHfo`c(|QxAN|@ zln?=UlguGC0iRl!Yo(IM}lb$P0HX=__t|Rbm?=xNb>FCMvDdPVyYV zr#9Qz+d5s4$!M`>0y(uc^xf1}2X$sHsO=8w%!h&65kc+n0%t$0z^+(e*LAYmKj3zv zJfy;~Idzv-^u6p^h^ndD)V(l>>DF_uR?o335Nk*~Z8C#u9_=(0M~kWZSuYh-=Hgs! z$Jo+(Z7y97n6~APnMl^yoX5Pnb01b+9A>5(4(Y8qkcR(EvkLqH>k6=Rr6?`&7O@@@ zTE>+Fq$}>-p0?CyihJMDm=Hf#B;q7|uQQ!3wyt;q3s?=k!RinRrrH@#$BY(G#?x8G z)47Z~(B~*9pp0j-jAwEg&&7-uP{wmv#&cxE;~`R551S)m%A68Y{MfZFVc};mt&_Pq ztzVbxa|*(5AG2><)S<%cVzu%oQ3AS2q&{>TH%1@`)*foL#-Lo9i7>p#8S}ipZ@&J;- zYH1WoiX2@L^bP?XBYBd_`s_Cq7`pW%EBZ$kuk=fD<%|pxaUz&wTNT8%oBuTukgwbg zpQG=Dj#0Mh>#?k4kxCO6>ql3zlHko&59TYK({^eKdVAuc>1|$xcCHu0AKer)z3=OP z?|)YQ1zL1?32TY063wQm9CQUZw$RPa_H^QXtZu!o4M=Lr=VY;kgxQcX3=i{bBv6!B z0rFPI4Kxyi>?;ab`G=G8zt#|^{&!ZU9_?))swMZ~74t9y-?S>B!?QiAzqV zOGPAh2nnrl46pcv7&F#+c*z{@+*Qaxf6W@nj^0(saJXkqhIUcX3^t3jN4cF7=?Y3b+LN$yl*M>X=Ou9T^Fxq`OypY42pVqK4a&J1imzum9ds7WH z`-(0Q?a-%2Iu8J-@pKyyH*OuBTy6N?OFA6{Q>gTNPM3MW1|nFdNQCJEK)(QC_$v8T zwdt#4876Ce{QHOrCq1<>cKFvaarxm5HpZtT&ne@$orWC$p=IL84X3a0W~Rfx#Hl%G z&g>1wsL!jt&D(7enp5%mZb-(t`^YotFbC^c9~0e2_wuIgqLKW;tX$`uqem~;(XAiV znILf*&we+(KF&eFA6tKDL#dI`13n~;?(JJ6EktMOD7b!oPTF24Vy)loXslQ1+KW$Z z>WuEKAH86m{tt|8ti1I0F0&)3<1d@@Ym^f$hPa*_8gZnlO2=Z9;O^F194Tv@{xUWg zWw$%O7VV_)w_2Uk)}uNMW_VdZwCT_A>gUkdI{AnMXhk}@Bpn?jV7L$qC6}ZlH-{vB zQVlDdLSo%f9Z9l83#f)ASq)3-$4*8P>FAl4jwD)|e3jH%C~=B2 zXCS{)xSHnT=+)2C3H3gB*c)so_KKnbiwSznu<(FoYr~w_TR-;P7c2bGlwhuK#l`;I z+vkHx`ppJdX9hWPlv8_vdH!07m%!)}2kjA)fXziM-y~K4g0WTqAf>r5!xW&khHc|Q zTNg*XEDH*69H)?UwHdW@aF?ML>1`Zm$7ORhAK7HUj$YGNAtw^tKJx@q(|4LVI#9i} zIuw>mnDmDcUDaAWl+Y~_2hrx?jFe6xey7uF($Ghk#b58);B)~^cAJJu@fro64X36) zqY-ZOfC=b)N-R$ml-03Uq#qi`%@sIyfxX&>ufNs9TPa`*krT0-x5jR^fVz2W*3Db% z$1X-#WA8gGdjo6ieP9JBw(VOi>j9v!F+18iWAE3GU0R`D9=kxdOl0~vV?2ijb=mrD zcg>9LWk>kvvvz89WFj4zU;-YPwH^VhxaD6V?jBzO5V&U^JlR*A6A18`?)*%_x z+lj+p#*BusLcAycQ4yJDmNT|BMyJ=T5h2@^WP6k)HKxuXenG8w4knA)qvSlrr~0(E zS{n2lWZRCPkf94vG8u9jT6Y>UWH1cfA`YY4^tv`sQFL8kh2iG|LwNvfhM#X|u~ zUB;hNn@4udYVgP|N7mjSwZYp%Q*ArC^pXcCKC-Lbppjkm>Fw>9nwQ1YyzO5yMtx2= z&0{*uJMgx_jrP~4cVw{@#B8Bt{JGf{OjP$Z_Q^Y6F{}Np`0B29eQHb=Q)BKjJ81j` zsGE+z>%5Zj&g^cw_a+%TmYb6e&SZ0GAGC<|PYBNjv}cY2+cT&k%@LWaswM7)R&WE3 zc;h9Jgjp>O%c-f^Y9niqH!xEpfQ{UinVZrXSxhv`Vxrkz&d^i$Y1K_US8)#T$Qoeh z!0&IPFA)3J84nqV@m=ZoUNz!yPQ|z5VQ}y`@U(3-3=p2ym(e*(2m?ic5|q64g(uag z4aYMJNTQ1<6&x3Lz_ZPS9<_zaJy8b2J`yq zr*1Jxy-fS%f-tMe-hv(CIR>89y(dCH=q#bv9H%SXi`A}qNqzc6J0?ayvDM^M&9@c! zSd&EzPz!x0$VmH7w?rUq?<#WFrP)cm=PBtgc9X`eYjyyd}Aq`1Ry9 zW-(dE6xBzr)=WK|YJ*bYQ;}sO;WE_oT%uZ^aZPnrocQsKV$Zfw(NLAegjg06^`G^j z>g;blR6W9a_`;zB=`=jMPjc=dZ``D1rbI!8m z^jQH5DvW82F_69CZ%Slc`AT4AJMbfw;sF?NqS|gR6->W!m6jRix^?r-z+*ej-Zva` z6HBnQL$#ZYJ1IIl>p9b?6U%T@GD|7WvI}{!$KRBBHWBarn;3Kl>7ec9n%D$z&JqD< zv;Tcq&2RmlMy*-pW)~{VZ`8E6ZCJKav-6@D=VX7^CZ-d2MXa`lLVAnPnrCJt-ddk# z6PQRxfe+1k(U`@uW`w>h;7gwSe(0Qz#BSLe&|s?h@)evsVorV=io=#RGPL$`;KCl3F(L&bFLM+EXfazH;?KdGXZ1xRU*c)Pu%yApqD(E?dVs^yyo$s{~82Mg(CL0cf&XVj<*Bj=n!<#f)f5@v#CL^2Xe$HG`8T zYbTw3Wm1MJTtwT`P(gJM_DnX-CG*U>wZ_NK=Zq>NcQG!GYa3m_S{jF|ES0k?w*E9B z10Z9CQ0azwFQz?ZpKqthkx&wiRfCd$7%{&Mh#^?9h7A%)Lf|!;iV~?aeP( zEuh+NIAh?rwa>H4ee_{jmv~lrT|O-9 zGSA9#co^CWqSfXYy!n0}`{b5;GdR9${J}m31>c9Ql zyZ+>=wQo&SpZoGXe^-CK`=-XpWJQv6Hj?CtBuN&Oc@Y2F9UHGtI+LWt|EvG2-G6!Q zkG{IEbn`>;#+f1COL_mZ3Vw~zll^hokZ za$WM3!vBAilz;P&osUsN=Rf}AKYqDW6?U>_zzy(vRP?Co!OsUJojrPV>#<0WUOj4h zT%kvw9(6so>T#nUsUC~Mvu?w@q2o#)ZqS18GEojjcECv;zOAh|cWK3SGe-kLl> z1^%Ise;eiYlmAP}pWQ)ED$jkObX{_5^6g|V|KFETJ!mLyF@z72wmbQ{eZMZ* z!vE^qd}_YNyFOmfw^Px5_D}8nn1SD6E&E3DEhFNtj~DZ-cmCve0X&=58|nIo>5oT$ zw@$n~SkZaM$BA*|j^ByCv+<2Uh3&^m-;CjYCn1@QZwB^b$2jBSj}_w#tT6tIkCP+r zK*Kz2+GkHtVqgE~1+Nx-ti;)j1U`Zyb|L>*iBkkE%)j}&5NEEo-h_tF^t^_WM{Q8J z_jjpgHownT$)11i3N*Cs{WvShGwOUT+W()jGPSOJwag!GM(^cf;DlS#7p$N+_axO7 zbmM)=HhmQdms?62*H)!o4J(?`Se@pvwpQ?WdL>@3i_9UO#PYVy&_lLo2`#jKB&IfY7jI)40lGOH5 z&x8DvWwcMx-N~VLbnreR->|NDgv7rFvu%a^^Jd6H=yUkF=6MZSLao@m)W2_~st1$5 zq}BH)BniiSQdM7tur)}nSNH9OgSti40|f6&uH3`p5%3q2>?hGJ#GY@G`C-b6sx{^L zCPA^(fh0Y^m)(F;bDax-qL#}xeIQtqw@^>d{Y2G|%GIYlk5Ew7=(m%FCe~7sl7?(2HEC+$K$#p18*XW?Aq&~hp6%pp<68E z8nLzm1Ttf*dMkM!0c6it$RxslnOi@~Z z9|7iWKHisH_gNwjz#bx~B>fwF5U|zrX0Lvk-q;7GU%Q_?2LN+Z@^aVr3t(yd};BmO4tErLIz=vq68A7L+QbYH4Aq zyR@j(Q|c|%_z8i&QoWRx{;~9TpWJEiAEfNx5V{qlBBRyTP+|73jq4);TXEK38fMpl zliDntgvB=l-h!oeWOzqXt5si2{`eL?I*37|WTs{Y4aB$j{vgw}uhYSUfR||KDU%_e z<2tIiE@}Lae@x|rd{s44-H#A+Qb}MW8+%A`dHdaJbZmsLYLRXpOm-6TjvBPOGBM8M zG-!EL=04iIhmzmS7rYga`lx>XQ?h&=unz!SDf6LxKY5g{d8CFS>6X7G9<|G$5kpOH z9R3Ve~`YHR1Q+7N`3=K%Be;TCMtCR_>!a8yhn(Cga6fdl~cC}<3TuR zKKx~jN%cq#J`CKi&!24&P4SJ~V6*YE&AOH9)Tj(~7dfG%O7H7g^z)W36|1WSaL{&jc4ASn-%BEgV~^l$t5Dg#m^|C%T+Dn`uJvudgo zwg7o%XXXz>#zo^{fs|=G3lPm4INP)q(f!V zXiUu$$XMY&=1H5eStmViG$wUt2aVIunS!c3YcNR=C_jyVde& zG(|&XH*zflRFj!6+EWl#gN3Aeb)ii@SUDE^3>!fdW%E|J8|K#j@ym}vQIOqK*BCDb zmL7?MRn#d;m$HyJt4DpT^3m#pDQlSgn~#o39M0$VgT|_Fg5ll*Me{1m4N&RKzcgw` zYbm3aL{TjjziE6JO#V=_FoBNpn5oa$)ndYE&WX$O`mggARv|v=?5(a76Wv4gKJ__} ztkfqrohSZ=V<(8{Uv6_)d!{?om zqCQkfnHfSvvp022TxnPyX(W;>i||$-tFZ@?Wd~`*gCxgnaU8fwCVkeW_mEA)le$>b zZdK(<{~lsRo8dFFdopH~*h$emnymWpEW*?sFrQSfe9PLXIf^QbBkt!T==tagzi^oSg4(g~g-dER9_>&O7rS zdPNk^Oz`XSUG7l4pR!3%9`>&JvWvO00VSXP9_vf-uUKBL3N_qKiF*n*YKX15) zu2)Zf6#A`+WS_r>ppp~W^u>DraJFC- z@$jK%zUGMLdy}t74j=xVTfbIBlXFRpkXlgpc$ zp^qS3iLQ_N?xC;evmD}x;Cxy{@N);La6gr~5fC-EyhiE)At8;tMjxc?BF&>hzlZcF zQ+ak=7B!ADel|zk69vi#)X3_x`J(QU{A4gAO0wSe^S|gAOI?m)pOIi{XwjIY-kfJd z$yU$>W>I!B@fCl~rk>X@ z+jo~qu9^|YE|vWt%pzycHv*+XN_r*Ja-WOy3k?UEMV~3eFX0tkliczRQx_V~rS|^@ z8h)J=4QF$^#yKgoZGHT_>GB|E7np4ud@?@}YS2;R^r#i)@|$~3pWJo9|sCu6RZzeV;)_qi79AKb#~)vaWS{gyY_ zX|Ht0jz{pvh`JQi=+wF3@T~rr_G)%Xr!}StR)^^$-7#o=g z2g8_*O`Kp7&x%~|Cpa!e7BD>7Wk@o+4p7+#w->R|=By%UbT5zBDe4pn$=lMF%IqzFQ z`k;yZpoCqJy3U|f?wl|}H_8YC+IMM8`=)Pb=)6#7jO;Y8Z(p}>h%j`f5D1C-?SL-> z7`Vat`fB#W5;h&o&y^Uo7jW4rusf{RFk{DQ)=?acy3b;n!pu7~3XZgHOY8Kzu6xzI zR1cKjdXr0zC!|(DBnLo&;SiG?l>GB>D&$9C=uzj$ zP$6OoJ;|oZ1(n~&avEn$-`WMyj+F$Z{O4IW>w}_Br}jWMZlA28)Zbsrk``-*DhjhuUgUFt)zSQjoM z0L;P7_q$%eL0NgQhadtV*{QCAil;;A`_4n-e3hZRCjq;~k3>HkR6yKRMq{nbzs+K~ zmo{p>>@+I?$ZAK4bz_XSn?kExp+G`eHv%S(&%B%6vT$c^0ov(!4R{UOItr~o8ZL_h z5oD=)v|Uz^c0u93p*!*wmI`Jt=Nf0J7A0SOsi+z`9k)Oa_)#uP9|U5a|J_h?{hRIF zZH+7}h^>6*L(Y_Wlo*Z1dpt#XgAiqSUItA+!$yi*n;Hh@+6#@j@vgQ!TgJ!Bf znY8g_Xr8rjsT}lXwEY&fW7L@mCj^Y_j=C?dSA;&J69V`9eR71hqsI^TvQCJ+Te~W! zF1@(+LIrf5$i#D&;7e_{0HVV^&IGsYW`XR71y}}P7B_SIc%MoBLgwt#x@GRr;=bVE zuln{T5jzL~DSlx1Sl1rtIZKxx1>&qE{OGW{&BKv~pNJwU{DKtnoWuUSZ8WM`b)VhA zt!Wp|dO^{10s@M#_pa=d=ZxP~Dc2zK%NovH01s0G0SA3n{}PKST$;%5!2QYxlkj~o zkZ|4s%26>;I%>-)-A_dBH%Ld-f9w_gboHwk@wCMS-LmAVfROIo!s&BBOAzJ`D!WHe zHJUOX2O)m_jpLp@R>rhI0;nbKYr+)q7Kql4+^f0(6|EFxQv3A{KQ2d*vHfFItPl_b zRWtG-jfmzrtW@0BP#&qKeOuYy&$hdSb=D4Gpo1vxvy+2Se3hP5U3Q>x2=|;I`I$I! zn28>|JB2)U%h*{LZRcQNn~QXSQ|?p?Kj?F5!tg8*Wg z;WN16H*yTxZxflGul0nRJWaopPfd-CP3s^eSmd$lFri= zD+w$J8Tbt}LHJ=cJ9nL|Fw_xc@3M9XyD55B!S_fTx?v*r7DZ$`R>GbbA-S%7%q$m2 zZ63u|w(%ohlScoV4v)KU>N-&wj$DJu7knjwM_4CXxvYwJKdP?;e#?Rc$-1$~48eB0 z*CxxdlyhJUsd2pfq@J#^v!h1Y!1~g=AKq>iOsp2@;b_|BG+f&qVe788I85X*{qHxQ z&|;C<@Ak%M2#4^K*-dwJ>t?C0zk~ygPDJN5^cU#>oe_4PfvSTj3Fn}JNnD%6!-Aj> zB?<3M1zA=P$K&GAalnTQZ%zzdP6d<3g{GhO`lYmkBEBai?lIi}izRc7FNef^$~a&$ z7Jcp0&3eGI_mW&|K!3jvF;%VJFHisnCWc{y$j$Czx-CF(@Vn`RBne1~f*q=JPU+;N z(7ty47c_G4q<0&Meti?oSnZebx{VgrJt%~157<2*KghMsvh}%fwk)|TT-r} zCcOB`E~?-qctSE~d9t$Y+DeuRv3MB;g~WC;Uc;!qvN_EQhoFudI6utGxjegr!J=?! z15VNNz@Me9e>{~}eR-?K%-##>gcWGmgtF0dt0OCyt_CZ!`~6aWP_Djz<~0u}d81(C zCO6lV;-P`#mX#V!7ALE;&sv`RiQ=DBTO5G(x&sh=@!i;Av6eIoRIqJFKLSV_oZGo| z>RvOSFGj7~@^0hj&5x{A4&_xF^wP~z2m+0ZqptjOc7t&B`{6AN^6I}q*ShtRN21eJ zr=-Y3?5OQ-HfK3Be?2HH2ri2QqGa%aL=GA#Dn|@AbUAw|cpPU=Xj6SAVk&D1Q75uG z9>M(Xx-s{AE?JTY2j$iO=59gn+fcXlAuGImdB?oJ)qx&&N#_R^(c%sUXa3$1J;zZY zt0*g@bbwLO1EFuGoR^XGqgQeM!#%>~sA_{2pL#?VZ0_ShH;Y%UmWE$Pe!jf&yVh-;p|4IM~{^$UzW=*?W({YoR&5bdTy& zJA1L_YRr?RFtGgRDTa{7z6JNaPGzFG#`9!j1g9^iG7}gI}fg7wN@|aB&XRt0z zoMoS|^6n$7PTs3JU?O|PmbG!$TJTZf6980t>n6yZx}tc(0tO8(NTU^cpK_u=1Y&$` zTJ6`rBFOWaHc$rK&`DoT^=R=(`B|MC1SN{b;l5gbyn0AoxPf~U%ooKKddl(-@mRt< z{P03EIoF+Tzh?dUWmaHbFYM5B;PtRpo&4_W$9gcoZhK_6ctQ`5)JQW!s8!z-cHAG4yzWpeyQO$JFmbg9r)phA~mXtfjx`3e|L@ zWH*9*6_c{Bd|>2 zdSE2JENDz^t1)e4r=W&h7&?;t@&#MOEVOJCgIWk|=UO2q6m0P9lhNB$gF6?eolTv;90OyD*pYc_Y}}YC;Tt9N~~1-^EMy^(^*$ z3)N2K+07O+LLCvZQrQ^; zC893{v%tj)>x#yWYYg!0&fB^H zTiMa0%5isnUR}9q+I{@mU;We0o?BVj_j}rn4_23*lJm|#Ha6NFAP8hG=s|H#W$o|< zH5~7ig?drBp~_I~E;FE}k75w{5oGnhyVEEjzt_#1KyJ#qBR9yRKyPeu!agalO1~sk z3H`MzO#eK>)!y^FnwgNkksQxnVB79)u}*IZsA9+HVjI+B2gThBsv?|fFHU_Zf1=6U z{TcD48&b$!Hz7V_%~{9bF^FR`sj(MP2VFl$+{D0NVx zar66?%Z=w-?*O(hZB#p-$=G&2Nyyc2cUAw*<@&te5CcZDD2bLCK>CR%{xRZ+NnZnY zUtvQX3EBw{az`|wSodlz_!32@^|{VQrQgr%_0e^>jaNGTcZcJOZ<8VBnACX0&tGsm<^l|OK`s8g#6W^S$ z44w8v)-q#T5>b}*C%SaNdk4|yWhPr2Kh|^9GB*gHt2OXARt0FGcNbYOggct?MnU-Q zbwd>HNNWZZ0*^CVynBuRl1)OmGu3VBKI+ykd#5|RsU7;wE@iYIVUVn33~SW(C7bMC zJarYm|Ju9YcAX`v%&#mhj%F#9!8Ob`Bsvyb1sc7{ur0mxA5v zoAty#aKCVUuc|plfi#-NG!F#5UZ~?MuaV`irWltcx7{fO#eE+z_?{&oCd{!DuG$x` z*49-hH0RcEr*)Kf%)rOtM1n~LOFVd(*+~Fj#AI+F!>3!+f)kqX=`fdt4g)4kn9=>Z z{IW&q?pKk!IRpaAku^|U=;@o+A|>a=8Y~waw(GU>q`o0Kgi8ImUM{hDq3 zh=G4Cj3)8myLR(EEnb0VQ5msQ|GH8)KLE2sKZc_Lct85A;;MwZ^KdnF;@N9FHo3a2 zaD(3EF*sy-qUWM>@7CQC@N+Tl)uV1)d1UX{hgb3A*ECsCmk+hi{?p+pzsrRW{Hsvi zp{1$uu zf(KF|9QI}P2q#cj?2+31{5iaL9PHev>htFRvZVg)tt~sS+Y2@>>7t&;uFf7#x+T0< z_B`eTH2b8=*`@+>95-O=a{6Mwc!t*wk&^U@3|K7c_Wrjj2cP3TX7vO~%7%NNt`4EG zn1$zuQa?_0N$BPq@;rPo0Gxjxa=XKgwg@*f!k)m-*I9@5 z8FhoxrB1+K)}F&aj{NOL9D5btu%nNF`{N!PWpS{yW4+iuX4f|uh;gTpryqAZxP|AK zb)0siglx~tlJT!xjqW<#P0{($NoU#Kv7ganNMTkeJ7>&Zr_4ZGcWHg$6aOAi_X_G*;ku5*Aq?3A1~ zF*wO#ts>TW;RQSDG3DK3qdN>vnfS>`Bb%Jg!_F^2%Gf}I699gJH}c*R_y!JS)NcM4 z_tHd@H&8U=Av435ijhvg+jsFkzVD^GM1&)PEX?-VIdibm?gP`l?wzofdHaGH=iMb> z9gYchecoXlc-~js`4kx#@eS6IEmwllEg5jl+G68G>Ik-mud$zp=KIRi-osiiuz=*^ z{UE2j0EO#WDCz-I1_O>kZYPjY54|(OM(!UvtPAw zuOYmhaD1$&u-Z+Jz({e^)TxkhUc`6WfXVNr9G#*%Uir-4HVFjZE;w21{qn71>^NKddyvlXP#2IO*q_vxuzoi-!kxwl zTU0N=)(+X1R6;%6e117Kd#7$$vT>8LAJ+da_wH0zfD$0q)6 zb3d%UZ|*;NXRDn2v&7)Lh;VYBT`2ah=#L%IBO107ekU)#dVYZbb%yeb>dEmO)L_<^ z8qR#g5r4%j*^od74pLC@>y^8!wXKZp*Bke{V~R}}9LH)QPJs{g2?rg_Z9ScGp42Iw z*G0B)1;m#J+VpK?_5&+|@8ms#4C5E5!f5W|U9YdHyRrwZ7!kY7Flevc9X6l^f}lb^ zE@WR=ucmZ;xt9*2@N_1~iz(LkZYPSbv~{vobHT)f6tl(=1RbFD4Y4~hswd!)=u>BA z;PXnrQAUg45_a>&r5!He{PlX&_m%q#WE|nG{(D!Qxa5(+TXVqh~#fQWyMrCBx+Y zR3ZZQl_|2UQyqr=58{EhM6yKZIt)@}3G>M4&h((@<6FKg69gGv%fv$$eqjJIMccC* z@aqSG9Y3zW$}Q@4Q<45*EI;`~6-5KF_Sw80^8e%N^0=!0drS%pglJ?yP1!3)u0!)G z(DzcjFw}lg2%`t16SafU@Od*u!rlu*1OKS2yH4+=pY}4=C;R!F>bb88c30q8o`|wHxMQnxf`urU zQN`}HQC<830h=I3WRCgE`ON)FC)#M{eAgk=1< z@`m=IN0&0>ES01QJvyfDNoR~N5ZU7@E4w{nrxUpA@{)ewh)r{((9EAd@bvp))PIq4rcP_=lwQg3tdrh2x3Gr9pKVSh7jZUWQv*RTZ zXKav*+T$h@A`heo(Fjp+iwQ(SLhQVQ80! z-l6h4X_$BU+aXZvVhJ2}=$M)qkBAE2vHRhYAC+Roe;np_j}!Z1KCvIE7^=oQ07Uwl z!Q^_S5QM1rAP}AZsM*f5Kmc@H%W%49=ZDFVJ?`J(3N5I zV-X<27>ar(um7?hCgd|quuQc-DYkb=SL{^#pjq-fNzc`j;l&|0AHw{=AMJ8-l9UdDvv*aU>br2Ndo{GtOG&jRD_Q(J9ppNf#>H*>zSQ6qga^U`IHuM6{J zRgg|>Xu=nU~?STm2M)-0#S{fCT*XZ9-T?8Gqc{ezJKkRbK2VoVD z9)e))He1HT&%ns=EUof)?kGXq2XPiOeAcuAXZKn^sGgltK+r0d0bkb(`{=+c?Vbi& z*Yp$9SHcqFA2YB!mgo_x|9xQTpBxkCgCc_#{Kj#+{BxC-#XEK zOQ6Hz?@tB^5ojL_hW8WV?Ap!2K&L?Pn8s!H@L>BDg}gbIpEK>ksF#ywa5wh=pzf@1 z9t z=h9Dud|%0&{7@MmIctr7)qnIQ;?7r&van`BR)^KUIxd2|af)Wu@u2(00}nWKPp?q7 z_S0wYF<6{B+`SRF#IjPPKzMOxo8jdypOOt+I1r{qEG_K(;kR<(Gi;j!_Tf^u4mXREIjF{-gj!jfpqulO-|H_{-^;Xp=XcZiE+ZiyL%rNM zT9<7>e#eI(uaCjt?@#U)8GA?8D~hoc094;krCbk z{`->Jx<`q12G7CzXm@E+`;$uktPS=1()HCN>utT*vmkj{yD*3NV=d90?>4R9V-2!2 zY6)M1;F5uE9S>LLjc~%Gbv_Uz8NNn7s_fdrc|2ehyhn?R6#*)C9xhRk6aE$s`AEC` z_gmnq%iW-IdSz|heh+gAIB`AYS_ZmDHa@J;f^Edb5ws8ZgioTy&}~Lg!##o}I$gM6 z7+(PoXQg32PK9t+Cw9=b5#zLkzg@yZvsly6H`t4B1TIS!z|1f&Kf4H1A^2{}W|GnQ zp{@Z8575ky3f%}!qfX`Lbl@Xic^sxsMgS=hQT$YpeuEn+m;W`TTAh>igX(sl&d}#4 z{esp{+g-%M;~d+KB6fokt8f?k5z1bqZ^ z2#N%A3Hk}<5eyK_CnynILr^AIKyV$w^#q?H7$UfVAn73}5X>T&P0&kFOp-;;+uiQw zkmtvEz5jP2fXkmzu)2^W8^g}dzgNX7z~@M2Z2rS0;jozC`(-919~M=F9OROJME>3o z@s7SD_ttmR;5)h%5SzIHEY*;x%eWb;zLf6|m9x`80u&4(+=9WW9Y;W% zJfWU_q*XT3a)sGep$wCbYZ9~wPk+zAU4&06mknL`C=F>h1wqUc5)@y=`h83^9=pFy zX+JZB_ObkLlP$Gg$EceW^X9kN6p)AUs%zo)r0}06h0i60rAgtzr1#&7uD-Zg6*-N8 zu`mePKyY_}#SEKjgg9c0lb)a?=ot2iAI1H`MpX&BPrjx_70`&ykgdoI2#=`@MDV@< z-f{oIfWnHT@KmzO?=HmcJaB*pnqbr{)n9-JL0}h@Ivb&8vE;f{?~iV$A|0@+D=be6 zW68qyb9H_w5HpAmyFHOC2vojIJ-0lzF%t#n1kO(*21n4ktn3f^F7JEcs}y0Ejt`HQ zVIDRV569kv0m*8i`kzd0zEUCI5lD~AV>K@8_zzC{CV~YzkYok{x#6ywn#klI=^-ryG}U7Tf#eJ_vff`WrKJG1naP2cZTf z;-I=Q_5|3FD0?ReHZzDz1)p?xkXL2<0d1jj=ibK!1T>Zr0da|Z6M+LZIO;O!&9YDa zC*Ui2_ZR!F>+@NGWXohjcBn4uEy!ksS_@g~{VC@H4F~54alij`BiaWathAXFmx~TD>J04U{^j1+cN?c;0W8Dj6o+Zn*#orbf9ctr`&xM45)GE7zymTr&v5B#08VgX$hl%E)t2??;ill5$pl zFueg38>69sZt?_m+#m|(2UlF&2YYi60Q`~!nP3m5VVUARwb4*5T%8GmKdk4H&I+z0 zz^wmfaCF|Z293RSQ-z=H?9)jyetj?e;Qbw)Rk9|c*ms`A3+oiJth0m2 z!LWwYO5n1aI;(q6i1))X|9ifc2!X%+In1;&Px@bvA9k2=t)LbZ#?0D8}@w zK*rw~9TBO1kJu;JwK%eWmkEXWxAa{nR9R=z=R1qDOK>%vw5YRrnMwmV5~4~gpWG=xjD1ipRBoBB?!9PmgXuA zT^)t9RhTHKp0O*B$a>^AU$T9{ZVd+kd<*FZ*QTnQYh`xZ0?bX9eKFpo^w#*vAZu^cQx9yxST}MHnkGYdR>dtJDSvc8@>$CgOX!z=|fS>+z zwF!w}gN#uZ^^M9R!|e_~Zo}ZlLCuCH$g2hMwN~H8fV5%90XB5!5HexgWor?ufM0-G z0L^8mWp$td~T#cNTsgcR@EJ>!$2n zmYVSw$6Bg|lG*N*0ljPHPQyTqL&mo>{@yHRE*i?WbasNoB)e4=_Cr6e|NO_LSolg7 zN}u`yoShi8(1;t8-%19un~suKWGMD}GA6Qwm;Fd|M76xb(Ro9*FICWIe$VTl2Zts` z7T-3#O^k$fjt4QIE7zTd z7oay>(=Sz@Zh=*@nNEkpoz#cQa?+5kcX_hH*WmYU;fCUU^0?okD-#33B@ZVJ13L%j z5VG5<@pE{kyy?~-Az8@qSy`F4-=sRSZ!#gV!JFI>QCTu1?>=J3K)~_K@=qo=IWqA} zgQMV}<7oO3UGZ3<3nhhRN$)%VQfE1wf1p7CyARClN{Zlw$N)tF%hv~k2PXNP{%7qU zPgZo2&v%5bJRhx)^*CmEyg_!jy{CwnZYMiTJs^0QphR+fE`8#|ek?uw@ReMl6y(4R zpnxpJj)sAK0t^fK_L+b~CN2pT!W=;)hB7}$$V-;@s>wmSIdU+0AXEz|QP0#4|_^JsDh2TSf?;wzaD0PoUr%;R*)`mp-UKiZj03_!4oD116ukk0^=r;|Q+p7gnu*XN4A&k3o|d2ta80pYtn;EJzZ%M}AN zmr*+?AS481$Px(O0gOh>^_--DYZfVHiY6HB$4 zf2P&#Qt(xSvrEC9y03MAa(!o4e1x`3_6BWLbd@8zFMK}u39^oi+p=rR{h!N=7Qg9B z4c`_n$nStKH0{bqRv-Erv`)m}?S}<{3n|PGh>4Fsd&R=ar0>sl?0sJ%cO)CC2UUoe z`zDSx-Ils>Bmo{ktr_i+Ok)s*%hcN zC{?ei4F&!H1`YNkz8WOe_M~k-*{WF+@uoba*=k@5qjd4*tFZnkEBAE|d_l=zuE`}r z2Z&Uit+sD@kgb>94^dctROjB=JFP=`C|qxYYwdeD{>Sj3VIawYrLrlwfXQuv6(3&@ zwlrE$SpE^t&!yK&K9?-^jA+!NAERoByN(rCu9)521eA|mxk(@cR^Ct87j|n9LAbeF zac3`Gr_>ETDIb1xX)NgJ%i-uRMAc6VEq|e#96U>|yTXr!%5HP9_e9d?io58qH|^m{ zN?Dgpq+MIL z7X|*d;; zgNXI-c*Jof6r%57z?=F@19CfnRxY97WTD>Hm^?XBG#Np|9u>w<23b zh3=-h-X)uh&X~Qrd-j9&WllPMuysB2z7$nVrsQNEIxl%ILC0$>ER4-4VxHPWqsYZzqLaNiPms1>Z^v zx}5XPq!iWweepz6^rVCWho-xDK)!{?5}CjtqOdkRg|hnmILRJ5 zHzjp2`Da=c-(On(p`>s)DLk3<-lbOs`o5yV^>m9g>4oYFk0!mm%3e4G!0Z6}*lvF_ z>5nR>5BKl>q>pzCwj=}DJ%9DT-Yj_9cPDph7>MV9TCrDj`!^Vjw`=Ffej@x)<4&Oy z7G)2(TYgh)FDwPTCi|?9ElT^(D(pw?MU_@016w3E{!ESUR$}3uCJ~V- z{5>oQ;@gcoRq4(v72m0klH|@v5Ua$H>GVGPQ7v2~O@3;DVI54#9a$d<>Z|n>n)nD+|d0zaa`+;O2H<7+% zZnbwY!Dk8N+>wh%Cb;}Ox+Q*LmL7jk@V^rLZv+S?0x*PCt8^?Z~ei82lnnbba3~Q(MO-y`S^i-dv`1u z{p#)m)W3bzvN8T&GJ5BseFqO6*nRtByAK^auzlZ>(JhB|?AyEZ&vrk#_3>}+e(d%g zx8Az_mYuh(UcPqas@-F2)?U}MwNSqAn|t@Gr@edj?%aM*-St%e^&bj+6~QL8O z{@C`1ckjCM@m;%n3Jd#st}A?YOV4o6jkEd&%lccOzajk%&+Z$k%)G4FBK5zRcM9!#(gR}ZZX3g=Ii$cL! z@3Ba;mkNEe^qhG`l@DvU>fh08_2)gL2CHuqyhZRj!5ajx5u7DBL-6XXzREVWtf_9L zc7b4!;9UxTM(mvwfU)$sAbk#}&!P0WIDIY&fS#W#SZecoDz$TTc0T046(X;P$ZH|; zv$T(L$aqzeO6}7rj0}GFRdr)Q)xc)@mFh2htgBx$#3jbDqjg`j$#<9Thg% zwD(!-O6_SNUTax&7yv%<09AL9U%yWI{d9JJp;W0oC2WjVNUo3IRO$o0f^(ArehLW5 z7_8q;FK4dFKvF7I4pDNHaW^Zd{**dzfa<4vG$FOr2%DJMhd?8OtJE$9xMHlHq(GNS zG#X1WR1(17>rwE7S(W+^hlfAqW4E$@)N9!`&>9+AYzeVmf?@{ur<756J zet@VBC042z3nkiDkJ0oFTg{*QB-WLE;B=`*QWP3)gn&w|YF+-K$DnW0$%_ON1TU*| zG4^2nMd!!)VfyvMt%ax`Ze;>u9boI{La~~Hm{w^7_}|f5NY!0 zIVycUX4I;xR{bG$cN6R-c$B;!w0b&C-jf8dO7%yDK22|MTr#XO{?`QGQ?hoHSgX-d zl@2yU8G}a=DI_c7AA~L&Lm@W)feIR$c%?B==o1zy;}=M1GL@MP1RDu95o{sYM(_Z^ zLj=1B9wFFgD|k<#QhlLP{WYVL-GC^X`xQ)`CwZ6x)~Ue)PHZs_5?4cm&DU&k?lOX$ zX0-7)$=2Y54dH39@f5*HU?2ZQPo?pqN@tj373yuARWQv^jd$p1{8!dd<6Y%Uy+!bb zg65goeSbXu8|2-%psY0B3UD_r3GPUi7fbZO06e^qQQx+ z1fXadWYxY*0f=cR7;G5pj9=F?*cegXGbbtdPpAT@6R*N6T($xLM;Xx|Df3T-zaGOmch;v zKopJbRQa@$lLG{0n>>?!_WLTCyn|pJC9GtV6_{)gOcNX-0Kmx)6-*V0T_n~^>>L48 zouchz6#-m-v>+h}r%pWr(v_|}drk>3?S+K&)S%-jK~|e>!dH)8eG@YV!WvY zNHn3r$#)4Z5WGk50i7&TY^qGKfMAHcF=FdLIs=wMq!=RoAp)69B`pZ1)=&UFVDVVQ zs*+=kiLi!KXBlA|!2_(##34<3t3m!-hg_7UT4AN9&Z*HPOExX=D^sT#64)xu4_nch z1u;6%iZ(B`qBAC()H7;$N*Jk3y(>78gM)*_C5Mg+4^-6p7|41(PgMQ#h?mo=`Bwx=b%oFtJ`iQ|nP_T9sGH6Ba6y5XH2X zqB1SIsZ778VB&cNQ|AH-rZ=|6K4y4H2za{`s`bZ zP3~80=3q;noJrXcEHqwIFd@tg9=|~F2En@o=Ly~>I7e`iK)nqfe}@3n&b+Kx^?ib0 zX%z=+v)$mX{-$SSHp?nZ@f=i!*>NY+TIeV;?WtB~)9PtPxAMbtSo(;1X38_nQK&{0 zM`q8DC4<#kF4fGXj%WIqpNR(;N`=08noIqXg6|r6%Y2locSgFWP$(b;l&68$ioe>D zFx7X#$ajUH%8@&44e4MxCAD7=Aoh;z3MI9t!NrjmTj}kE5Up=6nFdz-+V0AsR`#H^ z_`XIta+QO2vel zsOHgLV?|lNSf-VuZtK$UFta=}Y6A&ILsRP+)q05YkXIK}*UITh~W;FEOSmgGr zmS|={i>#U-W^!XR$wXt_OC>F$15%gS+x)OHGoUf1pofW31=kw)r+c1ZO4->HZlA!jtcX4s6J0?g#~*+!B%oM)Rc{5@#0V zlLNV=wRong(Iy@M@Y!LY>I;DnWHC-W0yqsZQDcw_5Km)nsA`ta#6zK=iZ#@@fflD) zOY(FJw~eRanrB`lc)3;n6Ikb&SJa0ak20Do6Sk~2bp~XZ!3Ki%S<&X;vqJvhv!a^8 zXSE=M&n_kyBY22l7eS-YH;3o3RODin*g8zIQL|}y48ELfE!yOQR_P+aF*(|5#)3~S z#<~#YnmIRlP+8BO4-=Vsq@c>|E@g5s^xG<)NvQLI(|LdBtO5sX8oUkXX1-s$gCrLPg3fj`2qE&iB3tFmL&(A*i8wVN3Tc{2-8KeWU%MOUxW z#(I8>d^AY7uK${b60h;?l z$DW6g?sK-7&Dkp7ugb@RjF*wpQWniqGGkK3qZR*i%)u8+=J}AG3>nG`w9!0ev|*Oh zDSBO%Z!KX3V5bAvE?F)rZ%QOxIlj$2HbDoQWGIz}e8z%Zvf1-I6!9I0rH}6lqXh9C zw57L^JZ}LVYPgI)4#sAl5`l@@CCjzjZ=BAijMHbT)S4zZNx;lzUL<%)!SVOnMnBR% z`VqvzakHb%<~XnP;J-+e`7G3QoUV>rSKlWFy&ivs;4}era~z61eum)eoY7gOky*v! z>``_OMV$m#vUfBY8J<1b(?gh4WEPLX1%t!Iq@ZYXaKUU9Rkq9Pt{swsK7u&}bG^|~;`0PhX+Tce!rWwbX?}?q zS@Vg^R#)>&RGUqpPslLXb8~Ej=Vp2Gc~3rXNp0py>M@JPrCCJ*R+=SuCmjs;DQ|di zj4H$Oz0Fmjl8RZ5reits#ig;qF~#Ny92q(mZ)LE~f?L~1ErK89-X{O0gr3cdV$ZRDBGlfuTdrq?> z=eTmRUCwVy7nKfhh$MdnfO7kfCbNLr_-b&N=#Widi0BfFE}1i$0Ax|1o5UAmYH}|r z)Oi6@)I&7~4;N{4P}Qt@Y3^u`WTKtj+u~?{cB&{RFV*c4t1whr_F|^d)vBbNcc-ImaJaNGigPs^vVz71{ z2|Y+u-?BvYEla%aiPtUhnkQZZ*JWEEg=+Dt=fA4_$~NWbM1~watoUbM{4<)3S+g;s z3oN>T=wgd1RA=YC_W9X~Fnp{C;~q2i7cW`NkXpN8*q+tuu7-vQ#G$;;gE$(2#X>fK~WnSo*Ov+kj0c! zIppxXEGm#{*r)LXSY=b?(0r}*CN0sYEye6~sszz_mWYZ4q|`E{DQfR{W*ViYt?%F{ zM6L5255-CYAqV~ri6RL}535xyzNED~$JR8vCKII#<(3O2GbY&kr$jO&brMW8t?iiy#kzZm~ zF;&6xgh&x<1`73Hp;ZU8RvWYWv;@-By`w$SeJYW85;SN^W&*mMVo#DmP(b7 zWXCM^ZXFj`RXQ#NpkLAiB-1s!BFJ+TXr9d46F%`2nPhwQd5(GTqJNfh%=fE`$L6&v zmwXXe82wZBe8U-pMu}HPBFB7E{Z`9Fbu3`r0`!RNYg%2o2oGfl?`#?AQ08JBaE#)s zq#XzZx=(PvPcT%Xz^e?jstn|-P!L9VPVwyMq`f(4j$LX{XxXk zkJxzf$9XkVTar&ys~`5f!z4^(sh=Z3CDva|)r+K)^&%~Hq@)%+HDMm|TRBOh@q}>L zMpLs?Kvz{IfpMzPM~kIc#?t6)!(vr_LM5+31&SqJ*6B3Gx&dNm+om1fVJZT&Fn6@q zo(1MEg<3`DGOQ#_(JTQo1?C3K_J_#45WxblI(;EBCq!H@X<=rEoL-a2%5gKn+F{D4 zUC4%y(dT0HdD;2`)21RlFVViatZ9{pP5r-u(I~y;fL~+sR8trEBY^_KNXvGUjf((N zFO@0{NvL-vQd=Q4^t2<;h+2YQ&6kC3;(eji>aVQfucf?@6|Dra>zc&yUmJl=m98YS zU3EyErdhI%;d!7KnO!W)9-CFLi0obED@wyO;l0S7M^V+jjxv@N?@DeV%Iq#>&8Ejg zprN*%8wc|=6^}_{sya>VLf8Dt+SY7>);EKH1tYI|+n znenxW5$h%LwcK+OLYu8U%eF=}0kT<$9jrcIswAL?8xq=8`xOi;Im!-EOmLLOvxa5o z{2i$36)42Y!}F6~dCfyg8x7SlZ1(D&2a8u0ysdaY)zf?tvUWcvo61G)ds8XZQ_uw# z)NR?dt~P~0C|V~{Yw9ezKM|YO_$TO8NL0{DPS>=aJk&snmRO-z1^qUcTED2SpldIK z!{Pz$g2nB%BZ@ZDUTWoXGTSSNxc`nyC1sQb**2!hUdq#CQ^vBktzOnFD?xw#YWI9u zU}~MnD3TV5YavGfZ2=9gOZqS}ly+VByy_1w5Q@`W?W(auiXhLko*!J$>O}i>I??dV zzARLMGfCjuac!ko$rlROCfD{@0;fot@Z%2>vX**A%z;9xIB&F9bt<**4VQ=ewG_mE zP#zXPS@ee^nfxDVKdJSh%8x^ZpJXfiG&cMj@1y4)*&6fbBw)SaD7tLFe4?&8nUg4TpJQYayyX&1FD{4L&;p}l}u&bUoy@0sYJ@&3#?+u zztJ0XD+&fhP=41ZbJ8wyJ;a`ixqPIS>$wfC=;Pq9+_jrOrU*9tA~ivbjd9C6|MTB1t*u9CUViX*e7WwmCd zvi{e&gY|n#c^2C2$-p?9eUE9R<5G#JW%`{v%d}__QxWQzXEvi>#GC8o%9Xu2JS?+s zmb`doxzx0&9x=xSF;V!4VM2T@Q4VF+=S#nfpG2qbhg&M>G#$MYY zM7IG7vSy6RL}O~F<`A3q)%2t@S#Yg~xKnJpS%eJzZXO<12KmydYOZJD8dSKHxe^+? ze!B>q0>#|tI6Oz%U$R9yPO^cB=x(I)buo}&kZC6kT*A?3R$fs|MRS9}y0#9K zAjGJc$39l9FyAW7ldi1a?*B5Cz0e>QQ_0(uG7vjeXQf#Z+kvUz(cYqTnKTl!MFpy@ zR9}6!)B^wzXNr+N(QV=C!mi?6PW6TB9cFVei3HS2WAGAZ#s`kX0W;-f|{C zCc2ZnwYZ9Q&m9$JbsJPpXn`Q$ih|c*Trt`Q-8uQxE?qrRPv+4X)TV_rFu{hVTzfA~ zFHWDM=~Kg6y#?uWgIXeAYftMYu5K(SqAtWgf?B)O)|A9Xr?nla)GliJVLF?Yc@03< zm*5jusw~wah`3FvdZviM!Dcxh0hBAHFtkF|(~SqGc40uvr&YyptsnKJIjZ3X>&KO* z8$D$8xMHnKxb*f&C@6!SW9<$0WfEs^*eEQ**9+z?vZxqKJyxn8Xk=C1OQ;*X3OCJW z1K6+WTpODg&OOg90VY zT`j^l6Kq(lgJyo;ip>8VidlSRx|ZAwo^YCzrH(MCzL6(?I~2@Ei;I z94)eYuGEGc5yuS?V`ly5t`(QAO;|&_X&kN;OG+T%ZYY&CrpGiXgy0%oGZq2#$pDiy z>qA;YTY3!EeFn=5;Yd%3AK|et+!2rP=g1H3qOkvo1oQtbq?n}!& z6Eiu(&@E?Mih8dl+$yeXCn0oP^hLU833D>*;xn3ujuwe0P23Vo{qbjG-)CJzaYNcL z33Xd{)tB`U-7fKAc_>j5ITuQ0#UxKj%O>;c$81fE3&cW$)iag4q{$MQ#iCuO=hA2& z8fIWv9(Iwpu#S6KBy3Z^&mta3K5To71vThRU$y3^T(j2Ee+MT3jPK-Ncn(Xaur7a(fy zl?#?SPO4rmrzd5gZdeQ|eoIR?EchGb|_7=+52nV+i}p_fXegm~c=!fzEWpxL!P zJzrQckqj8R8rEFY*`eXtkn~V%LgSwmB=VF$8_)wX*3U#&CPngesqp^ zXDM}Rq#^c{tz}u_8@dw0O}i4KQ1A2TpU2+TYd*reRof)MQlPI(vuaX>@3nBy%9ZOS z=7#1tWXLU!6k8L`R11yk|IR7KL2TvTP^m*Yo+~3oP`;hTYp5u4t!tiXMOkQuJ=H98 z#K$~}P9-m^l8N~GDw8|)HU3yPH^KHTS8BC6iI!V7gK3K=rJ#$rRZb&kRI*8HqGKaY zkJUumPGZ(%OJ&0V%0bFRdw9utZDZMT%b4X^-;8oE$p}EB`3^&4i`CwD5Sj*pn5TYN z2C2HXnEKOu8!9q^RzIvwPa2b3xh02j^iM3C^)F`Xn+~YE zLa1Lf3>+3e$yio<9}ky`0E+EEv!7Fq7NPAXY_#cjq_+@ zoJT};jq}bp=bh0Sq!})U&Pb)nhB8*v$hJHe(TCt1zN1%?A`Ox}($Whq3vRJ0s-gS5 z7mE?}v+bah;h?J@H99Mf>M3!XhC~25trakmZ86?s4aaBuW3G4ex<7v7ne+X@Z3rRc zbwC`fzX6E-V?D4HtL1=0mI$%171p~q`de@}ftqR=HYx-b#4OLij<(8g7WR%0gfT(R?RBS%d-Vo_$l zpq}MtDw<)^tf& z?(^AP63W%Fe<(hhEheF!6@qL%gl|vJ7Q9M>BI{?ygTgdB=(SZPOrpvxqJSRry#^^jBB^`ReQy5a3DYsSi zu%nauMI6>7g}5-#^Vx|!A9A0|<~}FUsYVE!*`jrk`IuR@x(p_lhHNIk6-Kwt%_*OF zGlZ7v^;F~(c~=aso-l@6QoH0{DHG-;_lZfytJ_|U)gx(13;mOva^84JJZBnAetr|% z<2p@$$#d$iPxan#!Zj;SYjvnt|4<$_W#Ez3ndJCg!#a2aG2=-IP9E2d=L#G>?>&Y$`d9F>r`U-{@vjt0XlPRifRUSFVgN z*0vm*L2k?O#YMT|HPYe|n;1Q3nX^t$WOeES)eF#)J`W*+#<{~MUx3NCC4)J*1YO~V zMEh%pG>qUt7y1)~19gfzNAakKE+v;l0Oh+)=cDmD#&F+{0WvaMxR!ZnqqG;{)#$!i6P|GYZbj9fMlo22GX|7E^5MJZYgj{i_+KIVkiR{)4w;n8<_3^s9Ez6<&I}lt*y6llb*U>Xuavf0X9?v14bVX zK#DaMr-DQqjs}yxHqmAH(OG)veFHYU*9r=mGMRYe5iyD?>bn6FGP)nbn+ZJiioZX{ zf5Hee8?KRHXsoNu95Wf>?()Vu^O`r-nG1GiV@cwwaYtq5gx3*-N*W{0Y_j$nDl=?& zbs@kTZb%>AeoH0ktu!{a+6zmZYA8!=%R^}cW}6MPsRfKx+T@))V0dX(t;&{GUxubF za+p*aTkMR<+8`##(MJP3?E@*z1%0auuwF@D8}Lf3D~6o8E#(-ZhBmWoR4wksBEMf!1t= zW4$HWI3sJe42Tb8GOWQqL(fAkU~Qm>eBg(|>>u)_nvarZ7i+gGUD{b{zEQ9SvX4*5 zse>{PN%g2#+czSyFsWZ~YHFPDXGk~qdwS};5vsmYVds*fzlklbYI&al*QfSuPom7t`^stf>USfWZi7l33AhFN|FS+1nLvm(_nQTHt zsnLARYBXPSjSgLqJ?*_rTQB2pTAlGXtpVhs_un@uA^swvhb5|>kcUjica5j8cjV_P zS=1^#h30P@E)}FT^)%E!XL{NaAwOkj^mpU164`ulG?o|nkC+{+?)oHiRZX4i@kmMS zND^h88jVV0T2&NrN@!HZ-;{@kg7G)CwxGgn5LIA?jdK>hMmYYr2KY&%5C2ezqw)p4 zw%3aFw_-Akkbf%mv0th*zHei{s8})P8#^|P z5+<P38#(P8b>VW zZ42MI#;mtrrk1Qp4(Av3j06z*D<(8fpRCMmtxOBc?~p&;U_@hOXEarl5iHL3q)T%Q zwg%>`LU6#-PfC8N=;>C=k`#IBZOY_Yf9ulzOr&i}6AZL9Z9TEg>TO7ie3W-E0;H-Z zhAI=I`p0Ru?50+_bGV6ZI!H;U9srxzRvL_OrI?mX%2&%&aTp36Ii*VIyZS;3XX(aK zy~F5|DP*N1sCE%(wZi=+<&Ep}F=mqUeVXf;J0ejmtT0GQL(d(aeGOEQI*@uT@B*{WEz1)1+nl)dBsmFg!*gS)x zHTD&=hJ~@I2mvMK4W%=bb9#OHIRUtQ>b;iElq{J(3AfJ-RGRqJ9Fa2%lr8VM^MQBS z{IHPE(2K)u83Tp9uxVcM9no3AVz+EW5A0qG^d4l-B{8xPAr)BC5#Vp|8Ore1_o7~~ zP4D}cf z+s~1TnC`MNwF{immmgG6nOFdRJ)GWXTej)_eh59iUxL422Yb^e4Kc>Q`i73#jC`9% zbLJBe`Z~i1TUs{DEg@cMN;lY9L}QT{+A%9cw&KEaD?T$&n5V6ccQLcT>E^6duGW@S z)TbX%mBQw}>k?H%7Tbb`DD+_&3gw>67v9(+j?1;Prlv&RYS~gLU1|vpAo>(sN)70t zPY#q=J{b!7hq{~?6GmAX>C;{wIxI`yX4E2MJ_|WLTpONPCE?xNN2cannYv_U6RT_` zR(WEBB{p!tugcY*>ML8yQK&%+5>oniopDumX`w0F)xK<<)V_Q}U|+eHgekWOCmw+_ zMJM_gg@ijR6AJXr3Ddh%=VdU;6t7I|x<0V@qyUCgMc`_0Bu&!HN+Q?BvAkkhYvK_l zMJN@E1YW@G)LR{m`EI`aiO>2Kf5;T&v}EFya6&clim{7wE0g;L0F#{D=XT3_xk^$4 zk*JZk_A76i9d&<*Y)>N-Co7G;+JH&#U`Cg9MN^x{U{dLBVoX#T-!l3XCyVYH0u5%h zp`Rk0GHYbYEU&3I$nibE)a%B7#~_Nv{i&r_gFq(_JNRPK!jMh1@jco#zL!q;Maz7~ zeP@-%54G6(*qPR|=oK2NyW!WqPZbkXf2|Tkqg#XDQ$-^_qk~2&fH~Rn8DQ%eBYt6e4(9f7?G*?$I^fN@KV7<2tyTID1{?*(xVUx?t+rCEYX+(W2kj@`I_y zcDk7Ow81y=X(iO0gdQAPOf0Q5whvA$w_0mOa$E>b>kl?+ayXXsg*nw9(gF+(dDlQ! znK(IQU#H1uu* z%=FiSNzC-~(tLla64;x=U1Y5g#HbJNiS{P<*|uwPpT09FCQw=t{}95YZ&fGRs=8xD z5@nZ>|I}7JO8O|B5zk4&DcuW{HW^SvyQf)cECmkHsiMYdBPzvolLKpGYCs<~)F%y1 zr7QUeZs*ApmBz7(ltAOu4YJzi%%MJVSefdrOr9%feg*C4;@)U#%-nVQ_@F*L zXwJaNlagV6^#6KIPLg%V7F~C8jUf9N$93PhXHRfTb{X+RDtjlwIk@uNj%LaoskY(LuHu zyiN00U~#`^IhQI;d84sLD@`Aw`HuJYo!Xk6?vd@Fk3P1d1Ffh&sM*RD zb4ey(3}Plty{EY|Ke4_N_9jHXyZwdM=6-$gG;Dq3Ym<>6Wzf=ovf(YGaNSr-Mw2tq zR4u)cB4YPAmhsd+y>P0REr?GyOf*D~@**q+DpX${a=cHUY?-VEFj5!y z18=5>7A3KUt6)uIuBj#@Jc~2E&TdlKjt7^R#uJBWx!3}cVXHoU5;dk(=haCeNumC= z5I4Pqg`Hl-1}1G*!mJUYOs_+?nWWS=#}vmHMF5sHlHCP^&{bsOY+{wVHCajwHyP|f zb&17R*P=|ak?HU``%9Co({E^hauFFj{RWw^l(eM&=4m<8uP5rQKb6ae9*kg3P-)~! z#xk~H^+8nlb{gH&!-JaJ5Qg$_3mR}}dHdX|KL$dZs|Y70!W1tP3OnR*OGK*1j1{pK zx0^*{ilocRS*vEc1x;hm4D(HIr18{NL(=qqx$oeD$(N;UJWCF~2U_3h!6#rOu%NXO zv>X}aqKo;^!o+iWPy7WrRXNp8Ps-$FPg*3C0%aE_QU7iP7}}-5Z7PRNCC(fKa4F6G zcGqG0m|{lV+D|v$ald0J8gpS7sET!UUjvjK`EOt)80-p#4++0 zBGt4h(u_Ar5T?MFWV*4erNXE5E@nC*6Mkf>XH7IV+?Jh|7BTFsN-1}H_ZzZJ9%-?< zIJRKD?07{@mFgl8 zT0qO;HPE=aTpjo7;L_5NdXjv3#QzyGwqzifbrce4Z z?U(2#tzopifOqgTHAmgRN#hJQW>xmLe4x#ZETEjrYS*G4WhyB{L7x(B6>l^FryQiE z)!5j=NpqvCE)!6u=2Qj!X2x;I*g~b|8hxZ$pJ>ju)n3xwB-T%#K9r{c=Af|joR?@e z<|S*gn3~l_TQ}>KzN#TJtyO%Rp( zf}@JA5h`@D*&3(ioX&Nj-qGP3^)@5+P;=j9ftYB{hx;Kx^)T_h7WdEv9tHeCq9U#R z3x2}3rPA2K=2J%iI)vSZ4i&kOtM9Q_^zQU*4Q$h|G*4EV$CQ;#O>Z2TZQ|7ZD$N%y zam0wKc|_o+cQl)N)O3`F-BrBbd2TeA}f2n=J}xjlZgKAO-gJ_W-$3UIrZ2;pdC45X%6}sgCVD^DV}8b^ zc+pozYi~+Zu}*@qfel;_csK6Vh|nl;~kbvB?U1LHmGXn}X6w}j3ajkWGX*wqo4lI{YZ8D`xF zr?w$*_28UC&TPw^*hGKY6)9`xpk>V*v>~d|E6-Jm%;6D9H~IEg8n4nuHsuXL_e$5# z=xjB9UA0vrVVy0>_^+*vw5C*c%cq^@ZNd&f$~9g!?4Hm!?JaUlU%0o(5f!z-d9A(u zhAw?>>yr0SHqRi{4~%5qlglrdQh8!HfR+mM#`( zh0i(sEzW&p2C?^bS8>?BB~+=8*h@kZnsx5-7b-^{u!lawL8`W050!16qo#-SVz}kj z2mLW$QW=&^-(XI^FJl>MV(+!7xh`CqRtE4 zW}VoF8rJ0Oe;v8%{m?YQ)Am*RdQm^_t$rPN=#Z$a%W;Js3L#IcO}<{hwMjJ~6=A_H zd`=u|ohQ8r$$5>R=p{wIfb^Vze06B9pdBg}M}~(~DtqLooTumu4}4!jQzNDVRejwy zdC#1a2oxfQM1wXdlcA0RRbbvFoas)_0>=$Q~V1 zpcE#{p5UP$&-uQwiR?*V>}Stu$6>#z^Q`Ncsy^Hm_tO9+^TQPmbd$F#gzG30pbBhxA9GRT3^l1yvSa?oN^o?aI zpC!~Mj2G(@#)=IS3=u4uvseS`BS2Q|B~`F7^pRqXq;K*PzH8wH3kMbQ-Cc$H;4b0o z7QRMjWsAP5sJ^O8%eO7#XOxW*EFf5Hndj$fVAD;TEasn%wLJe7L$%)raD1kT&Z-ys zLyP(mGU|sdyK3FN)4Nz7w6N$U@0pL>ET@i2Yf6N)sFriuH{t>(UTVza6;hM-AMc z64qEey@jpX`Z~Fqb2SBE%@Td16??liWqrxRMnRV+h8BIm!>7kLI;^{~R=abp7?e=a z$1Mm!Po;Lz!nc5)(H6C;p7jaw$qI(DPfqYftWZI}mgjBeM^FyWGpNk=J{+@cj5^_9 z{reWaXr0&e8gQn?5kQeSLLcedx7HmxPjBB6XD3yMv_sgKw^+*BUwLIEW#VXU#bm?& zFdC@;gSGg3&no%YdfCq*w0Hchsd0Sqo{f%(I@|PMVyr;O{rLoq6qZlII4Umm5 zwnj@@py~||wXsk?tY`68tjf1y6$Y)0d-x>r>W?j_X5oZ|O$&`;#-F$Na|(5j9{QS1 zRJZ2o<^$ro`L4LGyb}VFY-#eR9LJV7W#J+`Zjnx}ZS^T6SG`&x25ZQg&5bO65lvixU=vZ42LVa>3#Dp#)>U0m(f{N_7)XVbl1l@hS74_HxN$DxA=C8 ze_Ekz3Cr0n@P|lCZ`1OxEpDsY*hS9dNx~^B)qySXMby#BAn}BFwMO{tTNWCICRvJ# zF53{=NVsm;iUSgskJzt?$ooA?Z!)B^;3dMC!p-|@( z3U!f3p-wBvhZM9EvV3bLPrY*Fq9=USmkJlXl5){2oY+Puw+y7H*FA2{xGy z*6>9Ok0_M4$t9J0IAUCWjC5hJR$^S`bwP$ry9V?!$3%KA>^L+x?3+nZ?9sNE{}$?v!DMUU z`mY_>zW?6GAG_=D&fWX@G3c$29C-XYPxPo>!RlStlgzts_knNk-MM@Fj(xj(w;njO zJCQ4lLWO$PzTK15_HTIdvF(rU-MQt!rd>mFi^A${l*F-nnz_nzhSUkKM9sY{ic4+x1h}W2^S8+PP=v z*sUv9ZQs6f?T)o8ckH=!%`GeT+`4P+iq)%EtK(Z%?%cUz?XA0S-L+!(u06ZQc5L6d zeCMv6d)Dr`b@{C;RxQ8fma*Mq+i%^meC_h(Yj4?c>+03F?%1(v&+1h>cJ5fSd&Tk< z%U7-$+p}x=uC=>Xt=_(Cg*sNS{1$;Rwsz&(6{~g%n|p3uwR6>))ysG9*|U1Z_8ogx z3zQXWm+#&+wteNQvE9p;uiT+v_v-Dp?pmqDZZ%sYz;7K}b<573w+6g#yZiA2k3Nyd zau(zNPkUb5OKecRJL*WI%pce;pHc8Aa+Kez>gw*9>FJpvcaLX;v*?|k?&?>s-h1`x)qAh1#re_Ez1Un@SST!1 zi%a!NxwX*D7fQ`42(nbm7pkpFzE-0)l^3hU;zFZREG<=*nuSVrslHTdm0HbKwa~~f z)|VFZt!AlE0=tX#e5qM#E*A=wM!CLNUar;}<%QaEtFl~JD%Q&RQ$^&u0EMf1Gd32YMO_1 zf4At~Hg%(ZNdJlU59xl?bQf~nP_-RHnES(m9yl5v(*4-!P6Mh`FQI$qA>EIV?mr5% z^79GyOv5rU-_0!__=fFamh0uNd#W|Ui-(+eV4TQN*C1DfaDqPM!~@~PEu%BiB_58( zN9l8(T|0pjBVFPlCytU6cQ8)ed{ynKu4y-oz4J#&U0udjIu%5dbi`J49$QfnTj^Hv zsv5;sG!a`tP^n5GtZu2RBRHky7dwcpbP+M)v6W7~q?dGrkt$lbvsgB&s)m4+(XAMW zt*D4HQEWx8bW3V}vAeK9F+Lev=@zw;*2(K?#V8__w%8qtt#lWRieAd&0bM8RcC~6r zt*D5tsEeIySuN<@yeeZWDq<@tVk;VAD>`B;T|--1&^v}ku@zOuR#cs_l?;16x4OL1 za@C%(@3_0?ZyGL*x|jCKxe5Z7&pa32YMNf(QV&;A@&ojY65dfz_Id0y9FFEn!*TnL z@KQ7ObcQ{#ZdiuuA(C0ju-w1+s*+eVr_?MJ*BT|yXv-~XpZfxrtK;Ij-hl+8&YC;iqqx4qe^N6+=mxkN8DqtfL=c8 z=<$klW6!XhKIp5Qp^K_z9V)fA2Ckvhn#x`=mp`j`=C*Cx+gX4gp!uG%Z~8k5F-Cb& z@w6Ssu@qI)oPkZlZ`3}5>ey;@Q&DYQ@f^*>wE!I=OjupL*vKgxJD{;_hq_IT0&v3v zHJupnhUE-&rFLV516A!q#Q`;4e#J91G(cB6pbR(=VKhbqst%0X6Y`~agFYk#e1<@y z#fm!2q3*!eD8`{$hl?E6e4-#k$!0r!Q>mUHD?K9^_ga)vGOA6d)MRI4*EE&ZIP zcgqMv=Mh29cS_ZQZWy|{w1i-6r=sNx>QZr0tK`ca#y*x|F~TH^B2N(bP)NQg=p)Qw z#;O@sOt^g&Y|qiZb!Y~|J$JFaYxZm2p{-rkx3&t5wKA+W%X8v+`VUf2Hi7GhV2WH( zG-m}N=o|b;2&ux@l?-dl49V87JA1~4g8(F^0})0AptP1@S7!k<1fhlA ziu8*ycxA>eW!PdGyba^PmsD;#oKlj`CB~LB?61uF^bOVZj2n*U-&C!E5fTSDypmz{ zS)mXH)SQ-So8FEArUhIFkzdZRm*#=fRDCsk9=Q&+47)h%^Sm{~Em>sjlNr{U6#})S z?PGl3=2A20b`3YgW{I)u8Fpn>SV)K=4c1Uy*Tev^ZukQi*)g(1phq+_?B$uE5vMTW z(HuSE6A9lu1fu3Ob^s|t1FUXj*yXv8|1QIiMa|FX9l0ata8Fpz_l3Z7PZD&~O3J{fB8MZz@h+7zCH(b@UAcAe9uflS1 zA_**F2$-jN95raswh?iw2*I1C`Qi$OcPdJ|@ZEtngbdg|O{b3mS{?K{hP$e+hU6}S z@$C#-ot0J`9{~o6%k<4XW5w=5^Z17mOo+if!dx}BVVNbtgjmc&`xu@PUXY9V)w4^c zTC8;?aPV4&y)rAssMiaEB`CELRLERfP3WOF2aa#(P;n!uVf>j#6$sQUiqhq-juxt!}8% z&{KvMnMVpkI5483k)sU3`Ba8on@0*s{wVFVZ|EC`ePd)CDMNVX(M%FAm<+~-*^5Sj zGPu8*VJowuHVSC1+x21^vpgsNLU4v=Vr~@*Wf{GH9)%ggaR$i04Z&2<{qKc+AbzPB zK>@Mv1(}h-vI0`mq+}YYZ@Cz&F)3&|n8SHdV`fyU@^SvXV$-ZPYzY}bS2JvRRuni4 z-m^dv!^Old0tL+jM?~uUf`+sabdU#UxWj$52=dNicuGi3^b1f(DpYc9gjf|JH%A4F z#*TSf7~s|RRm{R@HWgw;T6!L`$03b$d{U6p=1_66$3Z1oCM6JT7DX~b{7uLe42jtM zg>>9J)ZzfSAYf)UG$2)G92iGX8WySw+BM7QnhIp$C@`slWA}~862{m22LcT;j~K>T zO%fobax4b(3qy4)``X+Z)2WJRvG3&5u_QWE<=!F%7Ki82oU=9 zwE39?ba99>%jA-xDg5@6&-$A}8>&r>U?qqnpBRq3Lzgu*@D=BatmjwWZCdrqwny zeWC9ER)!7k74;?!Lcq^DOlgEO@RQmBjY?HtZLh5=ZKUq>RAmp2Yh45zc2rO47>2F% z;L6m=mu=s;hN0~Ee&2iP!iD|)ePnX(`?TZ&+5ei;yYL45yKw#!T#8uq z;K_!!8$k%mLv-X~hE*rE`kHCK8B3)&caiHlkNbuTucJSvIX%Z7M#qNx-sex3>FG~o z*g|U6SGn~PNXLc~3L2EtVuqDwdiI(FpLD1d(_L>I<*P9Tlvs6|T1|j3ia^>lAbgxc zMAXAbn{v%euG+8}Xn$INO@xA0kq>+b4pej6oP7+=D+UDE(+pcz5kVqG(sX+%!^-Kb z5T@g~i=(8NPD%MBYF@SnJ%hW}sA95+(q^&(clo%`FH(X=h5;zH&*sHAFdZQ|bc{;| zh&f%LqsND60qrwgpkZsAyV!7z_@D?$nA(A_asd*uG{k<8aOQ`>fSL{0IGl-`@nx8B z(-|MsTr7Sr!@hGK=^6&iW6HchQh~p-f+nj_nMi!mV7j@7*I{$Ps8bar zoDeavB>zdiBp)Xe4A}r}@rCuX=%`$yksW^SBI)EHnDB~MGrC>x+X;LOx)g8chy|a zyU;_DZx#z$v&F0{a)tD>*z5p7l2@qK03kuF;fm*gMiM~KYTBCv(?wnZX3TBVf>kA( zkxN6Zlf-bL@oYCEdEZFs=2n_;gLO!U95NP1DNaduP62wENp&alNlN`b^`FmGHR zMSab#8#}7iUF+TlU^T;Tj{>eAQkIJ2ns0GoZD6u^A2ndk|EbX$T8=A-bRTfA|80&!d+v7hCd%7)>ZMpZ5r|BZw85zeS^%uH@Gz?Ek_AxC$ z3O1U6bXZClkXpz_{1utdZ@~Q+Wbi_nU|hI8*;E%RgT_pua~I>**Z43J8l7+zd^W@O zNLP{dZNUu~Oj>x(v6#9@jh${&j$2gRT$L`@QT;jSlj$i(y$S88AB9PG90N9#{Fk8Q ze`W(_G-f(TbBBQ1&c5P7Mlr;IsYoAE#u$@R=CnCdX^3fj%256Yz9j<$3bkhELOc-lf5J zK9NeH^tS2~EdL6?wzF?ob6SKnG3m0Esr_;w=?^r265q zy=S_PJ(Os>fEl!p8T4^sAD{I^=)=X^&#>L&sC30^VRgxMY&sb8-z>m0>}1#*$5CPA zcZed0RrrhcGt51%`YbC>*I2#qCXx5;`09;GW2{!}Q~*u>qfAlw?~)k324NuGu_FBP1u(0fjusd0cvv z98eVA8LJZnJ-%j&I(foDteF@d?tUS|l6I;JboGs3HJ+DiBk>t43lZ~I5s_JI2Y%?> z6~y4Lnego*bjyb%+N9M%6jxl_aN020Ei5YGJ|Lv{i%}{HPm}XDT_GhP!8f+dt$7j) ziI%(o5BjDVn$1JrsIdKL{W}?UFj<1{z21-zLp5)@W>|Rv!z31Y;&sWvCbko@amM(- zH!#dm`&Op3kFud&%dl4`H}IB+t#YwJA|-|)4bZVU-op1Ka@D~{3?h;cWch?GfMQLb z%*+Ix2d4-wd^A=MxlhrWD#*olhIQ@}{Tqf$)3gAY>&5}L5$2BQup#K|N6-+EDX3%2 z3`5UOkI+a;1>az9&|R*pHWp+FCII!Oqaht2mQjo`bv6#CLY{;-I6NWuERf2X@D7<9 z5*&<8hs*P$a#)Av9wPK5=0H~r3#UlG5+P-Bb@Bos)I3GH(|gf9!39+Kp4TRe;pR%N zfnMZL*lyDd`%N%qAJPCJvS8fZzaipa@HK3@BJP)KV*QL)gX+vJ?}6jj zXd(1@rH81RYnj-`;-**=e2Fi&&E?N44QOR7E52kK1B4+_Hr!=|+uN5q)v8+2u($M5 zschsImmcFF@updh2yLYOKoL0+AVLc9fg(Z(5Nimb2Z{)>WI_Nu=zeP?Tg9CC64$V9 zA&9)zR9yyRL#dmbHk<|#nr(QBM`PE7tdKM~LC=+zfJ{#-6sY4)SlKlUPs|+oDt4^e zhC`5F7zGG@eiPxd$sIPJ+ZZ%5WniFi^E31Wg~Wpyx|3nrWUz8Vo+GwU046|;lARqJ zo%r0vmVp(R@;0ivv8x&A$>d>*23DxYW2s2u7q)2XxFnx|D(2Q3a$$#Jg~8=eDTk1u z-fkn(I0LOh$b!>Iy5JrU6|+cQWg_f!vtS(SiLg08R*n7G)G=%WM!zit@#bnnES@d7 zJh2^spFUcRw*z~*1hKt|P(k@lhP^fq)(KE=AzvKf=Ae6xc$KCae&dMKm9fa-#5SOU z^qJ7S6^L%fH)w!2mC^wN%Ozy?R9kc2DmVMcdNIiMp?Ggt&s5!%Tn|hEibqeR7<3at zwy)2_bzad3SWYL-bdQLH$<=O5FOk|$HDY63SVK*GMDU>_(r5ouc^ROdWd0N|R3R*P z=ROESA){RAIjzl}gZl!m6x^QaKU!OyaK_PF*Dww7c zgX*woEm%yKgC`(tLU5V<^TBB}Qis(*CCSsKg*)eiFnW}lstkeVpY9GUoIyiQ+bF%B>omdCyI_dw^-A)cgt!YZhVG!ho!Sj%YUnLc+LZyL6T zu?@P6RSaVrEn?L~(mr7UUVL(vuX&}4(A);IaG9R#L$Bo0es zbG43#n3LvX7e7y44IQ_1F(fovpk>%+ju`xg6L;^R3G>$>dgjP#v$3|^UpwZk1MNt6 zwVJS#?W*{mc)a2_H!!rj|(*Deq5kI@#6vwT2Dy#y^U| z46e#EN^VMk291x^t^XF0TYmC!{(fp)>B=jXJTc|T8}ejFp1dhf`ts!e$df;lC*PJQ zk0Ljm*Y)S}%Kw!o-;pOwmdVJIN94%~dGfeC0k-(y|5Ne=iT8y1$-VPm6n7bj$hbhgB9 z7gG}6lKOKP3!b9DN6{(A(Gf$(1Hht^f(0eT&o>rFw1~wz1zjRlHxD7+B^2HRR9JZM zjHpgV;ccuNx<^q+9`EK5f@7~ch5N@|cM98&z3vo#Qxu3VxxqdTVoL|U;g)Xnu|kH{ z_{wE$b=smUSO+CGV#q0QUMqEaa|jkn1uMEmO3-~l+#HzEifG18XV~|1c<_f}kqvFX zCYEK<&I7dL1QNCWD^_j&Ct5Fv)mjQBsWMv?+TvnqBeQyBXY($J8H zhBUNCPSpr=xy1?H!Tkw$zIbZVox2!tlc7C5v7Wn6B|Zc5-~`S28T%f*#v#DvsTCV< zIRS-qcK4^jnxEprgQ&B3UkO%l68(rq_p-y=VB7F>j=Oy!c$1BHAwgkrv#pMOVK|{j z_I-m}?h?ta+;2llZ~9Wm;q5gJ5tiRvp!cY_MQ4zDhV2 z_~YpX*we@j*57jK<03STtbENCTRO}wld$W*^Evc>_5sRfZa;DodP=Nt^D;EC!p=yB za!GlcwDE18%1l>2X&k=xjR^H*S1cK^% z<^(-I`K>=3jg4m>+c160c+4{GT@SkQxwo4}XRwXYA($?lx8DTFyT1;0eT|PXGcHIk z@ddoKrg-y}a;yu~Q`XBOw8S?SO3;787LP5mYy?rFG_h8ry@V#!3h7==-l;yQQ7#hk z#7ot4tC*|7wS2yuFITJZ(Nf7geekw8+{)+0zlJ=cODK&%MXY3X=8_AumMj*hm#jBStzxN> z&o;}Y2vQ)0&WqY-JcA>IZ6(yI7oUqSw!jemyUSB|6hTc!r>sW{I z{q|HoUPWUSY0uE-7cuDwi(Pd+<0;=;6NtWPdSO9Tw=N zHdYsEJ1tA44P)ZCZaCN^MmM|Sy=*KRr8 zYu0H``e9gj(T)0fW3@^l9OBFFOpfnR`fDY}V zOmM^&8L`Fvs?r_MiWRvz2EBoh8*g}}AhyiI;PFaZjF|(nD)<0Rg3Jjle%=gTj2DO= zy{#|6iGYQPE>K;FrCucR1u>Pd*c=<7A@sRSAVwoI_X3M{BY2yDaoa<#51nKnY!f{h_awjdpn2XhbH2qfJh43-bTYrYCEG!xJ#Y{ftVsX|*Q-Fp>CV09a+ zO?;6H@e)68^81It& zAgiNA(j#a5eD@Zch7mbZ%rOKY7io70SZv#p5FT_i{1n2BkuS9kEtDOY!1Fj8_OWBe zP>mBe2$ju=RX>2~61>TF-aSO`{su(*U&mY+WW!-ambs_$tv|c4o>DgA%Uw~uHuj-5 z@V)`~6RTIaqsqAKa~hYvmHkJ|8QKcqV2}TPl`NQ1KTN zihn?(7Yw6_Zjup>Vm4;tj~-MsZvH1WaJgx?RXB>|tMkeNtX6Pb4|RMPh)RP#g+B8uG; z5?c&seByQZ+!C*Yg^AZepv3NpAc{!i-Xc=bc#}wAx{=th9qa?WH3^wP-%ga=ZDva=*1NXco3VcMGATsiU3Cw$6REq2R#QKrq z4#V5aCOrQkWMtxX9b3B09N$8cE?E%0An(TJ`2-gqpCt$G2V~$64C$qLF6km>zqAZ#9R3@=c~tNd+jUU!6YJeI^`ojc z5k3aNqk><4952s!`JiV>C&i`Hg4D$PE}nk*@~M*-U&v-pomBAQ z4&^TPNTf3eeb0kv9gLmbeHP z=aiK$zaT0Ju0}9)2UQ%#8g`yAvUvn$o3@yOL*fv{d4=R2AeRWH+hlLU>La4(lq=3Y zg0}8?Q3ou|I0h0noE&8TaeALukm`<&J~?o~0SeCu=ztAF69yl+rVG~}y^KmcDESef z7zBAlka(Qpxl<>_0~@fWdo&f$_|8kj1@c(M_=yO&AP#qG@xZjyWw4^V+=1z#2vg1{}r7!d)!Ir@-XL8Zu0 zeS+vf{vz=VUjnjc;w|R_8FKZ&)3fd5po&~4d@WmdpA3TwFC(vVccpo$v{b;~sgv0( zDbPqcDp0w$cj(%5Plkv6a~A_aebq#LJBUOP8dXm zSB*+j`KL&GE2=I7v|P%ll|$4Avkisg%ImlgR6@94h>*w6pZ(vT`7gh)_u}KfZVc>| z-~OIo`S;)Vjb|%Qd3Qf^c=F0`{=~O``A?tt(HDRBg+KhY)xzsv|Mu0jzjN@`;-f$H zm5+Sm^8fl*2XFlc^LJkTlW%_VfBgP$J^6<}_E*3D=gq(S^S^gf|99+T-+HQ``l>+m`Dt=rGhE&d_9;Ja~r9LJa6dX9bhPIQk7h!7H;iO+hw+5W2g zP51CO|IL*ze&Qeck9_V+FB6Q$OLrQW3EX)FuF*l~PRQ>p&0i^*MI;Sn16`j5RkOO| zgL`*8SGyx-dy|(L-*Gx`+*uc|H@Sm{%9Y7wbA7$T+E;4D$^r{e{mO>}R6&lD&t5rO zzn!`Ejf+d{@jpV7<>#rlajwW;!{2`vD+fcW;kZpixG|_Rz8RNcZ|0Ll_I1nx9GwD9jF;2f6Q$VQ;>@>U0USnt2Sy1OB zDEl-@-C;k%&M0RU36EgPcG7wLkk@l;nZf z?UZ#=Ta(%=%cg&4xEy~Fk=EgIG$(^BBwVL*S8%*~_c``KLL&Hl@ToG+Zn8Gp!vAHq zj@kdB;rw!VOQ^YUv{WAY0_(!~qf13D#{ivAAT);7z1_(?l@>ybpJZ8Yq;y+9^LVAuf_(!^8}ObN9|SEHC*X%TDXuZg;UAJcMe=wW*ay= z!>)r8HI$Us&f;veHKSz|v|UA;1ePYp#K0Ag*Wv>^!o7p*qLtJJhnE*E?($ajP)fEv zscj}SnxHV%K=}6qeiFA`;1IQlO77vXaHo%Nm(%Y|&|<>Y!XLq?v9~}o7iH+YiT``7 zh&Jb;hZH#yp8RZAbrsR~soXQE= zBwi+A-T=1LKEkZVZlD)Nm=eZBYbW3@$($@h^=knK=-EynGolY9)im7FBsq|+6FrXP zfcP(ZJ<)9dndk!>7x+-CRA8-h-fr_>X?>{6d8pw@0gt#OfcM}?JfUSa1TpCm<_c=iTAlRZ}9`iLZ& z?!StfN#2ESQ&7(udU(W}(fc(nU8Gfr&cl5lYpK~^g02+$jx-tZb(Pm3M%*NRQE4}z zcchIN#`fm{OKR;VZ!zgJ6J;fJNk@;v%t5+_bwLg|5g!CqX?%Jz2Ky$iM-o6ViH3CK z`9ZjR1m$Vu@OfF$`=XZ3k3$X^l8#{*Ky!e74REPfS)6)((2ZKUjXvn3%vZsY@j4_Y zg{(%jBl)gz=t>LquU zeFMn2KUFT~8LNOEY@nCM>KNs0#Mdm^Ncxf5+5tvn8|dgY8vb{|`vq3T^*mc*1++eo z^AfHUaM$3JQ*mdBEuvfj_bPZUk2AVj#8nMf@_^C-UW;7TYM?t&zK3gKWSNW`$=!SK U(|-;&H)9{BiNM3p|92Gle@hk7CIA2c diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index ee72338b6..65770145c 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -453,9 +453,8 @@ ..\packages\Microsoft.Graph.Core.1.9.0\lib\net45\Microsoft.Graph.Core.dll - - False - ..\Binaries\Microsoft.Identity.Client.dll + + ..\packages\Microsoft.Identity.Client.4.15.0\lib\net45\Microsoft.Identity.Client.dll ..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll diff --git a/Commands/packages.config b/Commands/packages.config index 8dce26edd..43bf97d16 100644 --- a/Commands/packages.config +++ b/Commands/packages.config @@ -17,7 +17,7 @@ - + From b49e8924deb519c94195993f34b7f55ae41d1849 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Mon, 6 Jul 2020 00:19:35 +0200 Subject: [PATCH 111/130] Added changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7b833189..d56f6eba6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Koen Zomers [koenzomers] - Ellie Hussey [Professr] - Todd Klindt [ToddKlindt] +- Marc D Anderson [sympmarc] ## [3.22.2006.2] From 1086a86b666466128ce903bf778cd91f7496cee0 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Mon, 6 Jul 2020 00:20:37 +0200 Subject: [PATCH 112/130] Added extra sample on using ViewFields --- Commands/Lists/GetListItem.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Commands/Lists/GetListItem.cs b/Commands/Lists/GetListItem.cs index 550597b25..c73ba2264 100644 --- a/Commands/Lists/GetListItem.cs +++ b/Commands/Lists/GetListItem.cs @@ -32,20 +32,24 @@ namespace SharePointPnP.PowerShell.Commands.Lists SortOrder = 4)] [CmdletExample( Code = "PS:> Get-PnPListItem -List Tasks -Query \"bd6c5b3b-d960-4ee7-a02c-85dc6cd78cc3\"", - Remarks = "Retrieves all list items based on the CAML query specified", + Remarks = "Retrieves all available fields of list items based on the CAML query specified", SortOrder = 5)] + [CmdletExample( + Code = "PS:> Get-PnPListItem -List Tasks -Query \"\"", + Remarks = "Retrieves all list items modified today, retrieving the columns 'Title' and 'Modified'. When you use -Query, you can add a clause to retrieve specific columns (since you cannot use -Fields)", + SortOrder = 6)] [CmdletExample( Code = "PS:> Get-PnPListItem -List Tasks -PageSize 1000", Remarks = "Retrieves all list items from the Tasks list in pages of 1000 items", - SortOrder = 6)] + SortOrder = 7)] [CmdletExample( Code = "PS:> Get-PnPListItem -List Tasks -PageSize 1000 -ScriptBlock { Param($items) $items.Context.ExecuteQuery() } | % { $_.BreakRoleInheritance($true, $true) }", Remarks = "Retrieves all list items from the Tasks list in pages of 1000 items and breaks permission inheritance on each item", - SortOrder = 7)] + SortOrder = 8)] [CmdletExample( Code = "PS:> Get-PnPListItem -List Samples -FolderServerRelativeUrl \"/sites/contosomarketing/Lists/Samples/Demo\"", Remarks = "Retrieves all list items from the Demo folder in the Samples list located in the contosomarketing site collection", - SortOrder = 8)] + SortOrder = 9)] public class GetListItem : PnPWebCmdlet { private const string ParameterSet_BYID = "By Id"; From bf2e62170e4de5faad90f609b2a79952a63a79db Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 6 Jul 2020 22:53:01 +0200 Subject: [PATCH 113/130] Updated Teams Cmdlets --- CHANGELOG.md | 2 +- Commands/Base/PipeBinds/TeamsTabPipeBind.cs | 2 + Commands/Model/Teams/GraphException.cs | 25 ++ Commands/Model/Teams/TeamChannel.cs | 4 + Commands/Model/Teams/TeamChannelType.cs | 12 + Commands/Model/Teams/TeamTab.cs | 19 +- Commands/Model/Teams/TeamTabType.cs | 24 ++ Commands/Model/Teams/User.cs | 10 +- .../PnP.PowerShell.Core.Format.ps1xml | 50 ++- .../SharePointPnP.PowerShell.Commands.csproj | 11 + Commands/Teams/AddTeamsChannel.cs | 36 ++- Commands/Teams/AddTeamsTab.cs | 176 +++++++++++ Commands/Teams/AddTeamsUser.cs | 67 ++++ Commands/Teams/GetTeamsChannel.cs | 2 +- Commands/Teams/GetTeamsChannelMessage.cs | 6 + Commands/Teams/GetTeamsUser.cs | 69 +++++ Commands/Teams/RemoveTeamsTab.cs | 2 +- Commands/Teams/RemoveTeamsTeam.cs | 2 +- Commands/Teams/RemoveTeamsUser.cs | 66 ++++ Commands/Teams/SetTeamsChannel .cs | 87 ++++++ Commands/Teams/SetTeamsTab.cs | 70 +++++ Commands/Teams/SetTeamsTeam.cs | 174 +++++++++++ Commands/Teams/SetTeamsTeamPicture.cs | 72 +++++ Commands/Teams/SubmitTeamsChannelMessage.cs | 6 + Commands/Utilities/REST/GraphHelper.cs | 55 +++- Commands/Utilities/TeamsUtility.cs | 286 +++++++++++++++++- 26 files changed, 1308 insertions(+), 27 deletions(-) create mode 100644 Commands/Model/Teams/GraphException.cs create mode 100644 Commands/Model/Teams/TeamChannelType.cs create mode 100644 Commands/Model/Teams/TeamTabType.cs create mode 100644 Commands/Teams/AddTeamsTab.cs create mode 100644 Commands/Teams/AddTeamsUser.cs create mode 100644 Commands/Teams/GetTeamsUser.cs create mode 100644 Commands/Teams/RemoveTeamsUser.cs create mode 100644 Commands/Teams/SetTeamsChannel .cs create mode 100644 Commands/Teams/SetTeamsTab.cs create mode 100644 Commands/Teams/SetTeamsTeam.cs create mode 100644 Commands/Teams/SetTeamsTeamPicture.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index b7b833189..5f0bc7b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) -- Added New-PnPTeamsTeam, Add-PnPTeamsChannel, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsTab, Get-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam cmdlets +- Added Add-PnPTeamsChannel, Add-PnPTeamsTab, Add-PnPTeamsUser, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsChannelMessage, Get-PnPTeamsTab, Get-PnPTeamsTeam, Get-PnPTeamsUser, New-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam, Remove-PnPTeamsUser, Set-PnPTeamsChannel, Set-PnPTeamsTab, Set-PnPTeamsTeam, Set-PnPTeamsPicture, Submit-PnPTeamsChannelMessage cmdlets ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) diff --git a/Commands/Base/PipeBinds/TeamsTabPipeBind.cs b/Commands/Base/PipeBinds/TeamsTabPipeBind.cs index ceb1f91b6..93d5f022a 100644 --- a/Commands/Base/PipeBinds/TeamsTabPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsTabPipeBind.cs @@ -4,7 +4,9 @@ using System; using System.Linq; using System.Management.Automation; +using System.Net; using System.Net.Http; +using System.Web; namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds { diff --git a/Commands/Model/Teams/GraphException.cs b/Commands/Model/Teams/GraphException.cs new file mode 100644 index 000000000..231f86ec2 --- /dev/null +++ b/Commands/Model/Teams/GraphException.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public class GraphException : Exception + { + public GraphError Error { get; set; } + } + + public class GraphError + { + public string StatusCode { get; set; } + + public string Message { get; set; } + + public GraphError InnerError { get; set; } + + public Dictionary AdditionalData { get; set; } + + public string ThrowSite { get; set; } + } +} diff --git a/Commands/Model/Teams/TeamChannel.cs b/Commands/Model/Teams/TeamChannel.cs index d5c9be0d5..de6946840 100644 --- a/Commands/Model/Teams/TeamChannel.cs +++ b/Commands/Model/Teams/TeamChannel.cs @@ -31,6 +31,10 @@ public partial class TeamChannel /// public string DisplayName { get; set; } + /// + /// Defines the type of the Channel + /// + public string MembershipType { get; set; } /// /// Defines the Description of the Channel /// diff --git a/Commands/Model/Teams/TeamChannelType.cs b/Commands/Model/Teams/TeamChannelType.cs new file mode 100644 index 000000000..e9583848c --- /dev/null +++ b/Commands/Model/Teams/TeamChannelType.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public enum TeamChannelType + { + Public, + Private + } +} diff --git a/Commands/Model/Teams/TeamTab.cs b/Commands/Model/Teams/TeamTab.cs index 29a1032bf..50c3771fe 100644 --- a/Commands/Model/Teams/TeamTab.cs +++ b/Commands/Model/Teams/TeamTab.cs @@ -1,20 +1,35 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Web; namespace SharePointPnP.PowerShell.Commands.Model.Teams { public partial class TeamTab { + private string _displayName; #region Public Members /// /// Defines the Display Name of the Channel /// - public string DisplayName { get; set; } + public string DisplayName + { + get + { + return _displayName; + } + set + { + _displayName = HttpUtility.UrlDecode(value); + } + } + [JsonProperty("teamsApp@odata.bind")] + public string TeamsApp { get; set; } /// /// App definition identifier of the tab /// diff --git a/Commands/Model/Teams/TeamTabType.cs b/Commands/Model/Teams/TeamTabType.cs new file mode 100644 index 000000000..e58d3b91d --- /dev/null +++ b/Commands/Model/Teams/TeamTabType.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public enum TeamTabType + { + WebSite, + DocumentLibrary, + Wiki, + Planner, + MicrosoftStream, + MicrosoftForms, + Word, + Excel, + PowerPoint, + PDF, + OneNote, + PowerBI, + SharePointPageAndList, + Custom + } +} diff --git a/Commands/Model/Teams/User.cs b/Commands/Model/Teams/User.cs index 868ebeb51..466462883 100644 --- a/Commands/Model/Teams/User.cs +++ b/Commands/Model/Teams/User.cs @@ -4,10 +4,16 @@ namespace SharePointPnP.PowerShell.Commands.Model.Teams { - public class User + public class User : IEquatable { public string Id { get; set; } public string DisplayName { get; set; } - public string UserIdentityType { get; set; } + public string UserPrincipalName { get; set; } + public string UserType { get; set; } + + public bool Equals(User other) + { + return this.UserPrincipalName.Equals(other.UserPrincipalName, StringComparison.OrdinalIgnoreCase); + } } } diff --git a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml index 66c44a376..1c80d10c4 100644 --- a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml +++ b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml @@ -1879,6 +1879,9 @@ + + + @@ -1892,6 +1895,9 @@ Description + + MembershipType + @@ -1978,9 +1984,9 @@ - + - + @@ -2001,5 +2007,45 @@ + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.User + + + + + + + + + + + + + + + + + + + + + Id + + + UserPrincipalName + + + DisplayName + + + UserType + + + + + + \ No newline at end of file diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 70d63dc81..56f1fc6a5 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -709,12 +709,14 @@ + + @@ -726,6 +728,7 @@ + @@ -919,15 +922,23 @@ + + + + + + + + diff --git a/Commands/Teams/AddTeamsChannel.cs b/Commands/Teams/AddTeamsChannel.cs index c7732ff24..0d75fb238 100644 --- a/Commands/Teams/AddTeamsChannel.cs +++ b/Commands/Teams/AddTeamsChannel.cs @@ -2,6 +2,7 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; using System.Management.Automation; @@ -19,18 +20,25 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Add-PnPTeamsChannel -Team MyTeam -DisplayName \"My Channel\"", Remarks = "Adds a new channel to the specified Teams instance", SortOrder = 2)] + [CmdletExample( + Code = "PS:> Add-PnPTeamsChannel -Team MyTeam -DisplayName \"My Channel\" -Private", + Remarks = "Adds a new private channel to the specified Teams instance", + SortOrder = 3)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class AddTeamsChannel : PnPGraphCmdlet { [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] public TeamsTeamPipeBind Team; - [Parameter(Mandatory = true)] + [Parameter(Mandatory = true, HelpMessage = "The display name of the new channel. Letters, numbers and spaces are allowed.")] public string DisplayName; - [Parameter(Mandatory = false)] + [Parameter(Mandatory = false, HelpMessage = "An optional description of the channel.")] public string Description; + [Parameter(Mandatory = false, HelpMessage = "Specify to mark the channel as private.")] + public SwitchParameter Private; + protected override void ExecuteCmdlet() { Model.Teams.TeamChannel channel = null; @@ -38,10 +46,28 @@ protected override void ExecuteCmdlet() var groupId = Team.GetGroupId(HttpClient, AccessToken); if (groupId != null) { - channel = TeamsUtility.AddChannel(AccessToken, HttpClient, groupId, DisplayName, Description); - WriteObject(channel); + try + { + channel = TeamsUtility.AddChannel(AccessToken, HttpClient, groupId, DisplayName, Description, Private); + WriteObject(channel); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } } - + else + { + throw new PSArgumentException("Group not found"); + } + } } } diff --git a/Commands/Teams/AddTeamsTab.cs b/Commands/Teams/AddTeamsTab.cs new file mode 100644 index 000000000..6e4ec1f10 --- /dev/null +++ b/Commands/Teams/AddTeamsTab.cs @@ -0,0 +1,176 @@ +#if !ONPREMISES +using Microsoft.BusinessData.MetadataModel; +using Microsoft.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Add, "PnPTeamsTab")] + [CmdletHelp("Adds a tab to an existing Channel", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Add-PnPTeamsTab -Team \"My Team\" -Channel \"My Channel\" -DisplayName \"My Channel\" -Type WebSite -ContentUrl \"https://aka.ms/sppnp", + Remarks = "Adds a web site tab to the specified channel.", + SortOrder = 1)] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "TeamsAppId", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "EntityId", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "ContentUrl", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "RemoveUrl", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection")] + [CmdletAdditionalParameter(ParameterType = typeof(string), ParameterName = "WebSiteUrl", Mandatory = true, HelpMessage = @"Specifies the title of the new site collection")] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class AddTeamsTab : PnPGraphCmdlet, IDynamicParameters + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.", ValueFromPipeline = true)] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.", ValueFromPipeline = true)] + public TeamsChannelPipeBind Channel; + + + [Parameter(Mandatory = true, HelpMessage = "Specify the tab type")] + public string DisplayName; + + [Parameter(Mandatory = true, HelpMessage = "Specify the tab type")] + public TeamTabType Type; + + + private OfficeFileParameters officeFileParameters; + private DocumentLibraryParameters documentLibraryParameters; + private CustomParameters customParameters; + public object GetDynamicParameters() + { + switch (Type) + { + case TeamTabType.Word: + case TeamTabType.Excel: + case TeamTabType.PowerPoint: + case TeamTabType.PDF: + { + officeFileParameters = new OfficeFileParameters(); + return officeFileParameters; + } + case TeamTabType.DocumentLibrary: + case TeamTabType.WebSite: + { + documentLibraryParameters = new DocumentLibraryParameters(); + return documentLibraryParameters; + } + case TeamTabType.Custom: + { + customParameters = new CustomParameters(); + return customParameters; + } + } + return null; + } + + + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + var channelId = Channel.GetId(HttpClient, AccessToken, groupId); + if (channelId != null) + { + try + { + string entityId = null; + string contentUrl = null; + string removeUrl = null; + string webSiteUrl = null; + string teamsAppId = null; + switch (Type) + { + case TeamTabType.Word: + case TeamTabType.Excel: + case TeamTabType.PowerPoint: + case TeamTabType.PDF: + { + entityId = officeFileParameters.EntityId; + contentUrl = officeFileParameters.ContentUrl; + break; + } + case TeamTabType.DocumentLibrary: + case TeamTabType.WebSite: + { + contentUrl = documentLibraryParameters.ContentUrl; + break; + } + case TeamTabType.Custom: + { + entityId = customParameters.EntityId; + contentUrl = customParameters.ContentUrl; + removeUrl = customParameters.RemoveUrl; + webSiteUrl = customParameters.WebSiteUrl; + teamsAppId = customParameters.TeamsAppId; + break; + } + } + TeamsUtility.AddTab(HttpClient, AccessToken, groupId, channelId, DisplayName, Type, teamsAppId, entityId, contentUrl, removeUrl, webSiteUrl); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } + } + else + { + throw new PSArgumentException("Channel not found"); + } + } + else + { + throw new PSArgumentException("Group not found"); + } + + } + + public class OfficeFileParameters + { + [Parameter(Mandatory = true)] + public string EntityId; + + [Parameter(Mandatory = true)] + public string ContentUrl; + } + + public class DocumentLibraryParameters + { + [Parameter(Mandatory = true)] + public string ContentUrl; + } + + public class CustomParameters + { + [Parameter(Mandatory = true)] + public string TeamsAppId; + + [Parameter(Mandatory = false)] + public string EntityId; + + [Parameter(Mandatory = false)] + public string ContentUrl; + + [Parameter(Mandatory = false)] + public string RemoveUrl; + + [Parameter(Mandatory = false)] + public string WebSiteUrl; + } + } +} +#endif diff --git a/Commands/Teams/AddTeamsUser.cs b/Commands/Teams/AddTeamsUser.cs new file mode 100644 index 000000000..ecc9db2ff --- /dev/null +++ b/Commands/Teams/AddTeamsUser.cs @@ -0,0 +1,67 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Add, "PnPTeamsUser")] + [CmdletHelp("Adds a channel to an existing Microsoft Teams instance.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Add-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Owner", + Remarks = "Adds a user as an owner to the team", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Add-PnPTeamsUser -Team MyTeam -User john@doe.com -Role Member", + Remarks = "Adds a user as a member to the team", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class AddTeamsUser : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the UPN (e.g. john@doe.com)")] + public string User; + + [Parameter(Mandatory = true, HelpMessage = "Specify the role of the user")] + [ValidateSet(new[] { "Owner", "Member" })] + public string Role; + protected override void ExecuteCmdlet() + { + Model.Teams.TeamChannel channel = null; + + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + try + { + TeamsUtility.AddUser(HttpClient, AccessToken, groupId, User, Role); + WriteObject(channel); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } + } + else + { + throw new PSArgumentException("Group not found"); + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs index 346e0e2c3..ffdd62b3e 100644 --- a/Commands/Teams/GetTeamsChannel.cs +++ b/Commands/Teams/GetTeamsChannel.cs @@ -52,7 +52,7 @@ protected override void ExecuteCmdlet() } } else { - throw new PSArgumentException("Cannot find team", nameof(Team)); + throw new PSArgumentException("Team not found", nameof(Team)); } } } diff --git a/Commands/Teams/GetTeamsChannelMessage.cs b/Commands/Teams/GetTeamsChannelMessage.cs index 1f9cd1f67..6b50bb837 100644 --- a/Commands/Teams/GetTeamsChannelMessage.cs +++ b/Commands/Teams/GetTeamsChannelMessage.cs @@ -36,7 +36,13 @@ protected override void ExecuteCmdlet() if (channel != null) { WriteObject(TeamsUtility.GetMessages(HttpClient, AccessToken, groupId, channel.Id, IncludeDeleted), true); + } else + { + throw new PSArgumentException("Channel not found"); } + } else + { + throw new PSArgumentException("Team not found"); } } diff --git a/Commands/Teams/GetTeamsUser.cs b/Commands/Teams/GetTeamsUser.cs new file mode 100644 index 000000000..af675c201 --- /dev/null +++ b/Commands/Teams/GetTeamsUser.cs @@ -0,0 +1,69 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Get, "PnPTeamsUser")] + [CmdletHelp("Returns owners, members or guests from a team.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsUser -Team MyTeam", + Remarks = "Returns all owners, members or guests from the specified team.", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsUser -Team MyTeam -Role Owner", + Remarks = "Returns all owners from the specified team.", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsUser -Team MyTeam -Role Member", + Remarks = "Returns all members from the specified team.", + SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsUser -Team MyTeam -Role Guest", + Remarks = "Returns all guestss from the specified team.", + SortOrder = 4)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class GetTeamsUser : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = false, HelpMessage = "Specify to filter on the role of the user")] + [ValidateSet(new[] { "Owner", "Member", "Guest" })] + public string Role; + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + try + { + WriteObject(TeamsUtility.GetUsers(HttpClient, AccessToken, groupId, Role), true); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } + } + else + { + throw new PSArgumentException("Group not found"); + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs index 5cb6feaf2..224c68e46 100644 --- a/Commands/Teams/RemoveTeamsTab.cs +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -68,7 +68,7 @@ protected override void ExecuteCmdlet() } else { - throw new PSArgumentException("Cannot find channel"); + throw new PSArgumentException("Channel not found"); } } else diff --git a/Commands/Teams/RemoveTeamsTeam.cs b/Commands/Teams/RemoveTeamsTeam.cs index 874bd3d21..83a3d1103 100644 --- a/Commands/Teams/RemoveTeamsTeam.cs +++ b/Commands/Teams/RemoveTeamsTeam.cs @@ -43,7 +43,7 @@ protected override void ExecuteCmdlet() } else { - throw new PSArgumentException("Cannot find team"); + throw new PSArgumentException("Team not found"); } } } diff --git a/Commands/Teams/RemoveTeamsUser.cs b/Commands/Teams/RemoveTeamsUser.cs new file mode 100644 index 000000000..966500523 --- /dev/null +++ b/Commands/Teams/RemoveTeamsUser.cs @@ -0,0 +1,66 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPTeamsUser")] + [CmdletHelp("Removes users from a team.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Remove-PnPTeamsUser -Team MyTeam -User john@doe.com", + Remarks = "Removes the user specified from both owners and members of the team.", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsUser -Team MyTeam -User john@doe.com -Owner", + Remarks = "Removes the user john@doe.com from the owners of the team, but retains the user as a member.", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class RemoveTeamsUser : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.")] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the UPN (e.g. john@doe.com)")] + public string User; + + [Parameter(Mandatory = false, HelpMessage = @"Specify the role of the user you are removing from the team. Accepts ""Owner"" and ""Member"" as possible values. + If specified as ""Member"" then the specified user is removed from the Team completely even if they were the owner of the Team. If ""Owner"" is specified in the -Role parameter then the + specified user is removed as an owner of the team but stays as a team member. Defaults to ""Member"". Note: The last owner cannot be removed from the team.")] + [ValidateSet(new[] { "Owner", "Member" })] + public string Role = "Member"; + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + try + { + TeamsUtility.DeleteUser(HttpClient, AccessToken, groupId, User, Role); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } + } + else + { + throw new PSArgumentException("Group not found"); + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SetTeamsChannel .cs b/Commands/Teams/SetTeamsChannel .cs new file mode 100644 index 000000000..8b2d9011a --- /dev/null +++ b/Commands/Teams/SetTeamsChannel .cs @@ -0,0 +1,87 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Set, "PnPTeamsChannel")] + [CmdletHelp("Updates an existing Teams Channel", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsChannel -Team \"MyTeam\" -Channel \"MyChannel\" -DisplayName \"My Channel\"", + Remarks = "Updates the channel called 'MyChannel' to have the display name set to 'My Channel'", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class SetTeamsChannel : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.", ValueFromPipeline = true)] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.", ValueFromPipeline = true)] + public TeamsChannelPipeBind Identity; + + [Parameter(Mandatory = false, HelpMessage = "Changes the display name of the specified channel.")] + public string DisplayName; + + [Parameter(Mandatory = false, HelpMessage = "Changes the description of the specified channel.")] + public string Description; + + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + var teamChannel = Identity.GetChannel(HttpClient, AccessToken, groupId); + if (teamChannel != null) + { + if (ParameterSpecified(nameof(DisplayName)) && teamChannel.DisplayName != DisplayName) + { + teamChannel.DisplayName = DisplayName; + } else + { + teamChannel.DisplayName = null; + } + if (ParameterSpecified(nameof(Description)) && teamChannel.Description != Description) + { + teamChannel.Description = Description; + } else + { + teamChannel.Description = null; + } + teamChannel.MembershipType = null; + try + { + var updated = TeamsUtility.UpdateChannel(HttpClient, AccessToken, groupId, teamChannel.Id, teamChannel); + WriteObject(updated); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } + } + else + { + throw new PSArgumentException("Channel not found"); + } + } + else + { + throw new PSArgumentException("Group not found"); + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SetTeamsTab.cs b/Commands/Teams/SetTeamsTab.cs new file mode 100644 index 000000000..f95219dc9 --- /dev/null +++ b/Commands/Teams/SetTeamsTab.cs @@ -0,0 +1,70 @@ +#if !ONPREMISES +using Microsoft.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.IO; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Set, "PnPTeamsTab")] + [CmdletHelp("Updates Teams Tab settings", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsTab -Team \"MyTeam\" -Channel \"My Channel\" -Identity \"Wiki\" -DisplayName \"Channel Wiki\"", + Remarks = "Updates the tab named 'Wiki' and changes the display name of the tab to 'Channel Wiki'", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class SetTeamsTab : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id of the team to retrieve.", ValueFromPipeline = true)] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "Specify the channel id of the team to retrieve.", ValueFromPipeline = true)] + public TeamsChannelPipeBind Channel; + + [Parameter(Mandatory = false, HelpMessage = "Identity of the tab.")] + public TeamsTabPipeBind Identity; + + [Parameter(Mandatory = false, HelpMessage = "The new name of the tab.")] + public string DisplayName; + + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + var channelId = Channel.GetId(HttpClient, AccessToken, groupId); + if (channelId != null) + { + var tab = Identity.GetTab(HttpClient, AccessToken, groupId, channelId); + if (tab != null) + { + if (ParameterSpecified(nameof(DisplayName)) && tab.DisplayName != DisplayName) + { + tab.DisplayName = DisplayName; + } + TeamsUtility.UpdateTab(HttpClient, AccessToken, groupId, channelId, tab); + } + else + { + throw new PSArgumentException("Tab not found"); + } + } + else + { + throw new PSArgumentException("Channel not found"); + } + } + else + { + throw new PSArgumentException("Team not found"); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SetTeamsTeam.cs b/Commands/Teams/SetTeamsTeam.cs new file mode 100644 index 000000000..af67bad12 --- /dev/null +++ b/Commands/Teams/SetTeamsTeam.cs @@ -0,0 +1,174 @@ +#if !ONPREMISES +using OfficeDevPnP.Core.Framework.Provisioning.Model.Teams; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Set, "PnPTeamsTeam")] + [CmdletHelp("Updates an existing Team.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsChannel -Team \"MyTeam\" -DisplayName \"My Team\"", + Remarks = "Updates the team called 'MyTeam' to have the display name set to 'My Team'", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class SetTeamsTeam : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.", ValueFromPipeline = true)] + public TeamsTeamPipeBind Identity; + + [Parameter(Mandatory = false, HelpMessage = "Changes the display name of the specified team.")] + public string DisplayName; + + [Parameter(Mandatory = false, HelpMessage = "Changes the description of the specified team.")] + public string Description; + + [Parameter(Mandatory = false, HelpMessage = "Changes the visibility of the specified team.")] + public TeamVisibility Visibility; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Boolean value that determines whether or not members (not only owners) are allowed to add apps to the team.")] + public bool? AllowAddRemoveApps; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Boolean value that determines whether or not channels in the team can be @ mentioned so that all users who follow the channel are notified.")] + public bool? AllowChannelMentions; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not just owners) are allowed to create channels.")] + public bool? AllowCreateUpdateChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not only owners) can manage connectors in the team.")] + public bool? AllowCreateUpdateRemoveConnectors; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not only owners) can manage tabs in channels.")] + public bool? AllowCreateUpdateRemoveTabs; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members can use the custom memes functionality in teams.")] + public bool? AllowCustomMemes; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members (and not only owners) can delete channels in the team.")] + public bool? AllowDeleteChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not giphy can be used in the team.")] + public bool? AllowGiphy; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not guests can create channels in the team.")] + public bool? AllowGuestCreateUpdateChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not guests can delete in the team.")] + public bool? AllowGuestDeleteChannels; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not owners can delete messages that they or other members of the team have posted.")] + public bool? AllowOwnerDeleteMessages; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether stickers and memes usage is allowed in the team.")] + public bool? AllowStickersAndMemes; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether the entire team can be @ mentioned (which means that all users will be notified)")] + public bool? AllowTeamMentions; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not members can delete messages that they have posted.")] + public bool? AllowUserDeleteMessages; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not users can edit messages that they have posted.")] + public bool? AllowUserEditMessages; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines the level of sensitivity of giphy usage that is allowed in the team. Accepted values are \"Strict\" or \"Moderate\"")] + public Model.Teams.TeamGiphyContentRating GiphyContentRating; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets, HelpMessage = "Setting that determines whether or not private teams should be searchable from Teams clients for users who do not belong to that team. Set to $false to make those teams not discoverable from Teams clients.")] + public bool? ShowInTeamsSearchAndSuggestions; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] + public string Classification; + protected override void ExecuteCmdlet() + { + var groupId = Identity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + try + { + var team = TeamsUtility.GetTeam(AccessToken, HttpClient, groupId); + var updateGroup = false; + var group = new Group(); + if (team != null) + { + if (ParameterSpecified(nameof(DisplayName)) && team.DisplayName != DisplayName) + { + updateGroup = true; + group.DisplayName = DisplayName; + } + else + { + team.DisplayName = null; + } + if (ParameterSpecified(nameof(Description)) && team.Description != Description) + { + updateGroup = true; + group.Description = Description; + } + else + { + team.Description = null; + } + if((GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()) != team.Visibility) + { + group.Visibility = (GroupVisibility)Enum.Parse(typeof(GroupVisibility), Visibility.ToString()); + updateGroup = true; + } + team.IsArchived = null; // cannot update this value; + + if(updateGroup) + { + TeamsUtility.UpdateGroup(HttpClient, AccessToken, groupId, group); + } + + var teamCI = new TeamCreationInformation(); + teamCI.AllowAddRemoveApps = ParameterSpecified(nameof(AllowAddRemoveApps)) ? AllowAddRemoveApps : null; + teamCI.AllowChannelMentions = ParameterSpecified(nameof(AllowChannelMentions)) ? AllowChannelMentions : null; + teamCI.AllowCreateUpdateChannels = ParameterSpecified(nameof(AllowCreateUpdateChannels)) ? AllowCreateUpdateChannels : null; + teamCI.AllowCreateUpdateRemoveConnectors = ParameterSpecified(nameof(AllowCreateUpdateRemoveConnectors)) ? AllowCreateUpdateRemoveConnectors : null; + teamCI.AllowCreateUpdateRemoveTabs = ParameterSpecified(nameof(AllowCreateUpdateRemoveTabs)) ? AllowCreateUpdateRemoveTabs : null; + teamCI.AllowCustomMemes = ParameterSpecified(nameof(AllowCustomMemes)) ? AllowCustomMemes : null; + teamCI.AllowDeleteChannels = ParameterSpecified(nameof(AllowDeleteChannels)) ? AllowDeleteChannels : null; + teamCI.AllowGiphy = ParameterSpecified(nameof(AllowGiphy)) ? AllowGiphy : null; ; + teamCI.AllowGuestCreateUpdateChannels = ParameterSpecified(nameof(AllowGuestCreateUpdateChannels)) ? AllowGuestCreateUpdateChannels : null; + teamCI.AllowGuestDeleteChannels = ParameterSpecified(nameof(AllowGuestDeleteChannels)) ? AllowGuestDeleteChannels : null; + teamCI.AllowOwnerDeleteMessages = ParameterSpecified(nameof(AllowOwnerDeleteMessages)) ? AllowOwnerDeleteMessages : null; + teamCI.AllowStickersAndMemes = ParameterSpecified(nameof(AllowStickersAndMemes)) ? AllowStickersAndMemes : null; + teamCI.AllowTeamMentions = ParameterSpecified(nameof(AllowTeamMentions)) ? AllowTeamMentions : null; + teamCI.AllowUserDeleteMessages = ParameterSpecified(nameof(AllowUserDeleteMessages)) ? AllowUserDeleteMessages : null; + teamCI.AllowUserEditMessages = ParameterSpecified(nameof(AllowUserEditMessages)) ? AllowUserEditMessages : null; + teamCI.Classification = ParameterSpecified(nameof(Classification)) ? Classification : null; + + var updated = TeamsUtility.UpdateTeam(HttpClient, AccessToken, groupId, teamCI.ToTeam()); + WriteObject(updated); + } + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw ex; + } + } + + } + else + { + throw new PSArgumentException("Team not found"); + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SetTeamsTeamPicture.cs b/Commands/Teams/SetTeamsTeamPicture.cs new file mode 100644 index 000000000..e654cf584 --- /dev/null +++ b/Commands/Teams/SetTeamsTeamPicture.cs @@ -0,0 +1,72 @@ +#if !ONPREMISES +using Microsoft.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.IO; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Set, "PnPTeamsTeamPicture")] + [CmdletHelp("Sets the picture of an existing team.", + DetailedDescription = "Notice that this cmdlet will immediately return but it can take a few hours before the changes are reflected in Microsoft Teams.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsTeamPicture -Team \"MyTeam\" -Path \"c:\\myimage.jpg\"", + Remarks = "Updates the channel called 'MyChannel' to have the display name set to 'My Channel'", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class SetTeamsTeamPicture : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the group id, mailNickname or display name of the team to use.", ValueFromPipeline = true)] + public TeamsTeamPipeBind Team; + + [Parameter(Mandatory = true, HelpMessage = "The path to the image file.")] + public string Path; + + protected override void ExecuteCmdlet() + { + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + if (!System.IO.Path.IsPathRooted(Path)) + { + Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); + + } + var contentType = ""; + var fileInfo = new FileInfo(Path); + switch (fileInfo.Extension) + { + case ".jpg": + case ".jpeg": + { + contentType = "image/jpeg"; + break; + } + case ".png": + { + contentType = "image/png"; + break; + } + } + if (string.IsNullOrEmpty(contentType)) + { + throw new PSArgumentException("File is not of a supported content type (jpg/png)"); + } + var byteArray = System.IO.File.ReadAllBytes(Path); + TeamsUtility.SetTeamPicture(HttpClient, AccessToken, groupId, byteArray, contentType); + } + else + { + throw new PSArgumentException("Team not found"); + } + + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SubmitTeamsChannelMessage.cs b/Commands/Teams/SubmitTeamsChannelMessage.cs index 8557cdd11..1480b3ca5 100644 --- a/Commands/Teams/SubmitTeamsChannelMessage.cs +++ b/Commands/Teams/SubmitTeamsChannelMessage.cs @@ -52,7 +52,13 @@ protected override void ExecuteCmdlet() channelMessage.Body.ContentType = ContentType; TeamsUtility.PostMessage(HttpClient, AccessToken, groupId, channel.Id, channelMessage); + } else + { + throw new PSArgumentException("Channel not found"); } + } else + { + throw new PSArgumentException("Team not found"); } } diff --git a/Commands/Utilities/REST/GraphHelper.cs b/Commands/Utilities/REST/GraphHelper.cs index f4b942b1f..f3fdc164a 100644 --- a/Commands/Utilities/REST/GraphHelper.cs +++ b/Commands/Utilities/REST/GraphHelper.cs @@ -1,6 +1,7 @@ using Microsoft.Identity.Client; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; +using SharePointPnP.PowerShell.Commands.Model.Teams; using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +27,11 @@ private static HttpRequestMessage GetMessage(string url, HttpMethod method, stri message.Method = method; message.RequestUri = !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ? new Uri($"https://graph.microsoft.com/{url}") : new Uri(url); message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); - if (method == HttpMethod.Post || method == HttpMethod.Put) +#if NETSTANDARD2_1 + if (method == HttpMethod.Post || method == HttpMethod.Put || method == HttpMethod.Patch) +#else + if (method == HttpMethod.Post || method == HttpMethod.Put || method.Method == "PATCH") +#endif { message.Content = content; } @@ -63,6 +68,26 @@ public static async Task PostAsync(HttpClient httpClient, string url, st return await SendMessageAsync(httpClient, message); } + public static async Task PatchAsync(HttpClient httpClient, string accessToken, string url, T content) + { + var requestContent = new StringContent(JsonConvert.SerializeObject(content, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() })); + requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); +#if NETSTANDARD2_1 + var message = GetMessage(url, HttpMethod.Patch, accessToken, requestContent); +#else + var message = GetMessage(url, new HttpMethod("PATCH"), accessToken, requestContent); +#endif + var returnValue = await SendMessageAsync(httpClient, message); + if (!string.IsNullOrEmpty(returnValue)) + { + return JsonConvert.DeserializeObject(returnValue); + } + else + { + return default; + } + } + public static async Task PostAsync(HttpClient httpClient, string url, HttpContent content, string accessToken) { var message = GetMessage(url, HttpMethod.Post, accessToken, content); @@ -81,6 +106,24 @@ public static async Task PostAsync(HttpClient httpClient, string url, Http return default; } + public static async Task PutAsync(HttpClient httpClient, string url, string accessToken, HttpContent content) + { + var message = GetMessage(url, HttpMethod.Put, accessToken, content); + var stringContent = await SendMessageAsync(httpClient, message); + if (stringContent != null) + { + try + { + return JsonConvert.DeserializeObject(stringContent); + } + catch + { + return default; + } + } + return default; + } + public static async Task PostAsync(HttpClient httpClient, string url, T content, string accessToken) { var requestContent = new StringContent(JsonConvert.SerializeObject(content, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() })); @@ -127,9 +170,7 @@ public static async Task DeleteAsync(HttpClient httpClient, string url, st } } - - - public static async Task SendMessageAsync(HttpClient httpClient, HttpRequestMessage message) + private static async Task SendMessageAsync(HttpClient httpClient, HttpRequestMessage message) { var response = await httpClient.SendAsync(message); while (response.StatusCode == (HttpStatusCode)429) @@ -145,10 +186,14 @@ public static async Task SendMessageAsync(HttpClient httpClient, HttpReq } else { - return null; + var errorContent = await response.Content.ReadAsStringAsync(); + var exception = JsonConvert.DeserializeObject(errorContent); + throw exception; } } + + public static async Task GetResponseMessageAsync(HttpClient httpClient, HttpRequestMessage message) { var response = await httpClient.SendAsync(message); diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index 84432385e..6ab99477c 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -1,4 +1,5 @@ -using SharePointPnP.PowerShell.Commands.Model.Teams; +using Newtonsoft.Json; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities.REST; using System; using System.Collections.Generic; @@ -231,12 +232,158 @@ private static string CreateAlias(HttpClient httpClient, string accessToken) } while (teamName == string.Empty); return teamName; } + + public static Team UpdateTeam(HttpClient httpClient, string accessToken, string groupId, Team team) + { + return GraphHelper.PatchAsync(httpClient, accessToken, $"v1.0/teams/{groupId}", team).GetAwaiter().GetResult(); + } + + public static Group UpdateGroup(HttpClient httpClient, string accessToken, string groupId, Group group) + { + return GraphHelper.PatchAsync(httpClient, accessToken, $"v1.0/groups/{groupId}", group).GetAwaiter().GetResult(); + } + + public static void SetTeamPicture(HttpClient httpClient, string accessToken, string groupId, byte[] bytes, string contentType) + { + var byteArrayContent = new ByteArrayContent(bytes); + byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); + GraphHelper.PutAsync(httpClient, $"v1.0/groups/{groupId}/photo/$value", accessToken, byteArrayContent).GetAwaiter().GetResult(); + } #endregion + #region Users + public static void AddUser(HttpClient httpClient, string accessToken, string groupId, string upn, string role) + { + var user = GraphHelper.GetAsync(httpClient, $"v1.0/users/{upn}", accessToken).GetAwaiter().GetResult(); + + // check if the user is a member + bool isMember = false; + try + { + var members = GraphHelper.GetAsync>(httpClient, $"v1.0/groups/{groupId}/members?$filter=Id eq '{user.Id}'&$select=Id", accessToken).GetAwaiter().GetResult(); + isMember = members.Items.Any(); + } + catch (GraphException) + { } + + bool isOwner = false; + try + { + var owners = GraphHelper.GetAsync>(httpClient, $"v1.0/groups/{groupId}/owners?$filter=Id eq '{user.Id}'&$select=Id", accessToken).GetAwaiter().GetResult(); + isOwner = owners.Items.Any(); + } + catch (GraphException) + { + + } + + var value = new Dictionary + { + { + "@odata.id", + $"https://graph.microsoft.com/v1.0/directoryObjects/{user.Id}" + } + }; + var stringContent = new StringContent(JsonConvert.SerializeObject(value)); + stringContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + if (role == "Owner") + { + if (!isMember) + { + GraphHelper.PostAsync(httpClient, $"v1.0/groups/{groupId}/members/$ref", accessToken, stringContent).GetAwaiter().GetResult(); + } + GraphHelper.PostAsync(httpClient, $"v1.0/groups/{groupId}/owners/$ref", accessToken, stringContent).GetAwaiter().GetResult(); + } + else + { + GraphHelper.PostAsync(httpClient, $"v1.0/groups/{groupId}/members/$ref", accessToken, stringContent).GetAwaiter().GetResult(); + } + } + + public static List GetUsers(HttpClient httpClient, string accessToken, string groupId, string role) + { + var selectedRole = role != null ? role.ToLower() : null; + var owners = new List(); + var guests = new List(); + var members = new List(); + if (selectedRole != "guest") + { + owners = GraphHelper.GetAsync>(httpClient, $"v1.0/groups/{groupId}/owners?$select=Id,displayName,userPrincipalName,userType", accessToken).GetAwaiter().GetResult().Items.Select(t => new User() + { + Id = t.Id, + DisplayName = t.DisplayName, + UserPrincipalName = t.UserPrincipalName, + UserType = "Owner" + }).ToList(); + } + if (selectedRole != "owner") + { + var users = GraphHelper.GetAsync>(httpClient, $"v1.0/groups/{groupId}/members?$select=Id,displayName,userPrincipalName,userType", accessToken).GetAwaiter().GetResult().Items; + HashSet hashSet = new HashSet(owners.Select(u => u.Id)); + foreach (var user in users) + { + if (!hashSet.Contains(user.Id)) + { + if (user.UserType != null && user.UserType.ToLower().Equals("guest")) + { + guests.Add(new User() { DisplayName = user.DisplayName, Id = user.Id, UserPrincipalName = user.UserPrincipalName, UserType = "Guest" }); + } + else + { + members.Add(new User() { DisplayName = user.DisplayName, Id = user.Id, UserPrincipalName = user.UserPrincipalName, UserType = "Member" }); + } + } + } + } + var finalList = new List(); + if (string.IsNullOrEmpty(selectedRole)) + { + finalList.AddRange(owners); + finalList.AddRange(members); + finalList.AddRange(guests); + } + else if (selectedRole == "owner") + { + finalList.AddRange(owners); + } + else if (selectedRole == "member") + { + finalList.AddRange(members); + } + else if (selectedRole == "guest") + { + finalList.AddRange(guests); + } + return finalList; + } + + public static void DeleteUser(HttpClient httpClient, string accessToken, string groupId, string upn, string role) + { + var user = GraphHelper.GetAsync(httpClient, $"v1.0/users/{upn}?$select=Id", accessToken).GetAwaiter().GetResult(); + if (user != null) + { + // check if the user is an owner + var owners = GraphHelper.GetAsync>(httpClient, $"v1.0/groups/{groupId}/owners?$select=Id", accessToken).GetAwaiter().GetResult(); + if (owners.Items.Any() && owners.Items.FirstOrDefault(u => u.Id.Equals(user.Id, StringComparison.OrdinalIgnoreCase)) != null) + { + if (owners.Items.Count() == 1) + { + throw new PSInvalidOperationException("Last owner cannot be removed"); + } + GraphHelper.DeleteAsync(httpClient, $"v1.0/groups/{groupId}/owners/{user.Id}/$ref", accessToken).GetAwaiter().GetResult(); + } + if (!role.Equals("owner", StringComparison.OrdinalIgnoreCase)) + { + GraphHelper.DeleteAsync(httpClient, $"v1.0/groups/{groupId}/members/{user.Id}/$ref", accessToken).GetAwaiter().GetResult(); + } + } + } + + #endregion #region Channel public static IEnumerable GetChannels(string accessToken, HttpClient httpClient, string groupId) { - var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/teams/{groupId}/channels", accessToken).GetAwaiter().GetResult(); + var collection = GraphHelper.GetAsync>(httpClient, $"beta/teams/{groupId}/channels", accessToken).GetAwaiter().GetResult(); if (collection != null) { return collection.Items; @@ -262,14 +409,18 @@ public static bool DeleteChannel(string accessToken, HttpClient httpClient, stri } } - public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, string groupId, string displayName, string description) + public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, string groupId, string displayName, string description, bool isPrivate) { var channel = new TeamChannel() { Description = description, DisplayName = displayName, }; - return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels", channel, accessToken).GetAwaiter().GetResult(); + if (isPrivate) + { + channel.MembershipType = "private"; + } + return GraphHelper.PostAsync(httpClient, $"beta/teams/{groupId}/channels", channel, accessToken).GetAwaiter().GetResult(); } public static void PostMessage(HttpClient httpClient, string accessToken, string groupId, string channelId, TeamChannelMessage message) @@ -281,10 +432,10 @@ public static List GetMessages(HttpClient httpClient, string { List messages = new List(); var collection = GraphHelper.GetAsync>(httpClient, $"beta/teams/{groupId}/channels/{channelId}/messages", accessToken).GetAwaiter().GetResult(); - if(collection != null) + if (collection != null) { messages.AddRange(collection.Items); - while(collection != null && !string.IsNullOrEmpty(collection.NextLink)) + while (collection != null && !string.IsNullOrEmpty(collection.NextLink)) { collection = GraphHelper.GetAsync>(httpClient, collection.NextLink, accessToken).GetAwaiter().GetResult(); if (collection != null) @@ -296,11 +447,17 @@ public static List GetMessages(HttpClient httpClient, string if (includeDeleted) { return messages; - } else + } + else { return messages.Where(m => !m.DeletedDateTime.HasValue).ToList(); } } + + public static TeamChannel UpdateChannel(HttpClient httpClient, string accessToken, string groupId, string channelId, TeamChannel channel) + { + return GraphHelper.PatchAsync(httpClient, accessToken, $"beta/teams/{groupId}/channels/{channelId}", channel).GetAwaiter().GetResult(); + } #endregion #region Tabs @@ -324,6 +481,121 @@ public static bool DeleteTab(string accessToken, HttpClient httpClient, string g return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); } + public static void UpdateTab(HttpClient httpClient, string accessToken, string groupId, string channelId, TeamTab tab) + { + tab.Configuration = null; + GraphHelper.PatchAsync(httpClient, accessToken, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tab.Id}", tab).GetAwaiter().GetResult(); + } + + public static TeamTab AddTab(HttpClient httpClient, string accessToken, string groupId, string channelId, string displayName, TeamTabType tabType, string teamsAppId, string entityId, string contentUrl, string removeUrl, string websiteUrl) + { + TeamTab tab = new TeamTab(); + tab.Configuration = new TeamTabConfiguration(); + switch (tabType) + { + case TeamTabType.Custom: + { + tab.TeamsAppId = teamsAppId; + tab.Configuration.EntityId = entityId; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = removeUrl; + tab.Configuration.WebsiteUrl = websiteUrl; + break; + } + case TeamTabType.DocumentLibrary: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.files.sharepoint"; + tab.Configuration.EntityId = ""; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = null; + tab.Configuration.WebsiteUrl = null; + break; + } + case TeamTabType.WebSite: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.web"; + tab.Configuration.EntityId = null; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = null; + tab.Configuration.WebsiteUrl = contentUrl; + break; + } + case TeamTabType.Word: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.file.staticviewer.word"; + tab.Configuration.EntityId = entityId; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = null; + tab.Configuration.WebsiteUrl = null; + break; + } + case TeamTabType.Excel: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.file.staticviewer.excel"; + tab.Configuration.EntityId = entityId; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = null; + tab.Configuration.WebsiteUrl = null; + break; + } + case TeamTabType.PowerPoint: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.file.staticviewer.powerpoint"; + tab.Configuration.EntityId = entityId; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = null; + tab.Configuration.WebsiteUrl = null; + break; + } + case TeamTabType.PDF: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.file.staticviewer.pdf"; + tab.Configuration.EntityId = entityId; + tab.Configuration.ContentUrl = contentUrl; + tab.Configuration.RemoveUrl = null; + tab.Configuration.WebsiteUrl = null; + break; + } + case TeamTabType.Wiki: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.wiki"; + break; + } + case TeamTabType.Planner: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.planner"; + break; + } + case TeamTabType.MicrosoftStream: + { + tab.TeamsAppId = "com.microsoftstream.embed.skypeteamstab"; + break; + } + case TeamTabType.MicrosoftForms: + { + tab.TeamsAppId = "81fef3a6-72aa-4648-a763-de824aeafb7d"; + break; + } + case TeamTabType.OneNote: + { + tab.TeamsAppId = "0d820ecd-def2-4297-adad-78056cde7c78"; + break; + } + case TeamTabType.PowerBI: + { + tab.TeamsAppId = "com.microsoft.teamspace.tab.powerbi"; + break; + } + case TeamTabType.SharePointPageAndList: + { + tab.TeamsAppId = "2a527703-1f6f-4559-a332-d8a7d288cd88"; + break; + } + } + tab.DisplayName = displayName; + tab.TeamsApp = $"https://graph.microsoft.com/v1.0/appCatalogs/teamsApps/{tab.TeamsAppId}"; + return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs", tab, accessToken).GetAwaiter().GetResult(); + } #endregion #region Apps From b20e64b0a2ee8b3e3021999e7ec3d1d4711989c0 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 6 Jul 2020 22:58:38 +0200 Subject: [PATCH 114/130] Updated module file for teams --- ...P.PowerShell.Online.Commands.Format.ps1xml | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index 83fb387a7..6d02e93bf 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2204,5 +2204,45 @@ + + TeamTab + + SharePointPnP.PowerShell.Commands.Model.Teams.User + + + + + + + + + + + + + + + + + + + + + Id + + + UserPrincipalName + + + DisplayName + + + UserType + + + + + + From 17ded14dff8f11c49815b3697621d8c485f00f7c Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 7 Jul 2020 12:52:48 +0200 Subject: [PATCH 115/130] Updated Teams Cmdlets --- CHANGELOG.md | 2 +- Commands/Base/PipeBinds/TeamsAppPipeBind.cs | 43 ++++++++- Commands/Base/PipeBinds/TeamsTeamPipeBind.cs | 52 +++++++++-- Commands/Model/Teams/GraphException.cs | 2 +- .../SharePointPnP.PowerShell.Commands.csproj | 4 + Commands/Teams/GetTeamsApp.cs | 10 +-- Commands/Teams/GetTeamsTeam.cs | 4 + Commands/Teams/GetTeamsUser.cs | 1 + Commands/Teams/NewTeamsApp.cs | 59 +++++++++++++ Commands/Teams/RemoveTeamsApp.cs | 69 +++++++++++++++ Commands/Teams/RemoveTeamsChannel.cs | 34 ++++++-- Commands/Teams/RemoveTeamsTab.cs | 56 +++++++----- Commands/Teams/RemoveTeamsTeam.cs | 31 +++++-- Commands/Teams/RemoveTeamsUser.cs | 9 +- Commands/Teams/SetTeamsTeamArchivedState.cs | 87 +++++++++++++++++++ Commands/Teams/SetTeamsTeamPicture.cs | 43 +++++---- Commands/Teams/UpdateTeamsApp.cs | 72 +++++++++++++++ Commands/Utilities/REST/GraphHelper.cs | 61 ++++++++----- Commands/Utilities/TeamsUtility.cs | 69 ++++++++++++--- 19 files changed, 603 insertions(+), 105 deletions(-) create mode 100644 Commands/Teams/NewTeamsApp.cs create mode 100644 Commands/Teams/RemoveTeamsApp.cs create mode 100644 Commands/Teams/SetTeamsTeamArchivedState.cs create mode 100644 Commands/Teams/UpdateTeamsApp.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f0bc7b98..0fa8a002b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) -- Added Add-PnPTeamsChannel, Add-PnPTeamsTab, Add-PnPTeamsUser, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsChannelMessage, Get-PnPTeamsTab, Get-PnPTeamsTeam, Get-PnPTeamsUser, New-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam, Remove-PnPTeamsUser, Set-PnPTeamsChannel, Set-PnPTeamsTab, Set-PnPTeamsTeam, Set-PnPTeamsPicture, Submit-PnPTeamsChannelMessage cmdlets +- Added Add-PnPTeamsChannel, Add-PnPTeamsTab, Add-PnPTeamsUser, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsChannelMessage, Get-PnPTeamsTab, Get-PnPTeamsTeam, Get-PnPTeamsUser, New-PnPTeamsApp, New-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam, Remove-PnPTeamsUser, Set-PnPTeamsChannel, Set-PnPTeamsTab, Set-PnPTeamsTeam, Set-PnPTeamsPicture, Submit-PnPTeamsChannelMessage, Update-PnPTeamsApp cmdlets ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) diff --git a/Commands/Base/PipeBinds/TeamsAppPipeBind.cs b/Commands/Base/PipeBinds/TeamsAppPipeBind.cs index c8a0d849c..731e50392 100644 --- a/Commands/Base/PipeBinds/TeamsAppPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsAppPipeBind.cs @@ -1,4 +1,9 @@ -using System; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities.REST; +using System; +using System.Linq; +using System.Management.Automation; +using System.Net.Http; namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds { @@ -32,5 +37,41 @@ public TeamsAppPipeBind(string input) public Guid Id => _id; public string StringValue => _stringValue; + + public TeamApp GetApp(HttpClient httpClient, string accessToken) + { + if (Id != Guid.Empty) + { + var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/appCatalogs/teamsApps?$filter=id eq '{_id}'", accessToken).GetAwaiter().GetResult(); + if (collection != null && collection.Items.Any()) + { + return collection.Items.First(); + } + else + { + collection = GraphHelper.GetAsync>(httpClient, $"v1.0/appCatalogs/teamsApps?$filter=externalId eq '{_id}'", accessToken).GetAwaiter().GetResult(); + if (collection != null && collection.Items.Any()) + { + return collection.Items.First(); + } + } + } + else + { + var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/appCatalogs/teamsApps?$filter=displayName eq '{_stringValue}'", accessToken).GetAwaiter().GetResult(); + if (collection != null && collection.Items.Any()) + { + if (collection.Items.Count() == 1) + { + return collection.Items.First(); + } + else + { + throw new PSArgumentException("Multiple apps found with the same display name. Specify id instead to reference to the app."); + } + } + } + return null; + } } } diff --git a/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs b/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs index fae601ae7..c62dacfde 100644 --- a/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs +++ b/Commands/Base/PipeBinds/TeamsTeamPipeBind.cs @@ -48,21 +48,22 @@ public string GetGroupId(HttpClient httpClient, string accessToken) } else { - var collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{_stringValue}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken).GetAwaiter().GetResult(); - if(collection != null && collection.Items.Any()) - { + var collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{_stringValue}')&$select=Id", accessToken).GetAwaiter().GetResult(); + if (collection != null && collection.Items.Any()) + { return collection.Items.First().Id; } else { // find the team by displayName - var byDisplayNamecollection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{_stringValue}')&$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken).GetAwaiter().GetResult(); - if (byDisplayNamecollection != null) + var byDisplayNamecollection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{_stringValue}')&$select=Id", accessToken).GetAwaiter().GetResult(); + if (byDisplayNamecollection != null && byDisplayNamecollection.Items.Any()) { if (byDisplayNamecollection.Items.Count() == 1) { return byDisplayNamecollection.Items.First().Id; - } else + } + else { throw new PSArgumentException("We found more matches based on the identity value you entered. Use Get-PnPTeamsTeam to find the correct instance and use the GroupId from a team to select the correct team instead."); } @@ -72,5 +73,44 @@ public string GetGroupId(HttpClient httpClient, string accessToken) } } + public Team GetTeam(HttpClient httpClient, string accessToken) + { + try + { + if (!string.IsNullOrEmpty(_id)) + { + return GraphHelper.GetAsync(httpClient, $"v1.0/teams/{_id}", accessToken).GetAwaiter().GetResult(); + } + else + { + var collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and displayName eq '{_stringValue}')&$select=Id", accessToken).GetAwaiter().GetResult(); + if (collection != null && collection.Items.Any()) + { + if (collection.Items.Count() == 1) + { + return GraphHelper.GetAsync(httpClient, $"v1.0/teams/{collection.Items.First().Id}", accessToken).GetAwaiter().GetResult(); + } + else + { + throw new PSArgumentException("We found more matches based on the identity value you entered. Use Get-PnPTeamsTeam to find the correct instance and use the GroupId from a team to select the correct team instead."); + } + } + else + { + collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=(resourceProvisioningOptions/Any(x:x eq 'Team') and mailNickname eq '{_stringValue}')&$select=Id", accessToken).GetAwaiter().GetResult(); + if (collection != null && collection.Items.Count() == 1) + { + return GraphHelper.GetAsync(httpClient, $"v1.0/teams/{collection.Items.First().Id}", accessToken).GetAwaiter().GetResult(); + } + } + } + } + catch (GraphException ex) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + return null; + } + } } diff --git a/Commands/Model/Teams/GraphException.cs b/Commands/Model/Teams/GraphException.cs index 231f86ec2..d4456f868 100644 --- a/Commands/Model/Teams/GraphException.cs +++ b/Commands/Model/Teams/GraphException.cs @@ -12,7 +12,7 @@ public class GraphException : Exception public class GraphError { - public string StatusCode { get; set; } + public string Code { get; set; } public string Message { get; set; } diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 56f1fc6a5..ca6ebdd00 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -930,7 +930,9 @@ + + @@ -938,8 +940,10 @@ + + diff --git a/Commands/Teams/GetTeamsApp.cs b/Commands/Teams/GetTeamsApp.cs index 9529c1f3c..d6c8d5a75 100644 --- a/Commands/Teams/GetTeamsApp.cs +++ b/Commands/Teams/GetTeamsApp.cs @@ -38,14 +38,10 @@ protected override void ExecuteCmdlet() { if (ParameterSpecified(nameof(Identity))) { - var apps = TeamsUtility.GetApps(AccessToken, HttpClient); - if (Identity.Id != Guid.Empty) + var app = Identity.GetApp(HttpClient, AccessToken); + if (app != null) { - WriteObject(apps.FirstOrDefault(a => a.Id == Identity.Id.ToString() || a.ExternalId == a.Id.ToString())); - } - else - { - WriteObject(apps.FirstOrDefault(a => a.DisplayName.Equals(Identity.StringValue, StringComparison.OrdinalIgnoreCase))); + WriteObject(app); } } else diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs index c277b49db..87ed69290 100644 --- a/Commands/Teams/GetTeamsTeam.cs +++ b/Commands/Teams/GetTeamsTeam.cs @@ -19,6 +19,10 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPTeamsTeam -Identity $groupId", Remarks = "Retrieves a specific Microsoft Teams instance", SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPTeamsTeam -Identity $groupId", + Remarks = "Retrieves a specific Microsoft Teams instance", + SortOrder = 2)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsTeam : PnPGraphCmdlet diff --git a/Commands/Teams/GetTeamsUser.cs b/Commands/Teams/GetTeamsUser.cs index af675c201..c83767bb4 100644 --- a/Commands/Teams/GetTeamsUser.cs +++ b/Commands/Teams/GetTeamsUser.cs @@ -28,6 +28,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph Code = "PS:> Get-PnPTeamsUser -Team MyTeam -Role Guest", Remarks = "Returns all guestss from the specified team.", SortOrder = 4)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsUser : PnPGraphCmdlet { diff --git a/Commands/Teams/NewTeamsApp.cs b/Commands/Teams/NewTeamsApp.cs new file mode 100644 index 000000000..47ecf5768 --- /dev/null +++ b/Commands/Teams/NewTeamsApp.cs @@ -0,0 +1,59 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.New, "PnPTeamsApp")] + [CmdletHelp("Adds an app to the Teams App Catalog.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> New-PnPTeamsApp -Path c:\\myapp.zip", + Remarks = "Adds the app as defined in the zip file to the Teams App Catalog", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.AppCatalog_ReadWrite_All)] + public class NewTeamsApp : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "The path pointing to the packaged/zip file containing the app")] + public string Path; + + protected override void ExecuteCmdlet() + { + if (!System.IO.Path.IsPathRooted(Path)) + { + Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); + } + + if (System.IO.File.Exists(Path)) + { + try + { + var bytes = System.IO.File.ReadAllBytes(Path); + TeamsUtility.AddApp(HttpClient, AccessToken, bytes); + } + catch (GraphException ex) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw new PSInvalidOperationException(ex.Message); + } + } + } + else + { + new PSArgumentException("File not found"); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/RemoveTeamsApp.cs b/Commands/Teams/RemoveTeamsApp.cs new file mode 100644 index 000000000..32da564be --- /dev/null +++ b/Commands/Teams/RemoveTeamsApp.cs @@ -0,0 +1,69 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Commands.Utilities.REST; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Remove, "PnPTeamsApp")] + [CmdletHelp("Removes an app from the Teams AppCatalog.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Remove-PnPTeamsApp -Identity ac139d8b-fa2b-4ffe-88b3-f0b30158b58b", + Remarks = "Adds a new channel to the specified Teams instance", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Remove-PnPTeamsApp -Identity \"My Teams App\"", + Remarks = "Adds a new channel to the specified Teams instance", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Add-PnPTeamsChannel -Team MyTeam -DisplayName \"My Channel\" -Private", + Remarks = "Adds a new private channel to the specified Teams instance", + SortOrder = 3)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.AppCatalog_ReadWrite_All)] + public class RemoveTeamsApp : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "The id, externalid or display name of the app.")] + public TeamsAppPipeBind Identity; + + [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] + public SwitchParameter Force; + + protected override void ExecuteCmdlet() + { + var app = Identity.GetApp(HttpClient, AccessToken); + if (app == null) + { + throw new PSArgumentException("App not found"); + } + if (Force || ShouldContinue($"Do you want to remove {app.DisplayName}?", Properties.Resources.Confirm)) + { + var response = TeamsUtility.DeleteApp(HttpClient, AccessToken, app.Id); + if (!response.IsSuccessStatusCode) + { + if (GraphHelper.TryGetGraphException(response, out GraphException ex)) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + } + else + { + throw new PSInvalidOperationException("Removing app failed"); + } + } + else + { + WriteObject("App removed"); + } + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/RemoveTeamsChannel.cs b/Commands/Teams/RemoveTeamsChannel.cs index 0c788446e..3cbee5ca7 100644 --- a/Commands/Teams/RemoveTeamsChannel.cs +++ b/Commands/Teams/RemoveTeamsChannel.cs @@ -2,7 +2,9 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Commands.Utilities.REST; using System; using System.Management.Automation; @@ -23,7 +25,7 @@ public class RemoveTeamsChannel : PnPGraphCmdlet public TeamsTeamPipeBind Team; [Parameter(Mandatory = true)] - public string DisplayName; + public TeamsChannelPipeBind Identity; [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] public SwitchParameter Force; @@ -35,13 +37,33 @@ protected override void ExecuteCmdlet() var groupId = Team.GetGroupId(HttpClient, AccessToken); if (groupId != null) { - if (!TeamsUtility.DeleteChannel(AccessToken, HttpClient, groupId, DisplayName)) + var channel = Identity.GetChannel(HttpClient, AccessToken, groupId); + if (channel != null) { - WriteError(new ErrorRecord(new Exception($"Channel remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + var response = TeamsUtility.DeleteChannel(AccessToken, HttpClient, groupId, channel.Id); + if (!response.IsSuccessStatusCode) + { + if (GraphHelper.TryGetGraphException(response, out GraphException ex)) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + } + else + { + WriteError(new ErrorRecord(new Exception($"Channel remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + } + } + else + { + throw new PSArgumentException("Channel not found"); + } + } + else + { + throw new PSArgumentException("Team not found"); } - } else - { - throw new PSArgumentException("Team not found"); } } } diff --git a/Commands/Teams/RemoveTeamsTab.cs b/Commands/Teams/RemoveTeamsTab.cs index 224c68e46..6356b6cfd 100644 --- a/Commands/Teams/RemoveTeamsTab.cs +++ b/Commands/Teams/RemoveTeamsTab.cs @@ -2,7 +2,9 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Commands.Utilities.REST; using System.Management.Automation; namespace SharePointPnP.PowerShell.Commands.Graph @@ -36,46 +38,58 @@ public class RemoveTeamsTab : PnPGraphCmdlet protected override void ExecuteCmdlet() { - if (Force || ShouldContinue("Removing the tab will remove the settings of this tab too.", Properties.Resources.Confirm)) + + var groupId = Team.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - var groupId = Team.GetGroupId(HttpClient, AccessToken); - if (groupId != null) + var channelId = Channel.GetId(HttpClient, AccessToken, groupId); + if (channelId != null) { - var channelId = Channel.GetId(HttpClient, AccessToken, groupId); - if (channelId != null) + var tabId = string.Empty; + if (string.IsNullOrEmpty(Identity.Id)) + { + tabId = Identity.Id.ToString(); + } + else { - var tabId = string.Empty; - if (string.IsNullOrEmpty(Identity.Id)) + var tab = Identity.GetTab(HttpClient, AccessToken, groupId, channelId); + if (tab != null) { - tabId = Identity.Id.ToString(); + tabId = tab.Id; } else { - var tab = Identity.GetTab(HttpClient, AccessToken, groupId, channelId); - if (tab != null) + throw new PSArgumentException("Cannot find tab"); + } + } + if (Force || ShouldContinue("Removing the tab will remove the settings of this tab too.", Properties.Resources.Confirm)) + { + var response = TeamsUtility.DeleteTab(AccessToken, HttpClient, groupId, channelId, tabId); + if (!response.IsSuccessStatusCode) + { + if (GraphHelper.TryGetGraphException(response, out GraphException ex)) { - tabId = tab.Id; + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } } else { - throw new PSArgumentException("Cannot find tab"); + throw new PSInvalidOperationException("Tab remove failed"); } } - if (!TeamsUtility.DeleteTab(AccessToken, HttpClient, groupId, channelId, tabId)) - { - throw new PSInvalidOperationException("Tab remove failed"); - } - } - else - { - throw new PSArgumentException("Channel not found"); } } else { - throw new PSArgumentException("Team not found", nameof(Team)); + throw new PSArgumentException("Channel not found"); } } + else + { + throw new PSArgumentException("Team not found", nameof(Team)); + } } } } diff --git a/Commands/Teams/RemoveTeamsTeam.cs b/Commands/Teams/RemoveTeamsTeam.cs index 83a3d1103..eb618d6e8 100644 --- a/Commands/Teams/RemoveTeamsTeam.cs +++ b/Commands/Teams/RemoveTeamsTeam.cs @@ -2,7 +2,9 @@ using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Commands.Utilities.REST; using System; using System.Management.Automation; @@ -31,20 +33,31 @@ public class RemoveTeamsTeam : PnPGraphCmdlet protected override void ExecuteCmdlet() { - if (Force || ShouldContinue("Removing the team will remove all messages in all channels in the team.", Properties.Resources.Confirm)) + var groupId = Identity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) { - var groupId = Identity.GetGroupId(HttpClient, AccessToken); - if (groupId != null) + if (Force || ShouldContinue("Removing the team will remove all messages in all channels in the team.", Properties.Resources.Confirm)) { - if (!TeamsUtility.DeleteTeam(AccessToken, HttpClient, groupId)) + var response = TeamsUtility.DeleteTeam(AccessToken, HttpClient, groupId); + if (!response.IsSuccessStatusCode) { - WriteError(new ErrorRecord(new Exception($"Team remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + if (GraphHelper.TryGetGraphException(response, out GraphException ex)) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + } + else + { + WriteError(new ErrorRecord(new Exception($"Team remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); + } } } - else - { - throw new PSArgumentException("Team not found"); - } + } + else + { + throw new PSArgumentException("Team not found"); } } } diff --git a/Commands/Teams/RemoveTeamsUser.cs b/Commands/Teams/RemoveTeamsUser.cs index 966500523..187136e38 100644 --- a/Commands/Teams/RemoveTeamsUser.cs +++ b/Commands/Teams/RemoveTeamsUser.cs @@ -34,6 +34,10 @@ public class RemoveTeamsUser : PnPGraphCmdlet specified user is removed as an owner of the team but stays as a team member. Defaults to ""Member"". Note: The last owner cannot be removed from the team.")] [ValidateSet(new[] { "Owner", "Member" })] public string Role = "Member"; + + [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] + public SwitchParameter Force; + protected override void ExecuteCmdlet() { var groupId = Team.GetGroupId(HttpClient, AccessToken); @@ -41,7 +45,10 @@ protected override void ExecuteCmdlet() { try { - TeamsUtility.DeleteUser(HttpClient, AccessToken, groupId, User, Role); + if (Force || ShouldContinue($"Remove user with UPN {User}?", Properties.Resources.Confirm)) + { + TeamsUtility.DeleteUser(HttpClient, AccessToken, groupId, User, Role); + } } catch (GraphException ex) { diff --git a/Commands/Teams/SetTeamsTeamArchivedState.cs b/Commands/Teams/SetTeamsTeamArchivedState.cs new file mode 100644 index 000000000..8c23cb396 --- /dev/null +++ b/Commands/Teams/SetTeamsTeamArchivedState.cs @@ -0,0 +1,87 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Commands.Utilities.REST; +using SharePointPnP.PowerShell.Core.Attributes; +using System; +using System.Linq; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Set, "PnPTeamsTeamArchivedState")] + [CmdletHelp("Sets the archived state of a team.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $true", + Remarks = "Archives the team as identified.", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $false", + Remarks = "Unarchives the team as identified.", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Set-PnPTeamsTeamArchivedState -Identity \"My Team\" -Archived $true -SetSiteReadOnlyForMembers $true", + Remarks = "Archives the team as identified and sets the underlying SharePoint Online Site Collection as read only for members", + SortOrder = 3)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Directory_ReadWrite_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + [CmdletTokenType(TokenType = TokenType.Delegate)] + public class SetTeamsTeamArchivedState : PnPGraphCmdlet + { + [Parameter(Mandatory = true, HelpMessage = "Specify the name, id or external id of the app.")] + public TeamsTeamPipeBind Identity; + + [Parameter(Mandatory = true)] + public bool Archived; + + [Parameter(Mandatory = false)] + public bool? SetSiteReadOnlyForMembers; + + protected override void ExecuteCmdlet() + { + if (!Archived && SetSiteReadOnlyForMembers.HasValue) + { + throw new PSArgumentException("You can only modify the read only state of a site when archiving a team"); + } + var groupId = Identity.GetGroupId(HttpClient, AccessToken); + if (groupId != null) + { + var team = Identity.GetTeam(HttpClient, AccessToken); + if (Archived == team.IsArchived) + { + throw new PSInvalidOperationException($"Team {team.DisplayName} {(Archived ? "has already been" : "is not")} archived"); + } + var response = TeamsUtility.SetTeamArchivedState(HttpClient, AccessToken, groupId, Archived, SetSiteReadOnlyForMembers); + if (!response.IsSuccessStatusCode) + { + if (GraphHelper.TryGetGraphException(response, out GraphException ex)) + { + if (ex.Error != null) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + } + else + { + throw new PSInvalidOperationException("Setting archived state failed."); + } + } + else + { + WriteObject($"Team {(Archived ? "archived" : "unarchived")}."); + + } + } + else + { + throw new PSArgumentException("Team not found"); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Teams/SetTeamsTeamPicture.cs b/Commands/Teams/SetTeamsTeamPicture.cs index e654cf584..b31bc6b5a 100644 --- a/Commands/Teams/SetTeamsTeamPicture.cs +++ b/Commands/Teams/SetTeamsTeamPicture.cs @@ -38,28 +38,35 @@ protected override void ExecuteCmdlet() Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); } - var contentType = ""; - var fileInfo = new FileInfo(Path); - switch (fileInfo.Extension) + if (System.IO.File.Exists(Path)) { - case ".jpg": - case ".jpeg": - { - contentType = "image/jpeg"; - break; - } - case ".png": - { - contentType = "image/png"; - break; - } + var contentType = ""; + var fileInfo = new FileInfo(Path); + switch (fileInfo.Extension) + { + case ".jpg": + case ".jpeg": + { + contentType = "image/jpeg"; + break; + } + case ".png": + { + contentType = "image/png"; + break; + } + } + if (string.IsNullOrEmpty(contentType)) + { + throw new PSArgumentException("File is not of a supported content type (jpg/png)"); + } + var byteArray = System.IO.File.ReadAllBytes(Path); + TeamsUtility.SetTeamPicture(HttpClient, AccessToken, groupId, byteArray, contentType); } - if (string.IsNullOrEmpty(contentType)) + else { - throw new PSArgumentException("File is not of a supported content type (jpg/png)"); + throw new PSArgumentException("File not found"); } - var byteArray = System.IO.File.ReadAllBytes(Path); - TeamsUtility.SetTeamPicture(HttpClient, AccessToken, groupId, byteArray, contentType); } else { diff --git a/Commands/Teams/UpdateTeamsApp.cs b/Commands/Teams/UpdateTeamsApp.cs new file mode 100644 index 000000000..8ca1b7512 --- /dev/null +++ b/Commands/Teams/UpdateTeamsApp.cs @@ -0,0 +1,72 @@ +#if !ONPREMISES +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities; +using SharePointPnP.PowerShell.Commands.Utilities.REST; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsData.Update, "PnPTeamsApp")] + [CmdletHelp("Updates an existing app in the Teams App Catalog.", + Category = CmdletHelpCategory.Teams, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Update-PnPTeamsApp -Identity 4efdf392-8225-4763-9e7f-4edeb7f721aa -Path c:\\myapp.zip", + Remarks = "Updates the specified app in the teams app catalog with the contents of the referenced zip file.", + SortOrder = 1)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] + public class UpdateTeamsApp : PnPGraphCmdlet + { + [Parameter(Mandatory = true)] + public TeamsAppPipeBind Identity; + + [Parameter(Mandatory = true, HelpMessage = "The path pointing to the packaged/zip file containing the app")] + public string Path; + + protected override void ExecuteCmdlet() + { + if (!System.IO.Path.IsPathRooted(Path)) + { + Path = System.IO.Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, Path); + } + + if (System.IO.File.Exists(Path)) + { + var app = Identity.GetApp(HttpClient, AccessToken); + if (app != null) + { + + var bytes = System.IO.File.ReadAllBytes(Path); + var response = TeamsUtility.UpdateApp(HttpClient, AccessToken, bytes, app.Id); + if (!response.IsSuccessStatusCode) + { + if (GraphHelper.TryGetGraphException(response, out GraphException ex)) + { + throw new PSInvalidOperationException(ex.Error.Message); + } + else + { + throw new PSInvalidOperationException("Update app failed"); + } + } + else + { + WriteObject("App updated"); + } + } + else + { + throw new PSArgumentException("App not found"); + } + } + else + { + throw new PSArgumentException("File not found"); + } + } + } +} +#endif \ No newline at end of file diff --git a/Commands/Utilities/REST/GraphHelper.cs b/Commands/Utilities/REST/GraphHelper.cs index f3fdc164a..9b1a81e23 100644 --- a/Commands/Utilities/REST/GraphHelper.cs +++ b/Commands/Utilities/REST/GraphHelper.cs @@ -1,4 +1,5 @@ -using Microsoft.Identity.Client; +using Microsoft.Graph; +using Microsoft.Identity.Client; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using SharePointPnP.PowerShell.Commands.Model.Teams; @@ -15,6 +16,30 @@ namespace SharePointPnP.PowerShell.Commands.Utilities.REST { internal static class GraphHelper { + public static bool TryGetGraphException(HttpResponseMessage responseMessage, out GraphException exception) + { + if (responseMessage == null) + { + exception = null; + return false; + } + var content = responseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + if (string.IsNullOrEmpty(content)) + { + exception = null; + return false; + } + try + { + exception = JsonConvert.DeserializeObject(content); + return true; + } + catch + { + exception = null; + return false; + } + } private static HttpRequestMessage GetMessage(string url, HttpMethod method, string accessToken, HttpContent content = null) { @@ -62,12 +87,20 @@ public static async Task GetAsync(HttpClient httpClient, string url, strin return default(T); } - public static async Task PostAsync(HttpClient httpClient, string url, string accessToken, HttpContent content) + public static async Task PostAsync(HttpClient httpClient, string url, string accessToken, HttpContent content) { var message = GetMessage(url, HttpMethod.Post, accessToken, content); - return await SendMessageAsync(httpClient, message); + return await GetResponseMessageAsync(httpClient, message); + } + + public static async Task PutAsync(HttpClient httpClient, string url, string accessToken, HttpContent content) + { + var message = GetMessage(url, HttpMethod.Put, accessToken, content); + return await GetResponseMessageAsync(httpClient, message); } + + public static async Task PatchAsync(HttpClient httpClient, string accessToken, string url, T content) { var requestContent = new StringContent(JsonConvert.SerializeObject(content, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() })); @@ -88,6 +121,8 @@ public static async Task PatchAsync(HttpClient httpClient, string accessTo } } + + public static async Task PostAsync(HttpClient httpClient, string url, HttpContent content, string accessToken) { var message = GetMessage(url, HttpMethod.Post, accessToken, content); @@ -156,18 +191,11 @@ public static async Task PutAsync(HttpClient httpClient, string url, T con } } - public static async Task DeleteAsync(HttpClient httpClient, string url, string accessToken) + public static async Task DeleteAsync(HttpClient httpClient, string url, string accessToken) { var message = GetMessage(url, HttpMethod.Delete, accessToken); var response = await GetResponseMessageAsync(httpClient, message); - if (response.IsSuccessStatusCode) - { - return true; - } - else - { - return false; - } + return response; } private static async Task SendMessageAsync(HttpClient httpClient, HttpRequestMessage message) @@ -204,14 +232,7 @@ public static async Task GetResponseMessageAsync(HttpClient Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); response = await httpClient.SendAsync(CloneMessage(message)); } - if (response.IsSuccessStatusCode) - { - return response; - } - else - { - return null; - } + return response; } private static HttpRequestMessage CloneMessage(HttpRequestMessage req) diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs index 6ab99477c..60426a934 100644 --- a/Commands/Utilities/TeamsUtility.cs +++ b/Commands/Utilities/TeamsUtility.cs @@ -1,5 +1,7 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Site; using SharePointPnP.PowerShell.Commands.Utilities.REST; using System; using System.Collections.Generic; @@ -78,7 +80,7 @@ public static Team GetTeam(string accessToken, HttpClient httpClient, string gro } } - public static bool DeleteTeam(string accessToken, HttpClient httpClient, string groupId) + public static HttpResponseMessage DeleteTeam(string accessToken, HttpClient httpClient, string groupId) { return GraphHelper.DeleteAsync(httpClient, $"v1.0/groups/{groupId}", accessToken).GetAwaiter().GetResult(); } @@ -249,6 +251,22 @@ public static void SetTeamPicture(HttpClient httpClient, string accessToken, str byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType); GraphHelper.PutAsync(httpClient, $"v1.0/groups/{groupId}/photo/$value", accessToken, byteArrayContent).GetAwaiter().GetResult(); } + + public static HttpResponseMessage SetTeamArchivedState(HttpClient httpClient, string accessToken, string groupId, bool archived, bool? setSiteReadOnly) + { + if (archived) + { + StringContent content = new StringContent(JsonConvert.SerializeObject(setSiteReadOnly.HasValue ? new { shouldSetSpoSiteReadOnlyForMembers = setSiteReadOnly } : null)); + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/archive", accessToken, content).GetAwaiter().GetResult(); + } + else + { + StringContent content = new StringContent(""); + content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/unarchive", accessToken, content).GetAwaiter().GetResult(); + } + } #endregion #region Users @@ -380,6 +398,7 @@ public static void DeleteUser(HttpClient httpClient, string accessToken, string } #endregion + #region Channel public static IEnumerable GetChannels(string accessToken, HttpClient httpClient, string groupId) { @@ -394,19 +413,9 @@ public static IEnumerable GetChannels(string accessToken, HttpClien } } - public static bool DeleteChannel(string accessToken, HttpClient httpClient, string groupId, string displayName) + public static HttpResponseMessage DeleteChannel(string accessToken, HttpClient httpClient, string groupId, string channelId) { - // find the channel - var channels = GetChannels(accessToken, httpClient, groupId); - var channel = channels.FirstOrDefault(c => c.DisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase)); - if (channel != null) - { - return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channel.Id}", accessToken).GetAwaiter().GetResult(); - } - else - { - return false; - } + return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}", accessToken).GetAwaiter().GetResult(); } public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, string groupId, string displayName, string description, bool isPrivate) @@ -476,7 +485,7 @@ public static TeamTab GetTab(string accessToken, HttpClient httpClient, string g return GraphHelper.GetAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); } - public static bool DeleteTab(string accessToken, HttpClient httpClient, string groupId, string channelId, string tabId) + public static HttpResponseMessage DeleteTab(string accessToken, HttpClient httpClient, string groupId, string channelId, string tabId) { return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channelId}/tabs/{tabId}", accessToken).GetAwaiter().GetResult(); } @@ -608,6 +617,38 @@ public static IEnumerable GetApps(string accessToken, HttpClient httpCl } return null; } + + public static TeamApp AddApp(HttpClient httpClient, string accessToken, byte[] bytes) + { + var byteArrayContent = new ByteArrayContent(bytes); + byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip"); + var response = GraphHelper.PostAsync(httpClient, "v1.0/appCatalogs/teamsApps", accessToken, byteArrayContent).GetAwaiter().GetResult(); + if (!response.IsSuccessStatusCode) + { + if (GraphHelper.TryGetGraphException(response, out GraphException exception)) + { + throw exception; + } + } + else + { + var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + return JsonConvert.DeserializeObject(content); + } + return null; + } + + public static HttpResponseMessage UpdateApp(HttpClient httpClient, string accessToken, byte[] bytes, string appId) + { + var byteArrayContent = new ByteArrayContent(bytes); + byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip"); + return GraphHelper.PutAsync(httpClient, $"v1.0/appCatalogs/teamsApps/{appId}", accessToken, byteArrayContent).GetAwaiter().GetResult(); + } + + public static HttpResponseMessage DeleteApp(HttpClient httpClient, string accessToken, string appId) + { + return GraphHelper.DeleteAsync(httpClient, $"v1.0/appCatalogs/teamsApps/{appId}", accessToken).GetAwaiter().GetResult(); + } #endregion } } \ No newline at end of file From 6b5d517906c331008221c2d51ba859ca90f18505 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 7 Jul 2020 13:11:07 +0200 Subject: [PATCH 116/130] Update format files --- Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml | 6 +++--- .../SharePointPnP.PowerShell.Online.Commands.Format.ps1xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml index 1c80d10c4..2694309d0 100644 --- a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml +++ b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml @@ -1932,7 +1932,7 @@ - TeamTab + TeamApp SharePointPnP.PowerShell.Commands.Model.Teams.TeamApp @@ -1972,7 +1972,7 @@ - TeamTab + TeamChannelMessage SharePointPnP.PowerShell.Commands.Model.Teams.TeamChannelMessage @@ -2008,7 +2008,7 @@ - TeamTab + User SharePointPnP.PowerShell.Commands.Model.Teams.User diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index 6d02e93bf..a0ab3c2d8 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2129,7 +2129,7 @@ - TeamTab + TeamApp SharePointPnP.PowerShell.Commands.Model.Teams.TeamApp @@ -2169,7 +2169,7 @@ - TeamTab + TeamChannelMessage SharePointPnP.PowerShell.Commands.Model.Teams.TeamChannelMessage @@ -2205,7 +2205,7 @@ - TeamTab + User SharePointPnP.PowerShell.Commands.Model.Teams.User From 47c1142d8f872a64187477f8fe9bff76f8767e5f Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 7 Jul 2020 13:38:38 +0200 Subject: [PATCH 117/130] Removed duplicate changelog entry --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb3b27b94..ef3fb9eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) -- Added Add-PnPTeamsChannel, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsTab, Get-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam cmdlets - Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPMicrosoft365GroupMember`, `Add-PnPMicrosoft365GroupOwner`, `Remove-PnPMicrosoft365GroupMember`, `Remove-PnPMicrosoft365GroupOwner`, `Clear-PnPMicrosoft365GroupMember`, `Clear-PnPMicrosoft365GroupOwner` [PR #2750](https://github.com/pnp/PnP-PowerShell/pull/2750) - Added Add-PnPTeamsChannel, Add-PnPTeamsTab, Add-PnPTeamsUser, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsChannelMessage, Get-PnPTeamsTab, Get-PnPTeamsTeam, Get-PnPTeamsUser, New-PnPTeamsApp, New-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam, Remove-PnPTeamsUser, Set-PnPTeamsChannel, Set-PnPTeamsTab, Set-PnPTeamsTeam, Set-PnPTeamsPicture, Submit-PnPTeamsChannelMessage, Update-PnPTeamsApp cmdlets From c69fb520e1a425c1b1ed0628ac9860db71cf3251 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 7 Jul 2020 13:41:53 +0200 Subject: [PATCH 118/130] fixed changelog --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2da24d263..ecf94c605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added +- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown [PR #2754](https://github.com/pnp/PnP-PowerShell/pull/2754) - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) - Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPMicrosoft365GroupMember`, `Add-PnPMicrosoft365GroupOwner`, `Remove-PnPMicrosoft365GroupMember`, `Remove-PnPMicrosoft365GroupOwner`, `Clear-PnPMicrosoft365GroupMember`, `Clear-PnPMicrosoft365GroupOwner` [PR #2750](https://github.com/pnp/PnP-PowerShell/pull/2750) - Added Add-PnPTeamsChannel, Add-PnPTeamsTab, Add-PnPTeamsUser, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsChannelMessage, Get-PnPTeamsTab, Get-PnPTeamsTeam, Get-PnPTeamsUser, New-PnPTeamsApp, New-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam, Remove-PnPTeamsUser, Set-PnPTeamsChannel, Set-PnPTeamsTab, Set-PnPTeamsTeam, Set-PnPTeamsPicture, Submit-PnPTeamsChannelMessage, Update-PnPTeamsApp cmdlets ### Changed -- Updated implementation of `Copy-PnPFile` to now also support copying of files and folders accross site collections [PR #2749](https://github.com/pnp/PnP-PowerShell/pull/2749) - Updated implementation of `Move-PnPFile` to now also support moving of files and folders accross site collections [PR #2749](https://github.com/pnp/PnP-PowerShell/pull/2749) - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) - If a certain PnP PowerShell cmdlet needs access to the SharePoint Admin Center site in order to function correctly, it will now list this in the Synopsis section of the Get-Help for the cmdlet @@ -26,6 +26,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Koen Zomers [koenzomers] - Ellie Hussey [Professr] - Todd Klindt [ToddKlindt] +- Robin Meure [robinmeure] ## [3.22.2006.2] @@ -75,13 +76,12 @@ Intermediate release due to a fix in the underlying Core Library. ## [3.21.2005.0] ### Added -- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown [PR #2754](https://github.com/pnp/PnP-PowerShell/pull/2754) ### Changed - Invoke-PnPSearchQuery: Allow SelectProperties to take a comma separated string as well as an array ### Contributors -- Robin Meure [robinmeure] + ## [3.20.2004.0] From 342f705925e31a7fd2fa1f62339ad200bc996d65 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Tue, 7 Jul 2020 13:45:14 +0200 Subject: [PATCH 119/130] updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf94c605..47243686b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) - If a certain PnP PowerShell cmdlet needs access to the SharePoint Admin Center site in order to function correctly, it will now list this in the Synopsis section of the Get-Help for the cmdlet - Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) +- Updated test project structure [PR #2767](https://github.com/pnp/PnP-PowerShell/pull/2767) ### Contributors - Erwin van Hunen [erwinvanhunen] @@ -27,6 +28,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Ellie Hussey [Professr] - Todd Klindt [ToddKlindt] - Robin Meure [robinmeure] +- Paul Bullock [pkbullock] ## [3.22.2006.2] From a6db13556d0a121cada50d2019bf5aa23dca53eb Mon Sep 17 00:00:00 2001 From: KoenZomers Date: Tue, 7 Jul 2020 23:12:23 +0200 Subject: [PATCH 120/130] Updated MSAL to v4.16 --- Commands/SharePointPnP.PowerShell.Commands.csproj | 4 ++-- Commands/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 65770145c..9ff52d56e 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -453,8 +453,8 @@ ..\packages\Microsoft.Graph.Core.1.9.0\lib\net45\Microsoft.Graph.Core.dll - - ..\packages\Microsoft.Identity.Client.4.15.0\lib\net45\Microsoft.Identity.Client.dll + + ..\packages\Microsoft.Identity.Client.4.16.0\lib\net45\Microsoft.Identity.Client.dll ..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll diff --git a/Commands/packages.config b/Commands/packages.config index 43bf97d16..e3e47cc99 100644 --- a/Commands/packages.config +++ b/Commands/packages.config @@ -17,7 +17,7 @@ - + From ac9abcf63fda1e97ca8a71ef9fc8875a128c160e Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Wed, 8 Jul 2020 10:35:03 +0200 Subject: [PATCH 121/130] Updated reference to correct pipebind class --- Commands/Graph/AddMicrosoft365GroupMember.cs | 2 +- Commands/Graph/AddMicrosoft365GroupOwner.cs | 2 +- Commands/Graph/ClearMicrosoft365GroupMember.cs | 2 +- Commands/Graph/ClearMicrosoft365GroupOwner.cs | 2 +- Commands/Graph/RemoveMicrosoft365GroupMember.cs | 2 +- Commands/Graph/RemoveMicrosoft365GroupOwner.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Commands/Graph/AddMicrosoft365GroupMember.cs b/Commands/Graph/AddMicrosoft365GroupMember.cs index d09e89ee1..ed38053ea 100644 --- a/Commands/Graph/AddMicrosoft365GroupMember.cs +++ b/Commands/Graph/AddMicrosoft365GroupMember.cs @@ -26,7 +26,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class AddMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add members to")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to add to the Microsoft 365 Group as a member")] public string[] Users; diff --git a/Commands/Graph/AddMicrosoft365GroupOwner.cs b/Commands/Graph/AddMicrosoft365GroupOwner.cs index 2ba3cc26c..8646f7eba 100644 --- a/Commands/Graph/AddMicrosoft365GroupOwner.cs +++ b/Commands/Graph/AddMicrosoft365GroupOwner.cs @@ -27,7 +27,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class AddMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to add owners to")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to add to the Microsoft 365 Group as an owner")] public string[] Users; diff --git a/Commands/Graph/ClearMicrosoft365GroupMember.cs b/Commands/Graph/ClearMicrosoft365GroupMember.cs index 54903f967..e8db74fbd 100644 --- a/Commands/Graph/ClearMicrosoft365GroupMember.cs +++ b/Commands/Graph/ClearMicrosoft365GroupMember.cs @@ -22,7 +22,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class ClearMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove all members from")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/ClearMicrosoft365GroupOwner.cs b/Commands/Graph/ClearMicrosoft365GroupOwner.cs index c1d1dec27..be4f0b88a 100644 --- a/Commands/Graph/ClearMicrosoft365GroupOwner.cs +++ b/Commands/Graph/ClearMicrosoft365GroupOwner.cs @@ -22,7 +22,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class ClearMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove all owners from")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; protected override void ExecuteCmdlet() { diff --git a/Commands/Graph/RemoveMicrosoft365GroupMember.cs b/Commands/Graph/RemoveMicrosoft365GroupMember.cs index c21e8852e..df1739931 100644 --- a/Commands/Graph/RemoveMicrosoft365GroupMember.cs +++ b/Commands/Graph/RemoveMicrosoft365GroupMember.cs @@ -22,7 +22,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class RemoveMicrosoft365GroupMember : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove members from")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to remove as members from the Microsoft 365 Group")] public string[] Users; diff --git a/Commands/Graph/RemoveMicrosoft365GroupOwner.cs b/Commands/Graph/RemoveMicrosoft365GroupOwner.cs index 296d22bb3..3ea830d59 100644 --- a/Commands/Graph/RemoveMicrosoft365GroupOwner.cs +++ b/Commands/Graph/RemoveMicrosoft365GroupOwner.cs @@ -22,7 +22,7 @@ namespace SharePointPnP.PowerShell.Commands.Graph public class RemoveMicrosoft365GroupOwner : PnPGraphCmdlet { [Parameter(Mandatory = true, ValueFromPipeline = true, HelpMessage = "The Identity of the Microsoft 365 Group to remove owners from")] - public UnifiedGroupPipeBind Identity; + public Microsoft365GroupPipeBind Identity; [Parameter(Mandatory = true, HelpMessage = "The UPN(s) of the user(s) to remove as owners from the Microsoft 365 Group")] public string[] Users; From 64c4a9f463929d916471c1481b5e366be257e98e Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 9 Jul 2020 17:07:55 +0200 Subject: [PATCH 122/130] fixed team tab output --- .../SharePointPnP.PowerShell.Online.Commands.Format.ps1xml | 2 +- Commands/Teams/GetTeamsTab.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index a0ab3c2d8..e40964fb2 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2103,7 +2103,7 @@ TeamTab - OfficeDevPnP.Core.Framework.Provisioning.Model.Teams.TeamTab + SharePointPnP.PowerShell.Commands.Model.Teams.TeamTab diff --git a/Commands/Teams/GetTeamsTab.cs b/Commands/Teams/GetTeamsTab.cs index de1bcd4ef..7f3c022c6 100644 --- a/Commands/Teams/GetTeamsTab.cs +++ b/Commands/Teams/GetTeamsTab.cs @@ -63,7 +63,7 @@ protected override void ExecuteCmdlet() } else { - WriteObject(TeamsUtility.GetTabs(AccessToken, HttpClient, groupId, channelId)); + WriteObject(TeamsUtility.GetTabs(AccessToken, HttpClient, groupId, channelId), true); } } else From ee010c756c523f3ac72bb6323cdb6bf0e96c91fa Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Fri, 10 Jul 2020 15:11:56 +0200 Subject: [PATCH 123/130] Added fileversion cmdlets --- CHANGELOG.md | 1 + .../Base/PipeBinds/FileVersionPipeBind.cs | 36 ++++++ Commands/Files/GetFileVersion.cs | 59 +++++++++ Commands/Files/RemoveFileVersion.cs | 116 ++++++++++++++++++ Commands/Files/RestoreFileVersion.cs | 91 ++++++++++++++ .../PnP.PowerShell.Core.Format.ps1xml | 34 +++++ ...PnP.PowerShell.2013.Commands.Format.ps1xml | 34 +++++ ...PnP.PowerShell.2016.Commands.Format.ps1xml | 34 +++++ ...PnP.PowerShell.2019.Commands.Format.ps1xml | 34 +++++ ...P.PowerShell.Online.Commands.Format.ps1xml | 34 +++++ .../SharePointPnP.PowerShell.Commands.csproj | 4 + 11 files changed, 477 insertions(+) create mode 100644 Commands/Base/PipeBinds/FileVersionPipeBind.cs create mode 100644 Commands/Files/GetFileVersion.cs create mode 100644 Commands/Files/RemoveFileVersion.cs create mode 100644 Commands/Files/RestoreFileVersion.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index aefe23f5d..7106836a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Added support for enabling and disabling fields using `Set-PnPField -Identity FieldName -Values @{AllowDeletion=$false}` [PR #2766](https://github.com/pnp/PnP-PowerShell/pull/2766) - Added the following cmdlets to add/remove/clear owners and members of Microsoft 365 Groups: `Add-PnPMicrosoft365GroupMember`, `Add-PnPMicrosoft365GroupOwner`, `Remove-PnPMicrosoft365GroupMember`, `Remove-PnPMicrosoft365GroupOwner`, `Clear-PnPMicrosoft365GroupMember`, `Clear-PnPMicrosoft365GroupOwner` [PR #2750](https://github.com/pnp/PnP-PowerShell/pull/2750) - Added Add-PnPTeamsChannel, Add-PnPTeamsTab, Add-PnPTeamsUser, Get-PnPTeamsApp, Get-PnPTeamsChannel, Get-PnPTeamsChannelMessage, Get-PnPTeamsTab, Get-PnPTeamsTeam, Get-PnPTeamsUser, New-PnPTeamsApp, New-PnPTeamsTeam, Remove-PnPTeamsChannel, Remove-PnPTeamsTab, Remove-PnPTeamsTeam, Remove-PnPTeamsUser, Set-PnPTeamsChannel, Set-PnPTeamsTab, Set-PnPTeamsTeam, Set-PnPTeamsPicture, Submit-PnPTeamsChannelMessage, Update-PnPTeamsApp cmdlets +- Added Get-PnPFileVersion, Remove-PnPFileVersion, Restore-PnPFileVersion cmdlets ### Changed - Updated implementation of `Move-PnPFile` to now also support moving of files and folders accross site collections [PR #2749](https://github.com/pnp/PnP-PowerShell/pull/2749) diff --git a/Commands/Base/PipeBinds/FileVersionPipeBind.cs b/Commands/Base/PipeBinds/FileVersionPipeBind.cs new file mode 100644 index 000000000..aa8a5e4eb --- /dev/null +++ b/Commands/Base/PipeBinds/FileVersionPipeBind.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds +{ + public class FileVersionPipeBind + { + + private int _id = -1; + private string _label; + + + public FileVersionPipeBind(string label) + { + if (int.TryParse(label, out int id)) + { + _id = id; + } + else + { + _label = label; + } + } + + public FileVersionPipeBind(int id) + { + _id = id; + } + + public int Id => _id; + public string Label => _label; + } +} diff --git a/Commands/Files/GetFileVersion.cs b/Commands/Files/GetFileVersion.cs new file mode 100644 index 000000000..2481e72b3 --- /dev/null +++ b/Commands/Files/GetFileVersion.cs @@ -0,0 +1,59 @@ +using Microsoft.SharePoint.Client; +using OfficeDevPnP.Core.Utilities; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using System; +using System.IO; +using System.Management.Automation; +using File = Microsoft.SharePoint.Client.File; + +namespace SharePointPnP.PowerShell.Commands.Files +{ + [Cmdlet(VerbsCommon.Get, "PnPFileVersion", DefaultParameterSetName = "Return as file object")] + [CmdletHelp("Retrieves all versions of a file.", + Category = CmdletHelpCategory.Files, + OutputType = typeof(FileVersion), + OutputTypeLink = "https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ee543660(v=office.15)")] + [CmdletExample( + Code = @"PS:> Get-PnPFileVersion -Url Documents/MyDocument.docx", + Remarks = "Retrieves the file version information for the specified file.", + SortOrder = 1)] + public class GetFileVersion : PnPWebCmdlet + { + [Parameter(Mandatory = true)] + public string Url; + + protected override void ExecuteCmdlet() + { + var serverRelativeUrl = string.Empty; + + var webUrl = SelectedWeb.EnsureProperty(w => w.ServerRelativeUrl); + + if (!Url.ToLower().StartsWith(webUrl.ToLower())) + { + serverRelativeUrl = UrlUtility.Combine(webUrl, Url); + } + else + { + serverRelativeUrl = Url; + } + + File file; + +#if ONPREMISES + file = SelectedWeb.GetFileByServerRelativeUrl(serverRelativeUrl); +#else + file = SelectedWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(serverRelativeUrl)); +#endif + + ClientContext.Load(file, f => f.Exists, f => f.Versions.IncludeWithDefaultProperties(i => i.CreatedBy)); + ClientContext.ExecuteQueryRetry(); + + if (file.Exists) + { + var versions = file.Versions; + ClientContext.ExecuteQueryRetry(); + WriteObject(versions); + } + } + } +} diff --git a/Commands/Files/RemoveFileVersion.cs b/Commands/Files/RemoveFileVersion.cs new file mode 100644 index 000000000..7acb03aca --- /dev/null +++ b/Commands/Files/RemoveFileVersion.cs @@ -0,0 +1,116 @@ +using Microsoft.SharePoint.Client; +using OfficeDevPnP.Core.Utilities; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using System.Management.Automation; +using File = Microsoft.SharePoint.Client.File; +using Resources = SharePointPnP.PowerShell.Commands.Properties.Resources; + +namespace SharePointPnP.PowerShell.Commands.Files +{ + [Cmdlet(VerbsCommon.Remove, "PnPFileVersion", DefaultParameterSetName = "Return as file object")] + [CmdletHelp("Removes all or a specific file version.", + Category = CmdletHelpCategory.Files)] + [CmdletExample( + Code = @"PS:> Remove-PnPFileVersion -Url Documents/MyDocument.docx -Identity 512", + Remarks = "Removes the file version with Id 512", + SortOrder = 1)] + [CmdletExample( + Code = @"PS:> Remove-PnPFileVersion -Url Documents/MyDocument.docx -Identity ""Version 1.0""", + Remarks = "Removes the file version with label \"Version 1.0\"", + SortOrder = 2)] + [CmdletExample( + Code = @"PS:> Remove-PnPFileVersion -Url Documents/MyDocument.docx -All", + Remarks = "Removes all file versions", + SortOrder = 2)] + public class RemoveFileVersion : PnPWebCmdlet + { + private const string ParameterSetName_BYID = "By Id"; + private const string ParameterSetName_ALL = "All"; + + [Parameter(Mandatory = true, ParameterSetName = ParameterAttribute.AllParameterSets)] + public string Url; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSetName_ALL)] + public SwitchParameter All; + + [Parameter(Mandatory = false, ParameterSetName = ParameterSetName_BYID)] + public FileVersionPipeBind Identity; + + [Parameter(Mandatory = false, ParameterSetName = ParameterAttribute.AllParameterSets)] + public SwitchParameter Recycle; + + [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be requested and the action will be performed", ParameterSetName = ParameterAttribute.AllParameterSets)] + public SwitchParameter Force; + + + + protected override void ExecuteCmdlet() + { + var serverRelativeUrl = string.Empty; + + var webUrl = SelectedWeb.EnsureProperty(w => w.ServerRelativeUrl); + + if (!Url.ToLower().StartsWith(webUrl.ToLower())) + { + serverRelativeUrl = UrlUtility.Combine(webUrl, Url); + } + else + { + serverRelativeUrl = Url; + } + + File file; + +#if ONPREMISES + file = SelectedWeb.GetFileByServerRelativeUrl(serverRelativeUrl); +#else + file = SelectedWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(serverRelativeUrl)); +#endif + + ClientContext.Load(file, f => f.Exists, f => f.Versions.IncludeWithDefaultProperties(i => i.CreatedBy)); + ClientContext.ExecuteQueryRetry(); + + if (file.Exists) + { + var versions = file.Versions; + + switch (ParameterSetName) + { + case ParameterSetName_ALL: + { + if (Force || ShouldContinue("Remove all versions?", Resources.Confirm)) + { + versions.DeleteAll(); + ClientContext.ExecuteQueryRetry(); + } + break; + } + case ParameterSetName_BYID: + { + if (Force || ShouldContinue("Remove a version?", Resources.Confirm)) + { + if (!string.IsNullOrEmpty(Identity.Label)) + { + versions.DeleteByLabel(Identity.Label); + ClientContext.ExecuteQueryRetry(); + } + else if (Identity.Id != -1) + { + versions.DeleteByID(Identity.Id); + ClientContext.ExecuteQueryRetry(); + } + } + break; + } + } + } + else + { + throw new PSArgumentException("File not found", nameof(Url)); + } + } + } +} + + diff --git a/Commands/Files/RestoreFileVersion.cs b/Commands/Files/RestoreFileVersion.cs new file mode 100644 index 000000000..08e1e7766 --- /dev/null +++ b/Commands/Files/RestoreFileVersion.cs @@ -0,0 +1,91 @@ +using Microsoft.SharePoint.Client; +using OfficeDevPnP.Core.Utilities; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using Resources = SharePointPnP.PowerShell.Commands.Properties.Resources; +using System.Management.Automation; +using File = Microsoft.SharePoint.Client.File; + +namespace SharePointPnP.PowerShell.Commands.Files +{ + [Cmdlet(VerbsData.Restore, "PnPFileVersion", DefaultParameterSetName = "Return as file object")] + [CmdletHelp("Restores a specific file version.", + Category = CmdletHelpCategory.Files)] + [CmdletExample( + Code = @"PS:> Restore-PnPFileVersion -Url Documents/MyDocument.docx -Identity 512", + Remarks = "Restores the file version with Id 512", + SortOrder = 1)] + [CmdletExample( + Code = @"PS:> Restore-PnPFileVersion -Url Documents/MyDocument.docx -Identity ""Version 1.0""", + Remarks = "Restores the file version with label \"Version 1.0\"", + SortOrder = 2)] + public class RestoreFileVersion : PnPWebCmdlet + { + [Parameter(Mandatory = true)] + public string Url; + + [Parameter(Mandatory = false)] + public FileVersionPipeBind Identity; + + [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be requested and the action will be performed")] + public SwitchParameter Force; + + protected override void ExecuteCmdlet() + { + var serverRelativeUrl = string.Empty; + + var webUrl = SelectedWeb.EnsureProperty(w => w.ServerRelativeUrl); + + if (!Url.ToLower().StartsWith(webUrl.ToLower())) + { + serverRelativeUrl = UrlUtility.Combine(webUrl, Url); + } + else + { + serverRelativeUrl = Url; + } + + File file; + +#if ONPREMISES + file = SelectedWeb.GetFileByServerRelativeUrl(serverRelativeUrl); +#else + file = SelectedWeb.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(serverRelativeUrl)); +#endif + + ClientContext.Load(file, f => f.Exists, f => f.Versions.IncludeWithDefaultProperties(i => i.CreatedBy)); + ClientContext.ExecuteQueryRetry(); + + if (file.Exists) + { + var versions = file.Versions; + + if (Force || ShouldContinue("Restoring a previous version will overwrite the current version.", Resources.Confirm)) + { + if (!string.IsNullOrEmpty(Identity.Label)) + { + versions.RestoreByLabel(Identity.Label); + ClientContext.ExecuteQueryRetry(); + WriteObject("Version restored"); + } + else if (Identity.Id != -1) + { + var version = versions.GetById(Identity.Id); + ClientContext.Load(version); + ClientContext.ExecuteQueryRetry(); + + versions.RestoreByLabel(version.VersionLabel); + ClientContext.ExecuteQueryRetry(); + WriteObject("Version restored"); + } + } + } + else + { + throw new PSArgumentException("File not found", nameof(Url)); + } + } + } +} + + diff --git a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml index 2694309d0..52afe4aa2 100644 --- a/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml +++ b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml @@ -2047,5 +2047,39 @@ + + FileVersion + + Microsoft.SharePoint.Client.FileVersion + + + + + + + + + + + + + + + + + + Id + + + VersionLabel + + + Created + + + + + + \ No newline at end of file diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.2013.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.2013.Commands.Format.ps1xml index 60d97bab7..935d5ca12 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.2013.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.2013.Commands.Format.ps1xml @@ -1335,5 +1335,39 @@ + + FileVersion + + Microsoft.SharePoint.Client.FileVersion + + + + + + + + + + + + + + + + + + Id + + + VersionLabel + + + Created + + + + + + \ No newline at end of file diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.2016.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.2016.Commands.Format.ps1xml index 60d97bab7..935d5ca12 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.2016.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.2016.Commands.Format.ps1xml @@ -1335,5 +1335,39 @@ + + FileVersion + + Microsoft.SharePoint.Client.FileVersion + + + + + + + + + + + + + + + + + + Id + + + VersionLabel + + + Created + + + + + + \ No newline at end of file diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.2019.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.2019.Commands.Format.ps1xml index 1eec4e79f..c2f9fb9f6 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.2019.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.2019.Commands.Format.ps1xml @@ -1469,5 +1469,39 @@ + + FileVersion + + Microsoft.SharePoint.Client.FileVersion + + + + + + + + + + + + + + + + + + Id + + + VersionLabel + + + Created + + + + + + \ No newline at end of file diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index e40964fb2..51b7c4de8 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2244,5 +2244,39 @@ + + FileVersion + + Microsoft.SharePoint.Client.FileVersion + + + + + + + + + + + + + + + + + + Id + + + VersionLabel + + + Created + + + + + + diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index a18b6231f..536ee5379 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -622,12 +622,16 @@ + + + + From 57be16395443f587f28d9e3abd27ac4be462806d Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 12 Jul 2020 08:23:52 +0200 Subject: [PATCH 124/130] Updating to MSAL 4.16.1 --- Commands/SharePointPnP.PowerShell.Commands.csproj | 4 ++-- Commands/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index 65770145c..de125fc16 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -453,8 +453,8 @@ ..\packages\Microsoft.Graph.Core.1.9.0\lib\net45\Microsoft.Graph.Core.dll - - ..\packages\Microsoft.Identity.Client.4.15.0\lib\net45\Microsoft.Identity.Client.dll + + ..\packages\Microsoft.Identity.Client.4.16.1\lib\net45\Microsoft.Identity.Client.dll ..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll diff --git a/Commands/packages.config b/Commands/packages.config index 43bf97d16..45cceac5b 100644 --- a/Commands/packages.config +++ b/Commands/packages.config @@ -17,7 +17,7 @@ - + From b591e84b7adfcd379d6d7e4773573d39f9441eac Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 12 Jul 2020 08:25:28 +0200 Subject: [PATCH 125/130] Changelog update --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee17b9e73..bbb92b437 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) - Fixed timeouts on `Get-PnPSiteCollectionAdmin` when the site has a lot of users [PR #2769](https://github.com/pnp/PnP-PowerShell/pull/2769) - Updated test project structure [PR #2767](https://github.com/pnp/PnP-PowerShell/pull/2767) -- Updated the Microsoft Authentication Library (MSAL) to 4.16 which resolves an [issue in the MSAL library](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/pull/1891) which caused many of the `Connect-PnPOnline` options not to work in Azure Runbooks anymore [PR #2735](https://github.com/pnp/PnP-PowerShell/pull/2735) +- Updated the Microsoft Authentication Library (MSAL) to 4.16.1 which resolves an [issue in the MSAL library](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/pull/1891) which caused many of the `Connect-PnPOnline` options not to work in Azure Runbooks anymore [PR #2735](https://github.com/pnp/PnP-PowerShell/pull/2735) ### Contributors - Erwin van Hunen [erwinvanhunen] From 94bddb25b8d5aa92e5ca0088df400b56b190a233 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 12 Jul 2020 08:42:28 +0200 Subject: [PATCH 126/130] Excluded cross site collection copy for on-premises as on-premises doesn't have the required APIs for it --- Commands/Files/CopyFile.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Commands/Files/CopyFile.cs b/Commands/Files/CopyFile.cs index 415dbf024..af11c8e9a 100644 --- a/Commands/Files/CopyFile.cs +++ b/Commands/Files/CopyFile.cs @@ -14,6 +14,7 @@ namespace SharePointPnP.PowerShell.Commands.Files [Cmdlet(VerbsCommon.Copy, "PnPFile", SupportsShouldProcess = true)] [CmdletHelp("Copies a file or folder to a different location. This location can be within the same document library, same site, same site collection or even to another site collection on the same tenant. Currently there is a 200MB file size limit for the file or folder to be copied.", Category = CmdletHelpCategory.Files)] +#if !ONPREMISES [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Shared Documents in the site collection project to the Shared Documents library in the site collection otherproject. If a file named company.docx already exists, it won't perform the copy.", Code = @"PS:>Copy-PnPFile -ServerRelativeUrl ""/sites/project/Shared Documents/company.docx"" -TargetServerRelativeLibrary ""/sites/otherproject/Shared Documents""", @@ -22,6 +23,7 @@ namespace SharePointPnP.PowerShell.Commands.Files Remarks = "Copies a folder named Archive located in a document library called Shared Documents in the site collection project to the Shared Documents library in the site collection otherproject. If a folder named Archive already exists, it will overwrite it.", Code = @"PS:>Copy-PnPFile -ServerRelativeUrl ""/sites/project/Shared Documents/Archive"" -TargetServerRelativeLibrary ""/sites/otherproject/Shared Documents"" -OverwriteIfAlreadyExists", SortOrder = 2)] +#endif [CmdletExample( Remarks = "Copies a file named company.docx located in a document library called Documents to a new document named company2.docx in the same library.", Code = @"PS:>Copy-PnPFile -SourceUrl Documents/company.docx -TargetUrl Documents/company2.docx", @@ -75,7 +77,9 @@ public class CopyFile : PnPWebCmdlet public string SourceUrl = string.Empty; [Parameter(Mandatory = true, Position = 1, HelpMessage = "Server relative Url where to copy the file or folder to. Must not include the file name.")] +#if !ONPREMISES [Alias(nameof(MoveFile.TargetServerRelativeLibrary))] // Aliases is present to allow for switching between Move-PnPFile and Copy-PnPFile keeping the same parameters. +#endif public string TargetUrl = string.Empty; [Parameter(Mandatory = false, HelpMessage = "If provided, if a file already exists at the TargetUrl, it will be overwritten. If omitted, the copy operation will be canceled if the file already exists at the TargetUrl location.")] @@ -113,14 +117,18 @@ protected override void ExecuteCmdlet() if (Force || ShouldContinue(string.Format(Resources.CopyFile0To1, SourceUrl, TargetUrl), Resources.Confirm)) { +#if !ONPREMISES if (sourceWebUri != targetWebUri) { CopyToOtherSiteCollection(sourceUri, targetUri); } else { +#endif CopyWithinSameSiteCollection(currentContextUri, sourceWebUri, targetWebUri); +#if !ONPREMISES } +#endif } } @@ -271,6 +279,7 @@ private void CopyWithinSameSiteCollection(Uri currentContextUri, Uri sourceWebUr } } +#if !ONPREMISES /// /// Allows copying to another site collection /// @@ -284,6 +293,7 @@ private void CopyToOtherSiteCollection(Uri source, Uri destination) }); ClientContext.ExecuteQueryRetry(); } +#endif private void CopyFolder(Folder sourceFolder, Folder targetFolder) { From 834c452304d7ec1da2c994e9484aa55a32a9e712 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Sun, 12 Jul 2020 09:07:11 +0200 Subject: [PATCH 127/130] Removed functionality for on-premises --- CHANGELOG.md | 2 +- Commands/Principals/GetUser.cs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7106836a4..135b548b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added -- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown [PR #2754](https://github.com/pnp/PnP-PowerShell/pull/2754) +- Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` when used against SharePoint Online allowing for fine grained (broken) permissions on item, list and site level to be shown [PR #2754](https://github.com/pnp/PnP-PowerShell/pull/2754) - Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) - Added connection option to `Connect-PnPOnline` taking `-Scopes` and `-Credentials` to allow setting up a delegated permission token for use with Microsoft Graph and the Office 365 Management API. See [this wiki page](https://github.com/pnp/PnP-PowerShell/wiki/Connect-options#connect-using-scopes-and-credentials) for more details. [PR #2746](https://github.com/pnp/PnP-PowerShell/pull/2746) - Added support for enabling and disabling fields using `Set-PnPField -Identity FieldName -Values @{AllowDeletion=$false}` [PR #2766](https://github.com/pnp/PnP-PowerShell/pull/2766) diff --git a/Commands/Principals/GetUser.cs b/Commands/Principals/GetUser.cs index bd9e87fde..a6f8770db 100644 --- a/Commands/Principals/GetUser.cs +++ b/Commands/Principals/GetUser.cs @@ -41,15 +41,19 @@ namespace SharePointPnP.PowerShell.Commands.Principals Code = @"PS:> Get-PnPUser -WithRightsAssigned -Web subsite1", Remarks = "Returns only those users from the User Information List of the current site collection who currently have any kind of access rights given either directly to the user or Active Directory Group or given to the user or Active Directory Group via membership of a SharePoint Group to subsite 'subsite1'", SortOrder = 6)] +#if !ONPREMISES [CmdletExample( Code = @"PS:> Get-PnPUser -WithRightsAssignedDetailed", Remarks = "Returns all users who have been granted explicit access to the current site, lists and listitems", SortOrder = 7)] +#endif public class GetUser : PnPWebCmdlet { private const string PARAMETERSET_IDENTITY = "Identity based request"; private const string PARAMETERSET_WITHRIGHTSASSIGNED = "With rights assigned"; +#if !ONPREMISES private const string PARAMETERSET_WITHRIGHTSASSIGNEDDETAILED = "With rights assigned detailed"; +#endif [Parameter(Mandatory = false, ValueFromPipeline = true, ParameterSetName = PARAMETERSET_IDENTITY, HelpMessage = "User ID or login name")] public UserPipeBind Identity; @@ -57,8 +61,10 @@ public class GetUser : PnPWebCmdlet [Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_WITHRIGHTSASSIGNED, HelpMessage = "If provided, only users that currently have any kinds of access rights assigned to the current site collection will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] public SwitchParameter WithRightsAssigned; +#if !ONPREMISES [Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_WITHRIGHTSASSIGNEDDETAILED, HelpMessage = "If provided, only users that currently have any specific kind of access rights assigned to the current site, lists or listitems/documents will be returned. Otherwise all users, even those who previously had rights assigned, but not anymore at the moment, will be returned as the information is pulled from the User Information List. Only works if you don't provide an -Identity.")] public SwitchParameter WithRightsAssignedDetailed; +#endif /// /// Output type used with parameter WithRightsAssignedDetailed @@ -103,7 +109,11 @@ protected override void ExecuteCmdlet() List users = new List(); - if (WithRightsAssigned || WithRightsAssignedDetailed) + if (WithRightsAssigned +#if !ONPREMISES + || WithRightsAssignedDetailed +#endif + ) { // Get all the role assignments and role definition bindings to be able to see which users have been given rights directly on the site level SelectedWeb.Context.Load(SelectedWeb.RoleAssignments, ac => ac.Include(a => a.RoleDefinitionBindings, a => a.Member)); @@ -125,6 +135,7 @@ protected override void ExecuteCmdlet() allUsersWithPermissions.AddRange(usersWithDirectPermissions); allUsersWithPermissions.AddRange(usersWithGroupPermissions); +#if !ONPREMISES // Add the found users and add them to the custom object if (WithRightsAssignedDetailed) { @@ -144,6 +155,7 @@ protected override void ExecuteCmdlet() } } else +#endif { // Filter out the users that have been given rights at both places so they will only be returned once WriteObject(allUsersWithPermissions.GroupBy(u => u.Id).Select(u => u.First()), true); @@ -155,6 +167,7 @@ protected override void ExecuteCmdlet() WriteObject(SelectedWeb.SiteUsers, true); } +#if !ONPREMISES if (WithRightsAssignedDetailed) { SelectedWeb.Context.Load(SelectedWeb.Lists, l => l.Include(li => li.ItemCount, li => li.IsSystemList, li=>li.IsCatalog, li => li.RootFolder.ServerRelativeUrl, li => li.RoleAssignments, li => li.Title, li => li.HasUniqueRoleAssignments)); @@ -310,6 +323,7 @@ protected override void ExecuteCmdlet() WriteObject(new { userInformation.Title, userInformation.LoginName, userInformation.Email, Groups, Permissions }, true); } } +#endif } else { @@ -335,6 +349,7 @@ protected override void ExecuteCmdlet() } } +#if !ONPREMISES private void WriteProgress(ProgressRecord record, string message, int step, int count) { var percentage = Convert.ToInt32((100 / Convert.ToDouble(count)) * Convert.ToDouble(step)); @@ -373,5 +388,6 @@ private static List GetPermissions(RoleAssignmentCollection roleAs } return users; } +#endif } } From 683c930a320a8cbd87a18b370b74ce7cd3d6c2bd Mon Sep 17 00:00:00 2001 From: Bert Jansen Date: Mon, 13 Jul 2020 11:39:54 +0200 Subject: [PATCH 128/130] Updated modernization binaries for the July 2020 release --- .../SharePointPnP.Modernization.Framework.dll | Bin 850944 -> 850944 bytes .../SharePointPnP.Modernization.Framework.dll | Bin 830848 -> 830856 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Binaries/SharePointPnP.Modernization.Framework.dll b/Binaries/SharePointPnP.Modernization.Framework.dll index 071348c1ba9597ca050f42320ef3f15aa3d5dee9..fc5f60f04b3fd74a80108ca8dcb1114ee0eefafe 100644 GIT binary patch delta 185 zcmZqpVchV;ctQt@gf>rnV^3=jV`~pnYY%g44@+wg>((AN76HcV(eZof`34xTecQ|%Ai~F=Dy?frGrhH=ij*mRom^iPqGcYhRFfd%-KK%>Ndqzg{ k?d{)qgqax4r_cVuW6x^NpvPdaUGNu=661EpUp)UA0jljo6#xJL delta 185 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 Date: Mon, 13 Jul 2020 11:51:22 +0200 Subject: [PATCH 129/130] updated connection methods --- Commands/Base/ConnectOnline.cs | 16 +-- Commands/Base/DisconnectOnline.cs | 5 +- Commands/Base/PnPConnection.cs | 74 +++++++++--- Commands/Base/PnPConnectionHelper.cs | 131 ++-------------------- Commands/Base/PnPGraphCmdlet.cs | 2 +- Commands/Base/RequestAccessToken.cs | 2 +- Commands/Model/GraphToken.cs | 59 +++++++++- Commands/Properties/Resources.Designer.cs | 20 ++-- Commands/Properties/Resources.resx | 2 +- Commands/Utilities/BrowserHelper.cs | 45 ++++++++ Commands/Utilities/Clipboard.cs | 23 ++++ 11 files changed, 214 insertions(+), 165 deletions(-) diff --git a/Commands/Base/ConnectOnline.cs b/Commands/Base/ConnectOnline.cs index ae5cb8d0d..aba9193e2 100644 --- a/Commands/Base/ConnectOnline.cs +++ b/Commands/Base/ConnectOnline.cs @@ -86,11 +86,11 @@ namespace SharePointPnP.PowerShell.Commands.Base #endif #if !ONPREMISES [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -PnPO365ManagementShell", + Code = @"PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -PnPManagementShell", Remarks = @"This will authenticate you using the PnP O365 Management Shell Multi-Tenant application. A browser window will have to be opened where you have to enter a code that is shown in your PowerShell window.", SortOrder = 12)] [CmdletExample( - Code = @"PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -PnPO365ManagementShell -LaunchBrowser", + Code = @"PS:> Connect-PnPOnline -Url https://contoso.sharepoint.com -PnPManagementShell -LaunchBrowser", Remarks = @"This will authenticate you using the PnP O365 Management Shell Multi-Tenant application. A browser window will automatically open and the code you need to enter will be automatically copied to your clipboard.", SortOrder = 13)] #endif @@ -103,11 +103,11 @@ namespace SharePointPnP.PowerShell.Commands.Base #if !ONPREMISES [CmdletExample( Code = "PS:> Connect-PnPOnline -Scopes \"Mail.Read\",\"Files.Read\",\"ActivityFeed.Read\"", - Remarks = "Connects to Azure Active Directory interactively and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP.PowerShell with application id bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71 registered by the PnP PowerShell team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. It will ask you to authenticate for each of the APIs you have listed scopes for.", + Remarks = "Connects to Azure Active Directory interactively and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP Management Shell with application id 31359c7f-bd7e-475c-86db-fdb8c937548e registered by the PnP team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. It will ask you to authenticate for each of the APIs you have listed scopes for.", SortOrder = 15)] [CmdletExample( Code = "PS:> Connect-PnPOnline -Scopes \"Mail.Read\",\"Files.Read\",\"ActivityFeed.Read\" -Credentials (New-Object System.Management.Automation.PSCredential (\"johndoe@contoso.onmicrosoft.com\", (ConvertTo-SecureString \"password\" -AsPlainText -Force)))", - Remarks = "Connects to Azure Active Directory using delegated permissions and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP.PowerShell with application id bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71 registered by the PnP PowerShell team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. You must have logged on interactively with the same scopes at least once without using -Credentials to allow for the permission grant dialog to show and allow constent for the user account you would like to use.", + Remarks = "Connects to Azure Active Directory using delegated permissions and gets an OAuth 2.0 Access Token to consume the resources of the declared permission scopes. It will utilize the Azure Active Directory enterprise application named PnP Management Shell with application id 31359c7f-bd7e-475c-86db-fdb8c937548e registered by the PnP team. If you want to connect using your own Azure Active Directory application registration, use one of the Connect-PnPOnline cmdlets using a -ClientId attribute instead and pre-assign the required permissions/scopes/roles in your application registration in Azure Active Directory. The available permission scopes for Microsoft Graph are defined at the following URL: https://docs.microsoft.com/graph/permissions-reference . If the requested scope(s) have been used with this connect cmdlet before, they will not be asked for consent again. You can request scopes from different APIs in one Connect, i.e. from Microsoft Graph and the Microsoft Office Management API. You must have logged on interactively with the same scopes at least once without using -Credentials to allow for the permission grant dialog to show and allow constent for the user account you would like to use. You can provide this consent by logging in once with Connect-PnPOnline -Url -PnPManagementShell -LaunchBrowser, and provide consent. This is a one-time action. From that moment on you will be able to use the cmdlet as stated here.", SortOrder = 16)] #endif #if !ONPREMISES @@ -180,7 +180,6 @@ public class ConnectOnline : BasePSCmdlet private const string ParameterSet_GRAPHWITHAAD = "Microsoft Graph using Azure Active Directory"; private const string SPOManagementClientId = "9bc3ab49-b65d-410a-85ad-de819febfddc"; private const string SPOManagementRedirectUri = "https://oauth.spops.microsoft.com/"; - private const string MSALPnPPowerShellClientId = "bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71"; private const string GraphRedirectUri = "urn:ietf:wg:oauth:2.0:oob"; private const string ParameterSet_ACCESSTOKEN = "Access Token"; private static readonly Uri GraphAADLogin = new Uri("https://login.microsoftonline.com/"); @@ -445,7 +444,8 @@ public class ConnectOnline : BasePSCmdlet * Read and write directory data * Read and write identity providers * Access the directory as you")] - public SwitchParameter PnPO365ManagementShell; + [Alias("PnPO365ManagementShell")] + public SwitchParameter PnPManagementShell; [Parameter(Mandatory = false, ParameterSetName = ParameterSet_DEVICELOGIN, HelpMessage = "Launch a browser automatically and copy the code to enter to the clipboard")] [Parameter(Mandatory = false, ParameterSetName = ParameterSet_GRAPHDEVICELOGIN, HelpMessage = "Launch a browser automatically and copy the code to enter to the clipboard")] @@ -1103,14 +1103,14 @@ private PnPConnection ConnectAadWithScope(PSCredential credentials) // If we have Office 365 scopes, get a token for those first if (officeManagementApiScopes.Length > 0) { - var officeManagementApiToken = credentials == null ? OfficeManagementApiToken.AcquireApplicationTokenInteractive(MSALPnPPowerShellClientId, officeManagementApiScopes) : OfficeManagementApiToken.AcquireDelegatedTokenWithCredentials(MSALPnPPowerShellClientId, graphScopes, credentials.UserName, credentials.Password); + var officeManagementApiToken = credentials == null ? OfficeManagementApiToken.AcquireApplicationTokenInteractive(PnPConnection.DeviceLoginClientId, officeManagementApiScopes) : OfficeManagementApiToken.AcquireDelegatedTokenWithCredentials(PnPConnection.DeviceLoginClientId, graphScopes, credentials.UserName, credentials.Password); connection = PnPConnection.GetConnectionWithToken(officeManagementApiToken, TokenAudience.OfficeManagementApi, Host, InitializationType.InteractiveLogin, credentials, disableTelemetry: NoTelemetry.ToBool()); } // If we have Graph scopes, get a token for it if (graphScopes.Length > 0) { - var graphToken = credentials == null ? GraphToken.AcquireApplicationTokenInteractive(MSALPnPPowerShellClientId, graphScopes) : GraphToken.AcquireDelegatedTokenWithCredentials(MSALPnPPowerShellClientId, graphScopes, credentials.UserName, credentials.Password); + var graphToken = credentials == null ? GraphToken.AcquireApplicationTokenInteractive(PnPConnection.DeviceLoginClientId, graphScopes) : GraphToken.AcquireDelegatedTokenWithCredentials(PnPConnection.DeviceLoginClientId, graphScopes, credentials.UserName, credentials.Password); // If there's a connection already, add the AAD token to it, otherwise set up a new connection with it if (connection != null) diff --git a/Commands/Base/DisconnectOnline.cs b/Commands/Base/DisconnectOnline.cs index 3e740d6d1..c48e41837 100644 --- a/Commands/Base/DisconnectOnline.cs +++ b/Commands/Base/DisconnectOnline.cs @@ -4,6 +4,7 @@ using System.Management.Automation; using System.Reflection; using SharePointPnP.PowerShell.Commands.Provider; +using SharePointPnP.PowerShell.Commands.Model; namespace SharePointPnP.PowerShell.Commands.Base { @@ -79,7 +80,7 @@ internal static bool DisconnectProvidedService(PnPConnection connection) { return false; } - + GraphToken.ClearCaches(); connection.Context = null; connection = null; return true; @@ -99,6 +100,8 @@ internal static bool DisconnectCurrentService() PnPConnection.CurrentConnection.ClearTokens(); PnPConnection.CurrentConnection.Context = null; PnPConnection.CurrentConnection = null; + + return true; } } diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index bca78d9f0..650f2fc79 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -4,6 +4,7 @@ using OfficeDevPnP.Core.Extensions; using SharePointPnP.PowerShell.Commands.Enums; using SharePointPnP.PowerShell.Commands.Model; +using SharePointPnP.PowerShell.Commands.Utilities; using SharePointPnP.PowerShell.Core.Attributes; using System; using System.Collections.Generic; @@ -26,8 +27,8 @@ public class PnPConnection /// ClientId of the application registered in Azure Active Directory which should be used for the device oAuth flow /// internal const string DeviceLoginClientId = "31359c7f-bd7e-475c-86db-fdb8c937548e"; - private const string MSALPnPPowerShellClientId = "bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71"; - + //private const string MSALPnPPowerShellClientId = "bb0c5778-9d5c-41ea-a4a8-8cd417b3ab71"; + //private const string MSALPnPPowerShellClientId = DeviceLoginClientId; #endregion #region Properties @@ -63,9 +64,6 @@ public HttpClient HttpClient public static PnPConnection CurrentConnection { get; internal set; } public ConnectionType ConnectionType { get; protected set; } - public IPublicClientApplication PublicClientApp { get; internal set; } - public IConfidentialClientApplication ConfidentialClientApp { get; internal set; } - /// /// Indication for telemetry through which method a connection has been established /// @@ -142,6 +140,41 @@ internal string TryGetAccessToken(TokenAudience tokenAudience, string[] roles = return TryGetToken(tokenAudience, roles)?.AccessToken; } + internal static Action DeviceLoginCallback(PSHost host, bool launchBrowser) + { + return deviceCodeResult => + { + if (launchBrowser) + { + Utilities.Clipboard.CopyNew(deviceCodeResult.UserCode); + host?.UI.WriteLine($"Code {deviceCodeResult.UserCode} has been copied to clipboard"); +#if !NETSTANDARD2_1 + BrowserHelper.LaunchBrowser(deviceCodeResult.VerificationUrl, (success) => + { + }); +#else + OpenBrowser(returnData["verification_url"]); + messageCallback(returnData["message"]); + + var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); + + if (tokenResult != null) + { + progressCallback("Token received"); + spoConnection = new PnPConnection(tokenResult, ConnectionMethod.GraphDeviceLogin, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, PnPPSVersionTag, host, disableTelemetry, InitializationType.GraphDeviceLogin); + } + else + { + progressCallback("No token received."); + } +#endif + } + else + { + host?.UI.WriteLine(deviceCodeResult.Message); + } + }; + } /// /// Tries to get a token for the provided audience /// @@ -175,19 +208,26 @@ internal GenericToken TryGetToken(TokenAudience tokenAudience, string[] orRoles switch (tokenAudience) { case TokenAudience.MicrosoftGraph: - if (!string.IsNullOrEmpty(Tenant)) + if (ConnectionMethod == ConnectionMethod.DeviceLogin || ConnectionMethod == ConnectionMethod.GraphDeviceLogin) { - if (Certificate != null) - { - token = GraphToken.AcquireApplicationToken(Tenant, ClientId, Certificate); - } - else if (ClientSecret != null) - { - token = GraphToken.AcquireApplicationToken(Tenant, ClientId, ClientSecret); - } - else if (Scopes != null) + token = GraphToken.AcquireApplicationTokenDeviceLogin(PnPConnection.DeviceLoginClientId, Scopes, DeviceLoginCallback(null, false)); + } + else + { + if (!string.IsNullOrEmpty(Tenant)) { - token = PSCredential == null ? GraphToken.AcquireApplicationTokenInteractive(MSALPnPPowerShellClientId, Scopes) : GraphToken.AcquireDelegatedTokenWithCredentials(MSALPnPPowerShellClientId, Scopes, PSCredential.UserName, PSCredential.Password); + if (Certificate != null) + { + token = GraphToken.AcquireApplicationToken(Tenant, ClientId, Certificate); + } + else if (ClientSecret != null) + { + token = GraphToken.AcquireApplicationToken(Tenant, ClientId, ClientSecret); + } + else if (Scopes != null) + { + token = PSCredential == null ? GraphToken.AcquireApplicationTokenInteractive(DeviceLoginClientId, Scopes) : GraphToken.AcquireDelegatedTokenWithCredentials(DeviceLoginClientId, Scopes, PSCredential.UserName, PSCredential.Password); + } } } break; @@ -651,7 +691,7 @@ internal ClientContext CloneContext(string url) else { #endif - throw; + throw; #if !ONPREMISES && !NETSTANDARD2_1 } #endif diff --git a/Commands/Base/PnPConnectionHelper.cs b/Commands/Base/PnPConnectionHelper.cs index 6128ae2e4..cedd0f225 100644 --- a/Commands/Base/PnPConnectionHelper.cs +++ b/Commands/Base/PnPConnectionHelper.cs @@ -155,65 +155,13 @@ private static PnPConnection InstantiateHighTrustConnection(ClientContext contex internal static PnPConnection InstantiateDeviceLoginConnection(string url, bool launchBrowser, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, Action messageCallback, Action progressCallback, Func cancelRequest, PSHost host, bool disableTelemetry) { - PnPConnection spoConnection = null; var connectionUri = new Uri(url); - HttpClient client = new HttpClient(); - var result = client.GetStringAsync($"https://login.microsoftonline.com/common/oauth2/devicecode?resource={connectionUri.Scheme}://{connectionUri.Host}&client_id={PnPConnection.DeviceLoginClientId}").GetAwaiter().GetResult(); - var returnData = JsonConvert.DeserializeObject>(result); + var scopes = new[] { $"{connectionUri.Scheme}://{connectionUri.Host}//.default" }; // the second double slash is not a typo. var context = new ClientContext(url); - messageCallback(returnData["message"]); - - if (launchBrowser) - { - Utilities.Clipboard.Copy(returnData["user_code"]); - messageCallback("Code has been copied to clipboard"); -#if !NETSTANDARD2_1 - BrowserHelper.OpenBrowser(returnData["verification_url"], (success) => - { - if (success) - { - var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); - if (tokenResult != null) - { - progressCallback("Token received"); - spoConnection = new PnPConnection(context, tokenResult, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, null, url.ToString(), tenantAdminUrl, PnPPSVersionTag, host, disableTelemetry, InitializationType.DeviceLogin); - } - else - { - progressCallback("No token received."); - } - } - }); -#else - OpenBrowser(returnData["verification_url"]); - messageCallback(returnData["message"]); - var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); - - if (tokenResult != null) - { - progressCallback("Token received"); - spoConnection = new PnPConnection(context, tokenResult, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, null, url.ToString(), tenantAdminUrl, PnPPSVersionTag, host, disableTelemetry, InitializationType.DeviceLogin); - } - else - { - progressCallback("No token received."); - } -#endif - } - else - { - var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); - if (tokenResult != null) - { - progressCallback("Token received"); - spoConnection = PnPConnection.GetConnectionWithToken(tokenResult, TokenAudience.SharePointOnline, host, InitializationType.DeviceLogin, null, url, context, minimalHealthScore, PnPPSVersionTag, disableTelemetry); - } - else - { - progressCallback("No token received."); - } - } + var tokenResult = GraphToken.AcquireApplicationTokenDeviceLogin(PnPConnection.DeviceLoginClientId, scopes, PnPConnection.DeviceLoginCallback(host, launchBrowser)); + var spoConnection = new PnPConnection(context, tokenResult, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, null, url.ToString(), tenantAdminUrl, PnPPSVersionTag, host, disableTelemetry, InitializationType.DeviceLogin); + spoConnection.Scopes = scopes; if (spoConnection != null) { @@ -232,73 +180,12 @@ internal static PnPConnection InstantiateGraphAccessTokenConnection(string acces internal static PnPConnection InstantiateGraphDeviceLoginConnection(bool launchBrowser, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, Action messageCallback, Action progressCallback, Func cancelRequest, PSHost host, bool disableTelemetry) { - var connectionUri = new Uri("https://graph.microsoft.com"); - HttpClient client = new HttpClient(); - var result = client.GetStringAsync($"https://login.microsoftonline.com/common/oauth2/devicecode?resource={connectionUri.Scheme}://{connectionUri.Host}&client_id={PnPConnection.DeviceLoginClientId}").GetAwaiter().GetResult(); - var returnData = JsonConvert.DeserializeObject>(result); - - PnPConnection spoConnection = null; - - if (launchBrowser) - { - Utilities.Clipboard.Copy(returnData["user_code"]); - messageCallback("Code has been copied to clipboard"); -#if !NETSTANDARD2_1 - BrowserHelper.OpenBrowser(returnData["verification_url"], (success) => - { - if (success) - { - var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); - if (tokenResult != null) - { - progressCallback("Token received"); - spoConnection = new PnPConnection(tokenResult, ConnectionMethod.GraphDeviceLogin, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, PnPPSVersionTag, host, disableTelemetry, InitializationType.GraphDeviceLogin); - } - else - { - progressCallback("No token received."); - } - } - }); -#else - OpenBrowser(returnData["verification_url"]); - messageCallback(returnData["message"]); - - var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); - - if (tokenResult != null) - { - progressCallback("Token received"); - spoConnection = new PnPConnection(tokenResult, ConnectionMethod.GraphDeviceLogin, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, PnPPSVersionTag, host, disableTelemetry, InitializationType.GraphDeviceLogin); - } - else - { - progressCallback("No token received."); - } -#endif - } - else - { - messageCallback(returnData["message"]); - - var tokenResult = GetTokenResult(connectionUri, returnData, messageCallback, progressCallback, cancelRequest); - - if (tokenResult != null) - { - progressCallback("Token received"); - spoConnection = new PnPConnection(tokenResult, ConnectionMethod.GraphDeviceLogin, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, PnPPSVersionTag, host, disableTelemetry, InitializationType.GraphDeviceLogin); - spoConnection.ConnectionMethod = ConnectionMethod.GraphDeviceLogin; - } - else - { - progressCallback("No token received."); - } - } + var tokenResult = GraphToken.AcquireApplicationTokenDeviceLogin(PnPConnection.DeviceLoginClientId, new[] { "Group.Read.All", "openid", "email", "profile", "Group.ReadWrite.All", "User.Read.All", "Directory.ReadWrite.All" }, PnPConnection.DeviceLoginCallback(host, launchBrowser)); + var spoConnection = new PnPConnection(tokenResult, ConnectionMethod.GraphDeviceLogin, ConnectionType.O365, minimalHealthScore, retryCount, retryWait, PnPPSVersionTag, host, disableTelemetry, InitializationType.GraphDeviceLogin); + spoConnection.Scopes = new[] { "Group.Read.All", "openid", "email", "profile", "Group.ReadWrite.All", "User.Read.All", "Directory.ReadWrite.All" }; return spoConnection; } - - private static GenericToken GetTokenResult(Uri connectionUri, Dictionary returnData, Action messageCallback, Action progressCallback, Func cancelRequest) { HttpClient client = new HttpClient(); @@ -575,7 +462,7 @@ internal static PnPConnection InitiateAzureAdAppOnlyConnectionWithClientIdClient /// Certificate to try to clean up the local cached copy of the private key of internal static void CleanupCryptoMachineKey(X509Certificate2 certificate) { - if(!certificate.HasPrivateKey) + if (!certificate.HasPrivateKey) { // If somehow a public key certificate was passed in, we can't clean it up, thus we have nothing to do here return; @@ -584,7 +471,7 @@ internal static void CleanupCryptoMachineKey(X509Certificate2 certificate) var privateKey = (RSACryptoServiceProvider)certificate.PrivateKey; string uniqueKeyContainerName = privateKey.CspKeyContainerInfo.UniqueKeyContainerName; certificate.Reset(); - + var programDataPath = Environment.GetEnvironmentVariable("ProgramData"); if (string.IsNullOrEmpty(programDataPath)) { diff --git a/Commands/Base/PnPGraphCmdlet.cs b/Commands/Base/PnPGraphCmdlet.cs index 605a60305..f02b000d7 100644 --- a/Commands/Base/PnPGraphCmdlet.cs +++ b/Commands/Base/PnPGraphCmdlet.cs @@ -63,7 +63,7 @@ public GraphToken Token if (PnPConnection.CurrentConnection.TryGetToken(Enums.TokenAudience.MicrosoftGraph, ByPassPermissionCheck.ToBool() ? null : orRequiredRoles.ToArray(), ByPassPermissionCheck.ToBool() ? null : andRequiredRoles.ToArray(), tokenType) is GraphToken token) { // Microsoft Graph Access Token available, return it - return token; + return (GraphToken)token; } } diff --git a/Commands/Base/RequestAccessToken.cs b/Commands/Base/RequestAccessToken.cs index 1b47f1d03..fd0064220 100644 --- a/Commands/Base/RequestAccessToken.cs +++ b/Commands/Base/RequestAccessToken.cs @@ -39,7 +39,7 @@ public class RequestAccessToken : BasePSCmdlet { [Parameter(Mandatory = false, HelpMessage = "The Azure Application Client Id to use to retrieve the token. Defaults to the PnP Office 365 Management Shell")] - public string ClientId = PnPConnection.DeviceLoginClientId; // defaults to PnPO365ManagementShell + public string ClientId = PnPConnection.DeviceLoginClientId; // defaults to PnPManagementShell [Parameter(Mandatory = false, HelpMessage = "The scopes to retrieve the token for. Defaults to AllSites.FullControl")] public string Resource; diff --git a/Commands/Model/GraphToken.cs b/Commands/Model/GraphToken.cs index 6171526a7..d3084d3a0 100644 --- a/Commands/Model/GraphToken.cs +++ b/Commands/Model/GraphToken.cs @@ -5,8 +5,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Management.Automation; +using System.Runtime.CompilerServices; using System.Security; using System.Security.Cryptography.X509Certificates; +using System.Threading.Tasks; namespace SharePointPnP.PowerShell.Commands.Model { @@ -122,7 +125,6 @@ public static GenericToken AcquireApplicationToken(string tenant, string clientI { tokenResult = confidentialClientApplication.AcquireTokenForClient(new[] { $"{ResourceIdentifier}/{DefaultScope}" }).ExecuteAsync().GetAwaiter().GetResult(); } - return new GraphToken(tokenResult.AccessToken); } @@ -144,6 +146,43 @@ public static GenericToken AcquireApplicationTokenInteractive(string clientId, s } + if (publicClientApplication == null) + { + publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithDefaultRedirectUri().Build(); + } + + AuthenticationResult tokenResult = null; + + //if (publicClientApplication == null) + //{ + // publicClientApplication = PublicClientApplicationBuilder.Create(clientId).WithAuthority($"{OAuthBaseUrl}organizations/").WithDefaultRedirectUri().Build(); + + //} + var account = publicClientApplication.GetAccountsAsync().GetAwaiter().GetResult(); + + try + { + tokenResult = publicClientApplication.AcquireTokenSilent(scopes, account.First()).ExecuteAsync().GetAwaiter().GetResult(); + } + catch + { + tokenResult = publicClientApplication.AcquireTokenInteractive(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray()).ExecuteAsync().GetAwaiter().GetResult(); + } + return new GraphToken(tokenResult.AccessToken); + } + + public static GraphToken AcquireApplicationTokenDeviceLogin(string clientId, string[] scopes, Action callBackAction) + { + if (string.IsNullOrEmpty(clientId)) + { + throw new ArgumentNullException(nameof(clientId)); + } + if (scopes == null || scopes.Length == 0) + { + throw new ArgumentNullException(nameof(scopes)); + } + + if (publicClientApplication == null) { publicClientApplication = PublicClientApplicationBuilder.Create(clientId).Build(); @@ -164,12 +203,18 @@ public static GenericToken AcquireApplicationTokenInteractive(string clientId, s } catch { - tokenResult = publicClientApplication.AcquireTokenInteractive(scopes.Select(s => $"{ResourceIdentifier}/{s}").ToArray()).ExecuteAsync().GetAwaiter().GetResult(); + var builder = publicClientApplication.AcquireTokenWithDeviceCode(scopes, result => + { + if (callBackAction != null) + { + callBackAction(result); + } + return Task.FromResult(0); + }); + tokenResult = builder.ExecuteAsync().GetAwaiter().GetResult(); } - return new GraphToken(tokenResult.AccessToken); } - /// /// Tries to acquire a delegated Microsoft Graph Access Token for the provided scopes using the provided credentials /// @@ -216,5 +261,11 @@ public static GenericToken AcquireDelegatedTokenWithCredentials(string clientId, return new GraphToken(tokenResult.AccessToken); } + + public static void ClearCaches() + { + GraphToken.publicClientApplication = null; + GraphToken.confidentialClientApplication = null; + } } } diff --git a/Commands/Properties/Resources.Designer.cs b/Commands/Properties/Resources.Designer.cs index 288e7a0b5..fa8f08820 100644 --- a/Commands/Properties/Resources.Designer.cs +++ b/Commands/Properties/Resources.Designer.cs @@ -79,7 +79,6 @@ internal static string ApplicationName { } /// - /// Looks up a localized string similar to The certificate located at '{0}' holds no private key. Ensure you provide the private key certificate, typically the .pfx file.. /// internal static string CertificateAtPathHasNoPrivateKey { @@ -87,26 +86,27 @@ internal static string CertificateAtPathHasNoPrivateKey { return ResourceManager.GetString("CertificateAtPathHasNoPrivateKey", resourceCulture); } } - /// Looks up a localized string similar to The provided certificate with the thumbprint '{0}' does not have a private key which is required for a connection to be established. Ensure you have imported the certificate containing the private key, typically the .pfx file, into the Windows Certificate Store.. + + /// + /// Looks up a localized string similar to No private key certificate has been found at '{0}'. /// - internal static string CertificateWithThumbprintDoesNotHavePrivateKey { + internal static string CertificateNotFoundAtPath { get { - return ResourceManager.GetString("CertificateWithThumbprintDoesNotHavePrivateKey", resourceCulture); + return ResourceManager.GetString("CertificateNotFoundAtPath", resourceCulture); } } /// - - /// Looks up a localized string similar to No private key certificate has been found at '{0}'. + /// Looks up a localized string similar to The provided certificate with the thumbprint '{0}' does not have a private key which is required for a connection to be established. Ensure you have imported the certificate containing the private key, typically the .pfx file, into the Windows Certificate Store.. /// - internal static string CertificateNotFoundAtPath { + internal static string CertificateWithThumbprintDoesNotHavePrivateKey { get { - return ResourceManager.GetString("CertificateNotFoundAtPath", resourceCulture); + return ResourceManager.GetString("CertificateWithThumbprintDoesNotHavePrivateKey", resourceCulture); } } /// - /// Looks up a localized string similar to No certificate with the thumbprint '{0}' has been found in the Windows certificate store. + /// Looks up a localized string similar to No certificate with the thumbprint '{0}' has been found in the Windows Certificate Store. /// internal static string CertificateWithThumbprintNotFound { get { @@ -386,7 +386,7 @@ internal static string NoContextPresent { } /// - /// Looks up a localized string similar to The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument but not -SPOManagementShell or -PnPO365ManagementShell to connect.. + /// Looks up a localized string similar to The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument but not -SPOManagementShell or -PnPOManagementShell to connect.. /// internal static string NoSharePointConnection { get { diff --git a/Commands/Properties/Resources.resx b/Commands/Properties/Resources.resx index f1a04ad37..5b6829372 100644 --- a/Commands/Properties/Resources.resx +++ b/Commands/Properties/Resources.resx @@ -151,7 +151,7 @@ No list found with id, title or url '{0}' diff --git a/Commands/Base/PnPConnectionHelper.cs b/Commands/Base/PnPConnectionHelper.cs index 01269629a..f23e294cf 100644 --- a/Commands/Base/PnPConnectionHelper.cs +++ b/Commands/Base/PnPConnectionHelper.cs @@ -453,7 +453,7 @@ internal static PnPConnection InitiateAzureADAppOnlyConnection(Uri url, string c string password = new System.Net.NetworkCredential(string.Empty, certificatePassword).Password; X509Certificate2 certificate = CertificateHelper.GetCertificateFromPEMstring(certificatePEM, privateKeyPEM, password); - return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate, true); + return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate, false); } /// @@ -534,7 +534,8 @@ private static PnPConnection InitiateAzureAdAppOnlyConnectionWithCert(Uri url, s { ConnectionMethod = ConnectionMethod.AzureADAppOnly, Certificate = certificate, - Tenant = tenant + Tenant = tenant, + DeleteCertificateFromCacheOnDisconnect = certificateFromFile }; return spoConnection; } From fcc27377597291a8c61c2e192ac78aa4115a3b32 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Wed, 24 Jun 2020 23:41:20 +0200 Subject: [PATCH 043/130] Added changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d63056620..1e51917b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) +- Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) ### Contributors - Gautam Sheth [gautamdsheth] From c007e3a6be4c77c7232551aacaa7df1e40f4fe20 Mon Sep 17 00:00:00 2001 From: Hussey Date: Wed, 24 Jun 2020 10:11:35 -0700 Subject: [PATCH 044/130] Added RowLimit parameter to Clear-PnPRecycleBinItem (re: #2315) --- Commands/RecycleBin/ClearRecycleBinItem.cs | 55 ++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/Commands/RecycleBin/ClearRecycleBinItem.cs b/Commands/RecycleBin/ClearRecycleBinItem.cs index 610cad6d2..920881109 100644 --- a/Commands/RecycleBin/ClearRecycleBinItem.cs +++ b/Commands/RecycleBin/ClearRecycleBinItem.cs @@ -21,6 +21,13 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin Code = @"PS:> Clear-PnpRecycleBinItem -Identity $item -Force", Remarks = "Permanently deletes the recycle bin item stored under variable $item from the recycle bin without asking for confirmation from the end user first", SortOrder = 3)] +#if !SP2013 + [CmdletExample( + Code = @"PS:> Clear-PnPRecycleBinItem -All -RowLimit 10000", + Remarks = "Permanently deletes up to 10,000 items in recycle bin", + SortOrder = 4)] +#endif + public class ClearRecycleBinItem : PnPSharePointCmdlet { [Parameter(Mandatory = true, HelpMessage = "Id of the recycle bin item or the recycle bin item itself to permanently delete", ValueFromPipeline = true, ParameterSetName = "Identity")] @@ -36,6 +43,10 @@ public class ClearRecycleBinItem : PnPSharePointCmdlet [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to permanently delete the recycle bin item")] public SwitchParameter Force; +#if !SP2013 + [Parameter(Mandatory = false, HelpMessage = "Limits deletion to specified number of items", ParameterSetName = "All")] + public int RowLimit = -1; +#endif protected override void ExecuteCmdlet() { @@ -52,21 +63,40 @@ protected override void ExecuteCmdlet() } break; case "All": -#if !ONPREMISES - if (SecondStageOnly) +#if !SP2013 + if (HasRowLimit()) { - if (Force || ShouldContinue(Resources.ClearSecondStageRecycleBin, Resources.Confirm)) - { - ClientContext.Site.RecycleBin.DeleteAllSecondStageItems(); + if (Force || ShouldContinue(SecondStageOnly ? Resources.ClearSecondStageRecycleBin : Resources.ClearBothRecycleBins, Resources.Confirm)) { + RecycleBinItemState recycleBinStage = SecondStageOnly ? RecycleBinItemState.SecondStageRecycleBin : RecycleBinItemState.None; + + RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, + recycleBinStage); + ClientContext.Load(items); + ClientContext.ExecuteQueryRetry(); + + items.DeleteAll(); ClientContext.ExecuteQueryRetry(); } } else +#endif { - if (Force || ShouldContinue(Resources.ClearBothRecycleBins, Resources.Confirm)) +#if !ONPREMISES + if (SecondStageOnly) { - ClientContext.Site.RecycleBin.DeleteAll(); - ClientContext.ExecuteQueryRetry(); + if (Force || ShouldContinue(Resources.ClearSecondStageRecycleBin, Resources.Confirm)) + { + ClientContext.Site.RecycleBin.DeleteAllSecondStageItems(); + ClientContext.ExecuteQueryRetry(); + } + } + else + { + if (Force || ShouldContinue(Resources.ClearBothRecycleBins, Resources.Confirm)) + { + ClientContext.Site.RecycleBin.DeleteAll(); + ClientContext.ExecuteQueryRetry(); + } } } break; @@ -76,9 +106,18 @@ protected override void ExecuteCmdlet() ClientContext.Site.RecycleBin.DeleteAll(); ClientContext.ExecuteQueryRetry(); } + } break; #endif } } + +#if !SP2013 + private bool HasRowLimit() + { + return RowLimit > 0; + } +#endif + } } From 6e856e2bd6e5ade3d925cdb491c760d2544010d2 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 00:15:05 +0200 Subject: [PATCH 045/130] Added changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6c3f1998..f5815b3c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added +- Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) ### Changed ### Contributors +- Ellie Hussey [Professr] ## [3.22.2006.2] From 956e8f0c1d0c291a74a89c5997642953d4a9e164 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 00:15:14 +0200 Subject: [PATCH 046/130] Cleanup of code --- Commands/RecycleBin/ClearRecycleBinItem.cs | 39 ++++++++++------------ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/Commands/RecycleBin/ClearRecycleBinItem.cs b/Commands/RecycleBin/ClearRecycleBinItem.cs index 920881109..c0d583dca 100644 --- a/Commands/RecycleBin/ClearRecycleBinItem.cs +++ b/Commands/RecycleBin/ClearRecycleBinItem.cs @@ -6,8 +6,9 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin { - [Cmdlet(VerbsCommon.Clear, "PnPRecycleBinItem", DefaultParameterSetName = "All")] + [Cmdlet(VerbsCommon.Clear, "PnPRecycleBinItem", DefaultParameterSetName = PARAMETERSET_ALL)] [CmdletHelp("Permanently deletes all or a specific recycle bin item", + SupportedPlatform = CmdletSupportedPlatform.All, Category = CmdletHelpCategory.RecycleBin)] [CmdletExample( Code = @"PS:> Get-PnPRecycleBinItem | ? FileLeafName -like ""*.docx"" | Clear-PnpRecycleBinItem", @@ -30,47 +31,49 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin public class ClearRecycleBinItem : PnPSharePointCmdlet { - [Parameter(Mandatory = true, HelpMessage = "Id of the recycle bin item or the recycle bin item itself to permanently delete", ValueFromPipeline = true, ParameterSetName = "Identity")] + const string PARAMETERSET_ALL = "All"; + const string PARAMETERSET_IDENTITY = "Identity"; + + [Parameter(Mandatory = true, HelpMessage = "Id of the recycle bin item or the recycle bin item itself to permanently delete", ValueFromPipeline = true, ParameterSetName = PARAMETERSET_IDENTITY)] public RecycleBinItemPipeBind Identity; - [Parameter(Mandatory = false, ParameterSetName = "All", HelpMessage = "Clears all items")] + [Parameter(Mandatory = false, ParameterSetName = PARAMETERSET_ALL, HelpMessage = "Clears all items")] public SwitchParameter All; #if !ONPREMISES - [Parameter(Mandatory = false, HelpMessage = "If provided, only all the items in the second stage recycle bin will be cleared", ParameterSetName = "All")] + [Parameter(Mandatory = false, HelpMessage = "If provided, only all the items in the second stage recycle bin will be cleared", ParameterSetName = PARAMETERSET_ALL)] public SwitchParameter SecondStageOnly = false; #endif [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to permanently delete the recycle bin item")] public SwitchParameter Force; #if !SP2013 - [Parameter(Mandatory = false, HelpMessage = "Limits deletion to specified number of items", ParameterSetName = "All")] - public int RowLimit = -1; + [Parameter(Mandatory = false, HelpMessage = "Limits deletion to specified number of items", ParameterSetName = PARAMETERSET_ALL)] + public int RowLimit; #endif protected override void ExecuteCmdlet() { switch (ParameterSetName) { - case "Identity": + case PARAMETERSET_IDENTITY: var recycleBinItem = Identity.GetRecycleBinItem(ClientContext.Site); - if (Force || - ShouldContinue(string.Format(Resources.ClearRecycleBinItem, recycleBinItem.LeafName), Resources.Confirm)) + if (Force || ShouldContinue(string.Format(Resources.ClearRecycleBinItem, recycleBinItem.LeafName), Resources.Confirm)) { recycleBinItem.DeleteObject(); ClientContext.ExecuteQueryRetry(); } break; - case "All": + case PARAMETERSET_ALL: #if !SP2013 - if (HasRowLimit()) + if (ParameterSpecified(nameof(RowLimit))) { - if (Force || ShouldContinue(SecondStageOnly ? Resources.ClearSecondStageRecycleBin : Resources.ClearBothRecycleBins, Resources.Confirm)) { + if (Force || ShouldContinue(SecondStageOnly ? Resources.ClearSecondStageRecycleBin : Resources.ClearBothRecycleBins, Resources.Confirm)) + { RecycleBinItemState recycleBinStage = SecondStageOnly ? RecycleBinItemState.SecondStageRecycleBin : RecycleBinItemState.None; - RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, - recycleBinStage); + RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, recycleBinStage); ClientContext.Load(items); ClientContext.ExecuteQueryRetry(); @@ -111,13 +114,5 @@ protected override void ExecuteCmdlet() #endif } } - -#if !SP2013 - private bool HasRowLimit() - { - return RowLimit > 0; - } -#endif - } } From aff48aedc45a6348e3359287577be81ece1f3dc7 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 00:18:09 +0200 Subject: [PATCH 047/130] Minor changes to align it with Clear-PnPRecycleBinItem --- Commands/RecycleBin/GetRecycleBinItem.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Commands/RecycleBin/GetRecycleBinItem.cs b/Commands/RecycleBin/GetRecycleBinItem.cs index 4d3f80cad..f5c29de61 100644 --- a/Commands/RecycleBin/GetRecycleBinItem.cs +++ b/Commands/RecycleBin/GetRecycleBinItem.cs @@ -57,7 +57,7 @@ public class GetRecycleBinItems : PnPRetrievalsCmdlet [Parameter(Mandatory = false, HelpMessage = "Limits return results to specified amount", ParameterSetName = ParameterSet_FIRSTSTAGE)] [Parameter(Mandatory = false, HelpMessage = "Limits return results to specified amount", ParameterSetName = ParameterSet_SECONDSTAGE)] [Parameter(Mandatory = false, HelpMessage = "Limits return results to specified amount", ParameterSetName = ParameterSet_ALL)] - public int RowLimit = -1; + public int RowLimit; #endif protected override void ExecuteCmdlet() { @@ -73,7 +73,7 @@ protected override void ExecuteCmdlet() else { #if !SP2013 - if (HasRowLimit()) + if (ParameterSpecified(nameof(RowLimit))) { RecycleBinItemState recycleBinStage; switch (ParameterSetName) @@ -148,12 +148,5 @@ protected override void ExecuteCmdlet() #endif } } - -#if !SP2013 - private bool HasRowLimit() - { - return RowLimit > 0; - } -#endif } } From d88e8a800479fbea911229d037f42fed23be5fe9 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 00:37:23 +0200 Subject: [PATCH 048/130] Added RowLimit to Restore-PnPRecycleBinItem as well, ensured the approach is consistent accross all three *-RecycleBinItem cmdlets --- Commands/RecycleBin/ClearRecycleBinItem.cs | 5 +- Commands/RecycleBin/GetRecycleBinItem.cs | 8 +- Commands/RecycleBin/RestoreRecycleBinItem.cs | 80 ++++++++++++++------ 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/Commands/RecycleBin/ClearRecycleBinItem.cs b/Commands/RecycleBin/ClearRecycleBinItem.cs index c0d583dca..5c76c7ce0 100644 --- a/Commands/RecycleBin/ClearRecycleBinItem.cs +++ b/Commands/RecycleBin/ClearRecycleBinItem.cs @@ -25,7 +25,7 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin #if !SP2013 [CmdletExample( Code = @"PS:> Clear-PnPRecycleBinItem -All -RowLimit 10000", - Remarks = "Permanently deletes up to 10,000 items in recycle bin", + Remarks = "Permanently deletes up to 10,000 items in the recycle bin", SortOrder = 4)] #endif @@ -44,7 +44,8 @@ public class ClearRecycleBinItem : PnPSharePointCmdlet [Parameter(Mandatory = false, HelpMessage = "If provided, only all the items in the second stage recycle bin will be cleared", ParameterSetName = PARAMETERSET_ALL)] public SwitchParameter SecondStageOnly = false; #endif - [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to permanently delete the recycle bin item")] + [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to restore the recycle bin item", ParameterSetName = PARAMETERSET_IDENTITY)] + [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to restore the recycle bin item", ParameterSetName = PARAMETERSET_ALL)] public SwitchParameter Force; #if !SP2013 diff --git a/Commands/RecycleBin/GetRecycleBinItem.cs b/Commands/RecycleBin/GetRecycleBinItem.cs index f5c29de61..b02690b96 100644 --- a/Commands/RecycleBin/GetRecycleBinItem.cs +++ b/Commands/RecycleBin/GetRecycleBinItem.cs @@ -14,7 +14,7 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin Category = CmdletHelpCategory.RecycleBin, OutputType = typeof(RecycleBinItem), SupportedPlatform = CmdletSupportedPlatform.All, - OutputTypeLink = "https://docs.microsoft.com/en-us/previous-versions/office/sharepoint-server/ee541897(v=office.15)")] + OutputTypeLink = "https://docs.microsoft.com/previous-versions/office/sharepoint-server/ee541897(v=office.15)")] [CmdletExample( Code = @"PS:> Get-PnPRecycleBinItem", Remarks = "Returns all items in both the first and the second stage recycle bins in the current site collection", @@ -89,14 +89,12 @@ protected override void ExecuteCmdlet() break; } - RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, - recycleBinStage); + RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, recycleBinStage); ClientContext.Load(items); ClientContext.ExecuteQueryRetry(); List recycleBinItemList = items.ToList(); WriteObject(recycleBinItemList, true); - } else { @@ -107,7 +105,6 @@ protected override void ExecuteCmdlet() switch (ParameterSetName) { - case ParameterSet_FIRSTSTAGE: WriteObject( recycleBinItemList.Where(i => i.ItemState == RecycleBinItemState.FirstStageRecycleBin), true); @@ -121,7 +118,6 @@ protected override void ExecuteCmdlet() WriteObject(recycleBinItemList, true); break; } - } #else ClientContext.Site.Context.Load(ClientContext.Site.RecycleBin, r => r.IncludeWithDefaultProperties(RetrievalExpressions)); diff --git a/Commands/RecycleBin/RestoreRecycleBinItem.cs b/Commands/RecycleBin/RestoreRecycleBinItem.cs index 880419770..72c6e2dec 100644 --- a/Commands/RecycleBin/RestoreRecycleBinItem.cs +++ b/Commands/RecycleBin/RestoreRecycleBinItem.cs @@ -1,4 +1,5 @@ -using System.Management.Automation; +using System; +using System.Management.Automation; using Microsoft.SharePoint.Client; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; @@ -6,8 +7,9 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin { - [Cmdlet(VerbsData.Restore, "PnPRecycleBinItem")] + [Cmdlet(VerbsData.Restore, "PnPRecycleBinItem", DefaultParameterSetName = PARAMETERSET_ALL)] [CmdletHelp("Restores the provided recycle bin item to its original location", + SupportedPlatform = CmdletSupportedPlatform.All, Category = CmdletHelpCategory.RecycleBin)] [CmdletExample( Code = @"PS:> Restore-PnpRecycleBinItem -Identity 72e4d749-d750-4989-b727-523d6726e442", @@ -17,40 +19,72 @@ namespace SharePointPnP.PowerShell.Commands.RecycleBin Code = @"PS:> Get-PnPRecycleBinItem | ? -Property LeafName -like ""*.docx"" | Restore-PnpRecycleBinItem", Remarks = "Restores all the items in the first and second stage recycle bins to their original location of which the filename ends with the .docx extension", SortOrder = 2)] +#if !SP2013 + [CmdletExample( + Code = @"PS:> Restore-PnPRecycleBinItem -All -RowLimit 10000", + Remarks = "Permanently restores up to 10,000 items in the recycle bin", + SortOrder = 4)] +#endif public class RestoreRecycleBinItem : PnPSharePointCmdlet { - [Parameter(Mandatory = true, HelpMessage = "Id of the recycle bin item or the recycle bin item object itself to restore", ValueFromPipeline = true, ParameterSetName = "Identity")] + const string PARAMETERSET_ALL = "All"; + const string PARAMETERSET_IDENTITY = "Identity"; + + [Parameter(Mandatory = true, HelpMessage = "Id of the recycle bin item or the recycle bin item object itself to restore", ValueFromPipeline = true, ParameterSetName = PARAMETERSET_IDENTITY)] public RecycleBinItemPipeBind Identity; - [Parameter(Mandatory = true, HelpMessage = "If provided all items will be stored ", ValueFromPipeline = true, ParameterSetName = "All")] + [Parameter(Mandatory = false, HelpMessage = "If provided all items will be stored ", ValueFromPipeline = true, ParameterSetName = PARAMETERSET_ALL)] + [Obsolete("No need to add the -All parameter anymore")] public SwitchParameter All; - [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to restore the recycle bin item")] + [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to restore the recycle bin item", ParameterSetName = PARAMETERSET_IDENTITY)] + [Parameter(Mandatory = false, HelpMessage = "If provided, no confirmation will be asked to restore the recycle bin item", ParameterSetName = PARAMETERSET_ALL)] public SwitchParameter Force; +#if !SP2013 + [Parameter(Mandatory = false, HelpMessage = "Limits restoration to specified number of items", ParameterSetName = PARAMETERSET_ALL)] + public int RowLimit; +#endif protected override void ExecuteCmdlet() { - if (ParameterSetName == "Identity") - { - var recycleBinItem = Identity.GetRecycleBinItem(ClientContext.Site); - - if (Force || - ShouldContinue(string.Format(Resources.RestoreRecycleBinItem, recycleBinItem.LeafName), - Resources.Confirm)) - { - recycleBinItem.Restore(); - ClientContext.ExecuteQueryRetry(); - } - } - else + switch (ParameterSetName) { - if (Force || ShouldContinue(Resources.RestoreRecycleBinItems, Resources.Confirm)) - { - ClientContext.Site.RecycleBin.RestoreAll(); - ClientContext.ExecuteQueryRetry(); - } + case PARAMETERSET_IDENTITY: + var recycleBinItem = Identity.GetRecycleBinItem(ClientContext.Site); + + if (Force || ShouldContinue(string.Format(Resources.RestoreRecycleBinItem, recycleBinItem.LeafName), Resources.Confirm)) + { + recycleBinItem.Restore(); + ClientContext.ExecuteQueryRetry(); + } + break; + + case PARAMETERSET_ALL: +#if !SP2013 + if (ParameterSpecified(nameof(RowLimit))) + { + if (Force || ShouldContinue(Resources.RestoreRecycleBinItems, Resources.Confirm)) + { + RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, RecycleBinItemState.None); + ClientContext.Load(items); + ClientContext.ExecuteQueryRetry(); + + items.RestoreAll(); + ClientContext.ExecuteQueryRetry(); + } + } + else +#endif + { + if (Force || ShouldContinue(Resources.RestoreRecycleBinItems, Resources.Confirm)) + { + ClientContext.Site.RecycleBin.RestoreAll(); + ClientContext.ExecuteQueryRetry(); + } + } + break; } } } From 371521e0404b683171d79a60f76f689cad8f5b56 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 00:52:27 +0200 Subject: [PATCH 049/130] Updated changelog to include Restore-PnPRecycleBinItem as well --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab9c8de96..6af9c256f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added -- Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) +- Added a `-RowLimit` parameter to `Clear-PnPRecycleBinItem` and `Restore-PnPRecycleBinItem` so that it can be used on recycle bins which hold more than 5000 items [PR #2760](https://github.com/pnp/PnP-PowerShell/pull/2760) ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) From c25c63e9946b40c834ce4620f41ae727037891f2 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 01:15:29 +0200 Subject: [PATCH 050/130] OutputTypeLinks specified in the CmdletHelp attribute will now be added to the RelatedLinks sections of Get-Help --- ModuleFilesGenerator/HelpFileGenerator.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ModuleFilesGenerator/HelpFileGenerator.cs b/ModuleFilesGenerator/HelpFileGenerator.cs index 2dee1f696..227da70ae 100644 --- a/ModuleFilesGenerator/HelpFileGenerator.cs +++ b/ModuleFilesGenerator/HelpFileGenerator.cs @@ -264,8 +264,13 @@ private XElement GetExamplesElement(Model.CmdletInfo cmdletInfo) private XElement GetRelatedLinksElement(Model.CmdletInfo cmdletInfo) { var relatedLinksElement = new XElement(maml + "relatedLinks"); - cmdletInfo.RelatedLinks.Insert(0, new CmdletRelatedLinkAttribute() { Text = "SharePoint Developer Patterns and Practices", Url = "http://aka.ms/sppnp" }); - + cmdletInfo.RelatedLinks.Insert(0, new CmdletRelatedLinkAttribute { Text = "SharePoint Developer Patterns and Practices", Url = "http://aka.ms/sppnp" }); + + if(!string.IsNullOrEmpty(cmdletInfo.OutputTypeLink)) + { + cmdletInfo.RelatedLinks.Insert(1, new CmdletRelatedLinkAttribute { Text = "Output type documentation", Url = cmdletInfo.OutputTypeLink }); + } + foreach (var link in cmdletInfo.RelatedLinks) { var navigationLinksElement = new XElement(maml + "navigationLink"); From f7f079d8bf7bde58723f2e1e59a256105b965136 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 01:51:20 +0200 Subject: [PATCH 051/130] Documentation fixes in Add-PnPOffice365GroupToSite --- Commands/Admin/AddOffice365GroupToSite.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Commands/Admin/AddOffice365GroupToSite.cs b/Commands/Admin/AddOffice365GroupToSite.cs index 197b086bc..17670564e 100644 --- a/Commands/Admin/AddOffice365GroupToSite.cs +++ b/Commands/Admin/AddOffice365GroupToSite.cs @@ -11,12 +11,12 @@ namespace SharePointPnP.PowerShell.Commands.Admin { [Cmdlet(VerbsCommon.Add, "PnPOffice365GroupToSite")] [CmdletHelp("Groupifies a classic team site by creating a Microsoft 365 group for it and connecting the site with the newly created group", - DetailedDescription = "This command allows you to add a Microsoft 365 Unified group to an existing classic site collection.", + DetailedDescription = "This command allows you to add a Microsoft 365 Unified group to an existing classic site collection, also known as groupifying.", SupportedPlatform = CmdletSupportedPlatform.Online, Category = CmdletHelpCategory.TenantAdmin)] [CmdletExample( Code = @"PS:> Add-PnPOffice365GroupToSite -Url ""https://contoso.sharepoint.com/sites/FinanceTeamsite"" -Alias ""FinanceTeamsite"" -DisplayName = ""My finance team site group""", - Remarks = @"This will add a group called MyGroup to the current site collection", SortOrder = 1)] + Remarks = @"This will groupify the FinanceTeamsite", SortOrder = 1)] public class AddOffice365GroupToSite: PnPAdminCmdlet { [Parameter(Mandatory = true, HelpMessage = @"Url of the site to be connected to an Microsoft 365 Group")] @@ -43,7 +43,7 @@ public class AddOffice365GroupToSite: PnPAdminCmdlet [Parameter(Mandatory = false, HelpMessage = "If specified the site will be associated to the hubsite as identified by this id")] public GuidPipeBind HubSiteId; - [Parameter(Mandatory = false, HelpMessage = "The array UPN values of the group's owners.")] + [Parameter(Mandatory = false, HelpMessage = "The array UPN values of the group's owners")] public string[] Owners; protected override void ExecuteCmdlet() { From 1f2dd74b8cb08ed2e7056be0117e8f66d426769b Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 01:54:36 +0200 Subject: [PATCH 052/130] Renamed to comply with Office 365 Group -> Microsoft 365 Group name change. Added alias to old cmdlet name for backwards compatibility. --- ...Office365GroupToSite.cs => AddMicrosoft365GroupToSite.cs} | 5 +++-- Commands/SharePointPnP.PowerShell.Commands.csproj | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) rename Commands/Admin/{AddOffice365GroupToSite.cs => AddMicrosoft365GroupToSite.cs} (95%) diff --git a/Commands/Admin/AddOffice365GroupToSite.cs b/Commands/Admin/AddMicrosoft365GroupToSite.cs similarity index 95% rename from Commands/Admin/AddOffice365GroupToSite.cs rename to Commands/Admin/AddMicrosoft365GroupToSite.cs index 17670564e..619b37a1c 100644 --- a/Commands/Admin/AddOffice365GroupToSite.cs +++ b/Commands/Admin/AddMicrosoft365GroupToSite.cs @@ -9,7 +9,7 @@ namespace SharePointPnP.PowerShell.Commands.Admin { - [Cmdlet(VerbsCommon.Add, "PnPOffice365GroupToSite")] + [Cmdlet(VerbsCommon.Add, "PnPMicrosoft365GroupToSite")] [CmdletHelp("Groupifies a classic team site by creating a Microsoft 365 group for it and connecting the site with the newly created group", DetailedDescription = "This command allows you to add a Microsoft 365 Unified group to an existing classic site collection, also known as groupifying.", SupportedPlatform = CmdletSupportedPlatform.Online, @@ -17,7 +17,8 @@ namespace SharePointPnP.PowerShell.Commands.Admin [CmdletExample( Code = @"PS:> Add-PnPOffice365GroupToSite -Url ""https://contoso.sharepoint.com/sites/FinanceTeamsite"" -Alias ""FinanceTeamsite"" -DisplayName = ""My finance team site group""", Remarks = @"This will groupify the FinanceTeamsite", SortOrder = 1)] - public class AddOffice365GroupToSite: PnPAdminCmdlet + [Alias("Add-PnPOffice365GroupToSite")] + public class AddMicrosoft365GroupToSite: PnPAdminCmdlet { [Parameter(Mandatory = true, HelpMessage = @"Url of the site to be connected to an Microsoft 365 Group")] public string Url; diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index ed7d2865d..6d0360abb 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -554,7 +554,7 @@ - + From 19b7ee2ce4c0fc493a8adaa00bf19fede34287fe Mon Sep 17 00:00:00 2001 From: James May Date: Thu, 25 Jun 2020 16:29:21 +1000 Subject: [PATCH 053/130] Measure-PnPList: add list view threshold note as raised in issue #2670 --- Commands/Diagnostic/MeasurePnPList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Commands/Diagnostic/MeasurePnPList.cs b/Commands/Diagnostic/MeasurePnPList.cs index e991c57de..93bca3142 100644 --- a/Commands/Diagnostic/MeasurePnPList.cs +++ b/Commands/Diagnostic/MeasurePnPList.cs @@ -12,7 +12,7 @@ namespace SharePointPnP.PowerShell.Commands.Diagnostic { [Cmdlet(VerbsDiagnostic.Measure, "PnPList")] - [CmdletHelp("Returns statistics on the list object", + [CmdletHelp("Returns statistics on the list object. This may fail on lists larger than the list view threshold", Category = CmdletHelpCategory.Diagnostic, SupportedPlatform = CmdletSupportedPlatform.Online | CmdletSupportedPlatform.SP2016 | CmdletSupportedPlatform.SP2019)] [CmdletExample( From e755996e1cc4bf1fd84066955c1c56134764248d Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Thu, 25 Jun 2020 13:20:06 +0530 Subject: [PATCH 054/130] Added fix for HTTP merge requests --- Commands/Base/InvokeSPRestMethod.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Commands/Base/InvokeSPRestMethod.cs b/Commands/Base/InvokeSPRestMethod.cs index 778047d1f..590886ec2 100644 --- a/Commands/Base/InvokeSPRestMethod.cs +++ b/Commands/Base/InvokeSPRestMethod.cs @@ -91,6 +91,7 @@ protected override void ExecuteCmdlet() { method = HttpMethod.Post; request.Headers.Add("X-HTTP-Method", "MERGE"); + request.Headers.Add("IF-MATCH", "*"); } if (!string.IsNullOrEmpty(accessToken)) From 9259930d2f5aaf88ba0d9a15ecedb679e62070c1 Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Thu, 25 Jun 2020 13:35:33 +0530 Subject: [PATCH 055/130] Additional fix for delete method as well --- Commands/Base/InvokeSPRestMethod.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Commands/Base/InvokeSPRestMethod.cs b/Commands/Base/InvokeSPRestMethod.cs index 590886ec2..908279b22 100644 --- a/Commands/Base/InvokeSPRestMethod.cs +++ b/Commands/Base/InvokeSPRestMethod.cs @@ -90,7 +90,11 @@ protected override void ExecuteCmdlet() if (Method == HttpRequestMethod.Merge) { method = HttpMethod.Post; - request.Headers.Add("X-HTTP-Method", "MERGE"); + request.Headers.Add("X-HTTP-Method", "MERGE"); + } + + if(Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Delete) + { request.Headers.Add("IF-MATCH", "*"); } From dea19a2fddb0cbd286060cf689dffc8177ba6f74 Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 10:05:35 +0200 Subject: [PATCH 056/130] Some code cleanup --- Commands/Base/InvokeSPRestMethod.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/Commands/Base/InvokeSPRestMethod.cs b/Commands/Base/InvokeSPRestMethod.cs index 590886ec2..bfd89b6a0 100644 --- a/Commands/Base/InvokeSPRestMethod.cs +++ b/Commands/Base/InvokeSPRestMethod.cs @@ -48,18 +48,17 @@ public class InvokeSPRestMethod : PnPSharePointCmdlet [Parameter(Mandatory = false, Position = 0, HelpMessage = "The Http method to execute. Defaults to GET.")] public HttpRequestMethod Method = HttpRequestMethod.Get; - [Parameter(Mandatory = true, Position = 0, HelpMessage = "The url to execute.")] + [Parameter(Mandatory = true, Position = 0, HelpMessage = "The url to execute")] public string Url; [Parameter(Mandatory = false, HelpMessage = "A string or object to send")] public object Content; - [Parameter(Mandatory = false, HelpMessage = "The content type of the object to send. Defaults to 'application/json'")] + [Parameter(Mandatory = false, HelpMessage = "The content type of the object to send. Defaults to 'application/json'.")] public string ContentType = "application/json"; protected override void ExecuteCmdlet() { - if (Url.StartsWith("/")) { // prefix the url with the current web url @@ -69,16 +68,14 @@ protected override void ExecuteCmdlet() var accessToken = this.ClientContext.GetAccessToken(); var method = new HttpMethod(Method.ToString()); - //var method = new HttpMethod(Method.ToString().ToUpper()); - using (var handler = new System.Net.Http.HttpClientHandler()) + using (var handler = new HttpClientHandler()) { // we're not in app-only or user + app context, so let's fall back to cookie based auth - if (String.IsNullOrEmpty(accessToken)) + if (string.IsNullOrEmpty(accessToken)) { SetAuthenticationCookies(handler, ClientContext); } - using (var httpClient = new PnPHttpProvider(handler)) { var requestUrl = Url; @@ -96,7 +93,7 @@ protected override void ExecuteCmdlet() if (!string.IsNullOrEmpty(accessToken)) { - request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } else { @@ -105,7 +102,7 @@ protected override void ExecuteCmdlet() handler.Credentials = networkCredential; } } - request.Headers.Add("X-RequestDigest", (ClientContext as ClientContext).GetRequestDigest().GetAwaiter().GetResult()); + request.Headers.Add("X-RequestDigest", ClientContext.GetRequestDigest().GetAwaiter().GetResult()); if (Method == HttpRequestMethod.Post) { @@ -140,7 +137,6 @@ protected override void ExecuteCmdlet() } } } - } private void SetAuthenticationCookies(HttpClientHandler handler, ClientContext context) @@ -175,7 +171,6 @@ private void SetAuthenticationCookies(HttpClientHandler handler, ClientContext c } } - //Taken from "Remote Authentication in SharePoint Online Using the Client Object Model" //https://code.msdn.microsoft.com/Remote-Authentication-in-b7b6f43c @@ -202,7 +197,6 @@ internal static class CookieReader /// Returns Cookie contents as a string public static string GetCookie(string url) { - int size = 512; StringBuilder sb = new StringBuilder(size); if (!NativeMethods.InternetGetCookieEx(url, null, sb, ref size, INTERNET_COOKIE_HTTPONLY, IntPtr.Zero)) @@ -222,7 +216,6 @@ public static string GetCookie(string url) private static class NativeMethods { - [DllImport("wininet.dll", EntryPoint = "InternetGetCookieEx", CharSet = CharSet.Unicode, SetLastError = true)] public static extern bool InternetGetCookieEx( string url, From 0427b355de4c1fae39f4a6e2df4da6ba54f85d6a Mon Sep 17 00:00:00 2001 From: Gautam Sheth Date: Thu, 25 Jun 2020 13:36:34 +0530 Subject: [PATCH 057/130] Formatting fix --- Commands/Base/InvokeSPRestMethod.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Commands/Base/InvokeSPRestMethod.cs b/Commands/Base/InvokeSPRestMethod.cs index 908279b22..3a791bb18 100644 --- a/Commands/Base/InvokeSPRestMethod.cs +++ b/Commands/Base/InvokeSPRestMethod.cs @@ -90,10 +90,10 @@ protected override void ExecuteCmdlet() if (Method == HttpRequestMethod.Merge) { method = HttpMethod.Post; - request.Headers.Add("X-HTTP-Method", "MERGE"); + request.Headers.Add("X-HTTP-Method", "MERGE"); } - if(Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Delete) + if (Method == HttpRequestMethod.Merge || Method == HttpRequestMethod.Delete) { request.Headers.Add("IF-MATCH", "*"); } From fd33e2db9648686beca8e93c5847e659e21d47cb Mon Sep 17 00:00:00 2001 From: Koen Zomers Date: Thu, 25 Jun 2020 10:07:55 +0200 Subject: [PATCH 058/130] Added changelog entry --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e283177..54790bfa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Added ### Changed +- Fixed `Invoke-PnPSPRestMethod -Method Merge` not passing in the `If-Match: *` header and thereby causing failed requests [PR #2764](https://github.com/pnp/PnP-PowerShell/pull/2764) ### Contributors - +- Gautam Sheth [gautamdsheth] ## [3.22.2006.0] From 23659a38378e36d8dadf546c827dcba98c535ebe Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Thu, 25 Jun 2020 12:50:31 +0200 Subject: [PATCH 059/130] Prep for PowerShell V4 --- Commands/Base/PnPConnectionHelper.cs | 61 ++++++++++++++----- ...1xml => PnP.PowerShell.Core.Format.ps1xml} | 0 Commands/PnPPowerShell.csproj | 8 ++- Commands/Properties/AssemblyInfo.cs | 2 + .../ModuleManifestGenerator.cs | 10 +-- PostBuild.ps1 | 2 +- 6 files changed, 61 insertions(+), 22 deletions(-) rename Commands/ModuleFiles/{SharePointPnP.PowerShell.Core.Format.ps1xml => PnP.PowerShell.Core.Format.ps1xml} (100%) diff --git a/Commands/Base/PnPConnectionHelper.cs b/Commands/Base/PnPConnectionHelper.cs index 729347674..8716147e0 100644 --- a/Commands/Base/PnPConnectionHelper.cs +++ b/Commands/Base/PnPConnectionHelper.cs @@ -640,9 +640,6 @@ internal static PnPConnection InstantiateWebloginConnection(Uri url, int minimal #if !NETSTANDARD2_1 internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredential credentials, PSHost host, bool currentCredentials, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, bool disableTelemetry, bool skipAdminCheck = false, ClientAuthenticationMode authenticationMode = ClientAuthenticationMode.Default) -#else - internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredential credentials, PSHost host, bool currentCredentials, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, bool disableTelemetry, bool skipAdminCheck = false) -#endif { var context = new PnPClientContext(url.AbsoluteUri); @@ -654,7 +651,6 @@ internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredentia #endif context.RequestTimeout = requestTimeout; -#if !NETSTANDARD2_1 context.AuthenticationMode = authenticationMode; if (authenticationMode == ClientAuthenticationMode.FormsAuthentication) @@ -662,16 +658,11 @@ internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredentia var formsAuthInfo = new FormsAuthenticationLoginInfo(credentials.UserName, EncryptionUtility.ToInsecureString(credentials.Password)); context.FormsAuthenticationLoginInfo = formsAuthInfo; } -#endif if (!currentCredentials) { try { -#if !NETSTANDARD2_1 SharePointOnlineCredentials onlineCredentials = new SharePointOnlineCredentials(credentials.UserName, credentials.Password); -#else - var onlineCredentials = new System.Net.NetworkCredential(credentials.UserName, credentials.Password); -#endif context.Credentials = onlineCredentials; try { @@ -680,17 +671,12 @@ internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredentia #if !ONPREMISES catch (NotSupportedException) { -#if NETSTANDARD2_1 - // Legacy auth is not supported with .NET Standard - throw new Exception("Legacy auth is not supported with .NET Standard"); -#else // legacy auth? using (var authManager = new OfficeDevPnP.Core.AuthenticationManager()) { context = PnPClientContext.ConvertFrom(authManager.GetAzureADCredentialsContext(url.ToString(), credentials.UserName, credentials.Password)); context.ExecuteQueryRetry(); } -#endif } #endif catch (ClientRequestException) @@ -762,6 +748,53 @@ internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredentia spoConnection.ConnectionMethod = Model.ConnectionMethod.Credentials; return spoConnection; } +#endif + +#if NETSTANDARD2_1 + internal static PnPConnection InstantiateSPOnlineConnection(Uri url, PSCredential credentials, PSHost host, bool currentCredentials, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, bool disableTelemetry, bool skipAdminCheck = false) + { + var context = new PnPClientContext(url.AbsoluteUri); + + context.RetryCount = retryCount; + context.Delay = retryWait * 1000; + context.ApplicationName = Resources.ApplicationName; + context.DisableReturnValueCache = true; + context.RequestTimeout = requestTimeout; + + try + { + using (var authManager = new OfficeDevPnP.Core.AuthenticationManager()) + { + context = PnPClientContext.ConvertFrom(authManager.GetAzureADCredentialsContext(url.ToString(), credentials.UserName, credentials.Password)); + context.ExecuteQueryRetry(); + } + } + catch (ClientRequestException) + { + context.Credentials = new NetworkCredential(credentials.UserName, credentials.Password); + } + catch (ServerException) + { + context.Credentials = new NetworkCredential(credentials.UserName, credentials.Password); + } + var connectionType = ConnectionType.O365; + if (url.Host.ToUpperInvariant().EndsWith("SHAREPOINT.COM")) + { + connectionType = ConnectionType.O365; + } + + if (skipAdminCheck == false) + { + if (IsTenantAdminSite(context)) + { + connectionType = ConnectionType.TenantAdmin; + } + } + var spoConnection = new PnPConnection(context, connectionType, minimalHealthScore, retryCount, retryWait, credentials, url.ToString(), tenantAdminUrl, PnPPSVersionTag, host, disableTelemetry, InitializationType.Credentials); + spoConnection.ConnectionMethod = Model.ConnectionMethod.Credentials; + return spoConnection; + } +#endif #if !NETSTANDARD2_1 internal static PnPConnection InstantiateAdfsConnection(Uri url, bool useKerberos, PSCredential credentials, PSHost host, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, bool disableTelemetry, bool skipAdminCheck = false, string loginProviderName = null) diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Core.Format.ps1xml b/Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml similarity index 100% rename from Commands/ModuleFiles/SharePointPnP.PowerShell.Core.Format.ps1xml rename to Commands/ModuleFiles/PnP.PowerShell.Core.Format.ps1xml diff --git a/Commands/PnPPowerShell.csproj b/Commands/PnPPowerShell.csproj index 45556dcf0..fc6ccd91a 100644 --- a/Commands/PnPPowerShell.csproj +++ b/Commands/PnPPowerShell.csproj @@ -4,13 +4,16 @@ netstandard2.1 false true - SharePointPnP.PowerShell.Core + PnP.PowerShell.Core SharePointPnP.PowerShell.Commands false + PnP.PowerShell.Core + PnP.PowerShell.Core bin\DebugCore\ + TRACE;NETSTANDARD2_1 @@ -26,6 +29,7 @@ + @@ -111,7 +115,7 @@ - + Always diff --git a/Commands/Properties/AssemblyInfo.cs b/Commands/Properties/AssemblyInfo.cs index b65336ad1..4e38be33f 100644 --- a/Commands/Properties/AssemblyInfo.cs +++ b/Commands/Properties/AssemblyInfo.cs @@ -23,6 +23,8 @@ [assembly: AssemblyProduct("SharePointPnP.PowerShell.SP2016.Commands")] #elif SP2019 [assembly: AssemblyProduct("SharePointPnP.PowerShell.SP2019.Commands")] +#elif NETSTANDARD2_1 +[assembly: AssemblyProduct("PnP.PowerShell.Online.Commands")] #else [assembly: AssemblyProduct("SharePointPnP.PowerShell.Online.Commands")] #endif diff --git a/ModuleFilesGenerator/ModuleManifestGenerator.cs b/ModuleFilesGenerator/ModuleManifestGenerator.cs index 20294b200..f06865ddf 100644 --- a/ModuleFilesGenerator/ModuleManifestGenerator.cs +++ b/ModuleFilesGenerator/ModuleManifestGenerator.cs @@ -71,7 +71,7 @@ internal void Generate() #if !NETCOREAPP3_0 var psd1Path = $"{new FileInfo(_assemblyPath).Directory}\\ModuleFiles\\SharePointPnPPowerShell{spVersion}.psd1"; #else - var psd1Path = $"{new FileInfo(_assemblyPath).Directory}\\ModuleFiles\\SharePointPnPPowerShellCore.psd1"; + var psd1Path = $"{new FileInfo(_assemblyPath).Directory}\\ModuleFiles\\PnPPowerShellCore.psd1"; #endif var cmdletsToExportString = string.Join(",", _cmdlets.Select(c => "'" + c.FullCommand + "'")); string aliasesToExportString = null; @@ -102,25 +102,25 @@ private void WriteModuleManifest(string path, string spVersion, string cmdletsTo PrivateData = @{{ PSData = @{{ ProjectUri = 'https://aka.ms/sppnp' - IconUri = 'https://raw.githubusercontent.com/pnp/media/master/optimized/pnp-projects/blue/png/pnp-powershell-300.png' + IconUri = 'https://github.com/pnp/media/blob/19f8d40f400f9f0d766a8efd69496d8f536b853f/parker/ms/300w/parker-ms-300.png' }} }} }}"; #else var manifest = $@"@{{ - RootModule = 'SharePointPnP.PowerShell.Core.dll' + RootModule = 'PnP.PowerShell.Core.dll' ModuleVersion = '{_assemblyVersion}' Description = 'SharePoint Patterns and Practices PowerShell Cmdlets for SharePoint Online' GUID = '0b0430ce-d799-4f3b-a565-f0dca1f31e17' Author = 'SharePoint Patterns and Practices' CompanyName = 'SharePoint Patterns and Practices' - PowerShellVersion = '5.0' + PowerShellVersion = '7.0' ProcessorArchitecture = 'None' FunctionsToExport = '*' CmdletsToExport = {cmdletsToExport} VariablesToExport = '*' AliasesToExport = '*' - FormatsToProcess = 'SharePointPnP.PowerShell.{spVersion}.Format.ps1xml' + FormatsToProcess = 'PnP.PowerShell.{spVersion}.Format.ps1xml' PrivateData = @{{ PSData = @{{ ProjectUri = 'https://aka.ms/sppnp' diff --git a/PostBuild.ps1 b/PostBuild.ps1 index 750e57b66..401fb72ed 100644 --- a/PostBuild.ps1 +++ b/PostBuild.ps1 @@ -5,7 +5,7 @@ if($ConfigurationName -like "Debug*") $documentsFolder = [environment]::getfolderpath("mydocuments"); if($TargetDir -like "*Core*") { - $DestinationFolder = "$documentsFolder\PowerShell\Modules\SharePointPnPPowerShellCore" + $DestinationFolder = "$documentsFolder\PowerShell\Modules\PnPPowerShellCore" } else { if($ConfigurationName -like "Debug15") { From 1aa39bf8a67045a9d7a595653a0ecbc8c56df40b Mon Sep 17 00:00:00 2001 From: Jens Otto Hatlevold Date: Thu, 25 Jun 2020 14:57:22 +0200 Subject: [PATCH 060/130] Adds possibility to set a fields AllowDeletion property --- Commands/Fields/SetField.cs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Commands/Fields/SetField.cs b/Commands/Fields/SetField.cs index c9838241f..5d41525d3 100644 --- a/Commands/Fields/SetField.cs +++ b/Commands/Fields/SetField.cs @@ -40,6 +40,7 @@ public class SetField : PnPWebCmdlet protected override void ExecuteCmdlet() { + const string allowDeletionPropertyKey = "AllowDeletion"; Field field = null; if (List != null) { @@ -84,7 +85,14 @@ protected override void ExecuteCmdlet() } } - ClientContext.Load(field); + if (Values.ContainsKey(allowDeletionPropertyKey)) + { + ClientContext.Load(field, f => f.SchemaXmlWithResourceTokens); + } + else + { + ClientContext.Load(field); + } ClientContext.ExecuteQueryRetry(); // Get a reference to the type-specific object to allow setting type-specific properties, i.e. LookupList and LookupField for Microsoft.SharePoint.Client.FieldLookup @@ -95,7 +103,10 @@ protected override void ExecuteCmdlet() var value = Values[key]; var property = typeSpecificField.GetType().GetProperty(key); - if (property == null) + + bool isAllowDeletionProperty = string.Equals(key, allowDeletionPropertyKey, StringComparison.Ordinal); + + if (property == null && !isAllowDeletionProperty) { WriteWarning($"No property '{key}' found on this field. Value will be ignored."); } @@ -103,7 +114,14 @@ protected override void ExecuteCmdlet() { try { - property.SetValue(typeSpecificField, value); + if (isAllowDeletionProperty) + { + field.SetAllowDeletion(value as bool?); + } + else + { + property.SetValue(typeSpecificField, value); + } } catch (Exception e) { From b2f84d68b93a2d05bae42562392d42cf488c95a1 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Fri, 26 Jun 2020 13:27:28 +0200 Subject: [PATCH 061/130] Teams Cmdlets --- .../SharePointPnP.PowerShell.Commands.csproj | 4 + Commands/Teams/AddTeamsChannel.cs | 62 ++++++++++++++ Commands/Teams/GetTeamsChannel.cs | 59 +++++++++++++ Commands/Teams/GetTeamsTeam.cs | 82 +++++++++++++++++++ Commands/Teams/RemoveTeamsChannel.cs | 68 +++++++++++++++ 5 files changed, 275 insertions(+) create mode 100644 Commands/Teams/AddTeamsChannel.cs create mode 100644 Commands/Teams/GetTeamsChannel.cs create mode 100644 Commands/Teams/GetTeamsTeam.cs create mode 100644 Commands/Teams/RemoveTeamsChannel.cs diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index ed7d2865d..b96e3fffc 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -897,6 +897,10 @@ + + + + diff --git a/Commands/Teams/AddTeamsChannel.cs b/Commands/Teams/AddTeamsChannel.cs new file mode 100644 index 000000000..3bf1df53a --- /dev/null +++ b/Commands/Teams/AddTeamsChannel.cs @@ -0,0 +1,62 @@ +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using OfficeDevPnP.Core.Utilities; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Collections.Generic; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Add, "PnPTeamsChannel")] + [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", + Category = CmdletHelpCategory.Graph, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup", + Remarks = "Retrieves all the Office 365 Groups", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", + Remarks = "Retrieves a specific Office 365 Group based on its ID", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", + Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", + SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", + Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", + SortOrder = 4)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $group", + Remarks = "Retrieves a specific Office 365 Group based on its object instance", + SortOrder = 5)] + public class AddTeamsChannel : PnPGraphCmdlet + { + [Parameter(Mandatory = true)] + public string GroupId; + + [Parameter(Mandatory = true)] + public string DisplayName; + + [Parameter(Mandatory = false)] + public string Description; + + protected override void ExecuteCmdlet() + { + if (JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) + { + var id = TeamsUtility.AddChannel(AccessToken, GroupId, DisplayName, Description); + WriteObject(new { Id = id, DisplayName, Description }); + + } + else + { + WriteWarning("The current access token lacks the Group.ReadWrite.All permission scope"); + } + } + } +} diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs new file mode 100644 index 000000000..d0d0df4c1 --- /dev/null +++ b/Commands/Teams/GetTeamsChannel.cs @@ -0,0 +1,59 @@ +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Teams +{ + [Cmdlet(VerbsCommon.Get, "PnPTeamsChannel")] + [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", + Category = CmdletHelpCategory.Graph, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup", + Remarks = "Retrieves all the Office 365 Groups", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", + Remarks = "Retrieves a specific Office 365 Group based on its ID", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", + Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", + SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", + Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", + SortOrder = 4)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $group", + Remarks = "Retrieves a specific Office 365 Group based on its object instance", + SortOrder = 5)] + public class GetTeamsChannel : PnPGraphCmdlet + { + [Parameter(Mandatory = true)] + public TeamPipeBind TeamIdentity; + + protected override void ExecuteCmdlet() + { + if (JwtUtility.HasScope(AccessToken, "Group.Read.All") || JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) + { + if (ParameterSpecified(nameof(TeamIdentity))) + { + WriteObject(TeamsUtility.GetChannels(AccessToken, TeamIdentity.GetTeamId()), true); + } + } + else + { + WriteWarning("The current access token lacks the Group.Read.All or equivalent permission scope"); + } + } + } +} diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs new file mode 100644 index 000000000..63b6d7fcb --- /dev/null +++ b/Commands/Teams/GetTeamsTeam.cs @@ -0,0 +1,82 @@ +using OfficeDevPnP.Core.Entities; +using OfficeDevPnP.Core.Framework.Graph; +using OfficeDevPnP.Core.Utilities; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Utilities; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; + +namespace SharePointPnP.PowerShell.Commands.Graph +{ + [Cmdlet(VerbsCommon.Get, "PnPTeamsTeam")] + [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", + Category = CmdletHelpCategory.Graph, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup", + Remarks = "Retrieves all the Office 365 Groups", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", + Remarks = "Retrieves a specific Office 365 Group based on its ID", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", + Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", + SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", + Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", + SortOrder = 4)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $group", + Remarks = "Retrieves a specific Office 365 Group based on its object instance", + SortOrder = 5)] + public class GetTeamsTeam : PnPGraphCmdlet + { + [Parameter(Mandatory = false)] + public string GroupId; + + [Parameter(Mandatory = false)] + public TeamIncludes[] Includes; + + protected override void ExecuteCmdlet() + { + if (JwtUtility.HasScope(AccessToken, "Group.Read.All") || JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) + { + var includeChannels = false; + var includeMessages = false; + var includeApps = false; + var includeSecurity = false; + if (ParameterSpecified(nameof(Includes))) + { + includeChannels = Includes.Contains(TeamIncludes.Channels); + includeApps = Includes.Contains(TeamIncludes.Apps); + includeSecurity = Includes.Contains(TeamIncludes.Security); + } + if (ParameterSpecified(nameof(GroupId))) + { + WriteObject(TeamsUtility.GetTeam(AccessToken, GroupId, includeChannels, includeMessages, includeApps, includeSecurity)); + } + else + { + WriteObject(TeamsUtility.GetAllTeams(AccessToken, includeChannels, includeMessages, includeApps, includeSecurity), true); + } + } + else + { + WriteWarning("The current access token lacks the Group.Read.All or equivalent permission scope"); + } + } + + public enum TeamIncludes + { + Channels, + Apps, + Security + } + } +} diff --git a/Commands/Teams/RemoveTeamsChannel.cs b/Commands/Teams/RemoveTeamsChannel.cs new file mode 100644 index 000000000..fd3f7ab63 --- /dev/null +++ b/Commands/Teams/RemoveTeamsChannel.cs @@ -0,0 +1,68 @@ +using OfficeDevPnP.Core.Framework.Graph; +using SharePointPnP.PowerShell.CmdletHelpAttributes; +using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Utilities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management.Automation; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Teams +{ + [Cmdlet(VerbsCommon.Remove, "PnPTeamsChannel")] + [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", + Category = CmdletHelpCategory.Graph, + SupportedPlatform = CmdletSupportedPlatform.Online)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup", + Remarks = "Retrieves all the Office 365 Groups", + SortOrder = 1)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", + Remarks = "Retrieves a specific Office 365 Group based on its ID", + SortOrder = 2)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", + Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", + SortOrder = 3)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", + Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", + SortOrder = 4)] + [CmdletExample( + Code = "PS:> Get-PnPUnifiedGroup -Identity $group", + Remarks = "Retrieves a specific Office 365 Group based on its object instance", + SortOrder = 5)] + public class RemoveTeamsChannel : PnPGraphCmdlet + { + [Parameter(Mandatory = true)] + public string GroupId; + + [Parameter(Mandatory = true)] + public string DisplayName; + + [Parameter(Mandatory = false, HelpMessage = "Specifying the Force parameter will skip the confirmation question.")] + public SwitchParameter Force; + + protected override void ExecuteCmdlet() + { + if (JwtUtility.HasScope(AccessToken, "Group.Read.All") || JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) + { + if (ParameterSpecified(nameof(GroupId))) + { + if (Force || ShouldContinue("Removing the channel will also remove all the messages in the channel.", Properties.Resources.Confirm)) + { + TeamsUtility.DeleteChannel(AccessToken, GroupId, DisplayName); + } + } + } + else + { + WriteWarning("The current access token lacks the Group.ReadWrite.All permission scope"); + } + + } + } +} From 7de265127a9bc1541d5ba1c045baf374548bb893 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:18:06 +0100 Subject: [PATCH 062/130] Added placeholder admin tests --- Tests/Admin/AddPnPHubSiteAssociationTests.cs | 63 +++++++ .../Admin/AddPnPOffice365GroupToSiteTests.cs | 63 +++++++ Tests/Admin/AddPnPOrgAssetsLibraryTests.cs | 63 +++++++ Tests/Admin/AddPnPOrgNewsSiteTests.cs | 63 +++++++ .../AddPnPSiteCollectionAppCatalogTests.cs | 63 +++++++ Tests/Admin/AddPnPTenantCdnOriginTests.cs | 63 +++++++ Tests/Admin/AddPnPTenantThemeTests.cs | 63 +++++++ Tests/Admin/GetPnPHideDefaultThemesTests.cs | 63 +++++++ Tests/Admin/GetPnPHomeSiteTests.cs | 63 +++++++ Tests/Admin/GetPnPHubSiteChildTests.cs | 63 +++++++ Tests/Admin/GetPnPHubSiteTests.cs | 63 +++++++ Tests/Admin/GetPnPKnowledgeHubSiteTests.cs | 63 +++++++ Tests/Admin/GetPnPOrgAssetsLibraryTests.cs | 63 +++++++ Tests/Admin/GetPnPOrgNewsSiteTests.cs | 63 +++++++ Tests/Admin/GetPnPTenantCdnEnabledTests.cs | 63 +++++++ Tests/Admin/GetPnPTenantCdnOriginTests.cs | 63 +++++++ Tests/Admin/GetPnPTenantCdnPoliciesTests.cs | 63 +++++++ Tests/Admin/GetPnPTenantIdTests.cs | 63 +++++++ .../GetPnPTenantSyncClientRestrictionTests.cs | 63 +++++++ Tests/Admin/GetPnPTenantTests.cs | 63 +++++++ Tests/Admin/GetPnPTenantThemeTests.cs | 63 +++++++ Tests/Admin/GrantPnPHubSiteRightsTests.cs | 63 +++++++ Tests/Admin/InvokePnPSPRestMethodTests.cs | 63 +++++++ Tests/Admin/RegisterPnPHubSiteTests.cs | 63 +++++++ Tests/Admin/RemovePnPHomeSiteTests.cs | 63 +++++++ .../Admin/RemovePnPHubSiteAssociationTests.cs | 63 +++++++ Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs | 63 +++++++ Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs | 63 +++++++ Tests/Admin/RemovePnPOrgNewsSiteTests.cs | 63 +++++++ .../RemovePnPSiteCollectionAppCatalogTests.cs | 63 +++++++ Tests/Admin/RemovePnPTenantCdnOriginTests.cs | 63 +++++++ Tests/Admin/RemovePnPTenantThemeTests.cs | 63 +++++++ Tests/Admin/RevokePnPHubSiteRightsTests.cs | 63 +++++++ Tests/Admin/SetPnPHideDefaultThemesTests.cs | 63 +++++++ Tests/Admin/SetPnPHomeSiteTests.cs | 63 +++++++ Tests/Admin/SetPnPHubSiteTests.cs | 63 +++++++ Tests/Admin/SetPnPKnowledgeHubSiteTests.cs | 63 +++++++ Tests/Admin/SetPnPTenantCdnEnabledTests.cs | 63 +++++++ Tests/Admin/SetPnPTenantCdnPolicyTests.cs | 63 +++++++ .../SetPnPTenantSyncClientRestrictionTests.cs | 63 +++++++ Tests/Admin/SetPnPTenantTests.cs | 63 +++++++ Tests/Admin/UnregisterPnPHubSiteTests.cs | 63 +++++++ Tests/Readme.md | 9 + Tests/SharePointPnP.PowerShell.Tests.csproj | 162 ++++++++++++++++++ 44 files changed, 2817 insertions(+) create mode 100644 Tests/Admin/AddPnPHubSiteAssociationTests.cs create mode 100644 Tests/Admin/AddPnPOffice365GroupToSiteTests.cs create mode 100644 Tests/Admin/AddPnPOrgAssetsLibraryTests.cs create mode 100644 Tests/Admin/AddPnPOrgNewsSiteTests.cs create mode 100644 Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs create mode 100644 Tests/Admin/AddPnPTenantCdnOriginTests.cs create mode 100644 Tests/Admin/AddPnPTenantThemeTests.cs create mode 100644 Tests/Admin/GetPnPHideDefaultThemesTests.cs create mode 100644 Tests/Admin/GetPnPHomeSiteTests.cs create mode 100644 Tests/Admin/GetPnPHubSiteChildTests.cs create mode 100644 Tests/Admin/GetPnPHubSiteTests.cs create mode 100644 Tests/Admin/GetPnPKnowledgeHubSiteTests.cs create mode 100644 Tests/Admin/GetPnPOrgAssetsLibraryTests.cs create mode 100644 Tests/Admin/GetPnPOrgNewsSiteTests.cs create mode 100644 Tests/Admin/GetPnPTenantCdnEnabledTests.cs create mode 100644 Tests/Admin/GetPnPTenantCdnOriginTests.cs create mode 100644 Tests/Admin/GetPnPTenantCdnPoliciesTests.cs create mode 100644 Tests/Admin/GetPnPTenantIdTests.cs create mode 100644 Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs create mode 100644 Tests/Admin/GetPnPTenantTests.cs create mode 100644 Tests/Admin/GetPnPTenantThemeTests.cs create mode 100644 Tests/Admin/GrantPnPHubSiteRightsTests.cs create mode 100644 Tests/Admin/InvokePnPSPRestMethodTests.cs create mode 100644 Tests/Admin/RegisterPnPHubSiteTests.cs create mode 100644 Tests/Admin/RemovePnPHomeSiteTests.cs create mode 100644 Tests/Admin/RemovePnPHubSiteAssociationTests.cs create mode 100644 Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs create mode 100644 Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs create mode 100644 Tests/Admin/RemovePnPOrgNewsSiteTests.cs create mode 100644 Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs create mode 100644 Tests/Admin/RemovePnPTenantCdnOriginTests.cs create mode 100644 Tests/Admin/RemovePnPTenantThemeTests.cs create mode 100644 Tests/Admin/RevokePnPHubSiteRightsTests.cs create mode 100644 Tests/Admin/SetPnPHideDefaultThemesTests.cs create mode 100644 Tests/Admin/SetPnPHomeSiteTests.cs create mode 100644 Tests/Admin/SetPnPHubSiteTests.cs create mode 100644 Tests/Admin/SetPnPKnowledgeHubSiteTests.cs create mode 100644 Tests/Admin/SetPnPTenantCdnEnabledTests.cs create mode 100644 Tests/Admin/SetPnPTenantCdnPolicyTests.cs create mode 100644 Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs create mode 100644 Tests/Admin/SetPnPTenantTests.cs create mode 100644 Tests/Admin/UnregisterPnPHubSiteTests.cs create mode 100644 Tests/Readme.md diff --git a/Tests/Admin/AddPnPHubSiteAssociationTests.cs b/Tests/Admin/AddPnPHubSiteAssociationTests.cs new file mode 100644 index 000000000..65f3c7b80 --- /dev/null +++ b/Tests/Admin/AddPnPHubSiteAssociationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddHubSiteAssociationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPHubSiteAssociationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPHubSiteAssociation",new CommandParameter("Site", "null"),new CommandParameter("HubSite", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs b/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs new file mode 100644 index 000000000..5684e14bb --- /dev/null +++ b/Tests/Admin/AddPnPOffice365GroupToSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddOffice365GroupToSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPOffice365GroupToSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPOffice365GroupToSite",new CommandParameter("Url", "null"),new CommandParameter("Alias", "null"),new CommandParameter("Description", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Classification", "null"),new CommandParameter("IsPublic", "null"),new CommandParameter("KeepOldHomePage", "null"),new CommandParameter("HubSiteId", "null"),new CommandParameter("Owners", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs b/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs new file mode 100644 index 000000000..755abf1e3 --- /dev/null +++ b/Tests/Admin/AddPnPOrgAssetsLibraryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddOrgAssetsLibraryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPOrgAssetsLibraryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPOrgAssetsLibrary",new CommandParameter("LibraryUrl", "null"),new CommandParameter("ThumbnailUrl", "null"),new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/AddPnPOrgNewsSiteTests.cs b/Tests/Admin/AddPnPOrgNewsSiteTests.cs new file mode 100644 index 000000000..4f0bb241c --- /dev/null +++ b/Tests/Admin/AddPnPOrgNewsSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddOrgNewsSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPOrgNewsSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPOrgNewsSite",new CommandParameter("OrgNewsSiteUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs b/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs new file mode 100644 index 000000000..277895f22 --- /dev/null +++ b/Tests/Admin/AddPnPSiteCollectionAppCatalogTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddSiteCollectionAppCatalogTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPSiteCollectionAppCatalogTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPSiteCollectionAppCatalog",new CommandParameter("Site", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/AddPnPTenantCdnOriginTests.cs b/Tests/Admin/AddPnPTenantCdnOriginTests.cs new file mode 100644 index 000000000..bb071c2dd --- /dev/null +++ b/Tests/Admin/AddPnPTenantCdnOriginTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddTenantCdnOriginTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTenantCdnOriginTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTenantCdnOrigin",new CommandParameter("OriginUrl", "null"),new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/AddPnPTenantThemeTests.cs b/Tests/Admin/AddPnPTenantThemeTests.cs new file mode 100644 index 000000000..a977d3b6a --- /dev/null +++ b/Tests/Admin/AddPnPTenantThemeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class AddTenantThemeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTenantThemeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTenantTheme",new CommandParameter("Overwrite", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Palette", "null"),new CommandParameter("IsInverted", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPHideDefaultThemesTests.cs b/Tests/Admin/GetPnPHideDefaultThemesTests.cs new file mode 100644 index 000000000..5b2fdfa8c --- /dev/null +++ b/Tests/Admin/GetPnPHideDefaultThemesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetHideDefaultThemesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPHideDefaultThemesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPHideDefaultThemes"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPHomeSiteTests.cs b/Tests/Admin/GetPnPHomeSiteTests.cs new file mode 100644 index 000000000..152feed22 --- /dev/null +++ b/Tests/Admin/GetPnPHomeSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetHomeSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPHomeSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPHomeSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPHubSiteChildTests.cs b/Tests/Admin/GetPnPHubSiteChildTests.cs new file mode 100644 index 000000000..3a411e5a7 --- /dev/null +++ b/Tests/Admin/GetPnPHubSiteChildTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetHubSiteChildTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPHubSiteChildTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPHubSiteChild",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPHubSiteTests.cs b/Tests/Admin/GetPnPHubSiteTests.cs new file mode 100644 index 000000000..d441fbe0e --- /dev/null +++ b/Tests/Admin/GetPnPHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPHubSite",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs b/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs new file mode 100644 index 000000000..c8790a82e --- /dev/null +++ b/Tests/Admin/GetPnPKnowledgeHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetKnowledgeHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPKnowledgeHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPKnowledgeHubSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs b/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs new file mode 100644 index 000000000..81402805c --- /dev/null +++ b/Tests/Admin/GetPnPOrgAssetsLibraryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetOrgAssetsLibraryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOrgAssetsLibraryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOrgAssetsLibrary"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPOrgNewsSiteTests.cs b/Tests/Admin/GetPnPOrgNewsSiteTests.cs new file mode 100644 index 000000000..db8fee138 --- /dev/null +++ b/Tests/Admin/GetPnPOrgNewsSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetOrgNewsSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOrgNewsSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOrgNewsSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantCdnEnabledTests.cs b/Tests/Admin/GetPnPTenantCdnEnabledTests.cs new file mode 100644 index 000000000..1a07cf312 --- /dev/null +++ b/Tests/Admin/GetPnPTenantCdnEnabledTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetTenantCdnEnabledTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantCdnEnabledTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantCdnEnabled",new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantCdnOriginTests.cs b/Tests/Admin/GetPnPTenantCdnOriginTests.cs new file mode 100644 index 000000000..48acf3c1a --- /dev/null +++ b/Tests/Admin/GetPnPTenantCdnOriginTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetTenantCdnOriginTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantCdnOriginTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantCdnOrigin",new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs b/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs new file mode 100644 index 000000000..c1a8f3f02 --- /dev/null +++ b/Tests/Admin/GetPnPTenantCdnPoliciesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetTenantCdnPoliciesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantCdnPoliciesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantCdnPolicies",new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantIdTests.cs b/Tests/Admin/GetPnPTenantIdTests.cs new file mode 100644 index 000000000..0ef05183b --- /dev/null +++ b/Tests/Admin/GetPnPTenantIdTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetTenantIdTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantIdTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantId",new CommandParameter("TenantUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs b/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs new file mode 100644 index 000000000..8b9ddb5b9 --- /dev/null +++ b/Tests/Admin/GetPnPTenantSyncClientRestrictionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetPnPTenantSyncClientRestrictionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantSyncClientRestrictionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantSyncClientRestriction"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantTests.cs b/Tests/Admin/GetPnPTenantTests.cs new file mode 100644 index 000000000..618525a4c --- /dev/null +++ b/Tests/Admin/GetPnPTenantTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetTenantTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenant"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GetPnPTenantThemeTests.cs b/Tests/Admin/GetPnPTenantThemeTests.cs new file mode 100644 index 000000000..8dbd29161 --- /dev/null +++ b/Tests/Admin/GetPnPTenantThemeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GetTenantThemeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantThemeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantTheme",new CommandParameter("Name", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/GrantPnPHubSiteRightsTests.cs b/Tests/Admin/GrantPnPHubSiteRightsTests.cs new file mode 100644 index 000000000..8fc750395 --- /dev/null +++ b/Tests/Admin/GrantPnPHubSiteRightsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class GrantHubSiteRightsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GrantPnPHubSiteRightsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Grant-PnPHubSiteRights",new CommandParameter("Identity", "null"),new CommandParameter("Principals", "null"),new CommandParameter("Rights", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/InvokePnPSPRestMethodTests.cs b/Tests/Admin/InvokePnPSPRestMethodTests.cs new file mode 100644 index 000000000..51c873f6b --- /dev/null +++ b/Tests/Admin/InvokePnPSPRestMethodTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class InvokeSPRestMethodTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void InvokePnPSPRestMethodTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Invoke-PnPSPRestMethod",new CommandParameter("Method", "null"),new CommandParameter("Url", "null"),new CommandParameter("Content", "null"),new CommandParameter("ContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RegisterPnPHubSiteTests.cs b/Tests/Admin/RegisterPnPHubSiteTests.cs new file mode 100644 index 000000000..3f832a5e4 --- /dev/null +++ b/Tests/Admin/RegisterPnPHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RegisterHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RegisterPnPHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Register-PnPHubSite",new CommandParameter("Site", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPHomeSiteTests.cs b/Tests/Admin/RemovePnPHomeSiteTests.cs new file mode 100644 index 000000000..92566d0ba --- /dev/null +++ b/Tests/Admin/RemovePnPHomeSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveHomeSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPHomeSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPHomeSite",new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPHubSiteAssociationTests.cs b/Tests/Admin/RemovePnPHubSiteAssociationTests.cs new file mode 100644 index 000000000..3b356fb2a --- /dev/null +++ b/Tests/Admin/RemovePnPHubSiteAssociationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveHubSiteAssociationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPHubSiteAssociationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPHubSiteAssociation",new CommandParameter("Site", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs b/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs new file mode 100644 index 000000000..ec5e64ad2 --- /dev/null +++ b/Tests/Admin/RemovePnPKnowledgeHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveKnowledgeHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPKnowledgeHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPKnowledgeHubSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs b/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs new file mode 100644 index 000000000..3bb731ce9 --- /dev/null +++ b/Tests/Admin/RemovePnPOrgAssetsLibraryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveOrgAssetsLibraryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPOrgAssetsLibraryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPOrgAssetsLibrary",new CommandParameter("LibraryUrl", "null"),new CommandParameter("ShouldRemoveFromCdn", "null"),new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPOrgNewsSiteTests.cs b/Tests/Admin/RemovePnPOrgNewsSiteTests.cs new file mode 100644 index 000000000..2ce92e694 --- /dev/null +++ b/Tests/Admin/RemovePnPOrgNewsSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveOrgNewsSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPOrgNewsSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPOrgNewsSite",new CommandParameter("OrgNewsSiteUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs b/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs new file mode 100644 index 000000000..ce5de5b71 --- /dev/null +++ b/Tests/Admin/RemovePnPSiteCollectionAppCatalogTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveSiteCollectionAppCatalogTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPSiteCollectionAppCatalogTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPSiteCollectionAppCatalog",new CommandParameter("Site", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPTenantCdnOriginTests.cs b/Tests/Admin/RemovePnPTenantCdnOriginTests.cs new file mode 100644 index 000000000..51df7f601 --- /dev/null +++ b/Tests/Admin/RemovePnPTenantCdnOriginTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveTenantCdnOriginTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPTenantCdnOriginTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPTenantCdnOrigin",new CommandParameter("OriginUrl", "null"),new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RemovePnPTenantThemeTests.cs b/Tests/Admin/RemovePnPTenantThemeTests.cs new file mode 100644 index 000000000..9dcd6b77b --- /dev/null +++ b/Tests/Admin/RemovePnPTenantThemeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RemoveTenantThemeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPTenantThemeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPTenantTheme",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/RevokePnPHubSiteRightsTests.cs b/Tests/Admin/RevokePnPHubSiteRightsTests.cs new file mode 100644 index 000000000..c3061d58c --- /dev/null +++ b/Tests/Admin/RevokePnPHubSiteRightsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class RevokeHubSiteRightsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RevokePnPHubSiteRightsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Revoke-PnPHubSiteRights",new CommandParameter("Identity", "null"),new CommandParameter("Principals", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPHideDefaultThemesTests.cs b/Tests/Admin/SetPnPHideDefaultThemesTests.cs new file mode 100644 index 000000000..84f6d03ed --- /dev/null +++ b/Tests/Admin/SetPnPHideDefaultThemesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetHideDefaultThemesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPHideDefaultThemesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPHideDefaultThemes",new CommandParameter("HideDefaultThemes", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPHomeSiteTests.cs b/Tests/Admin/SetPnPHomeSiteTests.cs new file mode 100644 index 000000000..5e0737a44 --- /dev/null +++ b/Tests/Admin/SetPnPHomeSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetHomeSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPHomeSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPHomeSite",new CommandParameter("Url", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPHubSiteTests.cs b/Tests/Admin/SetPnPHubSiteTests.cs new file mode 100644 index 000000000..84afd5cf0 --- /dev/null +++ b/Tests/Admin/SetPnPHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPHubSite",new CommandParameter("Identity", "null"),new CommandParameter("Title", "null"),new CommandParameter("LogoUrl", "null"),new CommandParameter("Description", "null"),new CommandParameter("SiteDesignId", "null"),new CommandParameter("HideNameInNavigation", "null"),new CommandParameter("RequiresJoinApproval", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs b/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs new file mode 100644 index 000000000..7eb9957a0 --- /dev/null +++ b/Tests/Admin/SetPnPKnowledgeHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetKnowledgeHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPKnowledgeHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPKnowledgeHubSite",new CommandParameter("KnowledgeHubSiteUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPTenantCdnEnabledTests.cs b/Tests/Admin/SetPnPTenantCdnEnabledTests.cs new file mode 100644 index 000000000..3520ea840 --- /dev/null +++ b/Tests/Admin/SetPnPTenantCdnEnabledTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetTenantCdnEnabledTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPTenantCdnEnabledTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTenantCdnEnabled",new CommandParameter("NoDefaultOrigins", "null"),new CommandParameter("Enable", "null"),new CommandParameter("CdnType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPTenantCdnPolicyTests.cs b/Tests/Admin/SetPnPTenantCdnPolicyTests.cs new file mode 100644 index 000000000..366a3872f --- /dev/null +++ b/Tests/Admin/SetPnPTenantCdnPolicyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetTenantCdnPolicyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPTenantCdnPolicyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTenantCdnPolicy",new CommandParameter("CdnType", "null"),new CommandParameter("PolicyType", "null"),new CommandParameter("PolicyValue", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs b/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs new file mode 100644 index 000000000..fad2cdc29 --- /dev/null +++ b/Tests/Admin/SetPnPTenantSyncClientRestrictionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetTenantSyncClientRestrictionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPTenantSyncClientRestrictionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTenantSyncClientRestriction",new CommandParameter("BlockMacSync", "null"),new CommandParameter("DisableReportProblemDialog", "null"),new CommandParameter("DomainGuids", "null"),new CommandParameter("Enable", "null"),new CommandParameter("ExcludedFileExtensions", "null"),new CommandParameter("GrooveBlockOption", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/SetPnPTenantTests.cs b/Tests/Admin/SetPnPTenantTests.cs new file mode 100644 index 000000000..75f173ac6 --- /dev/null +++ b/Tests/Admin/SetPnPTenantTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class SetTenantTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPTenantTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTenant",new CommandParameter("SpecialCharactersStateInFileFolderNames", "null"),new CommandParameter("MinCompatibilityLevel", "null"),new CommandParameter("MaxCompatibilityLevel", "null"),new CommandParameter("ExternalServicesEnabled", "null"),new CommandParameter("NoAccessRedirectUrl", "null"),new CommandParameter("SharingCapability", "null"),new CommandParameter("DisplayStartASiteOption", "null"),new CommandParameter("StartASiteFormUrl", "null"),new CommandParameter("ShowEveryoneClaim", "null"),new CommandParameter("ShowAllUsersClaim", "null"),new CommandParameter("ShowEveryoneExceptExternalUsersClaim", "null"),new CommandParameter("SearchResolveExactEmailOrUPN", "null"),new CommandParameter("OfficeClientADALDisabled", "null"),new CommandParameter("LegacyAuthProtocolsEnabled", "null"),new CommandParameter("RequireAcceptingAccountMatchInvitedAccount", "null"),new CommandParameter("ProvisionSharedWithEveryoneFolder", "null"),new CommandParameter("SignInAccelerationDomain", "null"),new CommandParameter("EnableGuestSignInAcceleration", "null"),new CommandParameter("UsePersistentCookiesForExplorerView", "null"),new CommandParameter("BccExternalSharingInvitations", "null"),new CommandParameter("BccExternalSharingInvitationsList", "null"),new CommandParameter("UserVoiceForFeedbackEnabled", "null"),new CommandParameter("PublicCdnEnabled", "null"),new CommandParameter("PublicCdnAllowedFileTypes", "null"),new CommandParameter("RequireAnonymousLinksExpireInDays", "null"),new CommandParameter("SharingAllowedDomainList", "null"),new CommandParameter("SharingBlockedDomainList", "null"),new CommandParameter("SharingDomainRestrictionMode", "null"),new CommandParameter("OneDriveStorageQuota", "null"),new CommandParameter("OneDriveForGuestsEnabled", "null"),new CommandParameter("IPAddressEnforcement", "null"),new CommandParameter("IPAddressAllowList", "null"),new CommandParameter("IPAddressWACTokenLifetime", "null"),new CommandParameter("UseFindPeopleInPeoplePicker", "null"),new CommandParameter("DefaultSharingLinkType", "null"),new CommandParameter("ODBMembersCanShare", "null"),new CommandParameter("ODBAccessRequests", "null"),new CommandParameter("PreventExternalUsersFromResharing", "null"),new CommandParameter("ShowPeoplePickerSuggestionsForGuestUsers", "null"),new CommandParameter("FileAnonymousLinkType", "null"),new CommandParameter("FolderAnonymousLinkType", "null"),new CommandParameter("NotifyOwnersWhenItemsReshared", "null"),new CommandParameter("NotifyOwnersWhenInvitationsAccepted", "null"),new CommandParameter("NotificationsInOneDriveForBusinessEnabled", "null"),new CommandParameter("NotificationsInSharePointEnabled", "null"),new CommandParameter("OwnerAnonymousNotification", "null"),new CommandParameter("CommentsOnSitePagesDisabled", "null"),new CommandParameter("SocialBarOnSitePagesDisabled", "null"),new CommandParameter("OrphanedPersonalSitesRetentionPeriod", "null"),new CommandParameter("DisallowInfectedFileDownload", "null"),new CommandParameter("DefaultLinkPermission", "null"),new CommandParameter("ConditionalAccessPolicy", "null"),new CommandParameter("AllowDownloadingNonWebViewableFiles", "null"),new CommandParameter("AllowEditing", "null"),new CommandParameter("ApplyAppEnforcedRestrictionsToAdHocRecipients", "null"),new CommandParameter("FilePickerExternalImageSearchEnabled", "null"),new CommandParameter("EmailAttestationRequired", "null"),new CommandParameter("EmailAttestationReAuthDays", "null"),new CommandParameter("HideDefaultThemes", "null"),new CommandParameter("DisabledWebPartIds", "null"),new CommandParameter("EnableAIPIntegration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Admin/UnregisterPnPHubSiteTests.cs b/Tests/Admin/UnregisterPnPHubSiteTests.cs new file mode 100644 index 000000000..2518a919d --- /dev/null +++ b/Tests/Admin/UnregisterPnPHubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Admin +{ + + [TestClass] + public class UnregisterHubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UnregisterPnPHubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Unregister-PnPHubSite",new CommandParameter("Site", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Readme.md b/Tests/Readme.md new file mode 100644 index 000000000..6d8fecb81 --- /dev/null +++ b/Tests/Readme.md @@ -0,0 +1,9 @@ +# Unit tests + +These are organised to match the same folder structure as the cmdlets for easy findability and association of tests. + + +## Useful attributes on a test + +* [Priority] - assigns priority in tests +* [Ignore] - disables the test diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 591bd42db..7bb3788ca 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -345,6 +345,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -354,6 +396,7 @@ + @@ -369,6 +412,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always @@ -380,6 +490,18 @@ Designer + + + + + + + + + + + + @@ -387,6 +509,46 @@ SharePointPnP.PowerShell.Commands + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7d61bef25221ae85d71e722a082a4d11bd9735e2 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:48:18 +0100 Subject: [PATCH 063/130] Added App Tests Placeholder --- Tests/Apps/AddPnPAppTests.cs | 63 +++++++++++++++++++ ...tServicePrincipalPermissionRequestTests.cs | 63 +++++++++++++++++++ ...tServicePrincipalPermissionRequestTests.cs | 63 +++++++++++++++++++ .../DisablePnPTenantServicePrincipalTests.cs | 63 +++++++++++++++++++ .../EnablePnPTenantServicePrincipalTests.cs | 63 +++++++++++++++++++ Tests/Apps/GetPnPAppInstanceTests.cs | 63 +++++++++++++++++++ Tests/Apps/GetPnPAppTests.cs | 63 +++++++++++++++++++ ...ntServicePrincipalPermissionGrantsTests.cs | 63 +++++++++++++++++++ ...ServicePrincipalPermissionRequestsTests.cs | 63 +++++++++++++++++++ .../Apps/GetPnPTenantServicePrincipalTests.cs | 63 +++++++++++++++++++ ...nPTenantServicePrincipalPermissionTests.cs | 63 +++++++++++++++++++ Tests/Apps/ImportPnPAppPackageTests.cs | 63 +++++++++++++++++++ Tests/Apps/InstallPnPAppTests.cs | 63 +++++++++++++++++++ Tests/Apps/PublishPnPAppTests.cs | 63 +++++++++++++++++++ Tests/Apps/RegisterPnPAppCatalogSiteTests.cs | 63 +++++++++++++++++++ Tests/Apps/RemovePnPAppTests.cs | 63 +++++++++++++++++++ ...nPTenantServicePrincipalPermissionTests.cs | 63 +++++++++++++++++++ Tests/Apps/SyncPnPAppToTeamsTests.cs | 63 +++++++++++++++++++ Tests/Apps/UninstallPnPAppInstanceTests.cs | 63 +++++++++++++++++++ Tests/Apps/UninstallPnPAppTests.cs | 63 +++++++++++++++++++ Tests/Apps/UnpublishPnPAppTests.cs | 63 +++++++++++++++++++ Tests/Apps/UpdatePnPAppTests.cs | 63 +++++++++++++++++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 23 ++++++- 23 files changed, 1408 insertions(+), 1 deletion(-) create mode 100644 Tests/Apps/AddPnPAppTests.cs create mode 100644 Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs create mode 100644 Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs create mode 100644 Tests/Apps/DisablePnPTenantServicePrincipalTests.cs create mode 100644 Tests/Apps/EnablePnPTenantServicePrincipalTests.cs create mode 100644 Tests/Apps/GetPnPAppInstanceTests.cs create mode 100644 Tests/Apps/GetPnPAppTests.cs create mode 100644 Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs create mode 100644 Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs create mode 100644 Tests/Apps/GetPnPTenantServicePrincipalTests.cs create mode 100644 Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs create mode 100644 Tests/Apps/ImportPnPAppPackageTests.cs create mode 100644 Tests/Apps/InstallPnPAppTests.cs create mode 100644 Tests/Apps/PublishPnPAppTests.cs create mode 100644 Tests/Apps/RegisterPnPAppCatalogSiteTests.cs create mode 100644 Tests/Apps/RemovePnPAppTests.cs create mode 100644 Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs create mode 100644 Tests/Apps/SyncPnPAppToTeamsTests.cs create mode 100644 Tests/Apps/UninstallPnPAppInstanceTests.cs create mode 100644 Tests/Apps/UninstallPnPAppTests.cs create mode 100644 Tests/Apps/UnpublishPnPAppTests.cs create mode 100644 Tests/Apps/UpdatePnPAppTests.cs diff --git a/Tests/Apps/AddPnPAppTests.cs b/Tests/Apps/AddPnPAppTests.cs new file mode 100644 index 000000000..9738d9052 --- /dev/null +++ b/Tests/Apps/AddPnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class AddAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPApp",new CommandParameter("Path", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Publish", "null"),new CommandParameter("SkipFeatureDeployment", "null"),new CommandParameter("Overwrite", "null"),new CommandParameter("Timeout", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs b/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs new file mode 100644 index 000000000..488eeb542 --- /dev/null +++ b/Tests/Apps/ApprovePnPTenantServicePrincipalPermissionRequestTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class ApproveTenantServicePrincipalPermissionRequestsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ApprovePnPTenantServicePrincipalPermissionRequestTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Approve-PnPTenantServicePrincipalPermissionRequest",new CommandParameter("RequestId", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs b/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs new file mode 100644 index 000000000..f7b81c7ee --- /dev/null +++ b/Tests/Apps/DenyPnPTenantServicePrincipalPermissionRequestTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class DenyTenantServicePrincipalPermissionRequestsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DenyPnPTenantServicePrincipalPermissionRequestTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Deny-PnPTenantServicePrincipalPermissionRequest",new CommandParameter("RequestId", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs b/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs new file mode 100644 index 000000000..ce9cf4346 --- /dev/null +++ b/Tests/Apps/DisablePnPTenantServicePrincipalTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class DisableTenantServicePrincipalTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPTenantServicePrincipalTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPTenantServicePrincipal",new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs b/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs new file mode 100644 index 000000000..ed6bb2e06 --- /dev/null +++ b/Tests/Apps/EnablePnPTenantServicePrincipalTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class EnableTenantServicePrincipalTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPTenantServicePrincipalTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPTenantServicePrincipal",new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/GetPnPAppInstanceTests.cs b/Tests/Apps/GetPnPAppInstanceTests.cs new file mode 100644 index 000000000..fdec1437f --- /dev/null +++ b/Tests/Apps/GetPnPAppInstanceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class GetAppInstanceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAppInstanceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAppInstance",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/GetPnPAppTests.cs b/Tests/Apps/GetPnPAppTests.cs new file mode 100644 index 000000000..fde5dfac2 --- /dev/null +++ b/Tests/Apps/GetPnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class GetAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs b/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs new file mode 100644 index 000000000..76ba19714 --- /dev/null +++ b/Tests/Apps/GetPnPTenantServicePrincipalPermissionGrantsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class GetTenantServicePrincipalPermissionGrantsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantServicePrincipalPermissionGrantsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantServicePrincipalPermissionGrants"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs b/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs new file mode 100644 index 000000000..66f47be94 --- /dev/null +++ b/Tests/Apps/GetPnPTenantServicePrincipalPermissionRequestsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class GetTenantServicePrincipalPermissionRequestsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantServicePrincipalPermissionRequestsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantServicePrincipalPermissionRequests"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/GetPnPTenantServicePrincipalTests.cs b/Tests/Apps/GetPnPTenantServicePrincipalTests.cs new file mode 100644 index 000000000..3c5a4089a --- /dev/null +++ b/Tests/Apps/GetPnPTenantServicePrincipalTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class GetTenantServicePrincipalTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantServicePrincipalTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantServicePrincipal"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs b/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs new file mode 100644 index 000000000..c8cef1b75 --- /dev/null +++ b/Tests/Apps/GrantPnPTenantServicePrincipalPermissionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class GrantTenantServicePrincipalPermissionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GrantPnPTenantServicePrincipalPermissionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Grant-PnPTenantServicePrincipalPermission",new CommandParameter("Scope", "null"),new CommandParameter("Resource", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/ImportPnPAppPackageTests.cs b/Tests/Apps/ImportPnPAppPackageTests.cs new file mode 100644 index 000000000..6a319777f --- /dev/null +++ b/Tests/Apps/ImportPnPAppPackageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class ImportAppPackageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ImportPnPAppPackageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Import-PnPAppPackage",new CommandParameter("Path", "null"),new CommandParameter("Force", "null"),new CommandParameter("LoadOnly", "null"),new CommandParameter("Locale", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/InstallPnPAppTests.cs b/Tests/Apps/InstallPnPAppTests.cs new file mode 100644 index 000000000..702ddfa85 --- /dev/null +++ b/Tests/Apps/InstallPnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class InstallAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void InstallPnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Install-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Wait", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/PublishPnPAppTests.cs b/Tests/Apps/PublishPnPAppTests.cs new file mode 100644 index 000000000..f445d9366 --- /dev/null +++ b/Tests/Apps/PublishPnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class PublishAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void PublishPnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Publish-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("SkipFeatureDeployment", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs b/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs new file mode 100644 index 000000000..dcea6e4e6 --- /dev/null +++ b/Tests/Apps/RegisterPnPAppCatalogSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class RegisterAppCatalogSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RegisterPnPAppCatalogSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Register-PnPAppCatalogSite",new CommandParameter("Url", "null"),new CommandParameter("Owner", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/RemovePnPAppTests.cs b/Tests/Apps/RemovePnPAppTests.cs new file mode 100644 index 000000000..0353b06e5 --- /dev/null +++ b/Tests/Apps/RemovePnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class RemoveAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs b/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs new file mode 100644 index 000000000..3f101898f --- /dev/null +++ b/Tests/Apps/RevokePnPTenantServicePrincipalPermissionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class RevokeTenantServicePrincipalTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RevokePnPTenantServicePrincipalPermissionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Revoke-PnPTenantServicePrincipalPermission",new CommandParameter("ObjectId", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/SyncPnPAppToTeamsTests.cs b/Tests/Apps/SyncPnPAppToTeamsTests.cs new file mode 100644 index 000000000..01d714cea --- /dev/null +++ b/Tests/Apps/SyncPnPAppToTeamsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class SyncAppToTeamsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SyncPnPAppToTeamsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Sync-PnPAppToTeams",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/UninstallPnPAppInstanceTests.cs b/Tests/Apps/UninstallPnPAppInstanceTests.cs new file mode 100644 index 000000000..8a246f9d6 --- /dev/null +++ b/Tests/Apps/UninstallPnPAppInstanceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class UninstallAppInstanceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UninstallPnPAppInstanceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Uninstall-PnPAppInstance",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/UninstallPnPAppTests.cs b/Tests/Apps/UninstallPnPAppTests.cs new file mode 100644 index 000000000..0c3a75cbf --- /dev/null +++ b/Tests/Apps/UninstallPnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class UninstallAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UninstallPnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Uninstall-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/UnpublishPnPAppTests.cs b/Tests/Apps/UnpublishPnPAppTests.cs new file mode 100644 index 000000000..beacb7691 --- /dev/null +++ b/Tests/Apps/UnpublishPnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class UnpublishAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UnpublishPnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Unpublish-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Apps/UpdatePnPAppTests.cs b/Tests/Apps/UpdatePnPAppTests.cs new file mode 100644 index 000000000..a88d2534e --- /dev/null +++ b/Tests/Apps/UpdatePnPAppTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Apps +{ + + [TestClass] + public class UpdateAppTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UpdatePnPAppTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Update-PnPApp",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 7bb3788ca..735b08b32 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -387,6 +387,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -510,7 +532,6 @@ - From a0e487732a1432f81ed3320577df28547e4c6ddd Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:49:14 +0100 Subject: [PATCH 064/130] Added placeholder base tests --- Tests/Base/AddPnPStoredCredentialTests.cs | 63 +++++++++++++++++++ Tests/Base/ConnectPnPOnlineTests.cs | 63 +++++++++++++++++++ .../DisablePnPPowerShellTelemetryTests.cs | 63 +++++++++++++++++++ Tests/Base/DisconnectPnPOnlineTests.cs | 63 +++++++++++++++++++ .../Base/EnablePnPPowerShellTelemetryTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPAccessTokenTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPAppAuthAccessTokenTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPAzureCertificateTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPConnectionTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPContextTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPExceptionTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPGraphAccessTokenTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPHealthScoreTests.cs | 63 +++++++++++++++++++ .../GetPnPPowerShellTelemetryEnabledTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPPropertyTests.cs | 63 +++++++++++++++++++ Tests/Base/GetPnPStoredCredentialTests.cs | 63 +++++++++++++++++++ ...tializePnPPowerShellAuthenticationTests.cs | 63 +++++++++++++++++++ Tests/Base/InvokePnPQueryTests.cs | 63 +++++++++++++++++++ Tests/Base/NewPnPAzureCertificateTests.cs | 63 +++++++++++++++++++ Tests/Base/RemovePnPStoredCredentialTests.cs | 63 +++++++++++++++++++ Tests/Base/RequestPnPAccessTokenTests.cs | 63 +++++++++++++++++++ Tests/Base/SetPnPContextTests.cs | 63 +++++++++++++++++++ Tests/Base/SetPnPTraceLogTests.cs | 63 +++++++++++++++++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 24 ++++++- 24 files changed, 1472 insertions(+), 1 deletion(-) create mode 100644 Tests/Base/AddPnPStoredCredentialTests.cs create mode 100644 Tests/Base/ConnectPnPOnlineTests.cs create mode 100644 Tests/Base/DisablePnPPowerShellTelemetryTests.cs create mode 100644 Tests/Base/DisconnectPnPOnlineTests.cs create mode 100644 Tests/Base/EnablePnPPowerShellTelemetryTests.cs create mode 100644 Tests/Base/GetPnPAccessTokenTests.cs create mode 100644 Tests/Base/GetPnPAppAuthAccessTokenTests.cs create mode 100644 Tests/Base/GetPnPAzureCertificateTests.cs create mode 100644 Tests/Base/GetPnPConnectionTests.cs create mode 100644 Tests/Base/GetPnPContextTests.cs create mode 100644 Tests/Base/GetPnPExceptionTests.cs create mode 100644 Tests/Base/GetPnPGraphAccessTokenTests.cs create mode 100644 Tests/Base/GetPnPHealthScoreTests.cs create mode 100644 Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs create mode 100644 Tests/Base/GetPnPPropertyTests.cs create mode 100644 Tests/Base/GetPnPStoredCredentialTests.cs create mode 100644 Tests/Base/InitializePnPPowerShellAuthenticationTests.cs create mode 100644 Tests/Base/InvokePnPQueryTests.cs create mode 100644 Tests/Base/NewPnPAzureCertificateTests.cs create mode 100644 Tests/Base/RemovePnPStoredCredentialTests.cs create mode 100644 Tests/Base/RequestPnPAccessTokenTests.cs create mode 100644 Tests/Base/SetPnPContextTests.cs create mode 100644 Tests/Base/SetPnPTraceLogTests.cs diff --git a/Tests/Base/AddPnPStoredCredentialTests.cs b/Tests/Base/AddPnPStoredCredentialTests.cs new file mode 100644 index 000000000..e8fecb1ac --- /dev/null +++ b/Tests/Base/AddPnPStoredCredentialTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class AddStoredCredentialTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPStoredCredentialTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPStoredCredential",new CommandParameter("Name", "null"),new CommandParameter("Username", "null"),new CommandParameter("Password", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/ConnectPnPOnlineTests.cs b/Tests/Base/ConnectPnPOnlineTests.cs new file mode 100644 index 000000000..1d87891da --- /dev/null +++ b/Tests/Base/ConnectPnPOnlineTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class ConnectOnlineTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ConnectPnPOnlineTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Connect-PnPOnline",new CommandParameter("ReturnConnection", "null"),new CommandParameter("Url", "null"),new CommandParameter("Credentials", "null"),new CommandParameter("CurrentCredentials", "null"),new CommandParameter("UseAdfs", "null"),new CommandParameter("UseAdfsCert", "null"),new CommandParameter("ClientCertificate", "null"),new CommandParameter("Kerberos", "null"),new CommandParameter("LoginProviderName", "null"),new CommandParameter("MinimalHealthScore", "null"),new CommandParameter("RetryCount", "null"),new CommandParameter("RetryWait", "null"),new CommandParameter("RequestTimeout", "null"),new CommandParameter("Realm", "null"),new CommandParameter("AppId", "null"),new CommandParameter("AppSecret", "null"),new CommandParameter("ClientSecret", "null"),new CommandParameter("UseWebLogin", "null"),new CommandParameter("AuthenticationMode", "null"),new CommandParameter("CreateDrive", "null"),new CommandParameter("DriveName", "null"),new CommandParameter("SPOManagementShell", "null"),new CommandParameter("PnPO365ManagementShell", "null"),new CommandParameter("LaunchBrowser", "null"),new CommandParameter("Graph", "null"),new CommandParameter("ClientId", "null"),new CommandParameter("RedirectUri", "null"),new CommandParameter("Tenant", "null"),new CommandParameter("CertificatePath", "null"),new CommandParameter("CertificateBase64Encoded", "null"),new CommandParameter("Certificate", "null"),new CommandParameter("CertificatePassword", "null"),new CommandParameter("PEMCertificate", "null"),new CommandParameter("PEMPrivateKey", "null"),new CommandParameter("Thumbprint", "null"),new CommandParameter("ClearTokenCache", "null"),new CommandParameter("AzureEnvironment", "null"),new CommandParameter("Scopes", "null"),new CommandParameter("AADDomain", "null"),new CommandParameter("AccessToken", "null"),new CommandParameter("TenantAdminUrl", "null"),new CommandParameter("SkipTenantAdminCheck", "null"),new CommandParameter("IgnoreSslErrors", "null"),new CommandParameter("NoTelemetry", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/DisablePnPPowerShellTelemetryTests.cs b/Tests/Base/DisablePnPPowerShellTelemetryTests.cs new file mode 100644 index 000000000..e19398735 --- /dev/null +++ b/Tests/Base/DisablePnPPowerShellTelemetryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class DisablePowerShellTelemetryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPPowerShellTelemetryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPPowerShellTelemetry",new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/DisconnectPnPOnlineTests.cs b/Tests/Base/DisconnectPnPOnlineTests.cs new file mode 100644 index 000000000..d11eee57f --- /dev/null +++ b/Tests/Base/DisconnectPnPOnlineTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class DisconnectOnlineTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisconnectPnPOnlineTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disconnect-PnPOnline",new CommandParameter("Connection", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/EnablePnPPowerShellTelemetryTests.cs b/Tests/Base/EnablePnPPowerShellTelemetryTests.cs new file mode 100644 index 000000000..068b09af7 --- /dev/null +++ b/Tests/Base/EnablePnPPowerShellTelemetryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class EnablePowerShellTelemetryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPPowerShellTelemetryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPPowerShellTelemetry",new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPAccessTokenTests.cs b/Tests/Base/GetPnPAccessTokenTests.cs new file mode 100644 index 000000000..92c75266c --- /dev/null +++ b/Tests/Base/GetPnPAccessTokenTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetPnPAccessTokenTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAccessTokenTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAccessToken",new CommandParameter("Decoded", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPAppAuthAccessTokenTests.cs b/Tests/Base/GetPnPAppAuthAccessTokenTests.cs new file mode 100644 index 000000000..8c22939c3 --- /dev/null +++ b/Tests/Base/GetPnPAppAuthAccessTokenTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetPnPAppAuthAccessTokenTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAppAuthAccessTokenTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAppAuthAccessToken"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPAzureCertificateTests.cs b/Tests/Base/GetPnPAzureCertificateTests.cs new file mode 100644 index 000000000..dee4b0308 --- /dev/null +++ b/Tests/Base/GetPnPAzureCertificateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetPnPAdalCertificateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAzureCertificateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAzureCertificate",new CommandParameter("CertificatePath", "null"),new CommandParameter("CertificatePassword", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPConnectionTests.cs b/Tests/Base/GetPnPConnectionTests.cs new file mode 100644 index 000000000..ed3f5fd90 --- /dev/null +++ b/Tests/Base/GetPnPConnectionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetPnPConnectionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPConnectionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPConnection"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPContextTests.cs b/Tests/Base/GetPnPContextTests.cs new file mode 100644 index 000000000..ed58db961 --- /dev/null +++ b/Tests/Base/GetPnPContextTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetSPOContextTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPContextTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPContext"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPExceptionTests.cs b/Tests/Base/GetPnPExceptionTests.cs new file mode 100644 index 000000000..f04d4e101 --- /dev/null +++ b/Tests/Base/GetPnPExceptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetExceptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPExceptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPException",new CommandParameter("All", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPGraphAccessTokenTests.cs b/Tests/Base/GetPnPGraphAccessTokenTests.cs new file mode 100644 index 000000000..3031b4006 --- /dev/null +++ b/Tests/Base/GetPnPGraphAccessTokenTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetGraphAccessTokenTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPGraphAccessTokenTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPGraphAccessToken",new CommandParameter("Decoded", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPHealthScoreTests.cs b/Tests/Base/GetPnPHealthScoreTests.cs new file mode 100644 index 000000000..b6b41b5a9 --- /dev/null +++ b/Tests/Base/GetPnPHealthScoreTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetHealthScoreTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPHealthScoreTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPHealthScore",new CommandParameter("Url", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs b/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs new file mode 100644 index 000000000..5dc3eb330 --- /dev/null +++ b/Tests/Base/GetPnPPowerShellTelemetryEnabledTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetPowerShellTelemetryEnabledTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPPowerShellTelemetryEnabledTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPPowerShellTelemetryEnabled"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPPropertyTests.cs b/Tests/Base/GetPnPPropertyTests.cs new file mode 100644 index 000000000..8b9e81661 --- /dev/null +++ b/Tests/Base/GetPnPPropertyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class EnsurePropertyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPPropertyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPProperty",new CommandParameter("ClientObject", "null"),new CommandParameter("Property", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/GetPnPStoredCredentialTests.cs b/Tests/Base/GetPnPStoredCredentialTests.cs new file mode 100644 index 000000000..cb825b7bf --- /dev/null +++ b/Tests/Base/GetPnPStoredCredentialTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class GetStoredCredentialTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPStoredCredentialTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPStoredCredential",new CommandParameter("Name", "null"),new CommandParameter("Type", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs b/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs new file mode 100644 index 000000000..777209634 --- /dev/null +++ b/Tests/Base/InitializePnPPowerShellAuthenticationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class InitializePowerShellAuthenticationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void InitializePnPPowerShellAuthenticationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Initialize-PnPPowerShellAuthentication",new CommandParameter("ApplicationName", "null"),new CommandParameter("Tenant", "null"),new CommandParameter("CertificatePath", "null"),new CommandParameter("CommonName", "null"),new CommandParameter("Country", "null"),new CommandParameter("State", "null"),new CommandParameter("Locality", "null"),new CommandParameter("Organization", "null"),new CommandParameter("OrganizationUnit", "null"),new CommandParameter("ValidYears", "null"),new CommandParameter("CertificatePassword", "null"),new CommandParameter("OutPath", "null"),new CommandParameter("Store", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/InvokePnPQueryTests.cs b/Tests/Base/InvokePnPQueryTests.cs new file mode 100644 index 000000000..96895f9d8 --- /dev/null +++ b/Tests/Base/InvokePnPQueryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class InvokeQueryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void InvokePnPQueryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Invoke-PnPQuery",new CommandParameter("RetryCount", "null"),new CommandParameter("RetryWait", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/NewPnPAzureCertificateTests.cs b/Tests/Base/NewPnPAzureCertificateTests.cs new file mode 100644 index 000000000..225edb3e8 --- /dev/null +++ b/Tests/Base/NewPnPAzureCertificateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class NewPnPAdalCertificateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPAzureCertificateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPAzureCertificate",new CommandParameter("CommonName", "null"),new CommandParameter("Country", "null"),new CommandParameter("State", "null"),new CommandParameter("Locality", "null"),new CommandParameter("Organization", "null"),new CommandParameter("OrganizationUnit", "null"),new CommandParameter("Out", "null"),new CommandParameter("OutPfx", "null"),new CommandParameter("OutCert", "null"),new CommandParameter("ValidYears", "null"),new CommandParameter("CertificatePassword", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/RemovePnPStoredCredentialTests.cs b/Tests/Base/RemovePnPStoredCredentialTests.cs new file mode 100644 index 000000000..53504fff8 --- /dev/null +++ b/Tests/Base/RemovePnPStoredCredentialTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class RemoveStoredCredentialTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPStoredCredentialTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPStoredCredential",new CommandParameter("Name", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/RequestPnPAccessTokenTests.cs b/Tests/Base/RequestPnPAccessTokenTests.cs new file mode 100644 index 000000000..a0855ad12 --- /dev/null +++ b/Tests/Base/RequestPnPAccessTokenTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class RequestAccessTokenTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RequestPnPAccessTokenTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Request-PnPAccessToken",new CommandParameter("ClientId", "null"),new CommandParameter("Resource", "null"),new CommandParameter("Scopes", "null"),new CommandParameter("Decoded", "null"),new CommandParameter("SetAsCurrent", "null"),new CommandParameter("Credentials", "null"),new CommandParameter("TenantUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/SetPnPContextTests.cs b/Tests/Base/SetPnPContextTests.cs new file mode 100644 index 000000000..b683aae21 --- /dev/null +++ b/Tests/Base/SetPnPContextTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class SetContextTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPContextTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPContext",new CommandParameter("Context", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Base/SetPnPTraceLogTests.cs b/Tests/Base/SetPnPTraceLogTests.cs new file mode 100644 index 000000000..69f449c1a --- /dev/null +++ b/Tests/Base/SetPnPTraceLogTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Base +{ + + [TestClass] + public class SetTraceLogTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPTraceLogTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTraceLog",new CommandParameter("On", "null"),new CommandParameter("LogFile", "null"),new CommandParameter("WriteToConsole", "null"),new CommandParameter("Level", "null"),new CommandParameter("Delimiter", "null"),new CommandParameter("IndentSize", "null"),new CommandParameter("AutoFlush", "null"),new CommandParameter("Off", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 735b08b32..04e347c82 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -410,6 +410,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -532,7 +555,6 @@ - From 542efce9a35938116311a1a1558585b95338b252 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:50:38 +0100 Subject: [PATCH 065/130] Added placeholder branding tests --- .../AddPnPApplicationCustomizerTests.cs | 63 ++++++++++++ Tests/Branding/AddPnPCustomActionTests.cs | 63 ++++++++++++ Tests/Branding/AddPnPJavaScriptBlockTests.cs | 63 ++++++++++++ Tests/Branding/AddPnPJavaScriptLinkTests.cs | 63 ++++++++++++ Tests/Branding/AddPnPNavigationNodeTests.cs | 63 ++++++++++++ Tests/Branding/DisablePnPResponsiveUITests.cs | 63 ++++++++++++ Tests/Branding/EnablePnPResponsiveUITests.cs | 63 ++++++++++++ .../GetPnPApplicationCustomizerTests.cs | 63 ++++++++++++ Tests/Branding/GetPnPCustomActionTests.cs | 63 ++++++++++++ Tests/Branding/GetPnPFooterTests.cs | 63 ++++++++++++ Tests/Branding/GetPnPHomePageTests.cs | 63 ++++++++++++ Tests/Branding/GetPnPJavaScriptLinkTests.cs | 63 ++++++++++++ Tests/Branding/GetPnPNavigationNodeTests.cs | 63 ++++++++++++ Tests/Branding/GetPnPThemeTests.cs | 63 ++++++++++++ .../RemovePnPApplicationCustomizerTests.cs | 63 ++++++++++++ Tests/Branding/RemovePnPCustomActionTests.cs | 63 ++++++++++++ .../Branding/RemovePnPJavaScriptLinkTests.cs | 63 ++++++++++++ .../Branding/RemovePnPNavigationNodeTests.cs | 63 ++++++++++++ .../SetPnPApplicationCustomizerTests.cs | 63 ++++++++++++ Tests/Branding/SetPnPFooterTests.cs | 63 ++++++++++++ Tests/Branding/SetPnPHomePageTests.cs | 63 ++++++++++++ Tests/Branding/SetPnPMasterPageTests.cs | 63 ++++++++++++ .../SetPnPMinimalDownloadStrategyTests.cs | 63 ++++++++++++ Tests/Branding/SetPnPThemeTests.cs | 63 ++++++++++++ Tests/Branding/SetPnPWebThemeTests.cs | 63 ++++++++++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 97 +++++-------------- 26 files changed, 1600 insertions(+), 72 deletions(-) create mode 100644 Tests/Branding/AddPnPApplicationCustomizerTests.cs create mode 100644 Tests/Branding/AddPnPCustomActionTests.cs create mode 100644 Tests/Branding/AddPnPJavaScriptBlockTests.cs create mode 100644 Tests/Branding/AddPnPJavaScriptLinkTests.cs create mode 100644 Tests/Branding/AddPnPNavigationNodeTests.cs create mode 100644 Tests/Branding/DisablePnPResponsiveUITests.cs create mode 100644 Tests/Branding/EnablePnPResponsiveUITests.cs create mode 100644 Tests/Branding/GetPnPApplicationCustomizerTests.cs create mode 100644 Tests/Branding/GetPnPCustomActionTests.cs create mode 100644 Tests/Branding/GetPnPFooterTests.cs create mode 100644 Tests/Branding/GetPnPHomePageTests.cs create mode 100644 Tests/Branding/GetPnPJavaScriptLinkTests.cs create mode 100644 Tests/Branding/GetPnPNavigationNodeTests.cs create mode 100644 Tests/Branding/GetPnPThemeTests.cs create mode 100644 Tests/Branding/RemovePnPApplicationCustomizerTests.cs create mode 100644 Tests/Branding/RemovePnPCustomActionTests.cs create mode 100644 Tests/Branding/RemovePnPJavaScriptLinkTests.cs create mode 100644 Tests/Branding/RemovePnPNavigationNodeTests.cs create mode 100644 Tests/Branding/SetPnPApplicationCustomizerTests.cs create mode 100644 Tests/Branding/SetPnPFooterTests.cs create mode 100644 Tests/Branding/SetPnPHomePageTests.cs create mode 100644 Tests/Branding/SetPnPMasterPageTests.cs create mode 100644 Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs create mode 100644 Tests/Branding/SetPnPThemeTests.cs create mode 100644 Tests/Branding/SetPnPWebThemeTests.cs diff --git a/Tests/Branding/AddPnPApplicationCustomizerTests.cs b/Tests/Branding/AddPnPApplicationCustomizerTests.cs new file mode 100644 index 000000000..a408ee397 --- /dev/null +++ b/Tests/Branding/AddPnPApplicationCustomizerTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class AddApplicationCustomizerTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPApplicationCustomizerTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPApplicationCustomizer",new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("ClientSideComponentProperties", "null"),new CommandParameter("ClientSideHostProperties", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/AddPnPCustomActionTests.cs b/Tests/Branding/AddPnPCustomActionTests.cs new file mode 100644 index 000000000..8d8a728ba --- /dev/null +++ b/Tests/Branding/AddPnPCustomActionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class AddCustomActionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPCustomActionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPCustomAction",new CommandParameter("Name", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Group", "null"),new CommandParameter("Location", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("Url", "null"),new CommandParameter("ImageUrl", "null"),new CommandParameter("CommandUIExtension", "null"),new CommandParameter("RegistrationId", "null"),new CommandParameter("Rights", "null"),new CommandParameter("RegistrationType", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("ClientSideComponentProperties", "null"),new CommandParameter("ClientSideHostProperties", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/AddPnPJavaScriptBlockTests.cs b/Tests/Branding/AddPnPJavaScriptBlockTests.cs new file mode 100644 index 000000000..e15b5093f --- /dev/null +++ b/Tests/Branding/AddPnPJavaScriptBlockTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class AddJavaScriptBlockTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPJavaScriptBlockTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPJavaScriptBlock",new CommandParameter("Name", "null"),new CommandParameter("Script", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("SiteScoped", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/AddPnPJavaScriptLinkTests.cs b/Tests/Branding/AddPnPJavaScriptLinkTests.cs new file mode 100644 index 000000000..5be44914b --- /dev/null +++ b/Tests/Branding/AddPnPJavaScriptLinkTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class AddJavaScriptLinkTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPJavaScriptLinkTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPJavaScriptLink",new CommandParameter("Name", "null"),new CommandParameter("Url", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("SiteScoped", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/AddPnPNavigationNodeTests.cs b/Tests/Branding/AddPnPNavigationNodeTests.cs new file mode 100644 index 000000000..34d55d2b0 --- /dev/null +++ b/Tests/Branding/AddPnPNavigationNodeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class AddNavigationNodeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPNavigationNodeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPNavigationNode",new CommandParameter("Location", "null"),new CommandParameter("Title", "null"),new CommandParameter("Url", "null"),new CommandParameter("Parent", "null"),new CommandParameter("Header", "null"),new CommandParameter("First", "null"),new CommandParameter("External", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/DisablePnPResponsiveUITests.cs b/Tests/Branding/DisablePnPResponsiveUITests.cs new file mode 100644 index 000000000..1d79492a7 --- /dev/null +++ b/Tests/Branding/DisablePnPResponsiveUITests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class DisableResponsiveUITests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPResponsiveUITest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPResponsiveUI"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/EnablePnPResponsiveUITests.cs b/Tests/Branding/EnablePnPResponsiveUITests.cs new file mode 100644 index 000000000..659604800 --- /dev/null +++ b/Tests/Branding/EnablePnPResponsiveUITests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class EnableResponsiveUITests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPResponsiveUITest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPResponsiveUI",new CommandParameter("InfrastructureSiteUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPApplicationCustomizerTests.cs b/Tests/Branding/GetPnPApplicationCustomizerTests.cs new file mode 100644 index 000000000..b604ae5b7 --- /dev/null +++ b/Tests/Branding/GetPnPApplicationCustomizerTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GetApplicationCustomizerTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPApplicationCustomizerTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPApplicationCustomizer",new CommandParameter("Identity", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ThrowExceptionIfCustomActionNotFound", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPCustomActionTests.cs b/Tests/Branding/GetPnPCustomActionTests.cs new file mode 100644 index 000000000..b0ff846dd --- /dev/null +++ b/Tests/Branding/GetPnPCustomActionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GetCustomActionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPCustomActionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPCustomAction",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ThrowExceptionIfCustomActionNotFound", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPFooterTests.cs b/Tests/Branding/GetPnPFooterTests.cs new file mode 100644 index 000000000..770118390 --- /dev/null +++ b/Tests/Branding/GetPnPFooterTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GettFooterTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPFooterTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPFooter"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPHomePageTests.cs b/Tests/Branding/GetPnPHomePageTests.cs new file mode 100644 index 000000000..2e86448a9 --- /dev/null +++ b/Tests/Branding/GetPnPHomePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GetHomePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPHomePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPHomePage"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPJavaScriptLinkTests.cs b/Tests/Branding/GetPnPJavaScriptLinkTests.cs new file mode 100644 index 000000000..6968faa4f --- /dev/null +++ b/Tests/Branding/GetPnPJavaScriptLinkTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GetJavaScriptLinkTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPJavaScriptLinkTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPJavaScriptLink",new CommandParameter("Name", "null"),new CommandParameter("Scope", "null"),new CommandParameter("ThrowExceptionIfJavaScriptLinkNotFound", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPNavigationNodeTests.cs b/Tests/Branding/GetPnPNavigationNodeTests.cs new file mode 100644 index 000000000..26acc2baf --- /dev/null +++ b/Tests/Branding/GetPnPNavigationNodeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GetNavigationNodeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPNavigationNodeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPNavigationNode",new CommandParameter("Location", "null"),new CommandParameter("Id", "null"),new CommandParameter("Tree", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/GetPnPThemeTests.cs b/Tests/Branding/GetPnPThemeTests.cs new file mode 100644 index 000000000..a3b4cbbf3 --- /dev/null +++ b/Tests/Branding/GetPnPThemeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class GetThemeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPThemeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTheme",new CommandParameter("DetectCurrentComposedLook", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/RemovePnPApplicationCustomizerTests.cs b/Tests/Branding/RemovePnPApplicationCustomizerTests.cs new file mode 100644 index 000000000..87db7904b --- /dev/null +++ b/Tests/Branding/RemovePnPApplicationCustomizerTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class RemoveApplicationCustomizerTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPApplicationCustomizerTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPApplicationCustomizer",new CommandParameter("Identity", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/RemovePnPCustomActionTests.cs b/Tests/Branding/RemovePnPCustomActionTests.cs new file mode 100644 index 000000000..8d44cc079 --- /dev/null +++ b/Tests/Branding/RemovePnPCustomActionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class RemoveCustomActionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPCustomActionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPCustomAction",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/RemovePnPJavaScriptLinkTests.cs b/Tests/Branding/RemovePnPJavaScriptLinkTests.cs new file mode 100644 index 000000000..b8cadc2fa --- /dev/null +++ b/Tests/Branding/RemovePnPJavaScriptLinkTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class RemoveJavaScriptLinkTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPJavaScriptLinkTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPJavaScriptLink",new CommandParameter("Identity", "null"),new CommandParameter("FromSite", "null"),new CommandParameter("Force", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/RemovePnPNavigationNodeTests.cs b/Tests/Branding/RemovePnPNavigationNodeTests.cs new file mode 100644 index 000000000..a6b2ca3f1 --- /dev/null +++ b/Tests/Branding/RemovePnPNavigationNodeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class RemoveNavigationNodeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPNavigationNodeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPNavigationNode",new CommandParameter("Identity", "null"),new CommandParameter("Location", "null"),new CommandParameter("Title", "null"),new CommandParameter("Header", "null"),new CommandParameter("All", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPApplicationCustomizerTests.cs b/Tests/Branding/SetPnPApplicationCustomizerTests.cs new file mode 100644 index 000000000..3ccf6f4e1 --- /dev/null +++ b/Tests/Branding/SetPnPApplicationCustomizerTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetApplicationCustomizerTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPApplicationCustomizerTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPApplicationCustomizer",new CommandParameter("Identity", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Sequence", "null"),new CommandParameter("ClientSideComponentProperties", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPFooterTests.cs b/Tests/Branding/SetPnPFooterTests.cs new file mode 100644 index 000000000..1e6245040 --- /dev/null +++ b/Tests/Branding/SetPnPFooterTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetFooterTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPFooterTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPFooter",new CommandParameter("Enabled", "null"),new CommandParameter("Layout", "null"),new CommandParameter("BackgroundTheme", "null"),new CommandParameter("Title", "null"),new CommandParameter("LogoUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPHomePageTests.cs b/Tests/Branding/SetPnPHomePageTests.cs new file mode 100644 index 000000000..5a52c20bd --- /dev/null +++ b/Tests/Branding/SetPnPHomePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetHomePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPHomePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPHomePage",new CommandParameter("RootFolderRelativeUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPMasterPageTests.cs b/Tests/Branding/SetPnPMasterPageTests.cs new file mode 100644 index 000000000..24d836fa8 --- /dev/null +++ b/Tests/Branding/SetPnPMasterPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetMasterPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPMasterPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPMasterPage",new CommandParameter("MasterPageServerRelativeUrl", "null"),new CommandParameter("CustomMasterPageServerRelativeUrl", "null"),new CommandParameter("MasterPageSiteRelativeUrl", "null"),new CommandParameter("CustomMasterPageSiteRelativeUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs b/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs new file mode 100644 index 000000000..22ad8cd61 --- /dev/null +++ b/Tests/Branding/SetPnPMinimalDownloadStrategyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetMinimalDownloadStrategyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPMinimalDownloadStrategyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPMinimalDownloadStrategy",new CommandParameter("On", "null"),new CommandParameter("Off", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPThemeTests.cs b/Tests/Branding/SetPnPThemeTests.cs new file mode 100644 index 000000000..7529605cb --- /dev/null +++ b/Tests/Branding/SetPnPThemeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetThemeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPThemeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTheme",new CommandParameter("ColorPaletteUrl", "null"),new CommandParameter("FontSchemeUrl", "null"),new CommandParameter("BackgroundImageUrl", "null"),new CommandParameter("ShareGenerated", "null"),new CommandParameter("ResetSubwebsToInherit", "null"),new CommandParameter("UpdateRootWebOnly", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Branding/SetPnPWebThemeTests.cs b/Tests/Branding/SetPnPWebThemeTests.cs new file mode 100644 index 000000000..46f6d1263 --- /dev/null +++ b/Tests/Branding/SetPnPWebThemeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Branding +{ + + [TestClass] + public class SetWebThemeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPWebThemeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPWebTheme",new CommandParameter("Theme", "null"),new CommandParameter("WebUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 04e347c82..1b58f5c95 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -433,6 +433,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -457,70 +482,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -535,13 +496,6 @@ Designer - - - - - - - @@ -555,7 +509,6 @@ - From eb20b0087d081f214410e2d416126a4e1ad83f89 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:51:22 +0100 Subject: [PATCH 066/130] Added placeholder client site page tests --- .../AddPnPClientSidePageSectionTests.cs | 63 +++++++++++++++++++ .../AddPnPClientSidePageTests.cs | 63 +++++++++++++++++++ .../AddPnPClientSideTextTests.cs | 63 +++++++++++++++++++ ...etPnPAvailableClientSideComponentsTests.cs | 63 +++++++++++++++++++ .../GetPnPClientSideComponentTests.cs | 63 +++++++++++++++++++ .../GetPnPClientSidePageTests.cs | 63 +++++++++++++++++++ .../MovePnPClientSideComponentTests.cs | 63 +++++++++++++++++++ .../RemovePnPClientSideComponentTests.cs | 63 +++++++++++++++++++ .../RemovePnPClientSidePageTests.cs | 63 +++++++++++++++++++ .../SetPnPClientSidePageTests.cs | 63 +++++++++++++++++++ .../SetPnPClientSideTextTests.cs | 63 +++++++++++++++++++ .../SetPnPClientSideWebPartTests.cs | 63 +++++++++++++++++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 13 +++- 13 files changed, 768 insertions(+), 1 deletion(-) create mode 100644 Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs create mode 100644 Tests/ClientSidePages/AddPnPClientSidePageTests.cs create mode 100644 Tests/ClientSidePages/AddPnPClientSideTextTests.cs create mode 100644 Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs create mode 100644 Tests/ClientSidePages/GetPnPClientSideComponentTests.cs create mode 100644 Tests/ClientSidePages/GetPnPClientSidePageTests.cs create mode 100644 Tests/ClientSidePages/MovePnPClientSideComponentTests.cs create mode 100644 Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs create mode 100644 Tests/ClientSidePages/RemovePnPClientSidePageTests.cs create mode 100644 Tests/ClientSidePages/SetPnPClientSidePageTests.cs create mode 100644 Tests/ClientSidePages/SetPnPClientSideTextTests.cs create mode 100644 Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs diff --git a/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs b/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs new file mode 100644 index 000000000..f425648fc --- /dev/null +++ b/Tests/ClientSidePages/AddPnPClientSidePageSectionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class AddClientSidePageSectionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPClientSidePageSectionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPClientSidePageSection",new CommandParameter("Page", "null"),new CommandParameter("SectionTemplate", "null"),new CommandParameter("Order", "null"),new CommandParameter("ZoneEmphasis", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/AddPnPClientSidePageTests.cs b/Tests/ClientSidePages/AddPnPClientSidePageTests.cs new file mode 100644 index 000000000..280360dc6 --- /dev/null +++ b/Tests/ClientSidePages/AddPnPClientSidePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class AddClientSidePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPClientSidePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPClientSidePage",new CommandParameter("Name", "null"),new CommandParameter("LayoutType", "null"),new CommandParameter("PromoteAs", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("CommentsEnabled", "null"),new CommandParameter("Publish", "null"),new CommandParameter("HeaderLayoutType", "null"),new CommandParameter("PublishMessage", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/AddPnPClientSideTextTests.cs b/Tests/ClientSidePages/AddPnPClientSideTextTests.cs new file mode 100644 index 000000000..9ec820f6d --- /dev/null +++ b/Tests/ClientSidePages/AddPnPClientSideTextTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class AddClientSideTextTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPClientSideTextTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPClientSideText",new CommandParameter("Page", "null"),new CommandParameter("Text", "null"),new CommandParameter("Order", "null"),new CommandParameter("Section", "null"),new CommandParameter("Column", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs b/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs new file mode 100644 index 000000000..148dd2aba --- /dev/null +++ b/Tests/ClientSidePages/GetPnPAvailableClientSideComponentsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class GetAvailableClientSideComponentsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAvailableClientSideComponentsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAvailableClientSideComponents",new CommandParameter("Page", "null"),new CommandParameter("Component", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs b/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs new file mode 100644 index 000000000..760fc5dc8 --- /dev/null +++ b/Tests/ClientSidePages/GetPnPClientSideComponentTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class GetClientSideControlTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPClientSideComponentTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPClientSideComponent",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/GetPnPClientSidePageTests.cs b/Tests/ClientSidePages/GetPnPClientSidePageTests.cs new file mode 100644 index 000000000..9ffc06cb8 --- /dev/null +++ b/Tests/ClientSidePages/GetPnPClientSidePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class GetClientSidePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPClientSidePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPClientSidePage",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs b/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs new file mode 100644 index 000000000..8a6b482ab --- /dev/null +++ b/Tests/ClientSidePages/MovePnPClientSideComponentTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class MoveClientSideWebPartTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MovePnPClientSideComponentTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Move-PnPClientSideComponent",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null"),new CommandParameter("Section", "null"),new CommandParameter("Column", "null"),new CommandParameter("Position", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs b/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs new file mode 100644 index 000000000..b2e08b76b --- /dev/null +++ b/Tests/ClientSidePages/RemovePnPClientSideComponentTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class RemoveClientSideComponentTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPClientSideComponentTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPClientSideComponent",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs b/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs new file mode 100644 index 000000000..d79f6de67 --- /dev/null +++ b/Tests/ClientSidePages/RemovePnPClientSidePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class RemoveClientSidePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPClientSidePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPClientSidePage",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/SetPnPClientSidePageTests.cs b/Tests/ClientSidePages/SetPnPClientSidePageTests.cs new file mode 100644 index 000000000..81af2cb5d --- /dev/null +++ b/Tests/ClientSidePages/SetPnPClientSidePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class SetClientSidePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPClientSidePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPClientSidePage",new CommandParameter("Identity", "null"),new CommandParameter("Name", "null"),new CommandParameter("Title", "null"),new CommandParameter("LayoutType", "null"),new CommandParameter("PromoteAs", "null"),new CommandParameter("CommentsEnabled", "null"),new CommandParameter("Publish", "null"),new CommandParameter("HeaderType", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("ThumbnailUrl", "null"),new CommandParameter("PublishMessage", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/SetPnPClientSideTextTests.cs b/Tests/ClientSidePages/SetPnPClientSideTextTests.cs new file mode 100644 index 000000000..cb067fa95 --- /dev/null +++ b/Tests/ClientSidePages/SetPnPClientSideTextTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class SetClientSideTextTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPClientSideTextTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPClientSideText",new CommandParameter("Page", "null"),new CommandParameter("InstanceId", "null"),new CommandParameter("Text", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs b/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs new file mode 100644 index 000000000..4d1abcfe5 --- /dev/null +++ b/Tests/ClientSidePages/SetPnPClientSideWebPartTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ClientSidePages +{ + + [TestClass] + public class SetClientSideWebPartTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPClientSideWebPartTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPClientSideWebPart",new CommandParameter("Page", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Title", "null"),new CommandParameter("PropertiesJson", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 1b58f5c95..18f18c6ba 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -458,6 +458,18 @@ + + + + + + + + + + + + @@ -509,7 +521,6 @@ - From fee7dd7012292b4ca86a60c11d882f1a836ed1db Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:52:38 +0100 Subject: [PATCH 067/130] Added placeholder content type tests --- Tests/ContentTypes/AddPnPContentTypeTests.cs | 63 +++++++++++++++++++ .../AddPnPContentTypeToListTests.cs | 63 +++++++++++++++++++ .../AddPnPFieldToContentTypeTests.cs | 63 +++++++++++++++++++ .../GetPnPContentTypePublishingHubUrlTests.cs | 63 +++++++++++++++++++ Tests/ContentTypes/GetPnPContentTypeTests.cs | 63 +++++++++++++++++++ .../RemovePnPContentTypeFromListTests.cs | 63 +++++++++++++++++++ .../ContentTypes/RemovePnPContentTypeTests.cs | 63 +++++++++++++++++++ .../RemovePnPFieldFromContentTypeTests.cs | 63 +++++++++++++++++++ .../SetPnPDefaultContentTypeToListTests.cs | 63 +++++++++++++++++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 19 +++--- 10 files changed, 576 insertions(+), 10 deletions(-) create mode 100644 Tests/ContentTypes/AddPnPContentTypeTests.cs create mode 100644 Tests/ContentTypes/AddPnPContentTypeToListTests.cs create mode 100644 Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs create mode 100644 Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs create mode 100644 Tests/ContentTypes/GetPnPContentTypeTests.cs create mode 100644 Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs create mode 100644 Tests/ContentTypes/RemovePnPContentTypeTests.cs create mode 100644 Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs create mode 100644 Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs diff --git a/Tests/ContentTypes/AddPnPContentTypeTests.cs b/Tests/ContentTypes/AddPnPContentTypeTests.cs new file mode 100644 index 000000000..c9c7fc81f --- /dev/null +++ b/Tests/ContentTypes/AddPnPContentTypeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class AddContentTypeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPContentTypeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPContentType",new CommandParameter("Name", "null"),new CommandParameter("ContentTypeId", "null"),new CommandParameter("Description", "null"),new CommandParameter("Group", "null"),new CommandParameter("ParentContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/AddPnPContentTypeToListTests.cs b/Tests/ContentTypes/AddPnPContentTypeToListTests.cs new file mode 100644 index 000000000..75b735c01 --- /dev/null +++ b/Tests/ContentTypes/AddPnPContentTypeToListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class AddContentTypeToListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPContentTypeToListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPContentTypeToList",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("DefaultContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs b/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs new file mode 100644 index 000000000..2d10fcbb4 --- /dev/null +++ b/Tests/ContentTypes/AddPnPFieldToContentTypeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class AddFieldToContentTypeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPFieldToContentTypeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPFieldToContentType",new CommandParameter("Field", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("Required", "null"),new CommandParameter("Hidden", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs b/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs new file mode 100644 index 000000000..e5e5e42f7 --- /dev/null +++ b/Tests/ContentTypes/GetPnPContentTypePublishingHubUrlTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class GetContentTypePublishingHubTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPContentTypePublishingHubUrlTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPContentTypePublishingHubUrl"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/GetPnPContentTypeTests.cs b/Tests/ContentTypes/GetPnPContentTypeTests.cs new file mode 100644 index 000000000..f50e08610 --- /dev/null +++ b/Tests/ContentTypes/GetPnPContentTypeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class GetContentTypeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPContentTypeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPContentType",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("InSiteHierarchy", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs b/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs new file mode 100644 index 000000000..836711332 --- /dev/null +++ b/Tests/ContentTypes/RemovePnPContentTypeFromListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class RemoveContentTypeFromListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPContentTypeFromListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPContentTypeFromList",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/RemovePnPContentTypeTests.cs b/Tests/ContentTypes/RemovePnPContentTypeTests.cs new file mode 100644 index 000000000..cc14c2af7 --- /dev/null +++ b/Tests/ContentTypes/RemovePnPContentTypeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class RemoveContentTypeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPContentTypeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPContentType",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs b/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs new file mode 100644 index 000000000..4729d612e --- /dev/null +++ b/Tests/ContentTypes/RemovePnPFieldFromContentTypeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class RemoveFieldFromContentTypeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPFieldFromContentTypeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPFieldFromContentType",new CommandParameter("Field", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("DoNotUpdateChildren", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs b/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs new file mode 100644 index 000000000..b0abe2617 --- /dev/null +++ b/Tests/ContentTypes/SetPnPDefaultContentTypeToListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ContentTypes +{ + + [TestClass] + public class SetDefaultContentTypeToListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPDefaultContentTypeToListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPDefaultContentTypeToList",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 18f18c6ba..c63a520cf 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -470,6 +470,15 @@ + + + + + + + + + @@ -478,7 +487,6 @@ - @@ -494,9 +502,6 @@ - - - Always @@ -508,10 +513,6 @@ Designer - - - - @@ -521,7 +522,6 @@ - @@ -538,7 +538,6 @@ - From 7a93799837635986d7fa651e56a0e83a69ae18c0 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:54:52 +0100 Subject: [PATCH 068/130] Added placeholder diagnostic tests --- Tests/Diagnostic/MeasurePnPListTests.cs | 63 +++++++++++++++++++ .../Diagnostic/MeasurePnPResponseTimeTests.cs | 63 +++++++++++++++++++ Tests/Diagnostic/MeasurePnPWebTests.cs | 63 +++++++++++++++++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 4 +- 4 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 Tests/Diagnostic/MeasurePnPListTests.cs create mode 100644 Tests/Diagnostic/MeasurePnPResponseTimeTests.cs create mode 100644 Tests/Diagnostic/MeasurePnPWebTests.cs diff --git a/Tests/Diagnostic/MeasurePnPListTests.cs b/Tests/Diagnostic/MeasurePnPListTests.cs new file mode 100644 index 000000000..e0a169e13 --- /dev/null +++ b/Tests/Diagnostic/MeasurePnPListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Diagnostic +{ + + [TestClass] + public class MeasurePnPListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MeasurePnPListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Measure-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("ItemLevel", "null"),new CommandParameter("BrokenPermissions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs b/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs new file mode 100644 index 000000000..d0fb29148 --- /dev/null +++ b/Tests/Diagnostic/MeasurePnPResponseTimeTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Diagnostic +{ + + [TestClass] + public class MeasureResponseTimeTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MeasurePnPResponseTimeTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Measure-PnPResponseTime",new CommandParameter("Url", "null"),new CommandParameter("Count", "null"),new CommandParameter("WarmUp", "null"),new CommandParameter("Timeout", "null"),new CommandParameter("Histogram", "null"),new CommandParameter("Mode", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Diagnostic/MeasurePnPWebTests.cs b/Tests/Diagnostic/MeasurePnPWebTests.cs new file mode 100644 index 000000000..4fcace84a --- /dev/null +++ b/Tests/Diagnostic/MeasurePnPWebTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Diagnostic +{ + + [TestClass] + public class MeasurePnPWebTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MeasurePnPWebTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Measure-PnPWeb",new CommandParameter("Identity", "null"),new CommandParameter("Recursive", "null"),new CommandParameter("IncludeHiddenList", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index c63a520cf..291c4b64a 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -481,6 +481,9 @@ + + + @@ -522,7 +525,6 @@ - From dde33f4d4ea00df57753070b9768515d0bb3951a Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 15:58:59 +0100 Subject: [PATCH 069/130] Added all remaining placeholder tests --- .../AddPnPContentTypeToDocumentSetTests.cs | 63 ++++ Tests/DocumentSets/AddPnPDocumentSetTests.cs | 63 ++++ .../GetPnPDocumentSetTemplateTests.cs | 63 ++++ ...emovePnPContentTypeFromDocumentSetTests.cs | 63 ++++ .../SetPnPDocumentSetFieldTests.cs | 63 ++++ Tests/Events/AddPnPEventReceiverTests.cs | 63 ++++ Tests/Events/GetPnPEventReceiverTests.cs | 63 ++++ Tests/Events/RemovePnPEventReceiverTests.cs | 63 ++++ .../NewPnPExtensibilityHandlerObjectTests.cs | 63 ++++ Tests/Features/DisablePnPFeatureTests.cs | 63 ++++ Tests/Features/EnablePnPFeatureTests.cs | 63 ++++ Tests/Features/GetPnPFeatureTests.cs | 63 ++++ Tests/Fields/AddPnPFieldFromXmlTests.cs | 63 ++++ Tests/Fields/AddPnPFieldTests.cs | 63 ++++ Tests/Fields/AddPnPTaxonomyFieldTests.cs | 63 ++++ Tests/Fields/GetPnPFieldTests.cs | 63 ++++ Tests/Fields/RemovePnPFieldTests.cs | 63 ++++ Tests/Fields/SetPnPFieldTests.cs | 63 ++++ Tests/Fields/SetPnPViewTests.cs | 63 ++++ Tests/Files/AddPnPFileTests.cs | 63 ++++ Tests/Files/AddPnPFolderTests.cs | 63 ++++ Tests/Files/CopyPnPFileTests.cs | 63 ++++ Tests/Files/FindPnPFileTests.cs | 63 ++++ Tests/Files/GetPnPFileTests.cs | 63 ++++ Tests/Files/GetPnPFolderItemTests.cs | 63 ++++ Tests/Files/GetPnPFolderTests.cs | 63 ++++ Tests/Files/MovePnPFileTests.cs | 63 ++++ Tests/Files/MovePnPFolderTests.cs | 63 ++++ Tests/Files/RemovePnPFileTests.cs | 63 ++++ Tests/Files/RemovePnPFolderTests.cs | 63 ++++ Tests/Files/RenamePnPFileTests.cs | 63 ++++ Tests/Files/RenamePnPFolderTests.cs | 63 ++++ Tests/Files/ResetPnPFileVersionTests.cs | 63 ++++ Tests/Files/ResolvePnPFolderTests.cs | 63 ++++ Tests/Files/SetPnPFileCheckedInTests.cs | 63 ++++ Tests/Files/SetPnPFileCheckedOutTests.cs | 63 ++++ Tests/Files/SetPnPFolderPermissionTests.cs | 63 ++++ Tests/Graph/AddPnPSiteClassificationTests.cs | 63 ++++ .../DisablePnPSiteClassificationTests.cs | 63 ++++ .../Graph/EnablePnPSiteClassificationTests.cs | 63 ++++ Tests/Graph/GetPnPAADUserTests.cs | 63 ++++ Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs | 63 ++++ Tests/Graph/GetPnPGraphSubscriptionTests.cs | 63 ++++ Tests/Graph/GetPnPSiteClassificationTests.cs | 63 ++++ Tests/Graph/GetPnPUnifiedGroupMembersTests.cs | 63 ++++ Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs | 63 ++++ Tests/Graph/GetPnPUnifiedGroupTests.cs | 63 ++++ Tests/Graph/NewPnPGraphSubscriptionTests.cs | 63 ++++ Tests/Graph/NewPnPUnifiedGroupTests.cs | 63 ++++ .../RemovePnPDeletedUnifiedGroupTests.cs | 63 ++++ .../Graph/RemovePnPGraphSubscriptionTests.cs | 63 ++++ .../Graph/RemovePnPSiteClassificationTests.cs | 63 ++++ Tests/Graph/RemovePnPUnifiedGroupTests.cs | 63 ++++ .../ResetPnPUnifiedGroupExpirationTests.cs | 63 ++++ .../RestorePnPDeletedUnifiedGroupTests.cs | 63 ++++ Tests/Graph/SetPnPGraphSubscriptionTests.cs | 63 ++++ Tests/Graph/SetPnPUnifiedGroupTests.cs | 63 ++++ .../Graph/UpdatePnPSiteClassificationTests.cs | 63 ++++ .../InformationManagement/GetPnPLabelTests.cs | 63 ++++ ...PnPListInformationRightsManagementTests.cs | 63 ++++ .../GetPnPSiteClosureTests.cs | 63 ++++ .../GetPnPSitePolicyTests.cs | 63 ++++ .../ResetPnPLabelTests.cs | 63 ++++ .../InformationManagement/SetPnPLabelTests.cs | 63 ++++ ...PnPListInformationRightsManagementTests.cs | 63 ++++ .../SetPnPSiteClosureTests.cs | 63 ++++ .../SetPnPSitePolicyTests.cs | 63 ++++ Tests/Lists/AddPnPListItemTests.cs | 63 ++++ Tests/Lists/AddPnPViewTests.cs | 63 ++++ .../Lists/ClearPnPDefaultColumnValuesTests.cs | 63 ++++ Tests/Lists/GetPnPDefaultColumnValuesTests.cs | 63 ++++ Tests/Lists/GetPnPListItemTests.cs | 63 ++++ Tests/Lists/GetPnPListTests.cs | 63 ++++ Tests/Lists/GetPnPViewTests.cs | 63 ++++ .../Lists/MovePnPListItemToRecycleBinTests.cs | 63 ++++ Tests/Lists/NewPnPListTests.cs | 63 ++++ Tests/Lists/RemovePnPListItemTests.cs | 63 ++++ Tests/Lists/RemovePnPListTests.cs | 63 ++++ Tests/Lists/RemovePnPViewTests.cs | 63 ++++ Tests/Lists/RequestPnPReIndexListTests.cs | 63 ++++ Tests/Lists/SetPnPDefaultColumnValuesTests.cs | 63 ++++ Tests/Lists/SetPnPListItemPermissionTests.cs | 63 ++++ Tests/Lists/SetPnPListItemTests.cs | 63 ++++ Tests/Lists/SetPnPListPermissionTests.cs | 63 ++++ Tests/Lists/SetPnPListTests.cs | 63 ++++ .../GetPnPManagementApiAccessTokenTests.cs | 63 ++++ ...etPnPOffice365CurrentServiceStatusTests.cs | 63 ++++ ...nPOffice365HistoricalServiceStatusTests.cs | 63 ++++ .../GetPnPOffice365ServiceMessageTests.cs | 63 ++++ .../GetPnPOffice365ServicesTests.cs | 63 ++++ ...tPnPOfficeManagementApiAccessTokenTests.cs | 63 ++++ .../GetPnPUnifiedAuditLogTests.cs | 63 ++++ Tests/Principals/AddPnPAlertTests.cs | 63 ++++ Tests/Principals/AddPnPUserToGroupTests.cs | 63 ++++ Tests/Principals/GetPnPAlertTests.cs | 63 ++++ Tests/Principals/GetPnPGroupMembersTests.cs | 63 ++++ .../Principals/GetPnPGroupPermissionsTests.cs | 63 ++++ Tests/Principals/GetPnPGroupTests.cs | 63 ++++ Tests/Principals/GetPnPUserTests.cs | 63 ++++ Tests/Principals/NewPnPGroupTests.cs | 63 ++++ Tests/Principals/NewPnPUserTests.cs | 63 ++++ Tests/Principals/RemovePnPAlertTests.cs | 63 ++++ Tests/Principals/RemovePnPGroupTests.cs | 63 ++++ .../Principals/RemovePnPUserFromGroupTests.cs | 63 ++++ Tests/Principals/RemovePnPUserTests.cs | 63 ++++ .../Principals/SetPnPGroupPermissionsTests.cs | 63 ++++ Tests/Principals/SetPnPGroupTests.cs | 63 ++++ ...dPnPDataRowsToProvisioningTemplateTests.cs | 63 ++++ .../AddPnPFileToProvisioningTemplateTests.cs | 63 ++++ ...PListFoldersToProvisioningTemplateTests.cs | 63 ++++ .../ApplyPnPProvisioningTemplateTests.cs | 63 ++++ ...xportPnPListToProvisioningTemplateTests.cs | 63 ++++ .../GetPnPProvisioningTemplateTests.cs | 63 ++++ .../GetPnPTenantTemplateTests.cs | 63 ++++ ...ovePnPFileFromProvisioningTemplateTests.cs | 63 ++++ ...SetPnPProvisioningTemplateMetadataTests.cs | 63 ++++ .../AddPnPProvisioningTemplateTests.cs | 63 ++++ .../AddPnPTenantSequenceSiteTests.cs | 63 ++++ .../AddPnPTenantSequenceSubSiteTests.cs | 63 ++++ .../AddPnPTenantSequenceTests.cs | 63 ++++ .../ApplyPnPTenantTemplateTests.cs | 63 ++++ .../ExportPnPClientSidePageTests.cs | 63 ++++ .../GetPnPTenantSequenceSiteTests.cs | 63 ++++ .../GetPnPTenantSequenceTests.cs | 63 ++++ ...PnPTenantSequenceCommunicationSiteTests.cs | 63 ++++ ...ewPnPTenantSequenceTeamNoGroupSiteTests.cs | 63 ++++ ...nPTenantSequenceTeamNoGroupSubSiteTests.cs | 63 ++++ .../NewPnPTenantSequenceTeamSiteTests.cs | 63 ++++ .../NewPnPTenantSequenceTests.cs | 63 ++++ .../NewPnPTenantTemplateTests.cs | 63 ++++ .../ReadPnPTenantTemplateTests.cs | 63 ++++ .../SavePnPTenantTemplateTests.cs | 63 ++++ .../TestPnPTenantTemplateTests.cs | 63 ++++ .../AddPnPHtmlPublishingPageLayoutTests.cs | 63 ++++ Tests/Publishing/AddPnPMasterPageTests.cs | 63 ++++ .../AddPnPPublishingImageRenditionTests.cs | 63 ++++ .../AddPnPPublishingPageLayoutTests.cs | 63 ++++ Tests/Publishing/AddPnPPublishingPageTests.cs | 63 ++++ Tests/Publishing/AddPnPWikiPageTests.cs | 63 ++++ .../GetPnPPublishingImageRenditionTests.cs | 63 ++++ .../Publishing/GetPnPWikiPageContentTests.cs | 63 ++++ .../RemovePnPPublishingImageRenditionTests.cs | 63 ++++ Tests/Publishing/RemovePnPWikiPageTests.cs | 63 ++++ .../SetPnPAvailablePageLayoutsTests.cs | 63 ++++ .../SetPnPDefaultPageLayoutTests.cs | 63 ++++ .../Publishing/SetPnPWikiPageContentTests.cs | 63 ++++ .../ClearPnPListItemAsRecordTests.cs | 63 ++++ ...PnPInPlaceRecordsManagementForSiteTests.cs | 63 ++++ ...PnPInPlaceRecordsManagementForSiteTests.cs | 63 ++++ .../GetPnPInPlaceRecordsManagementTests.cs | 63 ++++ .../GetPnPListRecordDeclarationTests.cs | 63 ++++ .../SetPnPInPlaceRecordsManagementTests.cs | 63 ++++ .../SetPnPListItemAsRecordTests.cs | 63 ++++ .../SetPnPListRecordDeclarationTests.cs | 63 ++++ .../TestPnPListItemIsRecordTests.cs | 63 ++++ .../RecycleBin/ClearPnPRecycleBinItemTests.cs | 63 ++++ .../ClearPnPTenantRecycleBinItemTests.cs | 63 ++++ Tests/RecycleBin/GetPnPRecycleBinItemTests.cs | 63 ++++ .../GetPnPTenantRecycleBinItemTests.cs | 63 ++++ .../RecycleBin/MovePnPRecycleBinItemTests.cs | 63 ++++ .../RestorePnPRecycleBinItemTests.cs | 63 ++++ .../RestorePnPTenantRecycleBinItemTests.cs | 63 ++++ .../Search/GetPnPSearchConfigurationTests.cs | 63 ++++ Tests/Search/GetPnPSearchCrawlLogTests.cs | 63 ++++ Tests/Search/GetPnPSearchSettingsTests.cs | 63 ++++ .../GetPnPSiteSearchQueryResultsTests.cs | 63 ++++ .../RemovePnPSearchConfigurationTests.cs | 63 ++++ .../Search/SetPnPSearchConfigurationTests.cs | 63 ++++ Tests/Search/SetPnPSearchSettingsTests.cs | 63 ++++ Tests/Search/SubmitPnPSearchQueryTests.cs | 63 ++++ Tests/SharePointPnP.PowerShell.Tests.csproj | 271 ++++++++++++++++-- Tests/Site/AddPnPRoleDefinitionTests.cs | 63 ++++ Tests/Site/AddPnPSiteCollectionAdminTests.cs | 63 ++++ Tests/Site/AddPnPTeamsTeamTests.cs | 63 ++++ ...isablePnPSharingForNonOwnersOfSiteTests.cs | 63 ++++ Tests/Site/EnablePnPCommSiteTests.cs | 63 ++++ Tests/Site/GetPnPAuditingTests.cs | 63 ++++ Tests/Site/GetPnPRoleDefinitionTests.cs | 63 ++++ .../GetPnPSharingForNonOwnersOfSiteTests.cs | 63 ++++ Tests/Site/GetPnPSiteCollectionAdminTests.cs | 63 ++++ Tests/Site/GetPnPSiteTests.cs | 63 ++++ Tests/Site/InstallPnPSolutionTests.cs | 63 ++++ Tests/Site/RemovePnPRoleDefinitionTests.cs | 63 ++++ .../Site/RemovePnPSiteCollectionAdminTests.cs | 63 ++++ Tests/Site/SetPnPAppSideLoadingTests.cs | 63 ++++ Tests/Site/SetPnPAuditingTests.cs | 63 ++++ Tests/Site/SetPnPSiteTests.cs | 63 ++++ .../TestPnPOffice365GroupAliasIsUsedTests.cs | 63 ++++ Tests/Site/UninstallPnPSolutionTests.cs | 63 ++++ .../SiteDesigns/AddPnPSiteDesignTaskTests.cs | 63 ++++ .../GetPnPSiteDesignRunStatusTests.cs | 63 ++++ Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs | 63 ++++ .../SiteDesigns/GetPnPSiteDesignTaskTests.cs | 63 ++++ Tests/Taxonomy/ExportPnPTaxonomyTests.cs | 63 ++++ .../Taxonomy/ExportPnPTermGroupToXmlTests.cs | 63 ++++ .../GetPnPSiteCollectionTermStoreTests.cs | 63 ++++ Tests/Taxonomy/GetPnPTaxonomyItemTests.cs | 63 ++++ Tests/Taxonomy/GetPnPTaxonomySessionTests.cs | 63 ++++ Tests/Taxonomy/GetPnPTermGroupTests.cs | 63 ++++ Tests/Taxonomy/GetPnPTermSetTests.cs | 63 ++++ Tests/Taxonomy/GetPnPTermTests.cs | 63 ++++ Tests/Taxonomy/ImportPnPTaxonomyTests.cs | 63 ++++ .../ImportPnPTermGroupFromXmlTests.cs | 63 ++++ Tests/Taxonomy/ImportPnPTermSetTests.cs | 63 ++++ Tests/Taxonomy/NewPnPTermGroupTests.cs | 63 ++++ Tests/Taxonomy/NewPnPTermLabelTests.cs | 63 ++++ Tests/Taxonomy/NewPnPTermSetTests.cs | 63 ++++ Tests/Taxonomy/NewPnPTermTests.cs | 63 ++++ Tests/Taxonomy/RemovePnPTaxonomyItemTests.cs | 63 ++++ Tests/Taxonomy/RemovePnPTermGroupTests.cs | 63 ++++ .../Taxonomy/SetPnPTaxonomyFieldValueTests.cs | 63 ++++ .../GetPnPUPABulkImportStatusTests.cs | 63 ++++ .../GetPnPUserOneDriveQuotaTests.cs | 63 ++++ .../GetPnPUserProfilePropertyTests.cs | 63 ++++ Tests/UserProfiles/NewPnPPersonalSiteTests.cs | 63 ++++ .../NewPnPUPABulkImportJobTests.cs | 63 ++++ ...ResetPnPUserOneDriveQuotaToDefaultTests.cs | 63 ++++ .../SetPnPUserOneDriveQuotaTests.cs | 63 ++++ .../SetPnPUserProfilePropertyTests.cs | 63 ++++ Tests/Utilities/SendPnPMailTests.cs | 63 ++++ .../WebParts/AddPnPClientSideWebPartTests.cs | 63 ++++ .../AddPnPWebPartToWebPartPageTests.cs | 63 ++++ .../WebParts/AddPnPWebPartToWikiPageTests.cs | 63 ++++ Tests/WebParts/GetPnPWebPartPropertyTests.cs | 63 ++++ Tests/WebParts/GetPnPWebPartTests.cs | 63 ++++ Tests/WebParts/GetPnPWebPartXmlTests.cs | 63 ++++ Tests/WebParts/RemovePnPWebPartTests.cs | 63 ++++ Tests/WebParts/SetPnPWebPartPropertyTests.cs | 63 ++++ .../AddPnPWebhookSubscriptionTests.cs | 63 ++++ .../GetPnPWebhookSubscriptionsTests.cs | 63 ++++ .../RemovePnPWebhookSubscriptionTests.cs | 63 ++++ .../SetPnPWebhookSubscriptionTests.cs | 63 ++++ .../AddPnPWorkflowDefinitionTests.cs | 63 ++++ .../AddPnPWorkflowSubscriptionTests.cs | 63 ++++ .../GetPnPWorkflowDefinitionTests.cs | 63 ++++ .../Workflows/GetPnPWorkflowInstanceTests.cs | 63 ++++ .../GetPnPWorkflowSubscriptionTests.cs | 63 ++++ .../RemovePnPWorkflowDefinitionTests.cs | 63 ++++ .../RemovePnPWorkflowSubscriptionTests.cs | 63 ++++ .../ResumePnPWorkflowInstanceTests.cs | 63 ++++ .../StartPnPWorkflowInstanceTests.cs | 63 ++++ .../Workflows/StopPnPWorkflowInstanceTests.cs | 63 ++++ 242 files changed, 15424 insertions(+), 30 deletions(-) create mode 100644 Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs create mode 100644 Tests/DocumentSets/AddPnPDocumentSetTests.cs create mode 100644 Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs create mode 100644 Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs create mode 100644 Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs create mode 100644 Tests/Events/AddPnPEventReceiverTests.cs create mode 100644 Tests/Events/GetPnPEventReceiverTests.cs create mode 100644 Tests/Events/RemovePnPEventReceiverTests.cs create mode 100644 Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs create mode 100644 Tests/Features/DisablePnPFeatureTests.cs create mode 100644 Tests/Features/EnablePnPFeatureTests.cs create mode 100644 Tests/Features/GetPnPFeatureTests.cs create mode 100644 Tests/Fields/AddPnPFieldFromXmlTests.cs create mode 100644 Tests/Fields/AddPnPFieldTests.cs create mode 100644 Tests/Fields/AddPnPTaxonomyFieldTests.cs create mode 100644 Tests/Fields/GetPnPFieldTests.cs create mode 100644 Tests/Fields/RemovePnPFieldTests.cs create mode 100644 Tests/Fields/SetPnPFieldTests.cs create mode 100644 Tests/Fields/SetPnPViewTests.cs create mode 100644 Tests/Files/AddPnPFileTests.cs create mode 100644 Tests/Files/AddPnPFolderTests.cs create mode 100644 Tests/Files/CopyPnPFileTests.cs create mode 100644 Tests/Files/FindPnPFileTests.cs create mode 100644 Tests/Files/GetPnPFileTests.cs create mode 100644 Tests/Files/GetPnPFolderItemTests.cs create mode 100644 Tests/Files/GetPnPFolderTests.cs create mode 100644 Tests/Files/MovePnPFileTests.cs create mode 100644 Tests/Files/MovePnPFolderTests.cs create mode 100644 Tests/Files/RemovePnPFileTests.cs create mode 100644 Tests/Files/RemovePnPFolderTests.cs create mode 100644 Tests/Files/RenamePnPFileTests.cs create mode 100644 Tests/Files/RenamePnPFolderTests.cs create mode 100644 Tests/Files/ResetPnPFileVersionTests.cs create mode 100644 Tests/Files/ResolvePnPFolderTests.cs create mode 100644 Tests/Files/SetPnPFileCheckedInTests.cs create mode 100644 Tests/Files/SetPnPFileCheckedOutTests.cs create mode 100644 Tests/Files/SetPnPFolderPermissionTests.cs create mode 100644 Tests/Graph/AddPnPSiteClassificationTests.cs create mode 100644 Tests/Graph/DisablePnPSiteClassificationTests.cs create mode 100644 Tests/Graph/EnablePnPSiteClassificationTests.cs create mode 100644 Tests/Graph/GetPnPAADUserTests.cs create mode 100644 Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs create mode 100644 Tests/Graph/GetPnPGraphSubscriptionTests.cs create mode 100644 Tests/Graph/GetPnPSiteClassificationTests.cs create mode 100644 Tests/Graph/GetPnPUnifiedGroupMembersTests.cs create mode 100644 Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs create mode 100644 Tests/Graph/GetPnPUnifiedGroupTests.cs create mode 100644 Tests/Graph/NewPnPGraphSubscriptionTests.cs create mode 100644 Tests/Graph/NewPnPUnifiedGroupTests.cs create mode 100644 Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs create mode 100644 Tests/Graph/RemovePnPGraphSubscriptionTests.cs create mode 100644 Tests/Graph/RemovePnPSiteClassificationTests.cs create mode 100644 Tests/Graph/RemovePnPUnifiedGroupTests.cs create mode 100644 Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs create mode 100644 Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs create mode 100644 Tests/Graph/SetPnPGraphSubscriptionTests.cs create mode 100644 Tests/Graph/SetPnPUnifiedGroupTests.cs create mode 100644 Tests/Graph/UpdatePnPSiteClassificationTests.cs create mode 100644 Tests/InformationManagement/GetPnPLabelTests.cs create mode 100644 Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs create mode 100644 Tests/InformationManagement/GetPnPSiteClosureTests.cs create mode 100644 Tests/InformationManagement/GetPnPSitePolicyTests.cs create mode 100644 Tests/InformationManagement/ResetPnPLabelTests.cs create mode 100644 Tests/InformationManagement/SetPnPLabelTests.cs create mode 100644 Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs create mode 100644 Tests/InformationManagement/SetPnPSiteClosureTests.cs create mode 100644 Tests/InformationManagement/SetPnPSitePolicyTests.cs create mode 100644 Tests/Lists/AddPnPListItemTests.cs create mode 100644 Tests/Lists/AddPnPViewTests.cs create mode 100644 Tests/Lists/ClearPnPDefaultColumnValuesTests.cs create mode 100644 Tests/Lists/GetPnPDefaultColumnValuesTests.cs create mode 100644 Tests/Lists/GetPnPListItemTests.cs create mode 100644 Tests/Lists/GetPnPListTests.cs create mode 100644 Tests/Lists/GetPnPViewTests.cs create mode 100644 Tests/Lists/MovePnPListItemToRecycleBinTests.cs create mode 100644 Tests/Lists/NewPnPListTests.cs create mode 100644 Tests/Lists/RemovePnPListItemTests.cs create mode 100644 Tests/Lists/RemovePnPListTests.cs create mode 100644 Tests/Lists/RemovePnPViewTests.cs create mode 100644 Tests/Lists/RequestPnPReIndexListTests.cs create mode 100644 Tests/Lists/SetPnPDefaultColumnValuesTests.cs create mode 100644 Tests/Lists/SetPnPListItemPermissionTests.cs create mode 100644 Tests/Lists/SetPnPListItemTests.cs create mode 100644 Tests/Lists/SetPnPListPermissionTests.cs create mode 100644 Tests/Lists/SetPnPListTests.cs create mode 100644 Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs create mode 100644 Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs create mode 100644 Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs create mode 100644 Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs create mode 100644 Tests/ManagementApi/GetPnPOffice365ServicesTests.cs create mode 100644 Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs create mode 100644 Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs create mode 100644 Tests/Principals/AddPnPAlertTests.cs create mode 100644 Tests/Principals/AddPnPUserToGroupTests.cs create mode 100644 Tests/Principals/GetPnPAlertTests.cs create mode 100644 Tests/Principals/GetPnPGroupMembersTests.cs create mode 100644 Tests/Principals/GetPnPGroupPermissionsTests.cs create mode 100644 Tests/Principals/GetPnPGroupTests.cs create mode 100644 Tests/Principals/GetPnPUserTests.cs create mode 100644 Tests/Principals/NewPnPGroupTests.cs create mode 100644 Tests/Principals/NewPnPUserTests.cs create mode 100644 Tests/Principals/RemovePnPAlertTests.cs create mode 100644 Tests/Principals/RemovePnPGroupTests.cs create mode 100644 Tests/Principals/RemovePnPUserFromGroupTests.cs create mode 100644 Tests/Principals/RemovePnPUserTests.cs create mode 100644 Tests/Principals/SetPnPGroupPermissionsTests.cs create mode 100644 Tests/Principals/SetPnPGroupTests.cs create mode 100644 Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs create mode 100644 Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs create mode 100644 Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs create mode 100644 Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs create mode 100644 Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs create mode 100644 Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs create mode 100644 Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs create mode 100644 Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs create mode 100644 Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs create mode 100644 Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs create mode 100644 Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs create mode 100644 Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs create mode 100644 Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs create mode 100644 Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs create mode 100644 Tests/Publishing/AddPnPMasterPageTests.cs create mode 100644 Tests/Publishing/AddPnPPublishingImageRenditionTests.cs create mode 100644 Tests/Publishing/AddPnPPublishingPageLayoutTests.cs create mode 100644 Tests/Publishing/AddPnPPublishingPageTests.cs create mode 100644 Tests/Publishing/AddPnPWikiPageTests.cs create mode 100644 Tests/Publishing/GetPnPPublishingImageRenditionTests.cs create mode 100644 Tests/Publishing/GetPnPWikiPageContentTests.cs create mode 100644 Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs create mode 100644 Tests/Publishing/RemovePnPWikiPageTests.cs create mode 100644 Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs create mode 100644 Tests/Publishing/SetPnPDefaultPageLayoutTests.cs create mode 100644 Tests/Publishing/SetPnPWikiPageContentTests.cs create mode 100644 Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs create mode 100644 Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs create mode 100644 Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs create mode 100644 Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs create mode 100644 Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs create mode 100644 Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs create mode 100644 Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs create mode 100644 Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs create mode 100644 Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs create mode 100644 Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs create mode 100644 Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs create mode 100644 Tests/RecycleBin/GetPnPRecycleBinItemTests.cs create mode 100644 Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs create mode 100644 Tests/RecycleBin/MovePnPRecycleBinItemTests.cs create mode 100644 Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs create mode 100644 Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs create mode 100644 Tests/Search/GetPnPSearchConfigurationTests.cs create mode 100644 Tests/Search/GetPnPSearchCrawlLogTests.cs create mode 100644 Tests/Search/GetPnPSearchSettingsTests.cs create mode 100644 Tests/Search/GetPnPSiteSearchQueryResultsTests.cs create mode 100644 Tests/Search/RemovePnPSearchConfigurationTests.cs create mode 100644 Tests/Search/SetPnPSearchConfigurationTests.cs create mode 100644 Tests/Search/SetPnPSearchSettingsTests.cs create mode 100644 Tests/Search/SubmitPnPSearchQueryTests.cs create mode 100644 Tests/Site/AddPnPRoleDefinitionTests.cs create mode 100644 Tests/Site/AddPnPSiteCollectionAdminTests.cs create mode 100644 Tests/Site/AddPnPTeamsTeamTests.cs create mode 100644 Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs create mode 100644 Tests/Site/EnablePnPCommSiteTests.cs create mode 100644 Tests/Site/GetPnPAuditingTests.cs create mode 100644 Tests/Site/GetPnPRoleDefinitionTests.cs create mode 100644 Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs create mode 100644 Tests/Site/GetPnPSiteCollectionAdminTests.cs create mode 100644 Tests/Site/GetPnPSiteTests.cs create mode 100644 Tests/Site/InstallPnPSolutionTests.cs create mode 100644 Tests/Site/RemovePnPRoleDefinitionTests.cs create mode 100644 Tests/Site/RemovePnPSiteCollectionAdminTests.cs create mode 100644 Tests/Site/SetPnPAppSideLoadingTests.cs create mode 100644 Tests/Site/SetPnPAuditingTests.cs create mode 100644 Tests/Site/SetPnPSiteTests.cs create mode 100644 Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs create mode 100644 Tests/Site/UninstallPnPSolutionTests.cs create mode 100644 Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs create mode 100644 Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs create mode 100644 Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs create mode 100644 Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs create mode 100644 Tests/Taxonomy/ExportPnPTaxonomyTests.cs create mode 100644 Tests/Taxonomy/ExportPnPTermGroupToXmlTests.cs create mode 100644 Tests/Taxonomy/GetPnPSiteCollectionTermStoreTests.cs create mode 100644 Tests/Taxonomy/GetPnPTaxonomyItemTests.cs create mode 100644 Tests/Taxonomy/GetPnPTaxonomySessionTests.cs create mode 100644 Tests/Taxonomy/GetPnPTermGroupTests.cs create mode 100644 Tests/Taxonomy/GetPnPTermSetTests.cs create mode 100644 Tests/Taxonomy/GetPnPTermTests.cs create mode 100644 Tests/Taxonomy/ImportPnPTaxonomyTests.cs create mode 100644 Tests/Taxonomy/ImportPnPTermGroupFromXmlTests.cs create mode 100644 Tests/Taxonomy/ImportPnPTermSetTests.cs create mode 100644 Tests/Taxonomy/NewPnPTermGroupTests.cs create mode 100644 Tests/Taxonomy/NewPnPTermLabelTests.cs create mode 100644 Tests/Taxonomy/NewPnPTermSetTests.cs create mode 100644 Tests/Taxonomy/NewPnPTermTests.cs create mode 100644 Tests/Taxonomy/RemovePnPTaxonomyItemTests.cs create mode 100644 Tests/Taxonomy/RemovePnPTermGroupTests.cs create mode 100644 Tests/Taxonomy/SetPnPTaxonomyFieldValueTests.cs create mode 100644 Tests/UserProfiles/GetPnPUPABulkImportStatusTests.cs create mode 100644 Tests/UserProfiles/GetPnPUserOneDriveQuotaTests.cs create mode 100644 Tests/UserProfiles/GetPnPUserProfilePropertyTests.cs create mode 100644 Tests/UserProfiles/NewPnPPersonalSiteTests.cs create mode 100644 Tests/UserProfiles/NewPnPUPABulkImportJobTests.cs create mode 100644 Tests/UserProfiles/ResetPnPUserOneDriveQuotaToDefaultTests.cs create mode 100644 Tests/UserProfiles/SetPnPUserOneDriveQuotaTests.cs create mode 100644 Tests/UserProfiles/SetPnPUserProfilePropertyTests.cs create mode 100644 Tests/Utilities/SendPnPMailTests.cs create mode 100644 Tests/WebParts/AddPnPClientSideWebPartTests.cs create mode 100644 Tests/WebParts/AddPnPWebPartToWebPartPageTests.cs create mode 100644 Tests/WebParts/AddPnPWebPartToWikiPageTests.cs create mode 100644 Tests/WebParts/GetPnPWebPartPropertyTests.cs create mode 100644 Tests/WebParts/GetPnPWebPartTests.cs create mode 100644 Tests/WebParts/GetPnPWebPartXmlTests.cs create mode 100644 Tests/WebParts/RemovePnPWebPartTests.cs create mode 100644 Tests/WebParts/SetPnPWebPartPropertyTests.cs create mode 100644 Tests/Webhooks/AddPnPWebhookSubscriptionTests.cs create mode 100644 Tests/Webhooks/GetPnPWebhookSubscriptionsTests.cs create mode 100644 Tests/Webhooks/RemovePnPWebhookSubscriptionTests.cs create mode 100644 Tests/Webhooks/SetPnPWebhookSubscriptionTests.cs create mode 100644 Tests/Workflows/AddPnPWorkflowDefinitionTests.cs create mode 100644 Tests/Workflows/AddPnPWorkflowSubscriptionTests.cs create mode 100644 Tests/Workflows/GetPnPWorkflowDefinitionTests.cs create mode 100644 Tests/Workflows/GetPnPWorkflowInstanceTests.cs create mode 100644 Tests/Workflows/GetPnPWorkflowSubscriptionTests.cs create mode 100644 Tests/Workflows/RemovePnPWorkflowDefinitionTests.cs create mode 100644 Tests/Workflows/RemovePnPWorkflowSubscriptionTests.cs create mode 100644 Tests/Workflows/ResumePnPWorkflowInstanceTests.cs create mode 100644 Tests/Workflows/StartPnPWorkflowInstanceTests.cs create mode 100644 Tests/Workflows/StopPnPWorkflowInstanceTests.cs diff --git a/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs b/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs new file mode 100644 index 000000000..75136fd19 --- /dev/null +++ b/Tests/DocumentSets/AddPnPContentTypeToDocumentSetTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.DocumentSets +{ + + [TestClass] + public class AddContentTypeToDocumentSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPContentTypeToDocumentSetTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPContentTypeToDocumentSet",new CommandParameter("ContentType", "null"),new CommandParameter("DocumentSet", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/DocumentSets/AddPnPDocumentSetTests.cs b/Tests/DocumentSets/AddPnPDocumentSetTests.cs new file mode 100644 index 000000000..fdaf5a323 --- /dev/null +++ b/Tests/DocumentSets/AddPnPDocumentSetTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.DocumentSets +{ + + [TestClass] + public class AddDocumentSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPDocumentSetTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPDocumentSet",new CommandParameter("List", "null"),new CommandParameter("Name", "null"),new CommandParameter("ContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs b/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs new file mode 100644 index 000000000..534f3192a --- /dev/null +++ b/Tests/DocumentSets/GetPnPDocumentSetTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.DocumentSets +{ + + [TestClass] + public class GetDocumentSetTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPDocumentSetTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPDocumentSetTemplate",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs b/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs new file mode 100644 index 000000000..6ebc1d4d0 --- /dev/null +++ b/Tests/DocumentSets/RemovePnPContentTypeFromDocumentSetTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.DocumentSets +{ + + [TestClass] + public class RemoveContentTypeFromDocumentSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPContentTypeFromDocumentSetTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPContentTypeFromDocumentSet",new CommandParameter("ContentType", "null"),new CommandParameter("DocumentSet", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs b/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs new file mode 100644 index 000000000..ef77761fa --- /dev/null +++ b/Tests/DocumentSets/SetPnPDocumentSetFieldTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.DocumentSets +{ + + [TestClass] + public class SetFieldInDocumentSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPDocumentSetFieldTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPDocumentSetField",new CommandParameter("DocumentSet", "null"),new CommandParameter("Field", "null"),new CommandParameter("SetSharedField", "null"),new CommandParameter("SetWelcomePageField", "null"),new CommandParameter("RemoveSharedField", "null"),new CommandParameter("RemoveWelcomePageField", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Events/AddPnPEventReceiverTests.cs b/Tests/Events/AddPnPEventReceiverTests.cs new file mode 100644 index 000000000..7f55d2e6c --- /dev/null +++ b/Tests/Events/AddPnPEventReceiverTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Events +{ + + [TestClass] + public class AddEventReceiverTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPEventReceiverTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPEventReceiver",new CommandParameter("List", "null"),new CommandParameter("Name", "null"),new CommandParameter("Url", "null"),new CommandParameter("EventReceiverType", "null"),new CommandParameter("Synchronization", "null"),new CommandParameter("SequenceNumber", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Events/GetPnPEventReceiverTests.cs b/Tests/Events/GetPnPEventReceiverTests.cs new file mode 100644 index 000000000..8df56a8fa --- /dev/null +++ b/Tests/Events/GetPnPEventReceiverTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Events +{ + + [TestClass] + public class GetEventReceiverTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPEventReceiverTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPEventReceiver",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Events/RemovePnPEventReceiverTests.cs b/Tests/Events/RemovePnPEventReceiverTests.cs new file mode 100644 index 000000000..d01f5ea9e --- /dev/null +++ b/Tests/Events/RemovePnPEventReceiverTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Events +{ + + [TestClass] + public class RemoveEventReceiverTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPEventReceiverTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPEventReceiver",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs b/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs new file mode 100644 index 000000000..9af9906f1 --- /dev/null +++ b/Tests/Extensibility/NewPnPExtensibilityHandlerObjectTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Extensibility +{ + + [TestClass] + public class NewExtensibilityHandlerObjectTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPExtensibilityHandlerObjectTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPExtensibilityHandlerObject",new CommandParameter("Assembly", "null"),new CommandParameter("Type", "null"),new CommandParameter("Configuration", "null"),new CommandParameter("Disabled", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Features/DisablePnPFeatureTests.cs b/Tests/Features/DisablePnPFeatureTests.cs new file mode 100644 index 000000000..9e9bcff63 --- /dev/null +++ b/Tests/Features/DisablePnPFeatureTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Features +{ + + [TestClass] + public class DisableFeatureTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPFeatureTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPFeature",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Features/EnablePnPFeatureTests.cs b/Tests/Features/EnablePnPFeatureTests.cs new file mode 100644 index 000000000..c32de2769 --- /dev/null +++ b/Tests/Features/EnablePnPFeatureTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Features +{ + + [TestClass] + public class EnableFeatureTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPFeatureTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPFeature",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Sandboxed", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Features/GetPnPFeatureTests.cs b/Tests/Features/GetPnPFeatureTests.cs new file mode 100644 index 000000000..c6d7fc6a5 --- /dev/null +++ b/Tests/Features/GetPnPFeatureTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Features +{ + + [TestClass] + public class GetFeatureTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPFeatureTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPFeature",new CommandParameter("Identity", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/AddPnPFieldFromXmlTests.cs b/Tests/Fields/AddPnPFieldFromXmlTests.cs new file mode 100644 index 000000000..713bfc4af --- /dev/null +++ b/Tests/Fields/AddPnPFieldFromXmlTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class AddFieldFromXmlTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPFieldFromXmlTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPFieldFromXml",new CommandParameter("List", "null"),new CommandParameter("FieldXml", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/AddPnPFieldTests.cs b/Tests/Fields/AddPnPFieldTests.cs new file mode 100644 index 000000000..bb6328830 --- /dev/null +++ b/Tests/Fields/AddPnPFieldTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class AddFieldTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPFieldTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPField",new CommandParameter("List", "null"),new CommandParameter("Field", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("InternalName", "null"),new CommandParameter("Type", "null"),new CommandParameter("Id", "null"),new CommandParameter("AddToDefaultView", "null"),new CommandParameter("Required", "null"),new CommandParameter("Group", "null"),new CommandParameter("ClientSideComponentId", "null"),new CommandParameter("ClientSideComponentProperties", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/AddPnPTaxonomyFieldTests.cs b/Tests/Fields/AddPnPTaxonomyFieldTests.cs new file mode 100644 index 000000000..0a7b18557 --- /dev/null +++ b/Tests/Fields/AddPnPTaxonomyFieldTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class AddTaxonomyFieldTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTaxonomyFieldTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTaxonomyField",new CommandParameter("List", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("InternalName", "null"),new CommandParameter("TermSetPath", "null"),new CommandParameter("TaxonomyItemId", "null"),new CommandParameter("TermPathDelimiter", "null"),new CommandParameter("Group", "null"),new CommandParameter("Id", "null"),new CommandParameter("AddToDefaultView", "null"),new CommandParameter("MultiValue", "null"),new CommandParameter("Required", "null"),new CommandParameter("FieldOptions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/GetPnPFieldTests.cs b/Tests/Fields/GetPnPFieldTests.cs new file mode 100644 index 000000000..0022f2cdf --- /dev/null +++ b/Tests/Fields/GetPnPFieldTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class GetFieldTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPFieldTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPField",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("InSiteHierarchy", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/RemovePnPFieldTests.cs b/Tests/Fields/RemovePnPFieldTests.cs new file mode 100644 index 000000000..5f012458f --- /dev/null +++ b/Tests/Fields/RemovePnPFieldTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class RemoveFieldTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPFieldTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPField",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/SetPnPFieldTests.cs b/Tests/Fields/SetPnPFieldTests.cs new file mode 100644 index 000000000..894522ce4 --- /dev/null +++ b/Tests/Fields/SetPnPFieldTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class SetFieldTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPFieldTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPField",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Values", "null"),new CommandParameter("UpdateExistingLists", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Fields/SetPnPViewTests.cs b/Tests/Fields/SetPnPViewTests.cs new file mode 100644 index 000000000..957a00350 --- /dev/null +++ b/Tests/Fields/SetPnPViewTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Fields +{ + + [TestClass] + public class SetViewTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPViewTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPView",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Values", "null"),new CommandParameter("Fields", "null"),new CommandParameter("Aggregations", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/AddPnPFileTests.cs b/Tests/Files/AddPnPFileTests.cs new file mode 100644 index 000000000..7d708cf75 --- /dev/null +++ b/Tests/Files/AddPnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class AddFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPFile",new CommandParameter("Path", "null"),new CommandParameter("Folder", "null"),new CommandParameter("FileName", "null"),new CommandParameter("NewFileName", "null"),new CommandParameter("Stream", "null"),new CommandParameter("Checkout", "null"),new CommandParameter("CheckInComment", "null"),new CommandParameter("Approve", "null"),new CommandParameter("ApproveComment", "null"),new CommandParameter("Publish", "null"),new CommandParameter("PublishComment", "null"),new CommandParameter("UseWebDav", "null"),new CommandParameter("Values", "null"),new CommandParameter("ContentType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/AddPnPFolderTests.cs b/Tests/Files/AddPnPFolderTests.cs new file mode 100644 index 000000000..9b6bd7a25 --- /dev/null +++ b/Tests/Files/AddPnPFolderTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class AddFolderTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPFolderTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPFolder",new CommandParameter("Name", "null"),new CommandParameter("Folder", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/CopyPnPFileTests.cs b/Tests/Files/CopyPnPFileTests.cs new file mode 100644 index 000000000..7cf6aae21 --- /dev/null +++ b/Tests/Files/CopyPnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class CopyFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void CopyPnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Copy-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SourceUrl", "null"),new CommandParameter("TargetUrl", "null"),new CommandParameter("OverwriteIfAlreadyExists", "null"),new CommandParameter("Force", "null"),new CommandParameter("SkipSourceFolderName", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/FindPnPFileTests.cs b/Tests/Files/FindPnPFileTests.cs new file mode 100644 index 000000000..2492fa6e0 --- /dev/null +++ b/Tests/Files/FindPnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class FindFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void FindPnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Find-PnPFile",new CommandParameter("Match", "null"),new CommandParameter("List", "null"),new CommandParameter("Folder", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/GetPnPFileTests.cs b/Tests/Files/GetPnPFileTests.cs new file mode 100644 index 000000000..64fb43936 --- /dev/null +++ b/Tests/Files/GetPnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class GetFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPFile",new CommandParameter("Url", "null"),new CommandParameter("Path", "null"),new CommandParameter("Filename", "null"),new CommandParameter("AsFile", "null"),new CommandParameter("AsListItem", "null"),new CommandParameter("ThrowExceptionIfFileNotFound", "null"),new CommandParameter("AsString", "null"),new CommandParameter("Force", "null"),new CommandParameter("AsFileObject", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/GetPnPFolderItemTests.cs b/Tests/Files/GetPnPFolderItemTests.cs new file mode 100644 index 000000000..a5f40b79b --- /dev/null +++ b/Tests/Files/GetPnPFolderItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class GetFolderItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPFolderItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPFolderItem",new CommandParameter("FolderSiteRelativeUrl", "null"),new CommandParameter("Identity", "null"),new CommandParameter("ItemType", "null"),new CommandParameter("ItemName", "null"),new CommandParameter("Recursive", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/GetPnPFolderTests.cs b/Tests/Files/GetPnPFolderTests.cs new file mode 100644 index 000000000..bd1d80a9b --- /dev/null +++ b/Tests/Files/GetPnPFolderTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class GetFolderTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPFolderTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPFolder",new CommandParameter("Url", "null"),new CommandParameter("List", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/MovePnPFileTests.cs b/Tests/Files/MovePnPFileTests.cs new file mode 100644 index 000000000..fa8ddf6bc --- /dev/null +++ b/Tests/Files/MovePnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class MoveFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MovePnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Move-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SiteRelativeUrl", "null"),new CommandParameter("TargetUrl", "null"),new CommandParameter("TargetServerRelativeLibrary", "null"),new CommandParameter("OverwriteIfAlreadyExists", "null"),new CommandParameter("AllowSchemaMismatch", "null"),new CommandParameter("AllowSmallerVersionLimitOnDestination", "null"),new CommandParameter("IgnoreVersionHistory", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/MovePnPFolderTests.cs b/Tests/Files/MovePnPFolderTests.cs new file mode 100644 index 000000000..cc459f367 --- /dev/null +++ b/Tests/Files/MovePnPFolderTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class MoveFolderTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MovePnPFolderTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Move-PnPFolder",new CommandParameter("Folder", "null"),new CommandParameter("TargetFolder", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/RemovePnPFileTests.cs b/Tests/Files/RemovePnPFileTests.cs new file mode 100644 index 000000000..8f58b9291 --- /dev/null +++ b/Tests/Files/RemovePnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class RemoveFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SiteRelativeUrl", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/RemovePnPFolderTests.cs b/Tests/Files/RemovePnPFolderTests.cs new file mode 100644 index 000000000..b5617f69b --- /dev/null +++ b/Tests/Files/RemovePnPFolderTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class RemoveFolderTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPFolderTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPFolder",new CommandParameter("Name", "null"),new CommandParameter("Folder", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/RenamePnPFileTests.cs b/Tests/Files/RenamePnPFileTests.cs new file mode 100644 index 000000000..0a60d2059 --- /dev/null +++ b/Tests/Files/RenamePnPFileTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class RenameFileTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RenamePnPFileTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Rename-PnPFile",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("SiteRelativeUrl", "null"),new CommandParameter("TargetFileName", "null"),new CommandParameter("OverwriteIfAlreadyExists", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/RenamePnPFolderTests.cs b/Tests/Files/RenamePnPFolderTests.cs new file mode 100644 index 000000000..e8dc9b127 --- /dev/null +++ b/Tests/Files/RenamePnPFolderTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class RenameFolderTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RenamePnPFolderTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Rename-PnPFolder",new CommandParameter("Folder", "null"),new CommandParameter("TargetFolderName", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/ResetPnPFileVersionTests.cs b/Tests/Files/ResetPnPFileVersionTests.cs new file mode 100644 index 000000000..241d2bd3b --- /dev/null +++ b/Tests/Files/ResetPnPFileVersionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class ResetFileVersionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ResetPnPFileVersionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Reset-PnPFileVersion",new CommandParameter("ServerRelativeUrl", "null"),new CommandParameter("CheckinType", "null"),new CommandParameter("CheckInComment", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/ResolvePnPFolderTests.cs b/Tests/Files/ResolvePnPFolderTests.cs new file mode 100644 index 000000000..27c8aa875 --- /dev/null +++ b/Tests/Files/ResolvePnPFolderTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class ResolveFolderTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ResolvePnPFolderTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Resolve-PnPFolder",new CommandParameter("SiteRelativePath", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/SetPnPFileCheckedInTests.cs b/Tests/Files/SetPnPFileCheckedInTests.cs new file mode 100644 index 000000000..ac6f90634 --- /dev/null +++ b/Tests/Files/SetPnPFileCheckedInTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class SetFileCheckedInTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPFileCheckedInTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPFileCheckedIn",new CommandParameter("Url", "null"),new CommandParameter("CheckinType", "null"),new CommandParameter("Comment", "null"),new CommandParameter("Approve", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/SetPnPFileCheckedOutTests.cs b/Tests/Files/SetPnPFileCheckedOutTests.cs new file mode 100644 index 000000000..9b9f14a9f --- /dev/null +++ b/Tests/Files/SetPnPFileCheckedOutTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class SetFileCheckedOutTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPFileCheckedOutTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPFileCheckedOut",new CommandParameter("Url", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Files/SetPnPFolderPermissionTests.cs b/Tests/Files/SetPnPFolderPermissionTests.cs new file mode 100644 index 000000000..3e7f48f84 --- /dev/null +++ b/Tests/Files/SetPnPFolderPermissionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Files +{ + + [TestClass] + public class SetFolderPermissionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPFolderPermissionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPFolderPermission",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("User", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null"),new CommandParameter("ClearExisting", "null"),new CommandParameter("InheritPermissions", "null"),new CommandParameter("SystemUpdate", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/AddPnPSiteClassificationTests.cs b/Tests/Graph/AddPnPSiteClassificationTests.cs new file mode 100644 index 000000000..6533840e7 --- /dev/null +++ b/Tests/Graph/AddPnPSiteClassificationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class AddSiteClassificationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPSiteClassificationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPSiteClassification",new CommandParameter("Classifications", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/DisablePnPSiteClassificationTests.cs b/Tests/Graph/DisablePnPSiteClassificationTests.cs new file mode 100644 index 000000000..aec5b4443 --- /dev/null +++ b/Tests/Graph/DisablePnPSiteClassificationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class DisableSiteClassificationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPSiteClassificationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPSiteClassification"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/EnablePnPSiteClassificationTests.cs b/Tests/Graph/EnablePnPSiteClassificationTests.cs new file mode 100644 index 000000000..ee69f6f58 --- /dev/null +++ b/Tests/Graph/EnablePnPSiteClassificationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class EnableSiteClassificationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPSiteClassificationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPSiteClassification",new CommandParameter("Classifications", "null"),new CommandParameter("DefaultClassification", "null"),new CommandParameter("UsageGuidelinesUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPAADUserTests.cs b/Tests/Graph/GetPnPAADUserTests.cs new file mode 100644 index 000000000..fee671b61 --- /dev/null +++ b/Tests/Graph/GetPnPAADUserTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetAADUserTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAADUserTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAADUser",new CommandParameter("Identity", "null"),new CommandParameter("Filter", "null"),new CommandParameter("OrderBy", "null"),new CommandParameter("Select", "null"),new CommandParameter("Delta", "null"),new CommandParameter("DeltaToken", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs b/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs new file mode 100644 index 000000000..1e56bc4d4 --- /dev/null +++ b/Tests/Graph/GetPnPDeletedUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetDeletedUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPDeletedUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPDeletedUnifiedGroup",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPGraphSubscriptionTests.cs b/Tests/Graph/GetPnPGraphSubscriptionTests.cs new file mode 100644 index 000000000..4f5b739a2 --- /dev/null +++ b/Tests/Graph/GetPnPGraphSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetGraphSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPGraphSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPGraphSubscription",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPSiteClassificationTests.cs b/Tests/Graph/GetPnPSiteClassificationTests.cs new file mode 100644 index 000000000..c95633192 --- /dev/null +++ b/Tests/Graph/GetPnPSiteClassificationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetSiteClassificationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteClassificationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteClassification"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs b/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs new file mode 100644 index 000000000..08eed24b5 --- /dev/null +++ b/Tests/Graph/GetPnPUnifiedGroupMembersTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetUnifiedGroupMembersTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUnifiedGroupMembersTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUnifiedGroupMembers",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs b/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs new file mode 100644 index 000000000..7eb13ef5a --- /dev/null +++ b/Tests/Graph/GetPnPUnifiedGroupOwnersTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetUnifiedGroupOwnersTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUnifiedGroupOwnersTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUnifiedGroupOwners",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/GetPnPUnifiedGroupTests.cs b/Tests/Graph/GetPnPUnifiedGroupTests.cs new file mode 100644 index 000000000..e2405b048 --- /dev/null +++ b/Tests/Graph/GetPnPUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class GetUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUnifiedGroup",new CommandParameter("Identity", "null"),new CommandParameter("ExcludeSiteUrl", "null"),new CommandParameter("IncludeClassification", "null"),new CommandParameter("IncludeHasTeam", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/NewPnPGraphSubscriptionTests.cs b/Tests/Graph/NewPnPGraphSubscriptionTests.cs new file mode 100644 index 000000000..0adf52f49 --- /dev/null +++ b/Tests/Graph/NewPnPGraphSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class NewGraphSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPGraphSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPGraphSubscription",new CommandParameter("ChangeType", "null"),new CommandParameter("NotificationUrl", "null"),new CommandParameter("Resource", "null"),new CommandParameter("ExpirationDateTime", "null"),new CommandParameter("ClientState", "null"),new CommandParameter("LatestSupportedTlsVersion", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/NewPnPUnifiedGroupTests.cs b/Tests/Graph/NewPnPUnifiedGroupTests.cs new file mode 100644 index 000000000..266a5892d --- /dev/null +++ b/Tests/Graph/NewPnPUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class NewPnPUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPUnifiedGroup",new CommandParameter("DisplayName", "null"),new CommandParameter("Description", "null"),new CommandParameter("MailNickname", "null"),new CommandParameter("Owners", "null"),new CommandParameter("Members", "null"),new CommandParameter("IsPrivate", "null"),new CommandParameter("GroupLogoPath", "null"),new CommandParameter("CreateTeam", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs b/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs new file mode 100644 index 000000000..6647ebc9e --- /dev/null +++ b/Tests/Graph/RemovePnPDeletedUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class RemoveDeletedUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPDeletedUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPDeletedUnifiedGroup",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/RemovePnPGraphSubscriptionTests.cs b/Tests/Graph/RemovePnPGraphSubscriptionTests.cs new file mode 100644 index 000000000..413d8fab1 --- /dev/null +++ b/Tests/Graph/RemovePnPGraphSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class RemoveGraphSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPGraphSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPGraphSubscription",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/RemovePnPSiteClassificationTests.cs b/Tests/Graph/RemovePnPSiteClassificationTests.cs new file mode 100644 index 000000000..a71fc8167 --- /dev/null +++ b/Tests/Graph/RemovePnPSiteClassificationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class RemoveSiteClassificationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPSiteClassificationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPSiteClassification",new CommandParameter("Classifications", "null"),new CommandParameter("Confirm", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/RemovePnPUnifiedGroupTests.cs b/Tests/Graph/RemovePnPUnifiedGroupTests.cs new file mode 100644 index 000000000..9cb32e752 --- /dev/null +++ b/Tests/Graph/RemovePnPUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class RemoveUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPUnifiedGroup",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs b/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs new file mode 100644 index 000000000..1e506108c --- /dev/null +++ b/Tests/Graph/ResetPnPUnifiedGroupExpirationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class ResetUnifiedGroupExpirationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ResetPnPUnifiedGroupExpirationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Reset-PnPUnifiedGroupExpiration",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs b/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs new file mode 100644 index 000000000..1f3652567 --- /dev/null +++ b/Tests/Graph/RestorePnPDeletedUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class RestoreDeletedUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RestorePnPDeletedUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Restore-PnPDeletedUnifiedGroup",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/SetPnPGraphSubscriptionTests.cs b/Tests/Graph/SetPnPGraphSubscriptionTests.cs new file mode 100644 index 000000000..ba437fbff --- /dev/null +++ b/Tests/Graph/SetPnPGraphSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class SetGraphSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPGraphSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPGraphSubscription",new CommandParameter("Identity", "null"),new CommandParameter("ExpirationDate", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/SetPnPUnifiedGroupTests.cs b/Tests/Graph/SetPnPUnifiedGroupTests.cs new file mode 100644 index 000000000..77d5cbfd8 --- /dev/null +++ b/Tests/Graph/SetPnPUnifiedGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class SetUnifiedGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPUnifiedGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPUnifiedGroup",new CommandParameter("Identity", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Description", "null"),new CommandParameter("Owners", "null"),new CommandParameter("Members", "null"),new CommandParameter("IsPrivate", "null"),new CommandParameter("GroupLogoPath", "null"),new CommandParameter("CreateTeam", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Graph/UpdatePnPSiteClassificationTests.cs b/Tests/Graph/UpdatePnPSiteClassificationTests.cs new file mode 100644 index 000000000..3e2e0a034 --- /dev/null +++ b/Tests/Graph/UpdatePnPSiteClassificationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Graph +{ + + [TestClass] + public class UpdateSiteClassificationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UpdatePnPSiteClassificationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Update-PnPSiteClassification",new CommandParameter("Settings", "null"),new CommandParameter("Classifications", "null"),new CommandParameter("DefaultClassification", "null"),new CommandParameter("UsageGuidelinesUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/GetPnPLabelTests.cs b/Tests/InformationManagement/GetPnPLabelTests.cs new file mode 100644 index 000000000..74f4a583a --- /dev/null +++ b/Tests/InformationManagement/GetPnPLabelTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class GetLabelTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPLabelTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPLabel",new CommandParameter("List", "null"),new CommandParameter("ValuesOnly", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs b/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs new file mode 100644 index 000000000..ba6035bd6 --- /dev/null +++ b/Tests/InformationManagement/GetPnPListInformationRightsManagementTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class GetListInformationRightsManagementTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPListInformationRightsManagementTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPListInformationRightsManagement",new CommandParameter("List", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/GetPnPSiteClosureTests.cs b/Tests/InformationManagement/GetPnPSiteClosureTests.cs new file mode 100644 index 000000000..2bdaee520 --- /dev/null +++ b/Tests/InformationManagement/GetPnPSiteClosureTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class GetSiteClosureTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteClosureTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteClosure"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/GetPnPSitePolicyTests.cs b/Tests/InformationManagement/GetPnPSitePolicyTests.cs new file mode 100644 index 000000000..ad747b59c --- /dev/null +++ b/Tests/InformationManagement/GetPnPSitePolicyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class GetSitePolicyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSitePolicyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSitePolicy",new CommandParameter("AllAvailable", "null"),new CommandParameter("Name", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/ResetPnPLabelTests.cs b/Tests/InformationManagement/ResetPnPLabelTests.cs new file mode 100644 index 000000000..666279f83 --- /dev/null +++ b/Tests/InformationManagement/ResetPnPLabelTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class ResetLabelTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ResetPnPLabelTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Reset-PnPLabel",new CommandParameter("List", "null"),new CommandParameter("SyncToItems", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/SetPnPLabelTests.cs b/Tests/InformationManagement/SetPnPLabelTests.cs new file mode 100644 index 000000000..2707486a8 --- /dev/null +++ b/Tests/InformationManagement/SetPnPLabelTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class SetLabelTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPLabelTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPLabel",new CommandParameter("List", "null"),new CommandParameter("Label", "null"),new CommandParameter("SyncToItems", "null"),new CommandParameter("BlockDeletion", "null"),new CommandParameter("BlockEdit", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs b/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs new file mode 100644 index 000000000..8d321bd76 --- /dev/null +++ b/Tests/InformationManagement/SetPnPListInformationRightsManagementTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class SetListInformationRightsManagementTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListInformationRightsManagementTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPListInformationRightsManagement",new CommandParameter("List", "null"),new CommandParameter("Enable", "null"),new CommandParameter("EnableExpiration", "null"),new CommandParameter("EnableRejection", "null"),new CommandParameter("AllowPrint", "null"),new CommandParameter("AllowScript", "null"),new CommandParameter("AllowWriteCopy", "null"),new CommandParameter("DisableDocumentBrowserView", "null"),new CommandParameter("DocumentAccessExpireDays", "null"),new CommandParameter("DocumentLibraryProtectionExpireDate", "null"),new CommandParameter("EnableDocumentAccessExpire", "null"),new CommandParameter("EnableDocumentBrowserPublishingView", "null"),new CommandParameter("EnableGroupProtection", "null"),new CommandParameter("EnableLicenseCacheExpire", "null"),new CommandParameter("LicenseCacheExpireDays", "null"),new CommandParameter("GroupName", "null"),new CommandParameter("PolicyDescription", "null"),new CommandParameter("PolicyTitle", "null"),new CommandParameter("TemplateId", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/SetPnPSiteClosureTests.cs b/Tests/InformationManagement/SetPnPSiteClosureTests.cs new file mode 100644 index 000000000..e24e5131c --- /dev/null +++ b/Tests/InformationManagement/SetPnPSiteClosureTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class SetSiteClosureTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPSiteClosureTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPSiteClosure",new CommandParameter("State", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/InformationManagement/SetPnPSitePolicyTests.cs b/Tests/InformationManagement/SetPnPSitePolicyTests.cs new file mode 100644 index 000000000..fc5082c7b --- /dev/null +++ b/Tests/InformationManagement/SetPnPSitePolicyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.InformationManagement +{ + + [TestClass] + public class ApplySitePolicyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPSitePolicyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPSitePolicy",new CommandParameter("Name", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/AddPnPListItemTests.cs b/Tests/Lists/AddPnPListItemTests.cs new file mode 100644 index 000000000..279b66895 --- /dev/null +++ b/Tests/Lists/AddPnPListItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class AddListItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPListItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("Values", "null"),new CommandParameter("Folder", "null"),new CommandParameter("Label", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/AddPnPViewTests.cs b/Tests/Lists/AddPnPViewTests.cs new file mode 100644 index 000000000..8d3de16e9 --- /dev/null +++ b/Tests/Lists/AddPnPViewTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class AddViewTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPViewTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPView",new CommandParameter("List", "null"),new CommandParameter("Title", "null"),new CommandParameter("Query", "null"),new CommandParameter("Fields", "null"),new CommandParameter("ViewType", "null"),new CommandParameter("RowLimit", "null"),new CommandParameter("Personal", "null"),new CommandParameter("SetAsDefault", "null"),new CommandParameter("Paged", "null"),new CommandParameter("Aggregations", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs b/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs new file mode 100644 index 000000000..a602e48b6 --- /dev/null +++ b/Tests/Lists/ClearPnPDefaultColumnValuesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class ClearDefaultColumnValuesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ClearPnPDefaultColumnValuesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Clear-PnPDefaultColumnValues",new CommandParameter("List", "null"),new CommandParameter("Field", "null"),new CommandParameter("Folder", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/GetPnPDefaultColumnValuesTests.cs b/Tests/Lists/GetPnPDefaultColumnValuesTests.cs new file mode 100644 index 000000000..c77448ab8 --- /dev/null +++ b/Tests/Lists/GetPnPDefaultColumnValuesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class GetDefaultColumnValuesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPDefaultColumnValuesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPDefaultColumnValues",new CommandParameter("List", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/GetPnPListItemTests.cs b/Tests/Lists/GetPnPListItemTests.cs new file mode 100644 index 000000000..8c7934fab --- /dev/null +++ b/Tests/Lists/GetPnPListItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class GetListItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPListItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("Id", "null"),new CommandParameter("UniqueId", "null"),new CommandParameter("Query", "null"),new CommandParameter("FolderServerRelativeUrl", "null"),new CommandParameter("Fields", "null"),new CommandParameter("PageSize", "null"),new CommandParameter("ScriptBlock", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/GetPnPListTests.cs b/Tests/Lists/GetPnPListTests.cs new file mode 100644 index 000000000..5811feb9a --- /dev/null +++ b/Tests/Lists/GetPnPListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class GetListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("ThrowExceptionIfListNotFound", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/GetPnPViewTests.cs b/Tests/Lists/GetPnPViewTests.cs new file mode 100644 index 000000000..5efbfb7bc --- /dev/null +++ b/Tests/Lists/GetPnPViewTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class GetViewTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPViewTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPView",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/MovePnPListItemToRecycleBinTests.cs b/Tests/Lists/MovePnPListItemToRecycleBinTests.cs new file mode 100644 index 000000000..7036f7214 --- /dev/null +++ b/Tests/Lists/MovePnPListItemToRecycleBinTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class MoveListItemToRecycleBinTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MovePnPListItemToRecycleBinTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Move-PnPListItemToRecycleBin",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/NewPnPListTests.cs b/Tests/Lists/NewPnPListTests.cs new file mode 100644 index 000000000..dd6a887d5 --- /dev/null +++ b/Tests/Lists/NewPnPListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class NewListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPList",new CommandParameter("Title", "null"),new CommandParameter("Template", "null"),new CommandParameter("Url", "null"),new CommandParameter("Hidden", "null"),new CommandParameter("EnableVersioning", "null"),new CommandParameter("QuickLaunchOptions", "null"),new CommandParameter("EnableContentTypes", "null"),new CommandParameter("OnQuickLaunch", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/RemovePnPListItemTests.cs b/Tests/Lists/RemovePnPListItemTests.cs new file mode 100644 index 000000000..0336a476b --- /dev/null +++ b/Tests/Lists/RemovePnPListItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class RemoveListItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPListItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/RemovePnPListTests.cs b/Tests/Lists/RemovePnPListTests.cs new file mode 100644 index 000000000..4e3899f0a --- /dev/null +++ b/Tests/Lists/RemovePnPListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class RemoveListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("Recycle", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/RemovePnPViewTests.cs b/Tests/Lists/RemovePnPViewTests.cs new file mode 100644 index 000000000..9859b2cd8 --- /dev/null +++ b/Tests/Lists/RemovePnPViewTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class RemoveViewTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPViewTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPView",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/RequestPnPReIndexListTests.cs b/Tests/Lists/RequestPnPReIndexListTests.cs new file mode 100644 index 000000000..f311a455c --- /dev/null +++ b/Tests/Lists/RequestPnPReIndexListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class RequestReIndexListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RequestPnPReIndexListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Request-PnPReIndexList",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/SetPnPDefaultColumnValuesTests.cs b/Tests/Lists/SetPnPDefaultColumnValuesTests.cs new file mode 100644 index 000000000..0c00f54f4 --- /dev/null +++ b/Tests/Lists/SetPnPDefaultColumnValuesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class SetDefaultColumnValuesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPDefaultColumnValuesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPDefaultColumnValues",new CommandParameter("List", "null"),new CommandParameter("Field", "null"),new CommandParameter("Value", "null"),new CommandParameter("Folder", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/SetPnPListItemPermissionTests.cs b/Tests/Lists/SetPnPListItemPermissionTests.cs new file mode 100644 index 000000000..3d5d350d8 --- /dev/null +++ b/Tests/Lists/SetPnPListItemPermissionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class SetListItemPermissionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListItemPermissionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPListItemPermission",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("User", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null"),new CommandParameter("ClearExisting", "null"),new CommandParameter("InheritPermissions", "null"),new CommandParameter("SystemUpdate", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/SetPnPListItemTests.cs b/Tests/Lists/SetPnPListItemTests.cs new file mode 100644 index 000000000..98daa012b --- /dev/null +++ b/Tests/Lists/SetPnPListItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class SetListItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPListItem",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("ContentType", "null"),new CommandParameter("Values", "null"),new CommandParameter("SystemUpdate", "null"),new CommandParameter("Label", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/SetPnPListPermissionTests.cs b/Tests/Lists/SetPnPListPermissionTests.cs new file mode 100644 index 000000000..b2f0ad044 --- /dev/null +++ b/Tests/Lists/SetPnPListPermissionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class SetListPermissionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListPermissionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPListPermission",new CommandParameter("Identity", "null"),new CommandParameter("Group", "null"),new CommandParameter("User", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Lists/SetPnPListTests.cs b/Tests/Lists/SetPnPListTests.cs new file mode 100644 index 000000000..1db990fc2 --- /dev/null +++ b/Tests/Lists/SetPnPListTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Lists +{ + + [TestClass] + public class SetListTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPList",new CommandParameter("Identity", "null"),new CommandParameter("EnableContentTypes", "null"),new CommandParameter("BreakRoleInheritance", "null"),new CommandParameter("ResetRoleInheritance", "null"),new CommandParameter("CopyRoleAssignments", "null"),new CommandParameter("ClearSubscopes", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Hidden", "null"),new CommandParameter("ForceCheckout", "null"),new CommandParameter("ListExperience", "null"),new CommandParameter("EnableAttachments", "null"),new CommandParameter("EnableFolderCreation", "null"),new CommandParameter("EnableVersioning", "null"),new CommandParameter("EnableMinorVersions", "null"),new CommandParameter("MajorVersions", "null"),new CommandParameter("MinorVersions", "null"),new CommandParameter("EnableModeration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs b/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs new file mode 100644 index 000000000..041437831 --- /dev/null +++ b/Tests/ManagementApi/GetPnPManagementApiAccessTokenTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetManagementApiAccessTokenTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPManagementApiAccessTokenTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPManagementApiAccessToken",new CommandParameter("TenantId", "null"),new CommandParameter("ClientId", "null"),new CommandParameter("ClientSecret", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs b/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs new file mode 100644 index 000000000..3ce3f6684 --- /dev/null +++ b/Tests/ManagementApi/GetPnPOffice365CurrentServiceStatusTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetOffice365CurrentServiceStatusTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOffice365CurrentServiceStatusTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOffice365CurrentServiceStatus",new CommandParameter("Workload", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs b/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs new file mode 100644 index 000000000..a2f91b195 --- /dev/null +++ b/Tests/ManagementApi/GetPnPOffice365HistoricalServiceStatusTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetOffice365HistoricalServiceStatusTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOffice365HistoricalServiceStatusTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOffice365HistoricalServiceStatus",new CommandParameter("Workload", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs b/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs new file mode 100644 index 000000000..fdbd1b606 --- /dev/null +++ b/Tests/ManagementApi/GetPnPOffice365ServiceMessageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetOffice365ServiceMessageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOffice365ServiceMessageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOffice365ServiceMessage",new CommandParameter("Workload", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs b/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs new file mode 100644 index 000000000..ea539ccd6 --- /dev/null +++ b/Tests/ManagementApi/GetPnPOffice365ServicesTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetOffice365ServicesTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOffice365ServicesTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOffice365Services"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs b/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs new file mode 100644 index 000000000..f541b1f6f --- /dev/null +++ b/Tests/ManagementApi/GetPnPOfficeManagementApiAccessTokenTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetOfficeManagementApiAccessTokenTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPOfficeManagementApiAccessTokenTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPOfficeManagementApiAccessToken",new CommandParameter("Decoded", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs b/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs new file mode 100644 index 000000000..6b3ecf2fa --- /dev/null +++ b/Tests/ManagementApi/GetPnPUnifiedAuditLogTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.ManagementApi +{ + + [TestClass] + public class GetUnifiedAuditLogTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUnifiedAuditLogTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUnifiedAuditLog",new CommandParameter("ContentType", "null"),new CommandParameter("StartTime", "null"),new CommandParameter("EndTime", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/AddPnPAlertTests.cs b/Tests/Principals/AddPnPAlertTests.cs new file mode 100644 index 000000000..a0718e8d7 --- /dev/null +++ b/Tests/Principals/AddPnPAlertTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class AddAlertTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPAlertTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPAlert",new CommandParameter("List", "null"),new CommandParameter("Title", "null"),new CommandParameter("User", "null"),new CommandParameter("DeliveryMethod", "null"),new CommandParameter("ChangeType", "null"),new CommandParameter("Frequency", "null"),new CommandParameter("Filter", "null"),new CommandParameter("Time", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/AddPnPUserToGroupTests.cs b/Tests/Principals/AddPnPUserToGroupTests.cs new file mode 100644 index 000000000..5a41bc301 --- /dev/null +++ b/Tests/Principals/AddPnPUserToGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class AddUserToGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPUserToGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPUserToGroup",new CommandParameter("LoginName", "null"),new CommandParameter("Identity", "null"),new CommandParameter("EmailAddress", "null"),new CommandParameter("SendEmail", "null"),new CommandParameter("EmailBody", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/GetPnPAlertTests.cs b/Tests/Principals/GetPnPAlertTests.cs new file mode 100644 index 000000000..ccd82308c --- /dev/null +++ b/Tests/Principals/GetPnPAlertTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class GetAlertTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAlertTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAlert",new CommandParameter("List", "null"),new CommandParameter("User", "null"),new CommandParameter("Title", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/GetPnPGroupMembersTests.cs b/Tests/Principals/GetPnPGroupMembersTests.cs new file mode 100644 index 000000000..f84a55a67 --- /dev/null +++ b/Tests/Principals/GetPnPGroupMembersTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class GetGroupMembersTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPGroupMembersTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPGroupMembers",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/GetPnPGroupPermissionsTests.cs b/Tests/Principals/GetPnPGroupPermissionsTests.cs new file mode 100644 index 000000000..01abcda82 --- /dev/null +++ b/Tests/Principals/GetPnPGroupPermissionsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class GetGroupPermissionsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPGroupPermissionsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPGroupPermissions",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/GetPnPGroupTests.cs b/Tests/Principals/GetPnPGroupTests.cs new file mode 100644 index 000000000..1c171da75 --- /dev/null +++ b/Tests/Principals/GetPnPGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class GetGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPGroup",new CommandParameter("Identity", "null"),new CommandParameter("AssociatedMemberGroup", "null"),new CommandParameter("AssociatedVisitorGroup", "null"),new CommandParameter("AssociatedOwnerGroup", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/GetPnPUserTests.cs b/Tests/Principals/GetPnPUserTests.cs new file mode 100644 index 000000000..e7bf20c77 --- /dev/null +++ b/Tests/Principals/GetPnPUserTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class GetUserTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUserTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUser",new CommandParameter("Identity", "null"),new CommandParameter("WithRightsAssigned", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/NewPnPGroupTests.cs b/Tests/Principals/NewPnPGroupTests.cs new file mode 100644 index 000000000..49d550988 --- /dev/null +++ b/Tests/Principals/NewPnPGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class NewGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPGroup",new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("Owner", "null"),new CommandParameter("AllowRequestToJoinLeave", "null"),new CommandParameter("AutoAcceptRequestToJoinLeave", "null"),new CommandParameter("AllowMembersEditMembership", "null"),new CommandParameter("OnlyAllowMembersViewMembership", "null"),new CommandParameter("DisallowMembersViewMembership", "null"),new CommandParameter("RequestToJoinEmail", "null"),new CommandParameter("SetAssociatedGroup", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/NewPnPUserTests.cs b/Tests/Principals/NewPnPUserTests.cs new file mode 100644 index 000000000..e714a4b9d --- /dev/null +++ b/Tests/Principals/NewPnPUserTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class NewUserTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPUserTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPUser",new CommandParameter("LoginName", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/RemovePnPAlertTests.cs b/Tests/Principals/RemovePnPAlertTests.cs new file mode 100644 index 000000000..76002e906 --- /dev/null +++ b/Tests/Principals/RemovePnPAlertTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class RemoveAlertTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPAlertTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPAlert",new CommandParameter("User", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/RemovePnPGroupTests.cs b/Tests/Principals/RemovePnPGroupTests.cs new file mode 100644 index 000000000..e08ced6bd --- /dev/null +++ b/Tests/Principals/RemovePnPGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class RemoveGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPGroup",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/RemovePnPUserFromGroupTests.cs b/Tests/Principals/RemovePnPUserFromGroupTests.cs new file mode 100644 index 000000000..c6a45699d --- /dev/null +++ b/Tests/Principals/RemovePnPUserFromGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class RemoveUserFromGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPUserFromGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPUserFromGroup",new CommandParameter("LoginName", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/RemovePnPUserTests.cs b/Tests/Principals/RemovePnPUserTests.cs new file mode 100644 index 000000000..f03275b7f --- /dev/null +++ b/Tests/Principals/RemovePnPUserTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class RemoveUserTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPUserTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPUser",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null"),new CommandParameter("Confirm", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/SetPnPGroupPermissionsTests.cs b/Tests/Principals/SetPnPGroupPermissionsTests.cs new file mode 100644 index 000000000..b089d3128 --- /dev/null +++ b/Tests/Principals/SetPnPGroupPermissionsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class SetGroupPermissionsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPGroupPermissionsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPGroupPermissions",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Principals/SetPnPGroupTests.cs b/Tests/Principals/SetPnPGroupTests.cs new file mode 100644 index 000000000..2027f4ab4 --- /dev/null +++ b/Tests/Principals/SetPnPGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Principals +{ + + [TestClass] + public class SetGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPGroup",new CommandParameter("Identity", "null"),new CommandParameter("SetAssociatedGroup", "null"),new CommandParameter("AddRole", "null"),new CommandParameter("RemoveRole", "null"),new CommandParameter("Title", "null"),new CommandParameter("Owner", "null"),new CommandParameter("Description", "null"),new CommandParameter("AllowRequestToJoinLeave", "null"),new CommandParameter("AutoAcceptRequestToJoinLeave", "null"),new CommandParameter("AllowMembersEditMembership", "null"),new CommandParameter("OnlyAllowMembersViewMembership", "null"),new CommandParameter("RequestToJoinEmail", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs new file mode 100644 index 000000000..68434ff34 --- /dev/null +++ b/Tests/Provisioning.Site/AddPnPDataRowsToProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class AddDataRowsToProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPDataRowsToProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPDataRowsToProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("List", "null"),new CommandParameter("Query", "null"),new CommandParameter("Fields", "null"),new CommandParameter("IncludeSecurity", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("TokenizeUrls", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs new file mode 100644 index 000000000..ca1921e1c --- /dev/null +++ b/Tests/Provisioning.Site/AddPnPFileToProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class AddFileToProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPFileToProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPFileToProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("Source", "null"),new CommandParameter("SourceUrl", "null"),new CommandParameter("Folder", "null"),new CommandParameter("Container", "null"),new CommandParameter("FileLevel", "null"),new CommandParameter("FileOverwrite", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs new file mode 100644 index 000000000..4136a4435 --- /dev/null +++ b/Tests/Provisioning.Site/AddPnPListFoldersToProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class AddListFoldersToProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPListFoldersToProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPListFoldersToProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("List", "null"),new CommandParameter("Recursive", "null"),new CommandParameter("IncludeSecurity", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs b/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs new file mode 100644 index 000000000..893f97fb0 --- /dev/null +++ b/Tests/Provisioning.Site/ApplyPnPProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class ApplyProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ApplyPnPProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Apply-PnPProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("TemplateId", "null"),new CommandParameter("ResourceFolder", "null"),new CommandParameter("OverwriteSystemPropertyBagValues", "null"),new CommandParameter("IgnoreDuplicateDataRowErrors", "null"),new CommandParameter("ProvisionContentTypesToSubWebs", "null"),new CommandParameter("ProvisionFieldsToSubWebs", "null"),new CommandParameter("ClearNavigation", "null"),new CommandParameter("Parameters", "null"),new CommandParameter("Handlers", "null"),new CommandParameter("ExcludeHandlers", "null"),new CommandParameter("ExtensibilityHandlers", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("InputInstance", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs b/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs new file mode 100644 index 000000000..90ebad459 --- /dev/null +++ b/Tests/Provisioning.Site/ExportPnPListToProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class ExportListToProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ExportPnPListToProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Export-PnPListToProvisioningTemplate",new CommandParameter("List", "null"),new CommandParameter("Out", "null"),new CommandParameter("Schema", "null"),new CommandParameter("Force", "null"),new CommandParameter("OutputInstance", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs b/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs new file mode 100644 index 000000000..09926cc4b --- /dev/null +++ b/Tests/Provisioning.Site/GetPnPProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class GetProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPProvisioningTemplate",new CommandParameter("Out", "null"),new CommandParameter("Schema", "null"),new CommandParameter("IncludeAllTermGroups", "null"),new CommandParameter("IncludeSiteCollectionTermGroup", "null"),new CommandParameter("IncludeSiteGroups", "null"),new CommandParameter("IncludeTermGroupsSecurity", "null"),new CommandParameter("IncludeSearchConfiguration", "null"),new CommandParameter("PersistBrandingFiles", "null"),new CommandParameter("PersistComposedLookFiles", "null"),new CommandParameter("PersistPublishingFiles", "null"),new CommandParameter("IncludeNativePublishingFiles", "null"),new CommandParameter("IncludeHiddenLists", "null"),new CommandParameter("IncludeAllClientSidePages", "null"),new CommandParameter("SkipVersionCheck", "null"),new CommandParameter("PersistMultiLanguageResources", "null"),new CommandParameter("ResourceFilePrefix", "null"),new CommandParameter("Handlers", "null"),new CommandParameter("ExcludeHandlers", "null"),new CommandParameter("ExtensibilityHandlers", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("ContentTypeGroups", "null"),new CommandParameter("Force", "null"),new CommandParameter("NoBaseTemplate", "null"),new CommandParameter("Encoding", "null"),new CommandParameter("TemplateDisplayName", "null"),new CommandParameter("TemplateImagePreviewUrl", "null"),new CommandParameter("TemplateProperties", "null"),new CommandParameter("OutputInstance", "null"),new CommandParameter("ExcludeContentTypesFromSyndication", "null"),new CommandParameter("ListsToExtract", "null"),new CommandParameter("Configuration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs b/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs new file mode 100644 index 000000000..e2988b4d4 --- /dev/null +++ b/Tests/Provisioning.Site/GetPnPTenantTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class GetTenantTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantTemplate",new CommandParameter("SiteUrl", "null"),new CommandParameter("Out", "null"),new CommandParameter("Force", "null"),new CommandParameter("AsInstance", "null"),new CommandParameter("Configuration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs b/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs new file mode 100644 index 000000000..14dd6db6b --- /dev/null +++ b/Tests/Provisioning.Site/RemovePnPFileFromProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class RemoveFileFromProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPFileFromProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPFileFromProvisioningTemplate",new CommandParameter("Path", "null"),new CommandParameter("FilePath", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs b/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs new file mode 100644 index 000000000..95f13aa13 --- /dev/null +++ b/Tests/Provisioning.Site/SetPnPProvisioningTemplateMetadataTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Site +{ + + [TestClass] + public class SetProvisioningTemplateMetadataTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPProvisioningTemplateMetadataTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPProvisioningTemplateMetadata",new CommandParameter("Path", "null"),new CommandParameter("TemplateDisplayName", "null"),new CommandParameter("TemplateImagePreviewUrl", "null"),new CommandParameter("TemplateProperties", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs b/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs new file mode 100644 index 000000000..d39fd49dd --- /dev/null +++ b/Tests/Provisioning.Tenant/AddPnPProvisioningTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class AddProvisioningTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPProvisioningTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPProvisioningTemplate",new CommandParameter("SiteTemplate", "null"),new CommandParameter("TenantTemplate", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs new file mode 100644 index 000000000..47a118a2d --- /dev/null +++ b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class AddTenantSequenceSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTenantSequenceSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTenantSequenceSite",new CommandParameter("Site", "null"),new CommandParameter("Sequence", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs new file mode 100644 index 000000000..dd3a5c258 --- /dev/null +++ b/Tests/Provisioning.Tenant/AddPnPTenantSequenceSubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class AddTenantSequenceSubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTenantSequenceSubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTenantSequenceSubSite",new CommandParameter("SubSite", "null"),new CommandParameter("Site", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs b/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs new file mode 100644 index 000000000..97ee32f52 --- /dev/null +++ b/Tests/Provisioning.Tenant/AddPnPTenantSequenceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class AddTenantSequenceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTenantSequenceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTenantSequence",new CommandParameter("Template", "null"),new CommandParameter("Sequence", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs new file mode 100644 index 000000000..edc49aa17 --- /dev/null +++ b/Tests/Provisioning.Tenant/ApplyPnPTenantTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class ApplyTenantTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ApplyPnPTenantTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Apply-PnPTenantTemplate",new CommandParameter("Path", "null"),new CommandParameter("Template", "null"),new CommandParameter("SequenceId", "null"),new CommandParameter("ResourceFolder", "null"),new CommandParameter("Handlers", "null"),new CommandParameter("ExcludeHandlers", "null"),new CommandParameter("ExtensibilityHandlers", "null"),new CommandParameter("TemplateProviderExtensions", "null"),new CommandParameter("Parameters", "null"),new CommandParameter("OverwriteSystemPropertyBagValues", "null"),new CommandParameter("IgnoreDuplicateDataRowErrors", "null"),new CommandParameter("ProvisionContentTypesToSubWebs", "null"),new CommandParameter("ProvisionFieldsToSubWebs", "null"),new CommandParameter("ClearNavigation", "null"),new CommandParameter("Configuration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs b/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs new file mode 100644 index 000000000..05e3245b1 --- /dev/null +++ b/Tests/Provisioning.Tenant/ExportPnPClientSidePageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class ExportClientSidePageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ExportPnPClientSidePageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Export-PnPClientSidePage",new CommandParameter("Identity", "null"),new CommandParameter("PersistBrandingFiles", "null"),new CommandParameter("Out", "null"),new CommandParameter("Force", "null"),new CommandParameter("Configuration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs b/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs new file mode 100644 index 000000000..856e964dc --- /dev/null +++ b/Tests/Provisioning.Tenant/GetPnPTenantSequenceSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class GetTenantSequenceSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantSequenceSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantSequenceSite",new CommandParameter("Sequence", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs b/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs new file mode 100644 index 000000000..b9db8d840 --- /dev/null +++ b/Tests/Provisioning.Tenant/GetPnPTenantSequenceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class GetTenantSequenceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantSequenceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantSequence",new CommandParameter("Template", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs new file mode 100644 index 000000000..2353c3d4a --- /dev/null +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceCommunicationSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class NewTenantSequenceCommunicationSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTenantSequenceCommunicationSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTenantSequenceCommunicationSite",new CommandParameter("Url", "null"),new CommandParameter("Title", "null"),new CommandParameter("Language", "null"),new CommandParameter("Owner", "null"),new CommandParameter("Description", "null"),new CommandParameter("Classification", "null"),new CommandParameter("SiteDesignId", "null"),new CommandParameter("HubSite", "null"),new CommandParameter("AllowFileSharingForGuestUsers", "null"),new CommandParameter("TemplateIds", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs new file mode 100644 index 000000000..65b061729 --- /dev/null +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class NewTenantSequenceTeamNoGroupSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTenantSequenceTeamNoGroupSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamNoGroupSite",new CommandParameter("Url", "null"),new CommandParameter("Title", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("Language", "null"),new CommandParameter("Owner", "null"),new CommandParameter("Description", "null"),new CommandParameter("HubSite", "null"),new CommandParameter("TemplateIds", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs new file mode 100644 index 000000000..0e3e902c9 --- /dev/null +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamNoGroupSubSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class NewTenantSequenceTeamNoGroupSubSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTenantSequenceTeamNoGroupSubSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamNoGroupSubSite",new CommandParameter("Url", "null"),new CommandParameter("Title", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("Language", "null"),new CommandParameter("Description", "null"),new CommandParameter("TemplateIds", "null"),new CommandParameter("QuickLaunchDisabled", "null"),new CommandParameter("UseDifferentPermissionsFromParentSite", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs new file mode 100644 index 000000000..653a6e3b4 --- /dev/null +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTeamSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class NewTenantSequenceTeamSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTenantSequenceTeamSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTenantSequenceTeamSite",new CommandParameter("Alias", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Classification", "null"),new CommandParameter("Public", "null"),new CommandParameter("HubSite", "null"),new CommandParameter("TemplateIds", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs new file mode 100644 index 000000000..c7377e0d5 --- /dev/null +++ b/Tests/Provisioning.Tenant/NewPnPTenantSequenceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class NewTenantSequenceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTenantSequenceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTenantSequence",new CommandParameter("Id", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs new file mode 100644 index 000000000..56d4d0b8b --- /dev/null +++ b/Tests/Provisioning.Tenant/NewPnPTenantTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class NewTenantTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTenantTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTenantTemplate",new CommandParameter("Author", "null"),new CommandParameter("Description", "null"),new CommandParameter("DisplayName", "null"),new CommandParameter("Generator", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs new file mode 100644 index 000000000..a3a4f5afa --- /dev/null +++ b/Tests/Provisioning.Tenant/ReadPnPTenantTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class ReadTenantTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ReadPnPTenantTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Read-PnPTenantTemplate",new CommandParameter("Path", "null"),new CommandParameter("TemplateProviderExtensions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs new file mode 100644 index 000000000..8972a8352 --- /dev/null +++ b/Tests/Provisioning.Tenant/SavePnPTenantTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class SaveTenantTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SavePnPTenantTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Save-PnPTenantTemplate",new CommandParameter("Template", "null"),new CommandParameter("Out", "null"),new CommandParameter("Schema", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs b/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs new file mode 100644 index 000000000..7fdfd07de --- /dev/null +++ b/Tests/Provisioning.Tenant/TestPnPTenantTemplateTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Provisioning.Tenant +{ + + [TestClass] + public class TestTenantTemplateTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void TestPnPTenantTemplateTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Test-PnPTenantTemplate",new CommandParameter("Template", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs b/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs new file mode 100644 index 000000000..b6664974b --- /dev/null +++ b/Tests/Publishing/AddPnPHtmlPublishingPageLayoutTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class AddHtmlPublishingPageLayoutTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPHtmlPublishingPageLayoutTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPHtmlPublishingPageLayout",new CommandParameter("SourceFilePath", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("AssociatedContentTypeID", "null"),new CommandParameter("DestinationFolderHierarchy", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/AddPnPMasterPageTests.cs b/Tests/Publishing/AddPnPMasterPageTests.cs new file mode 100644 index 000000000..126090e7e --- /dev/null +++ b/Tests/Publishing/AddPnPMasterPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class AddMasterPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPMasterPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPMasterPage",new CommandParameter("SourceFilePath", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("DestinationFolderHierarchy", "null"),new CommandParameter("UIVersion", "null"),new CommandParameter("DefaultCssFile", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs b/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs new file mode 100644 index 000000000..b5da9a1ba --- /dev/null +++ b/Tests/Publishing/AddPnPPublishingImageRenditionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class AddPublishingImageRenditionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPPublishingImageRenditionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPPublishingImageRendition",new CommandParameter("Name", "null"),new CommandParameter("Width", "null"),new CommandParameter("Height", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs b/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs new file mode 100644 index 000000000..9de85945d --- /dev/null +++ b/Tests/Publishing/AddPnPPublishingPageLayoutTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class AddPublishingPageLayoutTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPPublishingPageLayoutTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPPublishingPageLayout",new CommandParameter("SourceFilePath", "null"),new CommandParameter("Title", "null"),new CommandParameter("Description", "null"),new CommandParameter("AssociatedContentTypeID", "null"),new CommandParameter("DestinationFolderHierarchy", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/AddPnPPublishingPageTests.cs b/Tests/Publishing/AddPnPPublishingPageTests.cs new file mode 100644 index 000000000..40d426792 --- /dev/null +++ b/Tests/Publishing/AddPnPPublishingPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class AddPublishingPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPPublishingPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPPublishingPage",new CommandParameter("PageName", "null"),new CommandParameter("FolderPath", "null"),new CommandParameter("PageTemplateName", "null"),new CommandParameter("Title", "null"),new CommandParameter("Publish", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/AddPnPWikiPageTests.cs b/Tests/Publishing/AddPnPWikiPageTests.cs new file mode 100644 index 000000000..5609b6efe --- /dev/null +++ b/Tests/Publishing/AddPnPWikiPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class AddWikiPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPWikiPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPWikiPage",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Content", "null"),new CommandParameter("Layout", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs b/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs new file mode 100644 index 000000000..d51dad560 --- /dev/null +++ b/Tests/Publishing/GetPnPPublishingImageRenditionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class GetPublishingImageRenditionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPPublishingImageRenditionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPPublishingImageRendition",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/GetPnPWikiPageContentTests.cs b/Tests/Publishing/GetPnPWikiPageContentTests.cs new file mode 100644 index 000000000..c505d6f1e --- /dev/null +++ b/Tests/Publishing/GetPnPWikiPageContentTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class GetWikiPageContentTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWikiPageContentTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWikiPageContent",new CommandParameter("ServerRelativePageUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs b/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs new file mode 100644 index 000000000..79b6da251 --- /dev/null +++ b/Tests/Publishing/RemovePnPPublishingImageRenditionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class RemovePublishingImageRenditionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPPublishingImageRenditionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPPublishingImageRendition",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/RemovePnPWikiPageTests.cs b/Tests/Publishing/RemovePnPWikiPageTests.cs new file mode 100644 index 000000000..a0b903169 --- /dev/null +++ b/Tests/Publishing/RemovePnPWikiPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class RemoveWikiPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPWikiPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPWikiPage",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("SiteRelativePageUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs b/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs new file mode 100644 index 000000000..c1eabbf4e --- /dev/null +++ b/Tests/Publishing/SetPnPAvailablePageLayoutsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class SetAvailablePageLayoutsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPAvailablePageLayoutsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPAvailablePageLayouts",new CommandParameter("PageLayouts", "null"),new CommandParameter("AllowAllPageLayouts", "null"),new CommandParameter("InheritPageLayouts", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs b/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs new file mode 100644 index 000000000..c1c8dee2e --- /dev/null +++ b/Tests/Publishing/SetPnPDefaultPageLayoutTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class SetDefaultPageLayoutTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPDefaultPageLayoutTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPDefaultPageLayout",new CommandParameter("Title", "null"),new CommandParameter("InheritFromParentSite", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Publishing/SetPnPWikiPageContentTests.cs b/Tests/Publishing/SetPnPWikiPageContentTests.cs new file mode 100644 index 000000000..e64d3c50a --- /dev/null +++ b/Tests/Publishing/SetPnPWikiPageContentTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Publishing +{ + + [TestClass] + public class SetWikiPageContentTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPWikiPageContentTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPWikiPageContent",new CommandParameter("Content", "null"),new CommandParameter("Path", "null"),new CommandParameter("ServerRelativePageUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs b/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs new file mode 100644 index 000000000..cfedacb3e --- /dev/null +++ b/Tests/RecordsManagement/ClearPnPListItemAsRecordTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class ClearListItemAsRecordTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ClearPnPListItemAsRecordTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Clear-PnPListItemAsRecord",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs b/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs new file mode 100644 index 000000000..59e9b5854 --- /dev/null +++ b/Tests/RecordsManagement/DisablePnPInPlaceRecordsManagementForSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class DisableInPlaceRecordsManagementForSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPInPlaceRecordsManagementForSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPInPlaceRecordsManagementForSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs b/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs new file mode 100644 index 000000000..aaefc9650 --- /dev/null +++ b/Tests/RecordsManagement/EnablePnPInPlaceRecordsManagementForSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class EnableInPlaceRecordsManagementForSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPInPlaceRecordsManagementForSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPInPlaceRecordsManagementForSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs b/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs new file mode 100644 index 000000000..3c0aecd94 --- /dev/null +++ b/Tests/RecordsManagement/GetPnPInPlaceRecordsManagementTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class GetInPlaceRecordsManagementTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPInPlaceRecordsManagementTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPInPlaceRecordsManagement"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs b/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs new file mode 100644 index 000000000..4b5fa9d41 --- /dev/null +++ b/Tests/RecordsManagement/GetPnPListRecordDeclarationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class GetListRecordDeclarationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPListRecordDeclarationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPListRecordDeclaration",new CommandParameter("List", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs b/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs new file mode 100644 index 000000000..073d25c43 --- /dev/null +++ b/Tests/RecordsManagement/SetPnPInPlaceRecordsManagementTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class SetInPlaceRecordsManagementTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPInPlaceRecordsManagementTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPInPlaceRecordsManagement",new CommandParameter("Enabled", "null"),new CommandParameter("On", "null"),new CommandParameter("Off", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs b/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs new file mode 100644 index 000000000..3097b843f --- /dev/null +++ b/Tests/RecordsManagement/SetPnPListItemAsRecordTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class SetListItemAsRecordTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListItemAsRecordTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPListItemAsRecord",new CommandParameter("List", "null"),new CommandParameter("Identity", "null"),new CommandParameter("DeclarationDate", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs b/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs new file mode 100644 index 000000000..5e0a9b9e0 --- /dev/null +++ b/Tests/RecordsManagement/SetPnPListRecordDeclarationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class SetListRecordDeclarationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPListRecordDeclarationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPListRecordDeclaration",new CommandParameter("List", "null"),new CommandParameter("ManualRecordDeclaration", "null"),new CommandParameter("AutoRecordDeclaration", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs b/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs new file mode 100644 index 000000000..539c00510 --- /dev/null +++ b/Tests/RecordsManagement/TestPnPListItemIsRecordTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecordsManagement +{ + + [TestClass] + public class TestListItemIsRecordTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void TestPnPListItemIsRecordTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Test-PnPListItemIsRecord",new CommandParameter("List", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs b/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs new file mode 100644 index 000000000..996568d3e --- /dev/null +++ b/Tests/RecycleBin/ClearPnPRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class ClearRecycleBinItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ClearPnPRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Clear-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("All", "null"),new CommandParameter("SecondStageOnly", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs b/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs new file mode 100644 index 000000000..ab8a984c6 --- /dev/null +++ b/Tests/RecycleBin/ClearPnPTenantRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class ClearTenantRecycleBinItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ClearPnPTenantRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Clear-PnPTenantRecycleBinItem",new CommandParameter("Url", "null"),new CommandParameter("Wait", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs b/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs new file mode 100644 index 000000000..9725e2f3a --- /dev/null +++ b/Tests/RecycleBin/GetPnPRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class GetRecycleBinItemsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("FirstStage", "null"),new CommandParameter("SecondStage", "null"),new CommandParameter("RowLimit", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs b/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs new file mode 100644 index 000000000..2246615d4 --- /dev/null +++ b/Tests/RecycleBin/GetPnPTenantRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class GetTenantRecycleBinItemsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTenantRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTenantRecycleBinItem"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs b/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs new file mode 100644 index 000000000..7cf874658 --- /dev/null +++ b/Tests/RecycleBin/MovePnPRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class MoveRecycleBinItemsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void MovePnPRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Move-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs b/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs new file mode 100644 index 000000000..46f54b75c --- /dev/null +++ b/Tests/RecycleBin/RestorePnPRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class RestoreRecycleBinItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RestorePnPRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Restore-PnPRecycleBinItem",new CommandParameter("Identity", "null"),new CommandParameter("All", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs b/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs new file mode 100644 index 000000000..40ab83372 --- /dev/null +++ b/Tests/RecycleBin/RestorePnPTenantRecycleBinItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.RecycleBin +{ + + [TestClass] + public class RestoreTenantRecycleBinItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RestorePnPTenantRecycleBinItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Restore-PnPTenantRecycleBinItem",new CommandParameter("Url", "null"),new CommandParameter("Wait", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/GetPnPSearchConfigurationTests.cs b/Tests/Search/GetPnPSearchConfigurationTests.cs new file mode 100644 index 000000000..f5e583234 --- /dev/null +++ b/Tests/Search/GetPnPSearchConfigurationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class GetSearchConfigurationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSearchConfigurationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSearchConfiguration",new CommandParameter("Scope", "null"),new CommandParameter("Path", "null"),new CommandParameter("OutputFormat", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/GetPnPSearchCrawlLogTests.cs b/Tests/Search/GetPnPSearchCrawlLogTests.cs new file mode 100644 index 000000000..925326da4 --- /dev/null +++ b/Tests/Search/GetPnPSearchCrawlLogTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class GetSearchCrawlLogTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSearchCrawlLogTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSearchCrawlLog",new CommandParameter("LogLevel", "null"),new CommandParameter("RowLimit", "null"),new CommandParameter("Filter", "null"),new CommandParameter("ContentSource", "null"),new CommandParameter("StartDate", "null"),new CommandParameter("EndDate", "null"),new CommandParameter("RawFormat", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/GetPnPSearchSettingsTests.cs b/Tests/Search/GetPnPSearchSettingsTests.cs new file mode 100644 index 000000000..32cc7d945 --- /dev/null +++ b/Tests/Search/GetPnPSearchSettingsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class GetSearchSettingsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSearchSettingsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSearchSettings"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs b/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs new file mode 100644 index 000000000..66a318f22 --- /dev/null +++ b/Tests/Search/GetPnPSiteSearchQueryResultsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class GetSiteSearchQueryResultsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteSearchQueryResultsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteSearchQueryResults",new CommandParameter("Query", "null"),new CommandParameter("StartRow", "null"),new CommandParameter("MaxResults", "null"),new CommandParameter("All", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/RemovePnPSearchConfigurationTests.cs b/Tests/Search/RemovePnPSearchConfigurationTests.cs new file mode 100644 index 000000000..a7a83ea53 --- /dev/null +++ b/Tests/Search/RemovePnPSearchConfigurationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class RemoveSearchConfigurationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPSearchConfigurationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPSearchConfiguration",new CommandParameter("Configuration", "null"),new CommandParameter("Path", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/SetPnPSearchConfigurationTests.cs b/Tests/Search/SetPnPSearchConfigurationTests.cs new file mode 100644 index 000000000..5cb94d0ce --- /dev/null +++ b/Tests/Search/SetPnPSearchConfigurationTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class SetSearchConfigurationTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPSearchConfigurationTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPSearchConfiguration",new CommandParameter("Configuration", "null"),new CommandParameter("Path", "null"),new CommandParameter("Scope", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/SetPnPSearchSettingsTests.cs b/Tests/Search/SetPnPSearchSettingsTests.cs new file mode 100644 index 000000000..bc8abdf63 --- /dev/null +++ b/Tests/Search/SetPnPSearchSettingsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class SetSearchSettingsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPSearchSettingsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPSearchSettings",new CommandParameter("SearchBoxInNavBar", "null"),new CommandParameter("SearchPageUrl", "null"),new CommandParameter("SearchScope", "null"),new CommandParameter("Scope", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Search/SubmitPnPSearchQueryTests.cs b/Tests/Search/SubmitPnPSearchQueryTests.cs new file mode 100644 index 000000000..793ec41bf --- /dev/null +++ b/Tests/Search/SubmitPnPSearchQueryTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Search +{ + + [TestClass] + public class SubmitSearchQueryTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SubmitPnPSearchQueryTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Submit-PnPSearchQuery",new CommandParameter("Query", "null"),new CommandParameter("StartRow", "null"),new CommandParameter("MaxResults", "null"),new CommandParameter("All", "null"),new CommandParameter("TrimDuplicates", "null"),new CommandParameter("Properties", "null"),new CommandParameter("Refiners", "null"),new CommandParameter("Culture", "null"),new CommandParameter("QueryTemplate", "null"),new CommandParameter("SelectProperties", "null"),new CommandParameter("RefinementFilters", "null"),new CommandParameter("SortList", "null"),new CommandParameter("RankingModelId", "null"),new CommandParameter("ClientType", "null"),new CommandParameter("CollapseSpecification", "null"),new CommandParameter("HiddenConstraints", "null"),new CommandParameter("TimeZoneId", "null"),new CommandParameter("EnablePhonetic", "null"),new CommandParameter("EnableStemming", "null"),new CommandParameter("EnableQueryRules", "null"),new CommandParameter("SourceId", "null"),new CommandParameter("ProcessBestBets", "null"),new CommandParameter("ProcessPersonalFavorites", "null"),new CommandParameter("RelevantResults", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 291c4b64a..5fec4b3e0 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -484,17 +484,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -503,6 +734,16 @@ + + + + + + + + + + @@ -525,37 +766,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tests/Site/AddPnPRoleDefinitionTests.cs b/Tests/Site/AddPnPRoleDefinitionTests.cs new file mode 100644 index 000000000..b6791fc13 --- /dev/null +++ b/Tests/Site/AddPnPRoleDefinitionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class AddRoleDefinitionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPRoleDefinitionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPRoleDefinition",new CommandParameter("RoleName", "null"),new CommandParameter("Clone", "null"),new CommandParameter("Include", "null"),new CommandParameter("Exclude", "null"),new CommandParameter("Description", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/AddPnPSiteCollectionAdminTests.cs b/Tests/Site/AddPnPSiteCollectionAdminTests.cs new file mode 100644 index 000000000..80193ecc9 --- /dev/null +++ b/Tests/Site/AddPnPSiteCollectionAdminTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class AddSiteCollectionAdminTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPSiteCollectionAdminTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPSiteCollectionAdmin",new CommandParameter("Owners", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/AddPnPTeamsTeamTests.cs b/Tests/Site/AddPnPTeamsTeamTests.cs new file mode 100644 index 000000000..d3ca0887d --- /dev/null +++ b/Tests/Site/AddPnPTeamsTeamTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class AddTeamsTeamTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPTeamsTeamTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPTeamsTeam"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs b/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs new file mode 100644 index 000000000..31fcd87a5 --- /dev/null +++ b/Tests/Site/DisablePnPSharingForNonOwnersOfSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class DisableSharingForNonOwnersOfSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void DisablePnPSharingForNonOwnersOfSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Disable-PnPSharingForNonOwnersOfSite",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/EnablePnPCommSiteTests.cs b/Tests/Site/EnablePnPCommSiteTests.cs new file mode 100644 index 000000000..898d4d7f8 --- /dev/null +++ b/Tests/Site/EnablePnPCommSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class EnableCommSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void EnablePnPCommSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Enable-PnPCommSite",new CommandParameter("DesignPackageId", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/GetPnPAuditingTests.cs b/Tests/Site/GetPnPAuditingTests.cs new file mode 100644 index 000000000..f64c1f6b3 --- /dev/null +++ b/Tests/Site/GetPnPAuditingTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class GetAuditingTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPAuditingTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPAuditing"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/GetPnPRoleDefinitionTests.cs b/Tests/Site/GetPnPRoleDefinitionTests.cs new file mode 100644 index 000000000..a73784d7b --- /dev/null +++ b/Tests/Site/GetPnPRoleDefinitionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class GetRoleDefinitionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPRoleDefinitionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPRoleDefinition",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs b/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs new file mode 100644 index 000000000..177cd1e8c --- /dev/null +++ b/Tests/Site/GetPnPSharingForNonOwnersOfSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class GetSharingForNonOwnersOfSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSharingForNonOwnersOfSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSharingForNonOwnersOfSite",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/GetPnPSiteCollectionAdminTests.cs b/Tests/Site/GetPnPSiteCollectionAdminTests.cs new file mode 100644 index 000000000..077ffd73d --- /dev/null +++ b/Tests/Site/GetPnPSiteCollectionAdminTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class GetSiteCollectionAdminTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteCollectionAdminTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteCollectionAdmin"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/GetPnPSiteTests.cs b/Tests/Site/GetPnPSiteTests.cs new file mode 100644 index 000000000..1c2664980 --- /dev/null +++ b/Tests/Site/GetPnPSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class GetSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSite"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/InstallPnPSolutionTests.cs b/Tests/Site/InstallPnPSolutionTests.cs new file mode 100644 index 000000000..f22150ae2 --- /dev/null +++ b/Tests/Site/InstallPnPSolutionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class InstallSolutionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void InstallPnPSolutionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Install-PnPSolution",new CommandParameter("PackageId", "null"),new CommandParameter("SourceFilePath", "null"),new CommandParameter("MajorVersion", "null"),new CommandParameter("MinorVersion", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/RemovePnPRoleDefinitionTests.cs b/Tests/Site/RemovePnPRoleDefinitionTests.cs new file mode 100644 index 000000000..66a6906fb --- /dev/null +++ b/Tests/Site/RemovePnPRoleDefinitionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class RemoveRoleDefinitionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPRoleDefinitionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPRoleDefinition",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/RemovePnPSiteCollectionAdminTests.cs b/Tests/Site/RemovePnPSiteCollectionAdminTests.cs new file mode 100644 index 000000000..98b53ec28 --- /dev/null +++ b/Tests/Site/RemovePnPSiteCollectionAdminTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class RemoveSiteCollectionAdminTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPSiteCollectionAdminTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPSiteCollectionAdmin",new CommandParameter("Owners", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/SetPnPAppSideLoadingTests.cs b/Tests/Site/SetPnPAppSideLoadingTests.cs new file mode 100644 index 000000000..b99bd2516 --- /dev/null +++ b/Tests/Site/SetPnPAppSideLoadingTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class SetAppSideLoadingTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPAppSideLoadingTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPAppSideLoading",new CommandParameter("On", "null"),new CommandParameter("Off", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/SetPnPAuditingTests.cs b/Tests/Site/SetPnPAuditingTests.cs new file mode 100644 index 000000000..30fbbeaa1 --- /dev/null +++ b/Tests/Site/SetPnPAuditingTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class SetAuditingTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPAuditingTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPAuditing",new CommandParameter("EnableAll", "null"),new CommandParameter("DisableAll", "null"),new CommandParameter("RetentionTime", "null"),new CommandParameter("TrimAuditLog", "null"),new CommandParameter("EditItems", "null"),new CommandParameter("CheckOutCheckInItems", "null"),new CommandParameter("MoveCopyItems", "null"),new CommandParameter("DeleteRestoreItems", "null"),new CommandParameter("EditContentTypesColumns", "null"),new CommandParameter("SearchContent", "null"),new CommandParameter("EditUsersPermissions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/SetPnPSiteTests.cs b/Tests/Site/SetPnPSiteTests.cs new file mode 100644 index 000000000..81670305d --- /dev/null +++ b/Tests/Site/SetPnPSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class SetSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPSite",new CommandParameter("Identity", "null"),new CommandParameter("Classification", "null"),new CommandParameter("DisableFlows", "null"),new CommandParameter("LogoFilePath", "null"),new CommandParameter("Sharing", "null"),new CommandParameter("StorageMaximumLevel", "null"),new CommandParameter("StorageWarningLevel", "null"),new CommandParameter("UserCodeMaximumLevel", "null"),new CommandParameter("UserCodeWarningLevel", "null"),new CommandParameter("LockState", "null"),new CommandParameter("AllowSelfServiceUpgrade", "null"),new CommandParameter("NoScriptSite", "null"),new CommandParameter("Owners", "null"),new CommandParameter("CommentsOnSitePagesDisabled", "null"),new CommandParameter("DefaultLinkPermission", "null"),new CommandParameter("DefaultSharingLinkType", "null"),new CommandParameter("DisableAppViews", "null"),new CommandParameter("DisableCompanyWideSharingLinks", "null"),new CommandParameter("DisableSharingForNonOwners", "null"),new CommandParameter("LocaleId", "null"),new CommandParameter("NewUrl", "null"),new CommandParameter("RestrictedToGeo", "null"),new CommandParameter("SocialBarOnSitePagesDisabled", "null"),new CommandParameter("Wait", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs b/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs new file mode 100644 index 000000000..09d7b3c63 --- /dev/null +++ b/Tests/Site/TestPnPOffice365GroupAliasIsUsedTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class AddOffice365GroupAliasIsUsedTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void TestPnPOffice365GroupAliasIsUsedTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Test-PnPOffice365GroupAliasIsUsed",new CommandParameter("Alias", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Site/UninstallPnPSolutionTests.cs b/Tests/Site/UninstallPnPSolutionTests.cs new file mode 100644 index 000000000..09f410141 --- /dev/null +++ b/Tests/Site/UninstallPnPSolutionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Site +{ + + [TestClass] + public class UninstallSolutionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void UninstallPnPSolutionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Uninstall-PnPSolution",new CommandParameter("PackageId", "null"),new CommandParameter("PackageName", "null"),new CommandParameter("MajorVersion", "null"),new CommandParameter("MinorVersion", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs b/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs new file mode 100644 index 000000000..73a627cab --- /dev/null +++ b/Tests/SiteDesigns/AddPnPSiteDesignTaskTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.SiteDesigns +{ + + [TestClass] + public class AddSiteDesignTaskTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPSiteDesignTaskTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPSiteDesignTask",new CommandParameter("SiteDesignId", "null"),new CommandParameter("WebUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs b/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs new file mode 100644 index 000000000..4c833ecc5 --- /dev/null +++ b/Tests/SiteDesigns/GetPnPSiteDesignRunStatusTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.SiteDesigns +{ + + [TestClass] + public class GetSiteDesignRunStatusTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteDesignRunStatusTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteDesignRunStatus",new CommandParameter("Run", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs b/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs new file mode 100644 index 000000000..d786bf9c4 --- /dev/null +++ b/Tests/SiteDesigns/GetPnPSiteDesignRunTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.SiteDesigns +{ + + [TestClass] + public class GetSiteDesignRunTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteDesignRunTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteDesignRun",new CommandParameter("SiteDesignId", "null"),new CommandParameter("WebUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs b/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs new file mode 100644 index 000000000..da9864f6d --- /dev/null +++ b/Tests/SiteDesigns/GetPnPSiteDesignTaskTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.SiteDesigns +{ + + [TestClass] + public class GetSiteDesignTaskTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteDesignTaskTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteDesignTask",new CommandParameter("Identity", "null"),new CommandParameter("WebUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/ExportPnPTaxonomyTests.cs b/Tests/Taxonomy/ExportPnPTaxonomyTests.cs new file mode 100644 index 000000000..6243fd86d --- /dev/null +++ b/Tests/Taxonomy/ExportPnPTaxonomyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class ExportTaxonomyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ExportPnPTaxonomyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Export-PnPTaxonomy",new CommandParameter("TermSetId", "null"),new CommandParameter("IncludeID", "null"),new CommandParameter("Path", "null"),new CommandParameter("TermStoreName", "null"),new CommandParameter("Force", "null"),new CommandParameter("Delimiter", "null"),new CommandParameter("Lcid", "null"),new CommandParameter("Encoding", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/ExportPnPTermGroupToXmlTests.cs b/Tests/Taxonomy/ExportPnPTermGroupToXmlTests.cs new file mode 100644 index 000000000..cf007c86e --- /dev/null +++ b/Tests/Taxonomy/ExportPnPTermGroupToXmlTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class ExportTermGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ExportPnPTermGroupToXmlTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Export-PnPTermGroupToXml",new CommandParameter("Identity", "null"),new CommandParameter("Out", "null"),new CommandParameter("FullTemplate", "null"),new CommandParameter("Encoding", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/GetPnPSiteCollectionTermStoreTests.cs b/Tests/Taxonomy/GetPnPSiteCollectionTermStoreTests.cs new file mode 100644 index 000000000..4acc3719d --- /dev/null +++ b/Tests/Taxonomy/GetPnPSiteCollectionTermStoreTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class GetPnPSiteCollectionTermStoreTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPSiteCollectionTermStoreTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPSiteCollectionTermStore"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/GetPnPTaxonomyItemTests.cs b/Tests/Taxonomy/GetPnPTaxonomyItemTests.cs new file mode 100644 index 000000000..616d69411 --- /dev/null +++ b/Tests/Taxonomy/GetPnPTaxonomyItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class GetTaxonomyItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTaxonomyItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTaxonomyItem",new CommandParameter("TermPath", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/GetPnPTaxonomySessionTests.cs b/Tests/Taxonomy/GetPnPTaxonomySessionTests.cs new file mode 100644 index 000000000..fc70ce45c --- /dev/null +++ b/Tests/Taxonomy/GetPnPTaxonomySessionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class GetTaxonomySessionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTaxonomySessionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTaxonomySession"); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/GetPnPTermGroupTests.cs b/Tests/Taxonomy/GetPnPTermGroupTests.cs new file mode 100644 index 000000000..631def74c --- /dev/null +++ b/Tests/Taxonomy/GetPnPTermGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class GetTermGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTermGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTermGroup",new CommandParameter("Identity", "null"),new CommandParameter("TermStore", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/GetPnPTermSetTests.cs b/Tests/Taxonomy/GetPnPTermSetTests.cs new file mode 100644 index 000000000..d3cdc3c06 --- /dev/null +++ b/Tests/Taxonomy/GetPnPTermSetTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class GetTermSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTermSetTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTermSet",new CommandParameter("Identity", "null"),new CommandParameter("TermGroup", "null"),new CommandParameter("TermStore", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/GetPnPTermTests.cs b/Tests/Taxonomy/GetPnPTermTests.cs new file mode 100644 index 000000000..acf67619a --- /dev/null +++ b/Tests/Taxonomy/GetPnPTermTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class GetTermTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPTermTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPTerm",new CommandParameter("Identity", "null"),new CommandParameter("TermSet", "null"),new CommandParameter("TermGroup", "null"),new CommandParameter("TermStore", "null"),new CommandParameter("Recursive", "null"),new CommandParameter("IncludeChildTerms", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/ImportPnPTaxonomyTests.cs b/Tests/Taxonomy/ImportPnPTaxonomyTests.cs new file mode 100644 index 000000000..6af9b419e --- /dev/null +++ b/Tests/Taxonomy/ImportPnPTaxonomyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class ImportTaxonomyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ImportPnPTaxonomyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Import-PnPTaxonomy",new CommandParameter("Terms", "null"),new CommandParameter("Path", "null"),new CommandParameter("Lcid", "null"),new CommandParameter("TermStoreName", "null"),new CommandParameter("Delimiter", "null"),new CommandParameter("SynchronizeDeletions", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/ImportPnPTermGroupFromXmlTests.cs b/Tests/Taxonomy/ImportPnPTermGroupFromXmlTests.cs new file mode 100644 index 000000000..39a513bc9 --- /dev/null +++ b/Tests/Taxonomy/ImportPnPTermGroupFromXmlTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class ImportTermGroupFromXmlTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ImportPnPTermGroupFromXmlTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Import-PnPTermGroupFromXml",new CommandParameter("Xml", "null"),new CommandParameter("Path", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/ImportPnPTermSetTests.cs b/Tests/Taxonomy/ImportPnPTermSetTests.cs new file mode 100644 index 000000000..fa49f7eca --- /dev/null +++ b/Tests/Taxonomy/ImportPnPTermSetTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class ImportTermSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ImportPnPTermSetTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Import-PnPTermSet",new CommandParameter("GroupName", "null"),new CommandParameter("Path", "null"),new CommandParameter("TermSetId", "null"),new CommandParameter("SynchronizeDeletions", "null"),new CommandParameter("IsOpen", "null"),new CommandParameter("Contact", "null"),new CommandParameter("Owner", "null"),new CommandParameter("TermStoreName", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/NewPnPTermGroupTests.cs b/Tests/Taxonomy/NewPnPTermGroupTests.cs new file mode 100644 index 000000000..1f3d0d2ca --- /dev/null +++ b/Tests/Taxonomy/NewPnPTermGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class NewTermGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTermGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTermGroup",new CommandParameter("Name", "null"),new CommandParameter("Id", "null"),new CommandParameter("Description", "null"),new CommandParameter("TermStore", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/NewPnPTermLabelTests.cs b/Tests/Taxonomy/NewPnPTermLabelTests.cs new file mode 100644 index 000000000..79a05dd87 --- /dev/null +++ b/Tests/Taxonomy/NewPnPTermLabelTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class NewTermLabelTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTermLabelTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTermLabel",new CommandParameter("Term", "null"),new CommandParameter("Name", "null"),new CommandParameter("Lcid", "null"),new CommandParameter("IsDefault", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/NewPnPTermSetTests.cs b/Tests/Taxonomy/NewPnPTermSetTests.cs new file mode 100644 index 000000000..3c51214cd --- /dev/null +++ b/Tests/Taxonomy/NewPnPTermSetTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class NewTermSetTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTermSetTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTermSet",new CommandParameter("Name", "null"),new CommandParameter("Id", "null"),new CommandParameter("Lcid", "null"),new CommandParameter("TermGroup", "null"),new CommandParameter("Contact", "null"),new CommandParameter("Description", "null"),new CommandParameter("IsOpenForTermCreation", "null"),new CommandParameter("IsNotAvailableForTagging", "null"),new CommandParameter("Owner", "null"),new CommandParameter("StakeHolders", "null"),new CommandParameter("CustomProperties", "null"),new CommandParameter("TermStore", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/NewPnPTermTests.cs b/Tests/Taxonomy/NewPnPTermTests.cs new file mode 100644 index 000000000..ad991da07 --- /dev/null +++ b/Tests/Taxonomy/NewPnPTermTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class NewTermTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPTermTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPTerm",new CommandParameter("Name", "null"),new CommandParameter("Id", "null"),new CommandParameter("Lcid", "null"),new CommandParameter("TermSet", "null"),new CommandParameter("TermGroup", "null"),new CommandParameter("Description", "null"),new CommandParameter("CustomProperties", "null"),new CommandParameter("LocalCustomProperties", "null"),new CommandParameter("TermStore", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/RemovePnPTaxonomyItemTests.cs b/Tests/Taxonomy/RemovePnPTaxonomyItemTests.cs new file mode 100644 index 000000000..42592c95c --- /dev/null +++ b/Tests/Taxonomy/RemovePnPTaxonomyItemTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class RemoveTaxonomyItemTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPTaxonomyItemTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPTaxonomyItem",new CommandParameter("TermPath", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/RemovePnPTermGroupTests.cs b/Tests/Taxonomy/RemovePnPTermGroupTests.cs new file mode 100644 index 000000000..6e41fd23c --- /dev/null +++ b/Tests/Taxonomy/RemovePnPTermGroupTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class RemoveTermGroupTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPTermGroupTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPTermGroup",new CommandParameter("GroupName", "null"),new CommandParameter("TermStoreName", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Taxonomy/SetPnPTaxonomyFieldValueTests.cs b/Tests/Taxonomy/SetPnPTaxonomyFieldValueTests.cs new file mode 100644 index 000000000..359dd36bc --- /dev/null +++ b/Tests/Taxonomy/SetPnPTaxonomyFieldValueTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Taxonomy +{ + + [TestClass] + public class SetTaxonomyFieldValueTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPTaxonomyFieldValueTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPTaxonomyFieldValue",new CommandParameter("ListItem", "null"),new CommandParameter("InternalFieldName", "null"),new CommandParameter("TermId", "null"),new CommandParameter("Label", "null"),new CommandParameter("TermPath", "null"),new CommandParameter("Terms", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/GetPnPUPABulkImportStatusTests.cs b/Tests/UserProfiles/GetPnPUPABulkImportStatusTests.cs new file mode 100644 index 000000000..c9bd55777 --- /dev/null +++ b/Tests/UserProfiles/GetPnPUPABulkImportStatusTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class GetUPABulkImportStatusTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUPABulkImportStatusTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUPABulkImportStatus",new CommandParameter("JobId", "null"),new CommandParameter("IncludeErrorDetails", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/GetPnPUserOneDriveQuotaTests.cs b/Tests/UserProfiles/GetPnPUserOneDriveQuotaTests.cs new file mode 100644 index 000000000..d377ca7cc --- /dev/null +++ b/Tests/UserProfiles/GetPnPUserOneDriveQuotaTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class GetUserOneDriveQuotaTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUserOneDriveQuotaTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUserOneDriveQuota",new CommandParameter("Account", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/GetPnPUserProfilePropertyTests.cs b/Tests/UserProfiles/GetPnPUserProfilePropertyTests.cs new file mode 100644 index 000000000..4d18a762a --- /dev/null +++ b/Tests/UserProfiles/GetPnPUserProfilePropertyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class GetUserProfilePropertyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPUserProfilePropertyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPUserProfileProperty",new CommandParameter("Account", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/NewPnPPersonalSiteTests.cs b/Tests/UserProfiles/NewPnPPersonalSiteTests.cs new file mode 100644 index 000000000..3d064fade --- /dev/null +++ b/Tests/UserProfiles/NewPnPPersonalSiteTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class NewPersonalSiteTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPPersonalSiteTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPPersonalSite",new CommandParameter("Email", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/NewPnPUPABulkImportJobTests.cs b/Tests/UserProfiles/NewPnPUPABulkImportJobTests.cs new file mode 100644 index 000000000..d9252a6cd --- /dev/null +++ b/Tests/UserProfiles/NewPnPUPABulkImportJobTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class NewUPABulkImportJobTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void NewPnPUPABulkImportJobTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("New-PnPUPABulkImportJob",new CommandParameter("Folder", "null"),new CommandParameter("Path", "null"),new CommandParameter("UserProfilePropertyMapping", "null"),new CommandParameter("IdProperty", "null"),new CommandParameter("IdType", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/ResetPnPUserOneDriveQuotaToDefaultTests.cs b/Tests/UserProfiles/ResetPnPUserOneDriveQuotaToDefaultTests.cs new file mode 100644 index 000000000..6e5789683 --- /dev/null +++ b/Tests/UserProfiles/ResetPnPUserOneDriveQuotaToDefaultTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class ResetUserOneDriveQuotaMaxTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ResetPnPUserOneDriveQuotaToDefaultTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Reset-PnPUserOneDriveQuotaToDefault",new CommandParameter("Account", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/SetPnPUserOneDriveQuotaTests.cs b/Tests/UserProfiles/SetPnPUserOneDriveQuotaTests.cs new file mode 100644 index 000000000..3586a3bca --- /dev/null +++ b/Tests/UserProfiles/SetPnPUserOneDriveQuotaTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class SetUserOneDriveQuotaTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPUserOneDriveQuotaTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPUserOneDriveQuota",new CommandParameter("Account", "null"),new CommandParameter("Quota", "null"),new CommandParameter("QuotaWarning", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/UserProfiles/SetPnPUserProfilePropertyTests.cs b/Tests/UserProfiles/SetPnPUserProfilePropertyTests.cs new file mode 100644 index 000000000..755f56ee8 --- /dev/null +++ b/Tests/UserProfiles/SetPnPUserProfilePropertyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.UserProfiles +{ + + [TestClass] + public class SetUserProfilePropertyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPUserProfilePropertyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPUserProfileProperty",new CommandParameter("Account", "null"),new CommandParameter("PropertyName", "null"),new CommandParameter("Value", "null"),new CommandParameter("Values", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Utilities/SendPnPMailTests.cs b/Tests/Utilities/SendPnPMailTests.cs new file mode 100644 index 000000000..73147f103 --- /dev/null +++ b/Tests/Utilities/SendPnPMailTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Utilities +{ + + [TestClass] + public class SendMailTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SendPnPMailTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Send-PnPMail",new CommandParameter("Server", "null"),new CommandParameter("From", "null"),new CommandParameter("Password", "null"),new CommandParameter("To", "null"),new CommandParameter("Cc", "null"),new CommandParameter("Subject", "null"),new CommandParameter("Body", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/AddPnPClientSideWebPartTests.cs b/Tests/WebParts/AddPnPClientSideWebPartTests.cs new file mode 100644 index 000000000..419babb77 --- /dev/null +++ b/Tests/WebParts/AddPnPClientSideWebPartTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class AddClientSideWebPartTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPClientSideWebPartTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPClientSideWebPart",new CommandParameter("Page", "null"),new CommandParameter("DefaultWebPartType", "null"),new CommandParameter("Component", "null"),new CommandParameter("WebPartProperties", "null"),new CommandParameter("Order", "null"),new CommandParameter("Section", "null"),new CommandParameter("Column", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/AddPnPWebPartToWebPartPageTests.cs b/Tests/WebParts/AddPnPWebPartToWebPartPageTests.cs new file mode 100644 index 000000000..1006214b5 --- /dev/null +++ b/Tests/WebParts/AddPnPWebPartToWebPartPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class AddWebPartToWebPartPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPWebPartToWebPartPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPWebPartToWebPartPage",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Xml", "null"),new CommandParameter("Path", "null"),new CommandParameter("ZoneId", "null"),new CommandParameter("ZoneIndex", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/AddPnPWebPartToWikiPageTests.cs b/Tests/WebParts/AddPnPWebPartToWikiPageTests.cs new file mode 100644 index 000000000..a424d4676 --- /dev/null +++ b/Tests/WebParts/AddPnPWebPartToWikiPageTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class AddWebPartToWikiPageTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPWebPartToWikiPageTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPWebPartToWikiPage",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Xml", "null"),new CommandParameter("Path", "null"),new CommandParameter("Row", "null"),new CommandParameter("Column", "null"),new CommandParameter("AddSpace", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/GetPnPWebPartPropertyTests.cs b/Tests/WebParts/GetPnPWebPartPropertyTests.cs new file mode 100644 index 000000000..964a6194b --- /dev/null +++ b/Tests/WebParts/GetPnPWebPartPropertyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class GetWebPartPropertyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWebPartPropertyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWebPartProperty",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Key", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/GetPnPWebPartTests.cs b/Tests/WebParts/GetPnPWebPartTests.cs new file mode 100644 index 000000000..fe18be3ae --- /dev/null +++ b/Tests/WebParts/GetPnPWebPartTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class GetWebPartTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWebPartTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWebPart",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/GetPnPWebPartXmlTests.cs b/Tests/WebParts/GetPnPWebPartXmlTests.cs new file mode 100644 index 000000000..f391956e1 --- /dev/null +++ b/Tests/WebParts/GetPnPWebPartXmlTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class GetWebPartXmlTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWebPartXmlTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWebPartXml",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/RemovePnPWebPartTests.cs b/Tests/WebParts/RemovePnPWebPartTests.cs new file mode 100644 index 000000000..8aa1cae98 --- /dev/null +++ b/Tests/WebParts/RemovePnPWebPartTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class RemoveWebPartTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPWebPartTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPWebPart",new CommandParameter("Identity", "null"),new CommandParameter("Title", "null"),new CommandParameter("ServerRelativePageUrl", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/WebParts/SetPnPWebPartPropertyTests.cs b/Tests/WebParts/SetPnPWebPartPropertyTests.cs new file mode 100644 index 000000000..328b2abfd --- /dev/null +++ b/Tests/WebParts/SetPnPWebPartPropertyTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.WebParts +{ + + [TestClass] + public class SetWebPartPropertyTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPWebPartPropertyTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPWebPartProperty",new CommandParameter("ServerRelativePageUrl", "null"),new CommandParameter("Identity", "null"),new CommandParameter("Key", "null"),new CommandParameter("Value", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Webhooks/AddPnPWebhookSubscriptionTests.cs b/Tests/Webhooks/AddPnPWebhookSubscriptionTests.cs new file mode 100644 index 000000000..4502bf9a2 --- /dev/null +++ b/Tests/Webhooks/AddPnPWebhookSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Webhooks +{ + + [TestClass] + public class AddWebhookSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPWebhookSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPWebhookSubscription",new CommandParameter("List", "null"),new CommandParameter("NotificationUrl", "null"),new CommandParameter("ExpirationDate", "null"),new CommandParameter("ClientState", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Webhooks/GetPnPWebhookSubscriptionsTests.cs b/Tests/Webhooks/GetPnPWebhookSubscriptionsTests.cs new file mode 100644 index 000000000..f16059308 --- /dev/null +++ b/Tests/Webhooks/GetPnPWebhookSubscriptionsTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Webhooks +{ + + [TestClass] + public class GetWebhookSubscriptionsTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWebhookSubscriptionsTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWebhookSubscriptions",new CommandParameter("List", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Webhooks/RemovePnPWebhookSubscriptionTests.cs b/Tests/Webhooks/RemovePnPWebhookSubscriptionTests.cs new file mode 100644 index 000000000..f6be6b30c --- /dev/null +++ b/Tests/Webhooks/RemovePnPWebhookSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Webhooks +{ + + [TestClass] + public class RemoveWebhookSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPWebhookSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPWebhookSubscription",new CommandParameter("Identity", "null"),new CommandParameter("List", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Webhooks/SetPnPWebhookSubscriptionTests.cs b/Tests/Webhooks/SetPnPWebhookSubscriptionTests.cs new file mode 100644 index 000000000..4f35b3c14 --- /dev/null +++ b/Tests/Webhooks/SetPnPWebhookSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Webhooks +{ + + [TestClass] + public class SetWebhookSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void SetPnPWebhookSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Set-PnPWebhookSubscription",new CommandParameter("Subscription", "null"),new CommandParameter("List", "null"),new CommandParameter("NotificationUrl", "null"),new CommandParameter("ExpirationDate", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/AddPnPWorkflowDefinitionTests.cs b/Tests/Workflows/AddPnPWorkflowDefinitionTests.cs new file mode 100644 index 000000000..84d91bd7c --- /dev/null +++ b/Tests/Workflows/AddPnPWorkflowDefinitionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class AddWorkflowDefinitionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPWorkflowDefinitionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPWorkflowDefinition",new CommandParameter("Definition", "null"),new CommandParameter("DoNotPublish", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/AddPnPWorkflowSubscriptionTests.cs b/Tests/Workflows/AddPnPWorkflowSubscriptionTests.cs new file mode 100644 index 000000000..9cfaa7e18 --- /dev/null +++ b/Tests/Workflows/AddPnPWorkflowSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class AddWorkflowSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void AddPnPWorkflowSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Add-PnPWorkflowSubscription",new CommandParameter("Name", "null"),new CommandParameter("DefinitionName", "null"),new CommandParameter("List", "null"),new CommandParameter("StartManually", "null"),new CommandParameter("StartOnCreated", "null"),new CommandParameter("StartOnChanged", "null"),new CommandParameter("HistoryListName", "null"),new CommandParameter("TaskListName", "null"),new CommandParameter("AssociationValues", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/GetPnPWorkflowDefinitionTests.cs b/Tests/Workflows/GetPnPWorkflowDefinitionTests.cs new file mode 100644 index 000000000..9e2cc9e90 --- /dev/null +++ b/Tests/Workflows/GetPnPWorkflowDefinitionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class GetWorkflowDefinitionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWorkflowDefinitionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWorkflowDefinition",new CommandParameter("Name", "null"),new CommandParameter("PublishedOnly", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/GetPnPWorkflowInstanceTests.cs b/Tests/Workflows/GetPnPWorkflowInstanceTests.cs new file mode 100644 index 000000000..bbd833f90 --- /dev/null +++ b/Tests/Workflows/GetPnPWorkflowInstanceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class GetWorkflowInstanceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWorkflowInstanceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWorkflowInstance",new CommandParameter("List", "null"),new CommandParameter("ListItem", "null"),new CommandParameter("WorkflowSubscription", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/GetPnPWorkflowSubscriptionTests.cs b/Tests/Workflows/GetPnPWorkflowSubscriptionTests.cs new file mode 100644 index 000000000..272a64b3a --- /dev/null +++ b/Tests/Workflows/GetPnPWorkflowSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class GetWorkflowSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void GetPnPWorkflowSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Get-PnPWorkflowSubscription",new CommandParameter("Name", "null"),new CommandParameter("List", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/RemovePnPWorkflowDefinitionTests.cs b/Tests/Workflows/RemovePnPWorkflowDefinitionTests.cs new file mode 100644 index 000000000..9075c57dc --- /dev/null +++ b/Tests/Workflows/RemovePnPWorkflowDefinitionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class RemoveWorkflowDefinitionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPWorkflowDefinitionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPWorkflowDefinition",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/RemovePnPWorkflowSubscriptionTests.cs b/Tests/Workflows/RemovePnPWorkflowSubscriptionTests.cs new file mode 100644 index 000000000..2657bf8c7 --- /dev/null +++ b/Tests/Workflows/RemovePnPWorkflowSubscriptionTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class RemoveWorkflowSubscriptionTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void RemovePnPWorkflowSubscriptionTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Remove-PnPWorkflowSubscription",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/ResumePnPWorkflowInstanceTests.cs b/Tests/Workflows/ResumePnPWorkflowInstanceTests.cs new file mode 100644 index 000000000..3756a6e19 --- /dev/null +++ b/Tests/Workflows/ResumePnPWorkflowInstanceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class ResumeWorkflowInstanceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void ResumePnPWorkflowInstanceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Resume-PnPWorkflowInstance",new CommandParameter("Identity", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/StartPnPWorkflowInstanceTests.cs b/Tests/Workflows/StartPnPWorkflowInstanceTests.cs new file mode 100644 index 000000000..9750bc5be --- /dev/null +++ b/Tests/Workflows/StartPnPWorkflowInstanceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class StartWorkflowInstanceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void StartPnPWorkflowInstanceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Start-PnPWorkflowInstance",new CommandParameter("Subscription", "null"),new CommandParameter("ListItem", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file diff --git a/Tests/Workflows/StopPnPWorkflowInstanceTests.cs b/Tests/Workflows/StopPnPWorkflowInstanceTests.cs new file mode 100644 index 000000000..4f2cfd291 --- /dev/null +++ b/Tests/Workflows/StopPnPWorkflowInstanceTests.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Management.Automation.Runspaces; + +namespace SharePointPnP.PowerShell.Tests.Workflows +{ + + [TestClass] + public class StopWorkflowInstanceTests + { + #region Test Setup/CleanUp + + [TestInitialize] + public void Initialize() + { + using (var scope = new PSTestScope()) + { + // Example + // scope.ExecuteCommand("cmdlet", new CommandParameter("param1", prop)); + } + } + + [TestCleanup] + public void Cleanup() + { + using (var scope = new PSTestScope()) + { + try + { + + } + catch (Exception) + { + // Describe Exception + } + } + } + + #endregion + + #region Scaffolded Cmdlet Tests + + + + //TODO: This is a scaffold of the cmdlet - complete the unit test + //[TestMethod] + public void StopPnPWorkflowInstanceTest() + { + + using (var scope = new PSTestScope(true)) + { + // Complete writing cmd parameters + var results = scope.ExecuteCommand("Stop-PnPWorkflowInstance",new CommandParameter("Identity", "null"),new CommandParameter("Force", "null")); + Assert.IsNotNull(results); + } + + } + + + #endregion + } +} + \ No newline at end of file From c1e2723faeafb73ab612c2bd7c8a20c3d527bc95 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 16:00:38 +0100 Subject: [PATCH 070/130] Move original tests into subfolder --- Tests/{ => OldTests}/AdminTests.cs | 0 Tests/{ => OldTests}/BaseTests.cs | 0 Tests/{ => OldTests}/BrandingTests.cs | 0 Tests/{ => OldTests}/ClientSidePagesTests.cs | 0 Tests/{ => OldTests}/ContentTypeTests.cs | 0 Tests/{ => OldTests}/DiagnosticTests.cs | 0 Tests/{ => OldTests}/EventReceiverTests.cs | 0 Tests/{ => OldTests}/FeatureTests.cs | 0 Tests/{ => OldTests}/FieldsTests.cs | 0 Tests/{ => OldTests}/FilesTest.cs | 0 Tests/{ => OldTests}/GraphTests.cs | 0 Tests/{ => OldTests}/InvokeWebActionTest.cs | 0 .../ListDataRowProvisioningTemplate.cs | 0 Tests/{ => OldTests}/ListsTests.cs | 0 Tests/{ => OldTests}/PrincipalsTests.cs | 0 .../ProvisioningTemplateFromFolderTest.cs | 0 .../ProvisioningTemplateTests.cs | 0 Tests/SharePointPnP.PowerShell.Tests.csproj | 34 +++++++++---------- 18 files changed, 17 insertions(+), 17 deletions(-) rename Tests/{ => OldTests}/AdminTests.cs (100%) rename Tests/{ => OldTests}/BaseTests.cs (100%) rename Tests/{ => OldTests}/BrandingTests.cs (100%) rename Tests/{ => OldTests}/ClientSidePagesTests.cs (100%) rename Tests/{ => OldTests}/ContentTypeTests.cs (100%) rename Tests/{ => OldTests}/DiagnosticTests.cs (100%) rename Tests/{ => OldTests}/EventReceiverTests.cs (100%) rename Tests/{ => OldTests}/FeatureTests.cs (100%) rename Tests/{ => OldTests}/FieldsTests.cs (100%) rename Tests/{ => OldTests}/FilesTest.cs (100%) rename Tests/{ => OldTests}/GraphTests.cs (100%) rename Tests/{ => OldTests}/InvokeWebActionTest.cs (100%) rename Tests/{ => OldTests}/ListDataRowProvisioningTemplate.cs (100%) rename Tests/{ => OldTests}/ListsTests.cs (100%) rename Tests/{ => OldTests}/PrincipalsTests.cs (100%) rename Tests/{ => OldTests}/ProvisioningTemplateFromFolderTest.cs (100%) rename Tests/{ => OldTests}/ProvisioningTemplateTests.cs (100%) diff --git a/Tests/AdminTests.cs b/Tests/OldTests/AdminTests.cs similarity index 100% rename from Tests/AdminTests.cs rename to Tests/OldTests/AdminTests.cs diff --git a/Tests/BaseTests.cs b/Tests/OldTests/BaseTests.cs similarity index 100% rename from Tests/BaseTests.cs rename to Tests/OldTests/BaseTests.cs diff --git a/Tests/BrandingTests.cs b/Tests/OldTests/BrandingTests.cs similarity index 100% rename from Tests/BrandingTests.cs rename to Tests/OldTests/BrandingTests.cs diff --git a/Tests/ClientSidePagesTests.cs b/Tests/OldTests/ClientSidePagesTests.cs similarity index 100% rename from Tests/ClientSidePagesTests.cs rename to Tests/OldTests/ClientSidePagesTests.cs diff --git a/Tests/ContentTypeTests.cs b/Tests/OldTests/ContentTypeTests.cs similarity index 100% rename from Tests/ContentTypeTests.cs rename to Tests/OldTests/ContentTypeTests.cs diff --git a/Tests/DiagnosticTests.cs b/Tests/OldTests/DiagnosticTests.cs similarity index 100% rename from Tests/DiagnosticTests.cs rename to Tests/OldTests/DiagnosticTests.cs diff --git a/Tests/EventReceiverTests.cs b/Tests/OldTests/EventReceiverTests.cs similarity index 100% rename from Tests/EventReceiverTests.cs rename to Tests/OldTests/EventReceiverTests.cs diff --git a/Tests/FeatureTests.cs b/Tests/OldTests/FeatureTests.cs similarity index 100% rename from Tests/FeatureTests.cs rename to Tests/OldTests/FeatureTests.cs diff --git a/Tests/FieldsTests.cs b/Tests/OldTests/FieldsTests.cs similarity index 100% rename from Tests/FieldsTests.cs rename to Tests/OldTests/FieldsTests.cs diff --git a/Tests/FilesTest.cs b/Tests/OldTests/FilesTest.cs similarity index 100% rename from Tests/FilesTest.cs rename to Tests/OldTests/FilesTest.cs diff --git a/Tests/GraphTests.cs b/Tests/OldTests/GraphTests.cs similarity index 100% rename from Tests/GraphTests.cs rename to Tests/OldTests/GraphTests.cs diff --git a/Tests/InvokeWebActionTest.cs b/Tests/OldTests/InvokeWebActionTest.cs similarity index 100% rename from Tests/InvokeWebActionTest.cs rename to Tests/OldTests/InvokeWebActionTest.cs diff --git a/Tests/ListDataRowProvisioningTemplate.cs b/Tests/OldTests/ListDataRowProvisioningTemplate.cs similarity index 100% rename from Tests/ListDataRowProvisioningTemplate.cs rename to Tests/OldTests/ListDataRowProvisioningTemplate.cs diff --git a/Tests/ListsTests.cs b/Tests/OldTests/ListsTests.cs similarity index 100% rename from Tests/ListsTests.cs rename to Tests/OldTests/ListsTests.cs diff --git a/Tests/PrincipalsTests.cs b/Tests/OldTests/PrincipalsTests.cs similarity index 100% rename from Tests/PrincipalsTests.cs rename to Tests/OldTests/PrincipalsTests.cs diff --git a/Tests/ProvisioningTemplateFromFolderTest.cs b/Tests/OldTests/ProvisioningTemplateFromFolderTest.cs similarity index 100% rename from Tests/ProvisioningTemplateFromFolderTest.cs rename to Tests/OldTests/ProvisioningTemplateFromFolderTest.cs diff --git a/Tests/ProvisioningTemplateTests.cs b/Tests/OldTests/ProvisioningTemplateTests.cs similarity index 100% rename from Tests/ProvisioningTemplateTests.cs rename to Tests/OldTests/ProvisioningTemplateTests.cs diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 5fec4b3e0..436ddb8d4 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -344,7 +344,7 @@ - + @@ -409,7 +409,7 @@ - + @@ -479,8 +479,8 @@ - - + + @@ -489,7 +489,7 @@ - + @@ -497,8 +497,8 @@ - - + + @@ -506,7 +506,7 @@ - + @@ -555,8 +555,8 @@ - - + + @@ -582,7 +582,7 @@ - + @@ -624,8 +624,8 @@ - - + + @@ -713,7 +713,7 @@ - + @@ -727,13 +727,13 @@ - + - + - + From a5dbc0f99b3e8a132a032dd76294e2e14533b865 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 16:01:08 +0100 Subject: [PATCH 071/130] Rename of folder - less of the old please ;-) --- .../{OldTests => OriginalTests}/AdminTests.cs | 0 .../{OldTests => OriginalTests}/BaseTests.cs | 0 .../BrandingTests.cs | 0 .../ClientSidePagesTests.cs | 0 .../ContentTypeTests.cs | 0 .../DiagnosticTests.cs | 0 .../EventReceiverTests.cs | 0 .../FeatureTests.cs | 0 .../FieldsTests.cs | 0 .../{OldTests => OriginalTests}/FilesTest.cs | 0 .../{OldTests => OriginalTests}/GraphTests.cs | 0 .../InvokeWebActionTest.cs | 0 .../ListDataRowProvisioningTemplate.cs | 0 .../{OldTests => OriginalTests}/ListsTests.cs | 0 .../PrincipalsTests.cs | 0 .../ProvisioningTemplateFromFolderTest.cs | 0 .../ProvisioningTemplateTests.cs | 0 Tests/SharePointPnP.PowerShell.Tests.csproj | 34 +++++++++---------- 18 files changed, 17 insertions(+), 17 deletions(-) rename Tests/{OldTests => OriginalTests}/AdminTests.cs (100%) rename Tests/{OldTests => OriginalTests}/BaseTests.cs (100%) rename Tests/{OldTests => OriginalTests}/BrandingTests.cs (100%) rename Tests/{OldTests => OriginalTests}/ClientSidePagesTests.cs (100%) rename Tests/{OldTests => OriginalTests}/ContentTypeTests.cs (100%) rename Tests/{OldTests => OriginalTests}/DiagnosticTests.cs (100%) rename Tests/{OldTests => OriginalTests}/EventReceiverTests.cs (100%) rename Tests/{OldTests => OriginalTests}/FeatureTests.cs (100%) rename Tests/{OldTests => OriginalTests}/FieldsTests.cs (100%) rename Tests/{OldTests => OriginalTests}/FilesTest.cs (100%) rename Tests/{OldTests => OriginalTests}/GraphTests.cs (100%) rename Tests/{OldTests => OriginalTests}/InvokeWebActionTest.cs (100%) rename Tests/{OldTests => OriginalTests}/ListDataRowProvisioningTemplate.cs (100%) rename Tests/{OldTests => OriginalTests}/ListsTests.cs (100%) rename Tests/{OldTests => OriginalTests}/PrincipalsTests.cs (100%) rename Tests/{OldTests => OriginalTests}/ProvisioningTemplateFromFolderTest.cs (100%) rename Tests/{OldTests => OriginalTests}/ProvisioningTemplateTests.cs (100%) diff --git a/Tests/OldTests/AdminTests.cs b/Tests/OriginalTests/AdminTests.cs similarity index 100% rename from Tests/OldTests/AdminTests.cs rename to Tests/OriginalTests/AdminTests.cs diff --git a/Tests/OldTests/BaseTests.cs b/Tests/OriginalTests/BaseTests.cs similarity index 100% rename from Tests/OldTests/BaseTests.cs rename to Tests/OriginalTests/BaseTests.cs diff --git a/Tests/OldTests/BrandingTests.cs b/Tests/OriginalTests/BrandingTests.cs similarity index 100% rename from Tests/OldTests/BrandingTests.cs rename to Tests/OriginalTests/BrandingTests.cs diff --git a/Tests/OldTests/ClientSidePagesTests.cs b/Tests/OriginalTests/ClientSidePagesTests.cs similarity index 100% rename from Tests/OldTests/ClientSidePagesTests.cs rename to Tests/OriginalTests/ClientSidePagesTests.cs diff --git a/Tests/OldTests/ContentTypeTests.cs b/Tests/OriginalTests/ContentTypeTests.cs similarity index 100% rename from Tests/OldTests/ContentTypeTests.cs rename to Tests/OriginalTests/ContentTypeTests.cs diff --git a/Tests/OldTests/DiagnosticTests.cs b/Tests/OriginalTests/DiagnosticTests.cs similarity index 100% rename from Tests/OldTests/DiagnosticTests.cs rename to Tests/OriginalTests/DiagnosticTests.cs diff --git a/Tests/OldTests/EventReceiverTests.cs b/Tests/OriginalTests/EventReceiverTests.cs similarity index 100% rename from Tests/OldTests/EventReceiverTests.cs rename to Tests/OriginalTests/EventReceiverTests.cs diff --git a/Tests/OldTests/FeatureTests.cs b/Tests/OriginalTests/FeatureTests.cs similarity index 100% rename from Tests/OldTests/FeatureTests.cs rename to Tests/OriginalTests/FeatureTests.cs diff --git a/Tests/OldTests/FieldsTests.cs b/Tests/OriginalTests/FieldsTests.cs similarity index 100% rename from Tests/OldTests/FieldsTests.cs rename to Tests/OriginalTests/FieldsTests.cs diff --git a/Tests/OldTests/FilesTest.cs b/Tests/OriginalTests/FilesTest.cs similarity index 100% rename from Tests/OldTests/FilesTest.cs rename to Tests/OriginalTests/FilesTest.cs diff --git a/Tests/OldTests/GraphTests.cs b/Tests/OriginalTests/GraphTests.cs similarity index 100% rename from Tests/OldTests/GraphTests.cs rename to Tests/OriginalTests/GraphTests.cs diff --git a/Tests/OldTests/InvokeWebActionTest.cs b/Tests/OriginalTests/InvokeWebActionTest.cs similarity index 100% rename from Tests/OldTests/InvokeWebActionTest.cs rename to Tests/OriginalTests/InvokeWebActionTest.cs diff --git a/Tests/OldTests/ListDataRowProvisioningTemplate.cs b/Tests/OriginalTests/ListDataRowProvisioningTemplate.cs similarity index 100% rename from Tests/OldTests/ListDataRowProvisioningTemplate.cs rename to Tests/OriginalTests/ListDataRowProvisioningTemplate.cs diff --git a/Tests/OldTests/ListsTests.cs b/Tests/OriginalTests/ListsTests.cs similarity index 100% rename from Tests/OldTests/ListsTests.cs rename to Tests/OriginalTests/ListsTests.cs diff --git a/Tests/OldTests/PrincipalsTests.cs b/Tests/OriginalTests/PrincipalsTests.cs similarity index 100% rename from Tests/OldTests/PrincipalsTests.cs rename to Tests/OriginalTests/PrincipalsTests.cs diff --git a/Tests/OldTests/ProvisioningTemplateFromFolderTest.cs b/Tests/OriginalTests/ProvisioningTemplateFromFolderTest.cs similarity index 100% rename from Tests/OldTests/ProvisioningTemplateFromFolderTest.cs rename to Tests/OriginalTests/ProvisioningTemplateFromFolderTest.cs diff --git a/Tests/OldTests/ProvisioningTemplateTests.cs b/Tests/OriginalTests/ProvisioningTemplateTests.cs similarity index 100% rename from Tests/OldTests/ProvisioningTemplateTests.cs rename to Tests/OriginalTests/ProvisioningTemplateTests.cs diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index 436ddb8d4..bba1dd11e 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -344,7 +344,7 @@ - + @@ -409,7 +409,7 @@ - + @@ -479,8 +479,8 @@ - - + + @@ -489,7 +489,7 @@ - + @@ -497,8 +497,8 @@ - - + + @@ -506,7 +506,7 @@ - + @@ -555,8 +555,8 @@ - - + + @@ -582,7 +582,7 @@ - + @@ -624,8 +624,8 @@ - - + + @@ -713,7 +713,7 @@ - + @@ -727,13 +727,13 @@ - + - + - + From 461e2be246b75b49f605df1f66f69f3538dde00d Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 16:01:37 +0100 Subject: [PATCH 072/130] Moved tests i missed --- Tests/{ => OriginalTests}/WebPartsTests.cs | 0 Tests/{ => OriginalTests}/WebTests.cs | 0 Tests/{ => OriginalTests}/WebhookSubscriptionsTests.cs | 0 Tests/SharePointPnP.PowerShell.Tests.csproj | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename Tests/{ => OriginalTests}/WebPartsTests.cs (100%) rename Tests/{ => OriginalTests}/WebTests.cs (100%) rename Tests/{ => OriginalTests}/WebhookSubscriptionsTests.cs (100%) diff --git a/Tests/WebPartsTests.cs b/Tests/OriginalTests/WebPartsTests.cs similarity index 100% rename from Tests/WebPartsTests.cs rename to Tests/OriginalTests/WebPartsTests.cs diff --git a/Tests/WebTests.cs b/Tests/OriginalTests/WebTests.cs similarity index 100% rename from Tests/WebTests.cs rename to Tests/OriginalTests/WebTests.cs diff --git a/Tests/WebhookSubscriptionsTests.cs b/Tests/OriginalTests/WebhookSubscriptionsTests.cs similarity index 100% rename from Tests/WebhookSubscriptionsTests.cs rename to Tests/OriginalTests/WebhookSubscriptionsTests.cs diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index bba1dd11e..d52ce8f27 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -712,7 +712,7 @@ - + @@ -726,9 +726,9 @@ - + - + From 2999856f6e1a85fc51c5c6043d230adc600683a6 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 16:48:09 +0100 Subject: [PATCH 073/130] Revert "Companion binaries support the new feature" This reverts commit 30cb6b44e6f14e8526b32a94574e08fdf57b1a0e. --- .../SharePointPnP.Modernization.Framework.dll | Bin 865280 -> 850944 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Binaries/SharePointPnP.Modernization.Framework.dll b/Binaries/SharePointPnP.Modernization.Framework.dll index aaa48882400b64f1725ead3b3af96440dea79b82..071348c1ba9597ca050f42320ef3f15aa3d5dee9 100644 GIT binary patch delta 274859 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 M&UdSiUV04tADUJybN~PV From 4a63f50181e47d520d3f6825a7c6cd77a400136a Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Fri, 26 Jun 2020 16:48:29 +0100 Subject: [PATCH 074/130] Revert "Updated cmdlet parameters for the new replay layout commands" This reverts commit efd14c10c6fb763a4a6813e741b849182b606b4c. --- .../ConvertToClientSidePage.cs | 38 +------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/Commands/ClientSidePages/ConvertToClientSidePage.cs b/Commands/ClientSidePages/ConvertToClientSidePage.cs index bca548810..92bb41777 100644 --- a/Commands/ClientSidePages/ConvertToClientSidePage.cs +++ b/Commands/ClientSidePages/ConvertToClientSidePage.cs @@ -78,22 +78,6 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetConnection $target -UserMappingFile c:\\temp\user_mapping_file.csv", Remarks = "Converts a publishing page named 'somepage' to a client side page in the site specified by the TargetConnection connection. This allows to read a page in on-premises environment and create in another online locations including using specific user mappings between the two environments.", SortOrder = 14)] - - // Replay Function - [CmdletExample( - Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetConnection $target -ReplayLayoutCapture", - Remarks = "Converts a publishing page named 'somepage' to a client side page in the site specified by the TargetConnection connection. For Replay feature, Capture the first Transformation. " + - "Then make changes to layout in the page directly in SharePoint. Finally, run subsequent transformations with '-ReplayLayout' to apply your layout changes to all transforms with the same source " + - "page layout. Only applies to PublishingPage mode.", - SortOrder = 15)] - - [CmdletExample( - Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetConnection $target -ReplayLayout", - Remarks = "Converts a publishing page named 'somepage' to a client side page in the site specified by the TargetConnection connection. " + - "Ensure first you have captured with '-ReplayLayoutCapture' and made changes in the page in SharePoint. This cmdlet will apply your layout changes to all transforms with the same source page. " + - "Only applies to PublishingPage mode.", - SortOrder = 16)] - public class ConvertToClientSidePage : PnPWebCmdlet { private static string rootFolder = ""; @@ -230,12 +214,6 @@ public class ConvertToClientSidePage : PnPWebCmdlet [Parameter(Mandatory = false, HelpMessage = "Specifies a LDAP connection string e.g. LDAP://OU=Users,DC=Contoso,DC=local")] public string LDAPConnectionString = ""; - [Parameter(Mandatory = false, HelpMessage = "Captures the page to reference for layout changes")] - public SwitchParameter ReplayLayoutCapture = false; - - [Parameter(Mandatory = false, HelpMessage = "Applies the page layout changes from the page used to capture layout changes")] - public SwitchParameter ReplayLayout = false; - protected override void ExecuteCmdlet() { //Fix loading of modernization framework @@ -253,17 +231,7 @@ protected override void ExecuteCmdlet() { throw new Exception($"The page is either a blog page, a publishing page or a Delve blog page. Setting PublishingPage, BlogPage and DelveBlogPage to true is not valid."); } - - if (this.PublishingPage && this.ReplayLayoutCapture && this.ReplayLayout) - { - throw new Exception($"Please specify either ReplayLayoutCapture OR ReplayLayout, running both on the same transformation is not supported."); - } - - if (!this.PublishingPage && (this.ReplayLayoutCapture || this.ReplayLayout)) - { - throw new Exception($"Running ReplayLayoutCapture OR ReplayLayout is only supported on publishing pages"); - } - + ListItem page = null; if (this.PublishingPage) { @@ -486,9 +454,7 @@ protected override void ExecuteCmdlet() TargetPageFolderOverridesDefaultFolder = this.TargetPageFolderOverridesDefaultFolder, TermMappingFile = TermMappingFile, SkipTermStoreMapping = SkipTermStoreMapping, - RemoveEmptySectionsAndColumns = this.RemoveEmptySectionsAndColumns, - IsReplayCapture = this.ReplayLayoutCapture, - IsReplayLayout = this.ReplayLayout + RemoveEmptySectionsAndColumns = this.RemoveEmptySectionsAndColumns }; // Set mapping properties From d5b0aeb47479c3e37afa72e8cde9a90e6dd3d7c3 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Sun, 28 Jun 2020 16:24:30 +0200 Subject: [PATCH 075/130] Add Teams cmdlets --- CHANGELOG.md | 2 + Commands/Base/PipeBinds/TeamPipeBind.cs | 45 ----- Commands/Base/PnPConnection.cs | 14 ++ Commands/Base/PnPGraphCmdlet.cs | 3 + Commands/Model/Teams/Group.cs | 17 ++ Commands/Model/Teams/Team.cs | 126 +++++++++++++ Commands/Model/Teams/TeamAppInstance.cs | 20 ++ Commands/Model/Teams/TeamChannel.cs | 51 +++++ Commands/Model/Teams/TeamChannelMessage.cs | 20 ++ Commands/Model/Teams/TeamDiscoverySettings.cs | 20 ++ Commands/Model/Teams/TeamFunSettings.cs | 66 +++++++ Commands/Model/Teams/TeamGuestSettings.cs | 25 +++ Commands/Model/Teams/TeamMemberSettings.cs | 46 +++++ Commands/Model/Teams/TeamMessagingSettings.cs | 41 ++++ Commands/Model/Teams/TeamSecurity.cs | 40 ++++ Commands/Model/Teams/TeamSecurityUser.cs | 20 ++ Commands/Model/Teams/TeamTab.cs | 40 ++++ Commands/Model/Teams/TeamTabConfiguration.cs | 36 ++++ Commands/Model/Teams/TeamTabResource.cs | 53 ++++++ ...P.PowerShell.Online.Commands.Format.ps1xml | 16 +- .../SharePointPnP.PowerShell.Commands.csproj | 21 ++- Commands/Teams/AddTeamsChannel.cs | 36 +--- Commands/Teams/GetTeamsChannel.cs | 24 +-- Commands/Teams/GetTeamsTeam.cs | 76 +++----- Commands/Teams/RemoveTeamsChannel.cs | 42 +---- Commands/Utilities/REST/GraphCollection.cs | 19 ++ Commands/Utilities/REST/GraphHelper.cs | 175 ++++++++++++++++++ Commands/Utilities/REST/RestHelper.cs | 1 - Commands/Utilities/TeamsUtility.cs | 170 +++++++++++++++++ 29 files changed, 1079 insertions(+), 186 deletions(-) delete mode 100644 Commands/Base/PipeBinds/TeamPipeBind.cs create mode 100644 Commands/Model/Teams/Group.cs create mode 100644 Commands/Model/Teams/Team.cs create mode 100644 Commands/Model/Teams/TeamAppInstance.cs create mode 100644 Commands/Model/Teams/TeamChannel.cs create mode 100644 Commands/Model/Teams/TeamChannelMessage.cs create mode 100644 Commands/Model/Teams/TeamDiscoverySettings.cs create mode 100644 Commands/Model/Teams/TeamFunSettings.cs create mode 100644 Commands/Model/Teams/TeamGuestSettings.cs create mode 100644 Commands/Model/Teams/TeamMemberSettings.cs create mode 100644 Commands/Model/Teams/TeamMessagingSettings.cs create mode 100644 Commands/Model/Teams/TeamSecurity.cs create mode 100644 Commands/Model/Teams/TeamSecurityUser.cs create mode 100644 Commands/Model/Teams/TeamTab.cs create mode 100644 Commands/Model/Teams/TeamTabConfiguration.cs create mode 100644 Commands/Model/Teams/TeamTabResource.cs create mode 100644 Commands/Utilities/REST/GraphCollection.cs create mode 100644 Commands/Utilities/REST/GraphHelper.cs create mode 100644 Commands/Utilities/TeamsUtility.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e51917b5..ebb95c124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [3.23.2007.0] (not yet released) ### Added +- Added Get-PnPTeamsTeam, Get-PnPTeamsChannel, Add-PnPTeamsChannel, Remove-PnPTeamsChannel cmdlets ### Changed - Fixed issue where using `Disconnect-PnPOnline -Connection $variable` after having connected using `$variable = Connect-PnPOnline -CertificatePath -ReturnConnection`, it would not clean up the certificate on that connection instance passed in by $variable, but instead try to do it on the current connection context [PR #2755](https://github.com/pnp/PnP-PowerShell/pull/2755) - Fixed issue where using `Connect-PnPOnline` using `-Thumbnail` would delete the private key on some devices when running `Disconnect-PnPOnline` [PR #2759](https://github.com/pnp/PnP-PowerShell/pull/2759) ### Contributors +- Erwin van Hunen [erwinvanhunen] - Gautam Sheth [gautamdsheth] - Koen Zomers [koenzomers] diff --git a/Commands/Base/PipeBinds/TeamPipeBind.cs b/Commands/Base/PipeBinds/TeamPipeBind.cs deleted file mode 100644 index 07eaa9270..000000000 --- a/Commands/Base/PipeBinds/TeamPipeBind.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Microsoft.SharePoint.Client; -using OfficeDevPnP.Core.Framework.Provisioning.Model.Teams; -using System; - -namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds -{ - public sealed class TeamPipeBind - { - private Team team; - private string groupId; - - public TeamPipeBind(Guid id) - { - groupId = id.ToString(); - } - - public TeamPipeBind(string stringId) - { - if(Guid.TryParse(stringId, out Guid guidId)) - { - groupId = guidId.ToString(); - } else - { - throw new ArgumentException("ID is not in correct format, needs to be a GUID"); - } - } - - public TeamPipeBind(Team team) - { - this.team = team; - } - - internal string GetTeamId() - { - if (team != null) - { - return team.GroupId; - } - else - { - return groupId; - } - } - } -} diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index 239d796a0..f757182c4 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -9,6 +9,7 @@ using System.Management.Automation; using System.Management.Automation.Host; using System.Net; +using System.Net.Http; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.Web; @@ -28,6 +29,19 @@ public class PnPConnection #region Properties + private HttpClient httpClient; + + public HttpClient HttpClient + { + get + { + if (httpClient == null) + { + httpClient = new HttpClient(); + } + return httpClient; + } + } ///

/// User Agent identifier to use on all connections being made to the APIs /// diff --git a/Commands/Base/PnPGraphCmdlet.cs b/Commands/Base/PnPGraphCmdlet.cs index 2fd3c5b9b..067110809 100644 --- a/Commands/Base/PnPGraphCmdlet.cs +++ b/Commands/Base/PnPGraphCmdlet.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Management.Automation; +using System.Net.Http; namespace SharePointPnP.PowerShell.Commands.Base { @@ -59,6 +60,8 @@ public GraphToken Token /// Returns an Access Token for Microsoft Graph, if available, otherwise NULL ///

2h>Lt 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

public string AccessToken => Token?.AccessToken; + + public HttpClient HttpClient => PnPConnection.CurrentConnection.HttpClient; } } #endif \ No newline at end of file diff --git a/Commands/Model/Teams/Group.cs b/Commands/Model/Teams/Group.cs new file mode 100644 index 000000000..def19abfa --- /dev/null +++ b/Commands/Model/Teams/Group.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public class Group + { + public string Id { get; set; } + public string DisplayName { get; set; } + public string MailNickname { get; set; } + public string Description { get; set; } + public GroupVisibility Visibility { get; set; } + } +} diff --git a/Commands/Model/Teams/Team.cs b/Commands/Model/Teams/Team.cs new file mode 100644 index 000000000..40a2e103f --- /dev/null +++ b/Commands/Model/Teams/Team.cs @@ -0,0 +1,126 @@ +using Microsoft.Graph; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + /// + /// Defines Team for automated provisiong/update of Microsoft Teams + /// + public class Team + { + #region Public Members + public string DisplayName { get; set; } + /// + /// The Fun Settings for the Team + /// + public TeamFunSettings FunSettings { get; set; } + + /// + /// The Guest Settings for the Team + /// + public TeamGuestSettings GuestSettings { get; set; } + + /// + /// The Members Settings for the Team + /// + public TeamMemberSettings MemberSettings { get; set; } + + /// + /// The Messaging Settings for the Team + /// + public TeamMessagingSettings MessagingSettings { get; set; } + + /// + /// The Discovery Settings for the Team + /// + public TeamDiscoverySettings DiscoverySettings { get; set; } + + /// + /// Defines the Security settings for the Team + /// + public TeamSecurity Security { get; set; } + + ///// + ///// Defines the Channels for the Team + ///// + //public List Channels { get; private set; } = new List(); + + /// + /// Defines the Apps to install or update on the Team + /// + public List Apps { get; private set; } = new List(); + + public TeamSpecialization? Specialization { get; set; } + + /// + /// Declares the ID of the targt Group/Team to update, optional attribute. Cannot be used together with CloneFrom. + /// + public string GroupId { get; set; } + + /// + /// Declares the ID of another Team to Clone the current Team from + /// + public string CloneFrom { get; set; } + + /// + /// Declares whether the Team is archived or not + /// + public bool Archived { get; set; } + + /// + /// Declares the nickname for the Team, optional attribute + /// + public string MailNickname { get; set; } + + /// + /// Declares the description for the team + /// + public string Description { get; set; } + + public GroupVisibility? Visibility { get; set; } + + public bool IsArchived { get; set; } + #endregion + + } + + public enum GroupVisibility + { + NotSpecified, + Private, + Public + } + + /// + /// The Specialization for the Team + /// + public enum TeamSpecialization + { + /// + /// Default type for a team which gives the standard team experience + /// + None, + /// + /// Team created by an education user. All teams created by education user are of type Edu. + /// + EducationStandard, + /// + /// Team experience optimized for a class. This enables segmentation of features across O365. + /// + EducationClass, + /// + /// Team experience optimized for a PLC. Learn more about PLC here. + /// + EducationProfessionalLearningCommunity, + /// + /// Team type for an optimized experience for staff in an organization, where a staff leader, like a principal, is the admin and teachers are members in a team that comes with a specialized notebook. + /// + EducationStaff + } +} diff --git a/Commands/Model/Teams/TeamAppInstance.cs b/Commands/Model/Teams/TeamAppInstance.cs new file mode 100644 index 000000000..2e3207cf9 --- /dev/null +++ b/Commands/Model/Teams/TeamAppInstance.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public class TeamAppInstance + { + #region Public Members + + /// + /// Defines the unique ID of the App to install or update on the Team + /// + public string AppId { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamChannel.cs b/Commands/Model/Teams/TeamChannel.cs new file mode 100644 index 000000000..d5c9be0d5 --- /dev/null +++ b/Commands/Model/Teams/TeamChannel.cs @@ -0,0 +1,51 @@ +using Microsoft.Graph; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamChannel + { + #region Public Members + + /// + /// Defines a collection of Tabs for a Channel in a Team + /// + public List Tabs { get; private set; } + + /// + /// Defines a collection of Resources for Tabs in a Team Channel + /// + public List TabResources { get; private set; } + + /// + /// Defines a collection of Messages for a Team Channe + /// + public List Messages { get; private set; } + + /// + /// Defines the Display Name of the Channel + /// + public string DisplayName { get; set; } + + /// + /// Defines the Description of the Channel + /// + public string Description { get; set; } + + /// + /// Defines whether the Channel is Favorite by default for all members of the Team + /// + public bool? IsFavoriteByDefault { get; set; } + + /// + /// Declares the ID for the Channel + /// + public string Id { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamChannelMessage.cs b/Commands/Model/Teams/TeamChannelMessage.cs new file mode 100644 index 000000000..3937041ed --- /dev/null +++ b/Commands/Model/Teams/TeamChannelMessage.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamChannelMessage + { + #region Public Members + + /// + /// Defines a Message for a Channel in a Team + /// + public string Message { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamDiscoverySettings.cs b/Commands/Model/Teams/TeamDiscoverySettings.cs new file mode 100644 index 000000000..b5f9823e8 --- /dev/null +++ b/Commands/Model/Teams/TeamDiscoverySettings.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamDiscoverySettings + { + #region Public Members + + /// + /// Defines whether the Team is visible via search and suggestions from the Teams client + /// + public bool ShowInTeamsSearchAndSuggestions { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamFunSettings.cs b/Commands/Model/Teams/TeamFunSettings.cs new file mode 100644 index 000000000..2b58379f6 --- /dev/null +++ b/Commands/Model/Teams/TeamFunSettings.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamFunSettings + { + #region Private Members + + private string _giphyContentRating; + + #endregion + + #region Public Members + + /// + /// Defines whether Giphys are consented or not + /// + public bool AllowGiphy { get; set; } + + /// + /// Defines the Content Rating for Giphys + /// + public string GiphyContentRating + { + get + { + return (_giphyContentRating); + } + set + { + _giphyContentRating = value?.ToLower(); + } + } + + /// + /// Defines whether Stickers and Memes are consented or not + /// + public bool AllowStickersAndMemes { get; set; } + + /// + /// Defines whether Custom Memes are consented or not + /// + public bool AllowCustomMemes { get; set; } + + #endregion + } + + /// + /// Defines the Content Rating for Giphys + /// + public static class TeamGiphyContentRating + { + /// + /// Moderate Content Rating + /// + public const string Moderate = "moderate"; + /// + /// Strict Content Rating + /// + public const string Strict = "strict"; + } +} diff --git a/Commands/Model/Teams/TeamGuestSettings.cs b/Commands/Model/Teams/TeamGuestSettings.cs new file mode 100644 index 000000000..9e7c6f9fa --- /dev/null +++ b/Commands/Model/Teams/TeamGuestSettings.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamGuestSettings + { + #region Public Members + + /// + /// Defines whether Guests are allowed to create Channels or not + /// + public bool AllowCreateUpdateChannels { get; set; } + + /// + /// Defines whether Guests are allowed to delete Channels or not + /// + public bool AllowDeleteChannels { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamMemberSettings.cs b/Commands/Model/Teams/TeamMemberSettings.cs new file mode 100644 index 000000000..2f2141a1b --- /dev/null +++ b/Commands/Model/Teams/TeamMemberSettings.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamMemberSettings + { + + #region Public Members + + /// + /// Defines if members can add and update channels + /// + public bool AllowCreateUpdateChannels { get; set; } + + /// + /// Defines if members can delete channels + /// + public bool AllowDeleteChannels { get; set; } + + /// + /// Defines if members can add and remove apps + /// + public bool AllowAddRemoveApps { get; set; } + + /// + /// Defines if members can add, update, and remove tabs + /// + public bool AllowCreateUpdateRemoveTabs { get; set; } + + /// + /// Defines if members can add, update, and remove connectors + /// + public bool AllowCreateUpdateRemoveConnectors { get; set; } + + /// + /// Defines if members can create private channels + /// + public bool AllowCreatePrivateChannels { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamMessagingSettings.cs b/Commands/Model/Teams/TeamMessagingSettings.cs new file mode 100644 index 000000000..c1048205a --- /dev/null +++ b/Commands/Model/Teams/TeamMessagingSettings.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamMessagingSettings + { + #region Public Members + + /// + /// Defines if users can edit their messages + /// + public bool AllowUserEditMessages { get; set; } + + /// + /// Defines if users can delete their messages + /// + public bool AllowUserDeleteMessages { get; set; } + + /// + /// Defines if owners can delete any message + /// + public bool AllowOwnerDeleteMessages { get; set; } + + /// + /// Defines if @team mentions are allowed + /// + public bool AllowTeamMentions { get; set; } + + /// + /// Defines if @channel mentions are allowed + /// + public bool AllowChannelMentions { get; set; } + + #endregion + + } +} diff --git a/Commands/Model/Teams/TeamSecurity.cs b/Commands/Model/Teams/TeamSecurity.cs new file mode 100644 index 000000000..7bdf28831 --- /dev/null +++ b/Commands/Model/Teams/TeamSecurity.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamSecurity + { + #region Public Members + + /// + /// Defines the Owners of the Team + /// + public List Owners { get; private set; } = new List(); + + /// + /// Declares whether to clear existing owners before adding new ones + /// + public bool ClearExistingOwners { get; set; } + + /// + /// Defines the Members of the Team + /// + public List Members { get; private set; } = new List(); + + /// + /// Declares whether to clear existing members before adding new ones + /// + public bool ClearExistingMembers { get; set; } + + /// + /// Defines whether guests are allowed in the Team + /// + public bool AllowToAddGuests { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamSecurityUser.cs b/Commands/Model/Teams/TeamSecurityUser.cs new file mode 100644 index 000000000..4d88cb1a3 --- /dev/null +++ b/Commands/Model/Teams/TeamSecurityUser.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamSecurityUser + { + #region Public Members + + /// + /// Defines User Principal Name (UPN) of the target user + /// + public string UserPrincipalName { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamTab.cs b/Commands/Model/Teams/TeamTab.cs new file mode 100644 index 000000000..247cd1a18 --- /dev/null +++ b/Commands/Model/Teams/TeamTab.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamTab + { + #region Public Members + + /// + /// Defines the Display Name of the Channel + /// + public string DisplayName { get; set; } + + /// + /// App definition identifier of the tab + /// + public string TeamsAppId { get; set; } + + /// + /// Allows to remove an already existing Tab + /// + public bool Remove { get; set; } + + /// + /// Defines the Configuration for the Tab + /// + public TeamTabConfiguration Configuration { get; set; } + + /// + /// Declares the ID for the Tab + /// + public string ID { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamTabConfiguration.cs b/Commands/Model/Teams/TeamTabConfiguration.cs new file mode 100644 index 000000000..b3c4b7c3a --- /dev/null +++ b/Commands/Model/Teams/TeamTabConfiguration.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamTabConfiguration + { + #region Public Members + + /// + /// Identifier for the entity hosted by the Tab provider + /// + public string EntityId { get; set; } + + /// + /// Url used for rendering Tab contents in Teams + /// + public string ContentUrl { get; set; } + + + /// + /// Url called by Teams client when a Tab is removed using the Teams Client + /// + public string RemoveUrl { get; set; } + + /// + /// Url for showing Tab contents outside of Teams + /// + public string WebsiteUrl { get; set; } + + #endregion + } +} diff --git a/Commands/Model/Teams/TeamTabResource.cs b/Commands/Model/Teams/TeamTabResource.cs new file mode 100644 index 000000000..70d77dbeb --- /dev/null +++ b/Commands/Model/Teams/TeamTabResource.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Model.Teams +{ + public partial class TeamTabResource + { + #region Public Members + + /// + /// Defines the Configuration for the Tab Resource + /// + public string TabResourceSettings { get; set; } + + /// + /// Defines the Type of Resource for the Tab + /// + public TabResourceType Type { get; set; } + + /// + /// Defines the ID of the target Tab for the Resource + /// + public string TargetTabId { get; set; } + + #endregion + } + + /// + /// Defines the Types of Resources for the Tab + /// + public enum TabResourceType + { + /// + /// Defines a Generic resource type + /// + Generic, + /// + /// Defines a Notebook resource type + /// + Notebook, + /// + /// Defines a Planner resource type + /// + Planner, + /// + /// Defines a Schedule resource type + /// + Schedule, + } +} diff --git a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml index 1c915374c..b5cfa06d1 100644 --- a/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml +++ b/Commands/ModuleFiles/SharePointPnP.PowerShell.Online.Commands.Format.ps1xml @@ -2021,9 +2021,9 @@ - BaseTeam + Team - OfficeDevPnP.Core.Framework.Provisioning.Model.Teams.BaseTeam + SharePointPnP.PowerShell.Commands.Model.Teams.Team @@ -2037,14 +2037,11 @@ - + - - - @@ -2059,14 +2056,11 @@ Visibility - Archived + IsArchived MailNickname - - Description - @@ -2075,7 +2069,7 @@ TeamChannel - OfficeDevPnP.Core.Framework.Provisioning.Model.Teams.TeamChannel + SharePointPnP.PowerShell.Commands.Model.Teams.TeamChannel diff --git a/Commands/SharePointPnP.PowerShell.Commands.csproj b/Commands/SharePointPnP.PowerShell.Commands.csproj index b96e3fffc..96bdf150d 100644 --- a/Commands/SharePointPnP.PowerShell.Commands.csproj +++ b/Commands/SharePointPnP.PowerShell.Commands.csproj @@ -630,7 +630,6 @@ - @@ -706,6 +705,21 @@ + + + + + + + + + + + + + + + @@ -916,12 +930,15 @@ + + + @@ -1221,7 +1238,7 @@ - + diff --git a/Commands/Teams/AddTeamsChannel.cs b/Commands/Teams/AddTeamsChannel.cs index 3bf1df53a..94a9e3480 100644 --- a/Commands/Teams/AddTeamsChannel.cs +++ b/Commands/Teams/AddTeamsChannel.cs @@ -11,29 +11,14 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Add, "PnPTeamsChannel")] - [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", - Category = CmdletHelpCategory.Graph, + [CmdletHelp("Adds a channel to an existing Microsoft Teams instance.", + Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup", - Remarks = "Retrieves all the Office 365 Groups", + Code = "PS:> Add-PnPTeamsChannel -GroupId 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", + Remarks = "Adds a new channel to the specified Teams instance", SortOrder = 1)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", - Remarks = "Retrieves a specific Office 365 Group based on its ID", - SortOrder = 2)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", - Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", - SortOrder = 3)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", - Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", - SortOrder = 4)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $group", - Remarks = "Retrieves a specific Office 365 Group based on its object instance", - SortOrder = 5)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class AddTeamsChannel : PnPGraphCmdlet { [Parameter(Mandatory = true)] @@ -47,16 +32,7 @@ public class AddTeamsChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - if (JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) - { - var id = TeamsUtility.AddChannel(AccessToken, GroupId, DisplayName, Description); - WriteObject(new { Id = id, DisplayName, Description }); - - } - else - { - WriteWarning("The current access token lacks the Group.ReadWrite.All permission scope"); - } + WriteObject(TeamsUtility.AddChannel(AccessToken, HttpClient, GroupId, DisplayName, Description)); } } } diff --git a/Commands/Teams/GetTeamsChannel.cs b/Commands/Teams/GetTeamsChannel.cs index d0d0df4c1..58272d841 100644 --- a/Commands/Teams/GetTeamsChannel.cs +++ b/Commands/Teams/GetTeamsChannel.cs @@ -13,12 +13,12 @@ namespace SharePointPnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Get, "PnPTeamsChannel")] - [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", - Category = CmdletHelpCategory.Graph, + [CmdletHelp("Gets the channels for a specified Team.", + Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup", - Remarks = "Retrieves all the Office 365 Groups", + Code = "PS:> Get-PnPTeamsChannel -GroupId a6c1e0d7-f579-4993-81ab-4b666f8edea8", + Remarks = "Retrieves all channels for the specified team", SortOrder = 1)] [CmdletExample( Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", @@ -36,24 +36,16 @@ namespace SharePointPnP.PowerShell.Commands.Teams Code = "PS:> Get-PnPUnifiedGroup -Identity $group", Remarks = "Retrieves a specific Office 365 Group based on its object instance", SortOrder = 5)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsChannel : PnPGraphCmdlet { [Parameter(Mandatory = true)] - public TeamPipeBind TeamIdentity; + public GuidPipeBind GroupId; protected override void ExecuteCmdlet() { - if (JwtUtility.HasScope(AccessToken, "Group.Read.All") || JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) - { - if (ParameterSpecified(nameof(TeamIdentity))) - { - WriteObject(TeamsUtility.GetChannels(AccessToken, TeamIdentity.GetTeamId()), true); - } - } - else - { - WriteWarning("The current access token lacks the Group.Read.All or equivalent permission scope"); - } + WriteObject(TeamsUtility.GetChannels(AccessToken, HttpClient, GroupId.Id.ToString())); } } } diff --git a/Commands/Teams/GetTeamsTeam.cs b/Commands/Teams/GetTeamsTeam.cs index 63b6d7fcb..398a487cd 100644 --- a/Commands/Teams/GetTeamsTeam.cs +++ b/Commands/Teams/GetTeamsTeam.cs @@ -1,9 +1,11 @@ -using OfficeDevPnP.Core.Entities; +using Microsoft.Azure.ActiveDirectory.GraphClient; +using OfficeDevPnP.Core.Entities; using OfficeDevPnP.Core.Framework.Graph; using OfficeDevPnP.Core.Utilities; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; using SharePointPnP.PowerShell.Commands.Base.PipeBinds; +using SharePointPnP.PowerShell.Commands.Model.Teams; using SharePointPnP.PowerShell.Commands.Utilities; using System.Collections.Generic; using System.Linq; @@ -12,71 +14,47 @@ namespace SharePointPnP.PowerShell.Commands.Graph { [Cmdlet(VerbsCommon.Get, "PnPTeamsTeam")] - [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", - Category = CmdletHelpCategory.Graph, + [CmdletHelp("Gets one Microsoft Teams Team or a list of Teams.", + Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup", - Remarks = "Retrieves all the Office 365 Groups", + Code = "PS:> Get-PnPTeamsTeam", + Remarks = "Retrieves all the Microsoft Teams instances", SortOrder = 1)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", - Remarks = "Retrieves a specific Office 365 Group based on its ID", + Code = "PS:> Get-PnPTeamsTeam -GroupId $groupId", + Remarks = "Retrieves a specific Microsoft Teams instance", SortOrder = 2)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", - Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", - SortOrder = 3)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", - Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", - SortOrder = 4)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $group", - Remarks = "Retrieves a specific Office 365 Group based on its object instance", - SortOrder = 5)] + Code = "PS:> Get-PnPTeamsTeam -Visibility Public", + Remarks = "Retrieves all Microsoft Teams instances which are public visible", + SortOrder = 2)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_Read_All)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class GetTeamsTeam : PnPGraphCmdlet { - [Parameter(Mandatory = false)] - public string GroupId; + private const string ParameterSet_GroupId = "Retrieve a specific Team"; - [Parameter(Mandatory = false)] - public TeamIncludes[] Includes; + [Parameter(Mandatory = false, HelpMessage = "Specify the group id of the team to retrieve.")] + public GuidPipeBind GroupId; + + [Parameter(Mandatory = false, HelpMessage = "Specify the visibility of the teams to retrieve.")] + public GroupVisibility Visibility; protected override void ExecuteCmdlet() { - if (JwtUtility.HasScope(AccessToken, "Group.Read.All") || JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) + if (ParameterSpecified(nameof(GroupId))) { - var includeChannels = false; - var includeMessages = false; - var includeApps = false; - var includeSecurity = false; - if (ParameterSpecified(nameof(Includes))) - { - includeChannels = Includes.Contains(TeamIncludes.Channels); - includeApps = Includes.Contains(TeamIncludes.Apps); - includeSecurity = Includes.Contains(TeamIncludes.Security); - } - if (ParameterSpecified(nameof(GroupId))) - { - WriteObject(TeamsUtility.GetTeam(AccessToken, GroupId, includeChannels, includeMessages, includeApps, includeSecurity)); - } - else - { - WriteObject(TeamsUtility.GetAllTeams(AccessToken, includeChannels, includeMessages, includeApps, includeSecurity), true); - } + WriteObject(TeamsUtility.GetTeam(AccessToken, HttpClient, GroupId.Id.ToString())); + } + else if (ParameterSpecified(nameof(Visibility))) + { + WriteObject(TeamsUtility.GetTeams(AccessToken, HttpClient, Visibility), true); } else { - WriteWarning("The current access token lacks the Group.Read.All or equivalent permission scope"); + WriteObject(TeamsUtility.GetTeams(AccessToken, HttpClient), true); } } - - public enum TeamIncludes - { - Channels, - Apps, - Security - } } } diff --git a/Commands/Teams/RemoveTeamsChannel.cs b/Commands/Teams/RemoveTeamsChannel.cs index fd3f7ab63..7b1bf17c2 100644 --- a/Commands/Teams/RemoveTeamsChannel.cs +++ b/Commands/Teams/RemoveTeamsChannel.cs @@ -1,6 +1,7 @@ using OfficeDevPnP.Core.Framework.Graph; using SharePointPnP.PowerShell.CmdletHelpAttributes; using SharePointPnP.PowerShell.Commands.Base; +using SharePointPnP.PowerShell.Commands.Base.PipeBinds; using SharePointPnP.PowerShell.Commands.Utilities; using System; using System.Collections.Generic; @@ -12,33 +13,18 @@ namespace SharePointPnP.PowerShell.Commands.Teams { [Cmdlet(VerbsCommon.Remove, "PnPTeamsChannel")] - [CmdletHelp("Gets one Office 365 Group (aka Unified Group) or a list of Office 365 Groups. Requires the Azure Active Directory application permission 'Group.Read.All'.", - Category = CmdletHelpCategory.Graph, + [CmdletHelp("Removes a channel from a Microsoft Teams instance.", + Category = CmdletHelpCategory.Teams, SupportedPlatform = CmdletSupportedPlatform.Online)] [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup", - Remarks = "Retrieves all the Office 365 Groups", + Code = "PS:> Remove-PnPTeamsChannel -GroupId 4efdf392-8225-4763-9e7f-4edeb7f721aa -DisplayName \"My Channel\"", + Remarks = "Removes the channel specified from the team specified", SortOrder = 1)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupId", - Remarks = "Retrieves a specific Office 365 Group based on its ID", - SortOrder = 2)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupDisplayName", - Remarks = "Retrieves a specific or list of Office 365 Groups that start with the given DisplayName", - SortOrder = 3)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $groupSiteMailNickName", - Remarks = "Retrieves a specific or list of Office 365 Groups for which the email starts with the provided mail nickName", - SortOrder = 4)] - [CmdletExample( - Code = "PS:> Get-PnPUnifiedGroup -Identity $group", - Remarks = "Retrieves a specific Office 365 Group based on its object instance", - SortOrder = 5)] + [CmdletMicrosoftGraphApiPermission(MicrosoftGraphApiPermission.Group_ReadWrite_All)] public class RemoveTeamsChannel : PnPGraphCmdlet { [Parameter(Mandatory = true)] - public string GroupId; + public GuidPipeBind GroupId; [Parameter(Mandatory = true)] public string DisplayName; @@ -48,21 +34,13 @@ public class RemoveTeamsChannel : PnPGraphCmdlet protected override void ExecuteCmdlet() { - if (JwtUtility.HasScope(AccessToken, "Group.Read.All") || JwtUtility.HasScope(AccessToken, "Group.ReadWrite.All")) + if (Force || ShouldContinue("Removing the channel will also remove all the messages in the channel.", Properties.Resources.Confirm)) { - if (ParameterSpecified(nameof(GroupId))) + if (!TeamsUtility.DeleteChannel(AccessToken, HttpClient, GroupId.Id.ToString(), DisplayName)) { - if (Force || ShouldContinue("Removing the channel will also remove all the messages in the channel.", Properties.Resources.Confirm)) - { - TeamsUtility.DeleteChannel(AccessToken, GroupId, DisplayName); - } + WriteError(new ErrorRecord(new Exception($"Channel remove failed"), "REMOVEFAILED", ErrorCategory.InvalidResult, this)); } } - else - { - WriteWarning("The current access token lacks the Group.ReadWrite.All permission scope"); - } - } } } diff --git a/Commands/Utilities/REST/GraphCollection.cs b/Commands/Utilities/REST/GraphCollection.cs new file mode 100644 index 000000000..819cd72de --- /dev/null +++ b/Commands/Utilities/REST/GraphCollection.cs @@ -0,0 +1,19 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Utilities.REST +{ + + public class GraphCollection + { + [JsonProperty("@odata.nextLink")] + public string NextLink { get; set; } + + [JsonProperty("value")] + public IEnumerable Items { get; set; } + } +} diff --git a/Commands/Utilities/REST/GraphHelper.cs b/Commands/Utilities/REST/GraphHelper.cs new file mode 100644 index 000000000..aea5f814f --- /dev/null +++ b/Commands/Utilities/REST/GraphHelper.cs @@ -0,0 +1,175 @@ +using Microsoft.Identity.Client; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace SharePointPnP.PowerShell.Commands.Utilities.REST +{ + internal static class GraphHelper + { + + private static HttpRequestMessage GetMessage(string url, HttpMethod method, string accessToken, HttpContent content = null) + { + if (url.StartsWith("/")) + { + url = url.Substring(1); + } + + var message = new HttpRequestMessage(); + message.Method = method; + message.RequestUri = new Uri($"https://graph.microsoft.com/{url}"); + message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken); + if (method == HttpMethod.Post || method == HttpMethod.Put) + { + message.Content = content; + } + + return message; + } + + public static async Task GetAsync(HttpClient httpClient, string url, string accessToken) + { + var message = GetMessage(url, HttpMethod.Get, accessToken); + return await SendMessageAsync(httpClient, message); + } + + public static async Task GetAsync(HttpClient httpClient, string url, string accessToken) + { + var stringContent = await GetAsync(httpClient, url, accessToken); + if (stringContent != null) + { + try + { + return JsonConvert.DeserializeObject(stringContent); + } + catch + { + return default(T); + } + } + return default(T); + } + + public static async Task PostAsync(HttpClient httpClient, string url, string accessToken, HttpContent content) + { + var message = GetMessage(url, HttpMethod.Post, accessToken, content); + return await SendMessageAsync(httpClient, message); + } + + public static async Task PostAsync(HttpClient httpClient, string url, HttpContent content, string accessToken) + { + var message = GetMessage(url, HttpMethod.Post, accessToken, content); + var stringContent = await SendMessageAsync(httpClient, message); + if (stringContent != null) + { + try + { + return JsonConvert.DeserializeObject(stringContent); + } + catch + { + return default; + } + } + return default; + } + + public static async Task PostAsync(HttpClient httpClient, string url, T content, string accessToken) + { + var requestContent = new StringContent(JsonConvert.SerializeObject(content, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver() })); + requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); + var message = GetMessage(url, HttpMethod.Post, accessToken, requestContent); + var returnValue = await SendMessageAsync(httpClient, message); + if(!string.IsNullOrEmpty(returnValue)) + { + return JsonConvert.DeserializeObject(returnValue); + } else + { + return default; + } + } + + public static async Task DeleteAsync(HttpClient httpClient, string url, string accessToken) + { + var message = GetMessage(url, HttpMethod.Delete, accessToken); + var response = await GetResponseMessageAsync(httpClient, message); + if (response.IsSuccessStatusCode) + { + return true; + } + else + { + return false; + } + } + + + + public static async Task SendMessageAsync(HttpClient httpClient, HttpRequestMessage message) + { + var response = await httpClient.SendAsync(message); + while (response.StatusCode == (HttpStatusCode)429) + { + // throttled + var retryAfter = response.Headers.RetryAfter; + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + response = await httpClient.SendAsync(CloneMessage(message)); + } + if (response.IsSuccessStatusCode) + { + return await response.Content.ReadAsStringAsync(); + } + else + { + return null; + } + } + + public static async Task GetResponseMessageAsync(HttpClient httpClient, HttpRequestMessage message) + { + var response = await httpClient.SendAsync(message); + while (response.StatusCode == (HttpStatusCode)429) + { + // throttled + var retryAfter = response.Headers.RetryAfter; + Thread.Sleep(retryAfter.Delta.Value.Seconds * 1000); + response = await httpClient.SendAsync(CloneMessage(message)); + } + if (response.IsSuccessStatusCode) + { + return response; + } + else + { + return null; + } + } + + private static HttpRequestMessage CloneMessage(HttpRequestMessage req) + { + HttpRequestMessage clone = new HttpRequestMessage(req.Method, req.RequestUri); + + clone.Content = req.Content; + clone.Version = req.Version; + + foreach (KeyValuePair prop in req.Properties) + { + clone.Properties.Add(prop); + } + + foreach (KeyValuePair> header in req.Headers) + { + clone.Headers.TryAddWithoutValidation(header.Key, header.Value); + } + + return clone; + } + } +} diff --git a/Commands/Utilities/REST/RestHelper.cs b/Commands/Utilities/REST/RestHelper.cs index 391ed1c26..12f920407 100644 --- a/Commands/Utilities/REST/RestHelper.cs +++ b/Commands/Utilities/REST/RestHelper.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Threading.Tasks; using Microsoft.SharePoint.Client; using Newtonsoft.Json; diff --git a/Commands/Utilities/TeamsUtility.cs b/Commands/Utilities/TeamsUtility.cs new file mode 100644 index 000000000..a30fb2da1 --- /dev/null +++ b/Commands/Utilities/TeamsUtility.cs @@ -0,0 +1,170 @@ +using SharePointPnP.PowerShell.Commands.Model.Teams; +using SharePointPnP.PowerShell.Commands.Utilities.REST; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Web; + +namespace SharePointPnP.PowerShell.Commands.Utilities +{ + internal static class TeamsUtility + { + private const int PageSize = 100; + + #region Team + private static List GetGroupsWithTeam(HttpClient httpClient, string accessToken, GroupVisibility visibility = GroupVisibility.NotSpecified) + { + List groups = new List(); + string url = string.Empty; + var collection = GraphHelper.GetAsync>(httpClient, $"beta/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')&$select=Id,DisplayName,MailNickName,Description,Visibility&$top={PageSize}", accessToken).GetAwaiter().GetResult(); ; + if(collection != null) + { + groups.AddRange(collection.Items); + while(!string.IsNullOrEmpty(collection.NextLink)) + { + collection = GraphHelper.GetAsync>(httpClient, collection.NextLink, accessToken).GetAwaiter().GetResult(); + groups.AddRange(collection.Items); + } + } + if (visibility != GroupVisibility.NotSpecified) + { + return groups.Where(g => g.Visibility == visibility).ToList(); + } + else + { + return groups; + } + } + + public static List GetTeams(string accessToken, HttpClient httpClient, GroupVisibility visibility = GroupVisibility.NotSpecified) + { + List teams = new List(); + + var groups = GetGroupsWithTeam(httpClient, accessToken, visibility); + foreach (var group in groups) + { + Team team = ParseTeamJson(accessToken, httpClient, group.Id); + + if (team != null) + { + team.DisplayName = group.DisplayName; + team.MailNickname = group.MailNickname; + team.Visibility = group.Visibility; + teams.Add(team); + } + } + return teams; + } + + public static Team GetTeam(string accessToken, HttpClient httpClient, string groupId) + { + // get the group + var group = GraphHelper.GetAsync(httpClient, $"v1.0/groups/{groupId}?$select=Id,DisplayName,MailNickName,Description,Visibility", accessToken).GetAwaiter().GetResult(); + + Team team = ParseTeamJson(accessToken, httpClient, group.Id); + if (team != null) + { + team.DisplayName = group.DisplayName; + team.MailNickname = group.MailNickname; + team.Visibility = group.Visibility; + return team; + } else + { + return null; + } + } + + private static Team ParseTeamJson(string accessToken, HttpClient httpClient, string groupId) + { + // Get Settings + try + { + var team = GraphHelper.GetAsync(httpClient, $"v1.0/teams/{groupId}", accessToken).GetAwaiter().GetResult(); + if (team != null) + { + team.GroupId = groupId; + return team; + } else + { + return null; + } + + //team = GetTeamChannels(configuration, accessToken, groupId, team, scope); + //team = GetTeamApps(accessToken, groupId, team, scope); + //team = GetTeamSecurity(accessToken, groupId, team, scope); + //GetTeamPhoto(configuration, accessToken, groupId, team, scope); + } + catch (ApplicationException ex) + { +#if !NETSTANDARD2_1 + if (ex.InnerException is HttpException) + { + if (((HttpException)ex.InnerException).GetHttpCode() == 404) + { + // no team, swallow + return null; + } + else + { + throw ex; + } + } + else + { + throw ex; + } +#else + // untested change + if (ex.Message.StartsWith("404")) + { + // no team, swallow + } + else + { + throw ex; + } +#endif + } + } + #endregion + + #region Channel + public static IEnumerable GetChannels(string accessToken, HttpClient httpClient, string groupId) + { + var collection = GraphHelper.GetAsync>(httpClient, $"v1.0/teams/{groupId}/channels", accessToken).GetAwaiter().GetResult(); + if(collection != null) + { + return collection.Items; + } else + { + return null; + } + } + + public static bool DeleteChannel(string accessToken, HttpClient httpClient, string groupId, string displayName) + { + // find the channel + var channels = GetChannels(accessToken, httpClient, groupId); + var channel = channels.FirstOrDefault(c => c.DisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase)); + if (channel != null) + { + return GraphHelper.DeleteAsync(httpClient, $"v1.0/teams/{groupId}/channels/{channel.Id}", accessToken).GetAwaiter().GetResult(); + } else + { + return false; + } + } + + public static TeamChannel AddChannel(string accessToken, HttpClient httpClient, string groupId, string displayName, string description) + { + var channel = new TeamChannel() + { + Description = description, + DisplayName = displayName, + }; + return GraphHelper.PostAsync(httpClient, $"v1.0/teams/{groupId}/channels", channel, accessToken).GetAwaiter().GetResult(); + } + #endregion + } +} From 222a6954c6a0fd53496a0e346625d5987d914239 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Sun, 28 Jun 2020 21:53:26 +0100 Subject: [PATCH 076/130] Change the tests for class initialise to avoid creating multple site collections --- Tests/OriginalTests/FilesTest.cs | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Tests/OriginalTests/FilesTest.cs b/Tests/OriginalTests/FilesTest.cs index d1c1d5e06..df3beee64 100644 --- a/Tests/OriginalTests/FilesTest.cs +++ b/Tests/OriginalTests/FilesTest.cs @@ -12,15 +12,15 @@ namespace SharePointPnP.PowerShell.Tests [TestClass] public class FilesTests { - private string _site1Id; - private string _site2Id; - private string _site1Url; - private string _site2Url; - private string _site1RelativeUrl; - private string _site2RelativeUrl; + private static string _site1Id; + private static string _site2Id; + private static string _site1Url; + private static string _site2Url; + private static string _site1RelativeUrl; + private static string _site2RelativeUrl; - private string Site1RelativeFolderUrl + private static string Site1RelativeFolderUrl { get { @@ -52,12 +52,13 @@ private string Site2RelativeFolderUrl private const string EmptyFolderName = "EmptyFolder"; private const string TargetFileNameWithAmpersand = "Test & file.txt"; private const string TargetFileNameWithHashtag = "Test & file.txt"; - - [TestInitialize] - public void Initialize() + + [ClassInitialize] + public static void Initialize(TestContext testContext) { using (var ctx = TestCommon.CreateClientContext()) { + _site1Id = Guid.NewGuid().ToString(); _site2Id = Guid.NewGuid().ToString(); @@ -130,15 +131,16 @@ public void Initialize() } - [TestCleanup] - public void Cleanup() + [ClassCleanup] + public static void Cleanup() { using (var ctx = TestCommon.CreateTenantClientContext()) { Tenant tenant = new Tenant(ctx); - tenant.DeleteSiteCollection(_site1Url, false); - tenant.DeleteSiteCollection(_site2Url, false); + // For any accidents lets allow for recoverability + tenant.DeleteSiteCollection(_site1Url, true); + tenant.DeleteSiteCollection(_site2Url, true); } } From 13339300157756ee3b0278d33a4b4cdf736dfa67 Mon Sep 17 00:00:00 2001 From: Paul Bullock Date: Sun, 28 Jun 2020 21:54:07 +0100 Subject: [PATCH 077/130] Updated readme as a start of instructions on running/writing tests --- SharePointPnP.PowerShell.sln | 5 ++-- Tests/Readme.md | 9 ------- Tests/SharePointPnP.PowerShell.Tests.csproj | 2 +- Tests/UnitTests-Readme.md | 30 +++++++++++++++++++++ 4 files changed, 34 insertions(+), 12 deletions(-) delete mode 100644 Tests/Readme.md create mode 100644 Tests/UnitTests-Readme.md diff --git a/SharePointPnP.PowerShell.sln b/SharePointPnP.PowerShell.sln index dbfbb3710..984fe6adb 100644 --- a/SharePointPnP.PowerShell.sln +++ b/SharePointPnP.PowerShell.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2026 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30128.74 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharePointPnP.PowerShell.Commands", "Commands\SharePointPnP.PowerShell.Commands.csproj", "{1DDE6F0A-CA49-419A-9CE8-A6CA02F43CE0}" ProjectSection(ProjectDependencies) = postProject @@ -21,6 +21,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentat CHANGELOG.md = CHANGELOG.md CONTRIBUTING.md = CONTRIBUTING.md readme.md = readme.md + Tests\UnitTests-Readme.md = Tests\UnitTests-Readme.md version.txt = version.txt EndProjectSection EndProject diff --git a/Tests/Readme.md b/Tests/Readme.md deleted file mode 100644 index 6d8fecb81..000000000 --- a/Tests/Readme.md +++ /dev/null @@ -1,9 +0,0 @@ -# Unit tests - -These are organised to match the same folder structure as the cmdlets for easy findability and association of tests. - - -## Useful attributes on a test - -* [Priority] - assigns priority in tests -* [Ignore] - disables the test diff --git a/Tests/SharePointPnP.PowerShell.Tests.csproj b/Tests/SharePointPnP.PowerShell.Tests.csproj index d52ce8f27..e170c42aa 100644 --- a/Tests/SharePointPnP.PowerShell.Tests.csproj +++ b/Tests/SharePointPnP.PowerShell.Tests.csproj @@ -757,7 +757,7 @@ Designer - + diff --git a/Tests/UnitTests-Readme.md b/Tests/UnitTests-Readme.md new file mode 100644 index 000000000..4f64c8bd5 --- /dev/null +++ b/Tests/UnitTests-Readme.md @@ -0,0 +1,30 @@ +# Unit tests + +Unit tests for PnP Powershell are undergoing a revamp, this area may grow or change, and maybe subject to test breakages in the short term. + +## Tips for Writing Tests + +### Organising tests + +* The tests are organised in a subfolder and namespace that matches the cmdlets in the main project for easy findability and association of tests. +* Each cmdlet should have its own test class. +* A test placeholder has been pre-generated for + +### Performance + +* Aim for quickest possible test, if a test requires a component to be setup that is time consuming or has a long running operation, this +should be added to the test suite setup as a one time setup. +* [TestInitialize] and [TestCleanup] runs on EACH test, if you have setup requirements for a suite of tests use [ClassInitialize] and [ClassCleanup] + +### Sites + +When writing your tests ensure that you utilise the existing sites set out by the requirements for running the suite of tests. +Site creation for certiain template types can take a long time to execute and risk timing out the test run. + + +# Notes + +## Useful attributes on a test + +* [Priority] - assigns priority in tests +* [Ignore] - disables the test \ No newline at end of file From 17ea7a85aff53d055205daed381e0d6b6f40df1b Mon Sep 17 00:00:00 2001 From: Maximilian L <31658807+MrTantum@users.noreply.github.com> Date: Mon, 29 Jun 2020 10:15:07 +0200 Subject: [PATCH 078/130] Fixed timeouts on Get-PnPSiteCollectionAdmin Fixed timeouts on Get-PnPSiteCollectionAdmin on site collections with many users. --- Commands/Site/GetSiteCollectionAdmin.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Commands/Site/GetSiteCollectionAdmin.cs b/Commands/Site/GetSiteCollectionAdmin.cs index 1bc8de56a..47eafec0a 100644 --- a/Commands/Site/GetSiteCollectionAdmin.cs +++ b/Commands/Site/GetSiteCollectionAdmin.cs @@ -42,11 +42,11 @@ protected override void ExecuteCmdlet() g => g.LoginName) }; - ClientContext.Load(SelectedWeb.SiteUsers, users => users.Include(retrievalExpressions)); + var siteCollectionAdminUsersQuery = SelectedWeb.SiteUsers.Where(u => u.IsSiteAdmin); + var siteCollectionAdminUsers = ClientContext.LoadQuery(siteCollectionAdminUsersQuery.Include(retrievalExpressions)); ClientContext.ExecuteQueryRetry(); - var siteCollectionAdminUsers = SelectedWeb.SiteUsers.Where(su => su.IsSiteAdmin); WriteObject(siteCollectionAdminUsers, true); } } -} \ No newline at end of file +} From 34e5ee766117a5dfa0453a17f06506e4ee9eaef7 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 29 Jun 2020 17:03:45 +0200 Subject: [PATCH 079/130] Teams Cmdlets --- .../InitializePowerShellAuthentication.cs | 1 + Commands/Base/PipeBinds/TeamTabPipeBind.cs | 37 ++++++ Commands/Base/PnPConnection.cs | 43 +++++-- Commands/Base/PnPGraphCmdlet.cs | 16 ++- Commands/Model/AzureApp.cs | 18 +++ Commands/Model/Teams/TeamApp.cs | 14 +++ Commands/Model/Teams/TeamTab.cs | 2 +- .../PnP.PowerShell.Core.Format.ps1xml | 108 ++++++++++++++++++ .../SharePointPnP.PowerShell.Commands.csproj | 1 + Commands/Teams/GetTeamsApp.cs | 43 +++++++ Commands/Teams/GetTeamsChannel.cs | 29 ++--- Commands/Teams/GetTeamsTab.cs | 63 ++++++++++ Commands/Teams/GetTeamsTeam.cs | 8 +- Commands/Teams/RemoveTeamsTab.cs | 48 ++++++++ Commands/Teams/RemoveTeamsTeam.cs | 38 ++++++ Commands/Utilities/TeamsUtility.cs | 62 ++++++++-- .../CmdletMicrosoftGraphApiPermission.cs | 24 +++- 17 files changed, 507 insertions(+), 48 deletions(-) create mode 100644 Commands/Base/PipeBinds/TeamTabPipeBind.cs create mode 100644 Commands/Model/Teams/TeamApp.cs create mode 100644 Commands/Teams/GetTeamsApp.cs create mode 100644 Commands/Teams/GetTeamsTab.cs create mode 100644 Commands/Teams/RemoveTeamsTab.cs create mode 100644 Commands/Teams/RemoveTeamsTeam.cs diff --git a/Commands/Base/InitializePowerShellAuthentication.cs b/Commands/Base/InitializePowerShellAuthentication.cs index 8ac256a4c..c92d3d891 100644 --- a/Commands/Base/InitializePowerShellAuthentication.cs +++ b/Commands/Base/InitializePowerShellAuthentication.cs @@ -165,6 +165,7 @@ protected override void ProcessRecord() scopes.Add(permissionScopes.GetScope("MSGraph.Group.ReadWrite.All")); scopes.Add(permissionScopes.GetScope("SPO.User.Read.All")); scopes.Add(permissionScopes.GetScope("MSGraph.User.Read.All")); + scopes.Add(permissionScopes.GetScope("MSGraph.AppCatalog.ReadWrite.All"); } var scopesPayload = GetScopesPayload(scopes); diff --git a/Commands/Base/PipeBinds/TeamTabPipeBind.cs b/Commands/Base/PipeBinds/TeamTabPipeBind.cs new file mode 100644 index 000000000..5873317e7 --- /dev/null +++ b/Commands/Base/PipeBinds/TeamTabPipeBind.cs @@ -0,0 +1,37 @@ +using Microsoft.SharePoint.Client; +using System; + +namespace SharePointPnP.PowerShell.Commands.Base.PipeBinds +{ + public sealed class TeamTabPipeBind + { + private readonly Guid _id; + private readonly string _displayName; + + public TeamTabPipeBind() + { + _id = Guid.Empty; + } + + public TeamTabPipeBind(string input) + { + if (string.IsNullOrEmpty(input)) + { + throw new ArgumentException(nameof(input)); + } + if (Guid.TryParse(input, out Guid tabId)) + { + _id = tabId; + } + else + { + _displayName = input; + } + } + + + public Guid Id => _id; + + public string DisplayName => _displayName; + } +} diff --git a/Commands/Base/PnPConnection.cs b/Commands/Base/PnPConnection.cs index f757182c4..2f7270fa2 100644 --- a/Commands/Base/PnPConnection.cs +++ b/Commands/Base/PnPConnection.cs @@ -134,9 +134,9 @@ internal string TryGetAccessToken(TokenAudience tokenAudience, string[] roles = /// Tries to get a token for the provided audience ///
- The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument but not -SPOManagementShell or -PnPO365ManagementShell to connect. + The current connection holds no SharePoint context. Please use one of the Connect-PnPOnline commands which uses the -Url argument but not -SPOManagementShell or -PnPOManagementShell to connect. No connection to disconnect diff --git a/Commands/Utilities/BrowserHelper.cs b/Commands/Utilities/BrowserHelper.cs index 0d3142b25..f2174054f 100644 --- a/Commands/Utilities/BrowserHelper.cs +++ b/Commands/Utilities/BrowserHelper.cs @@ -55,6 +55,51 @@ public static void OpenBrowser(string url, Action success, System.Drawing. thread.Start(); thread.Join(); } + + public static void LaunchBrowser(string url, Action success, System.Drawing.Icon icon = null) + { + var thread = new Thread(() => + { + var form = new System.Windows.Forms.Form(); + if (icon != null) + { + form.Icon = icon; + } + var browser = new System.Windows.Forms.WebBrowser + { + ScriptErrorsSuppressed = true, + Dock = DockStyle.Fill + }; + + form.SuspendLayout(); + form.Width = 568; + form.Height = 1012; + form.Text = $"Authenticate"; + form.Controls.Add(browser); + form.ResumeLayout(false); + form.FormClosed += (sender, args) => + { + success(false); + }; + browser.Navigated += (sender, args) => + { + if (browser.Url.AbsoluteUri.Equals("https://login.microsoftonline.com/common/login", StringComparison.InvariantCultureIgnoreCase) || browser.Url.AbsoluteUri.StartsWith("https://login.microsoftonline.com/common/reprocess", StringComparison.InvariantCultureIgnoreCase)) + { + form.Close(); + success(true); + } + }; + browser.Navigate(url); + + form.Focus(); + form.ShowDialog(); + browser.Dispose(); + }); + + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); + thread.Join(); + } } } #endif \ No newline at end of file diff --git a/Commands/Utilities/Clipboard.cs b/Commands/Utilities/Clipboard.cs index 8c67af7fa..0612b02e5 100644 --- a/Commands/Utilities/Clipboard.cs +++ b/Commands/Utilities/Clipboard.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading; namespace SharePointPnP.PowerShell.Commands.Utilities { @@ -27,5 +28,27 @@ public static void Copy(string val) System.IO.File.Delete(tempfile); #endif } + + public static void CopyNew(string value) + { + Exception threadEx = null; + Thread staThread = new Thread( + + delegate () + { + try + { + System.Windows.Forms.Clipboard.SetText(value); + } + + catch (Exception ex) + { + threadEx = ex; + } + }); + staThread.SetApartmentState(ApartmentState.STA); + staThread.Start(); + staThread.Join(); + } } } From 45eb71cfcf670b1a64ef3ad1c5c22b2ee6163464 Mon Sep 17 00:00:00 2001 From: Erwin van Hunen Date: Mon, 13 Jul 2020 11:55:14 +0200 Subject: [PATCH 130/130] July 2020 Release --- CHANGELOG.md | 4 +++- Commands/Properties/AssemblyInfo.cs | 4 ++-- version.txt | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 231e4d963..e6dde0b63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). -## [3.23.2007.0] (not yet released) +## [3.24.2008.0] + +## [3.23.2007.0] ### Added - Added `-WithRightsAssignedDetailed` parameter to `Get-PnPUser` allowing for fine grained (broken) permissions on item, list and site level to be shown [PR #2754](https://github.com/pnp/PnP-PowerShell/pull/2754) diff --git a/Commands/Properties/AssemblyInfo.cs b/Commands/Properties/AssemblyInfo.cs index 782b64d16..86bf9b2f4 100644 --- a/Commands/Properties/AssemblyInfo.cs +++ b/Commands/Properties/AssemblyInfo.cs @@ -51,8 +51,8 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] #if !NETSTANDARD2_1 -[assembly: AssemblyVersion("3.22.2006.2")] -[assembly: AssemblyFileVersion("3.22.2006.2")] +[assembly: AssemblyVersion("3.23.2007.0")] +[assembly: AssemblyFileVersion("3.23.2007.0")] #else [assembly: AssemblyVersion("4.0.0.0")] [assembly: AssemblyFileVersion("4.0.0.0")] diff --git a/version.txt b/version.txt index df7248568..0fea99d2e 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -3.22.2006.2 \ No newline at end of file +3.23.2007.0 \ No newline at end of file