diff --git a/Binaries/SharePointPnP.Modernization.Framework.dll b/Binaries/SharePointPnP.Modernization.Framework.dll
index 9e72a5383..dcf7148f4 100644
Binary files a/Binaries/SharePointPnP.Modernization.Framework.dll and b/Binaries/SharePointPnP.Modernization.Framework.dll differ
diff --git a/Binaries/SharePointPnP.Modernization.Framework.xml b/Binaries/SharePointPnP.Modernization.Framework.xml
index 654e8e2c9..1cbe10919 100644
--- a/Binaries/SharePointPnP.Modernization.Framework.xml
+++ b/Binaries/SharePointPnP.Modernization.Framework.xml
@@ -2490,7 +2490,7 @@
Information about the page to transform
The path to the created modern page
-
+
Performs the logic needed to swap a genered Migrated_Page.aspx to Page.aspx and then Page.aspx to Old_Page.aspx
@@ -4265,6 +4265,13 @@
Page list item
Last modified by user/account
+
+
+ Get's the blog last published date time
+
+ Page list item
+ DateTime of the last modification
+
Get's the page page layout file
diff --git a/Binaries/release/SharePointPnP.Modernization.Framework.dll b/Binaries/release/SharePointPnP.Modernization.Framework.dll
index eb16ea7f7..f1721a993 100644
Binary files a/Binaries/release/SharePointPnP.Modernization.Framework.dll and b/Binaries/release/SharePointPnP.Modernization.Framework.dll differ
diff --git a/Binaries/release/SharePointPnP.Modernization.Framework.xml b/Binaries/release/SharePointPnP.Modernization.Framework.xml
index 654e8e2c9..1cbe10919 100644
--- a/Binaries/release/SharePointPnP.Modernization.Framework.xml
+++ b/Binaries/release/SharePointPnP.Modernization.Framework.xml
@@ -2490,7 +2490,7 @@
Information about the page to transform
The path to the created modern page
-
+
Performs the logic needed to swap a genered Migrated_Page.aspx to Page.aspx and then Page.aspx to Old_Page.aspx
@@ -4265,6 +4265,13 @@
Page list item
Last modified by user/account
+
+
+ Get's the blog last published date time
+
+ Page list item
+ DateTime of the last modification
+
Get's the page page layout file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 50cc4d2c5..5ccee2439 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,26 @@ 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/).
+## [Unreleased]
+
+### Added
+
+### Changed
+
+### Contributors
+
+## [3.14.1910.1]
+
+### Added
+
+- ConvertTo-PnPClientSidePage: Added support for logging to console via `-LogType Console`
+- Copy-PnPFile: Fixes (#2300)
+- ConvertTo-PnPClientSidePage: Added support for controlling the target page name is any cross site transformation (so wiki, web part, blog in addition the already existing option for publishing pages) via the `-TargetPageName` parameter
+
+### Changed
+
+### Contributors
+
## [3.14.1910.0]
### Added
@@ -18,6 +38,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Changed
+- Several documentation fixes
- Add-PnPClientSideWebPart now also works for SP2019
- Added -List parameter to Get-PnPFolder to retrieve all folders in a list
- Added owner paramter to New-PnPSite when create Communications site
@@ -28,11 +49,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Contributors
+- Aleksandr SaPozhkov [shurick81]
- Garry Trinder [garrytrinder]
- Koen Zomers [KoenZomers]
- Gautam Sheth [gautamdsheth]
- Giacomo Pozzoni [jackpoz]
- Paul Bullock [pkbullock]
+- Andres Mariano Gorzelany [get-itips]
## [3.13.1909.0]
diff --git a/Commands/ClientSidePages/ClientSidePageTransformatorLogType.cs b/Commands/ClientSidePages/ClientSidePageTransformatorLogType.cs
index b8ba1e7f0..7a41a20c5 100644
--- a/Commands/ClientSidePages/ClientSidePageTransformatorLogType.cs
+++ b/Commands/ClientSidePages/ClientSidePageTransformatorLogType.cs
@@ -6,6 +6,7 @@ public enum ClientSidePageTransformatorLogType
None = 0,
File = 1,
SharePoint = 2,
+ Console = 3,
}
}
#endif
\ No newline at end of file
diff --git a/Commands/ClientSidePages/ConvertToClientSidePage.cs b/Commands/ClientSidePages/ConvertToClientSidePage.cs
index cc6e5790b..6670fb82a 100644
--- a/Commands/ClientSidePages/ConvertToClientSidePage.cs
+++ b/Commands/ClientSidePages/ConvertToClientSidePage.cs
@@ -23,19 +23,19 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages
Category = CmdletHelpCategory.ClientSidePages, SupportedPlatform = CmdletSupportedPlatform.Online)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -Overwrite",
- Remarks = "Converts a wiki page named 'somepage' to a client side page",
+ Remarks = "Converts a wiki/web part page named 'somepage' to a client side page",
SortOrder = 1)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -Overwrite -WebPartMappingFile c:\contoso\webpartmapping.xml",
- Remarks = "Converts a wiki page named 'somepage' to a client side page using a custom provided mapping file",
+ Remarks = "Converts a wiki/web part page named 'somepage' to a client side page using a custom provided mapping file",
SortOrder = 2)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -Overwrite -AddPageAcceptBanner",
- Remarks = "Converts a wiki page named 'somepage' to a client side page and adds the page accept banner web part on top of the page. This requires that the SPFX solution holding the web part (https://github.com/SharePoint/sp-dev-modernization/blob/master/Solutions/PageTransformationUI/assets/sharepointpnp-pagetransformation-client.sppkg?raw=true) has been installed to the tenant app catalog",
+ Remarks = "Converts a wiki/web part page named 'somepage' to a client side page and adds the page accept banner web part on top of the page. This requires that the SPFX solution holding the web part (https://github.com/SharePoint/sp-dev-modernization/blob/master/Solutions/PageTransformationUI/assets/sharepointpnp-pagetransformation-client.sppkg?raw=true) has been installed to the tenant app catalog",
SortOrder = 3)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -Overwrite -CopyPageMetadata",
- Remarks = "Converts a wiki page named 'somepage' to a client side page, including the copying of the page metadata (if any)",
+ Remarks = "Converts a wiki/web part page named 'somepage' to a client side page, including the copying of the page metadata (if any)",
SortOrder = 4)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -PublishingPage -Overwrite -TargetWebUrl https://contoso.sharepoint.com/sites/targetmodernsite",
@@ -55,16 +55,20 @@ namespace SharePointPnP.PowerShell.Commands.ClientSidePages
SortOrder = 8)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -Overwrite -TargetWebUrl https://contoso.sharepoint.com/sites/targetmodernsite",
- Remarks = "Converts a wiki page named 'somepage' to a client side page in the https://contoso.sharepoint.com/sites/targetmodernsite site",
+ Remarks = "Converts a wiki/web part page named 'somepage' to a client side page in the https://contoso.sharepoint.com/sites/targetmodernsite site",
SortOrder = 9)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -LogType File -LogFolder c:\temp -LogVerbose -Overwrite",
- Remarks = "Converts a web part page named 'somepage' and creates a log file in c:\\temp using verbose logging",
+ Remarks = "Converts a wiki/web part page named 'somepage' and creates a log file in c:\\temp using verbose logging",
SortOrder = 10)]
[CmdletExample(
Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""somepage.aspx"" -LogType SharePoint -LogSkipFlush",
- Remarks = "Converts a web part page named 'somepage' and creates a log file in SharePoint but skip the actual write. Use this option to make multiple ConvertTo-PnPClientSidePage invocations create a single log",
+ Remarks = "Converts a wiki/web part page named 'somepage' and creates a log file in SharePoint but skip the actual write. Use this option to make multiple ConvertTo-PnPClientSidePage invocations create a single log",
SortOrder = 11)]
+ [CmdletExample(
+ Code = @"PS:> ConvertTo-PnPClientSidePage -Identity ""My post title"" -BlogPage -LogType Console -Overwrite -TargetWebUrl https://contoso.sharepoint.com/sites/targetmodernsite",
+ Remarks = "Converts a blog page with a title starting with 'my post title' to a client side page in the https://contoso.sharepoint.com/sites/targetmodernsite site",
+ SortOrder = 12)]
public class ConvertToClientSidePage : PnPWebCmdlet
{
private static string rootFolder = "";
@@ -165,6 +169,9 @@ public class ConvertToClientSidePage : PnPWebCmdlet
[Parameter(Mandatory = false, HelpMessage = "Name for the target page (only applies to publishing page transformation)")]
public string PublishingTargetPageName = "";
+ [Parameter(Mandatory = false, HelpMessage = "Name for the target page (only applies when doing cross site page transformation)")]
+ public string TargetPageName = "";
+
[Parameter(Mandatory = false, HelpMessage = "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.")] // do not remove '#!#99'
public SPOnlineConnection TargetConnection = null;
@@ -246,6 +253,8 @@ protected override void ExecuteCmdlet()
throw new Exception($"Provided pagelayout mapping file {this.PageLayoutMapping} does not exist");
}
+ bool crossSiteTransformation = TargetConnection != null || !string.IsNullOrEmpty(TargetWebUrl);
+
// Create target client context (when needed)
ClientContext targetContext = null;
if (TargetConnection == null)
@@ -337,6 +346,17 @@ protected override void ExecuteCmdlet()
pageTransformator.RegisterObserver(new MarkdownToSharePointObserver(targetContext ?? this.ClientContext, includeVerbose: this.LogVerbose, includeDebugEntries: this.LogVerbose));
}
}
+ else if (this.LogType == ClientSidePageTransformatorLogType.Console)
+ {
+ if (this.PublishingPage)
+ {
+ publishingPageTransformator.RegisterObserver(new ConsoleObserver(includeDebugEntries: this.LogVerbose));
+ }
+ else
+ {
+ pageTransformator.RegisterObserver(new ConsoleObserver(includeDebugEntries: this.LogVerbose));
+ }
+ }
// Clear the client side component cache
if (this.ClearCache)
@@ -356,7 +376,7 @@ protected override void ExecuteCmdlet()
KeepPageCreationModificationInformation = this.KeepPageCreationModificationInformation,
PostAsNews = this.PostAsNews,
DisablePageComments = this.DisablePageComments,
- TargetPageName = this.PublishingTargetPageName,
+ TargetPageName = !string.IsNullOrEmpty(this.PublishingTargetPageName) ? this.PublishingTargetPageName : this.TargetPageName,
SkipUrlRewrite = this.SkipUrlRewriting,
SkipDefaultUrlRewrite = this.SkipDefaultUrlRewriting,
UrlMappingFile = this.UrlMappingFile,
@@ -374,7 +394,7 @@ protected override void ExecuteCmdlet()
finally
{
// Flush log
- if (this.LogType != ClientSidePageTransformatorLogType.None && !this.LogSkipFlush)
+ if (this.LogType != ClientSidePageTransformatorLogType.None && this.LogType != ClientSidePageTransformatorLogType.Console && !this.LogSkipFlush)
{
publishingPageTransformator.FlushObservers();
}
@@ -406,6 +426,7 @@ protected override void ExecuteCmdlet()
SetAuthorInPageHeader = this.SetAuthorInPageHeader,
PostAsNews = this.PostAsNews,
DisablePageComments = this.DisablePageComments,
+ TargetPageName = crossSiteTransformation ? this.TargetPageName : "",
SkipUrlRewrite = this.SkipUrlRewriting,
SkipDefaultUrlRewrite = this.SkipDefaultUrlRewriting,
UrlMappingFile = this.UrlMappingFile,
@@ -427,7 +448,7 @@ protected override void ExecuteCmdlet()
finally
{
// Flush log
- if (this.LogType != ClientSidePageTransformatorLogType.None && !this.LogSkipFlush)
+ if (this.LogType != ClientSidePageTransformatorLogType.None && this.LogType != ClientSidePageTransformatorLogType.Console && !this.LogSkipFlush)
{
pageTransformator.FlushObservers();
}
diff --git a/Commands/ClientSidePages/ExportClientSidePage.cs b/Commands/ClientSidePages/ExportClientSidePage.cs
index 4a52d9928..45af92961 100644
--- a/Commands/ClientSidePages/ExportClientSidePage.cs
+++ b/Commands/ClientSidePages/ExportClientSidePage.cs
@@ -72,7 +72,7 @@ protected override void ProcessRecord()
private void ExtractTemplate(string dirName, string fileName, ExtractConfiguration configuration)
{
var outputTemplate = new ProvisioningTemplate();
- outputTemplate.Id = Guid.NewGuid().ToString("N");
+ outputTemplate.Id = $"TEMPLATE-{Guid.NewGuid():N}".ToUpper();
var helper = new OfficeDevPnP.Core.Framework.Provisioning.ObjectHandlers.Utilities.ClientSidePageContentsHelper();
ProvisioningTemplateCreationInformation ci = null;
if (configuration != null)
diff --git a/Commands/Files/CopyFile.cs b/Commands/Files/CopyFile.cs
index c12afb5fd..062ad6980 100644
--- a/Commands/Files/CopyFile.cs
+++ b/Commands/Files/CopyFile.cs
@@ -128,6 +128,7 @@ protected override void ExecuteCmdlet()
file = _sourceContext.Web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl(SourceUrl));
#endif
file.EnsureProperties(f => f.Name, f => f.Exists);
+ isFile = file.Exists;
}
catch
{
@@ -168,17 +169,17 @@ protected override void ExecuteCmdlet()
_targetContext = ClientContext.Clone(targetWebUri.AbsoluteUri);
var dstWeb = _targetContext.Web;
- dstWeb.EnsureProperty(s => s.Url);
+ dstWeb.EnsureProperties(s => s.Url, s => s.ServerRelativeUrl);
if (srcWeb.Url == dstWeb.Url)
{
try
{
- var targetFile = UrlUtility.Combine(TargetUrl, file.Name);
+ 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);
+ file?.CopyTo(targetFile, OverwriteIfAlreadyExists);
#else
- file.CopyToUsingPath(ResourcePath.FromDecodedUrl(targetFile), OverwriteIfAlreadyExists);
+ file?.CopyToUsingPath(ResourcePath.FromDecodedUrl(targetFile), OverwriteIfAlreadyExists);
#endif
_sourceContext.ExecuteQueryRetry();
return;
@@ -196,11 +197,15 @@ protected override void ExecuteCmdlet()
bool targetFolderExists = false;
try
{
+#if ONPREMISES
targetFolder = _targetContext.Web.GetFolderByServerRelativeUrl(TargetUrl);
+#else
+ 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;
+ targetFolderExists = true;
#else
targetFolder.EnsureProperties(f => f.Name);
try
@@ -226,8 +231,12 @@ protected override void ExecuteCmdlet()
foreach (List targetList in lists)
{
if (!TargetUrl.StartsWith(targetList.RootFolder.ServerRelativeUrl, StringComparison.InvariantCultureIgnoreCase)) continue;
- fileOrFolderName = Regex.Replace(TargetUrl, targetList.RootFolder.ServerRelativeUrl, "", RegexOptions.IgnoreCase).Trim('/');
- targetFolder = srcIsFolder ? targetList.RootFolder.EnsureFolder(fileOrFolderName) : targetList.RootFolder;
+ 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;
}
}
@@ -310,7 +319,7 @@ private File UploadFileWithSpecialCharacters(Folder folder, string fileName, Sys
{
throw new ArgumentException("Filename is required");
}
-
+
// Create the file
var newFileInfo = new FileCreationInformation()
{
diff --git a/Commands/Properties/AssemblyInfo.cs b/Commands/Properties/AssemblyInfo.cs
index 541ef6e55..28c9c4b1c 100644
--- a/Commands/Properties/AssemblyInfo.cs
+++ b/Commands/Properties/AssemblyInfo.cs
@@ -48,6 +48,6 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("3.14.1910.0")]
-[assembly: AssemblyFileVersion("3.14.1910.0")]
+[assembly: AssemblyVersion("3.14.1910.1")]
+[assembly: AssemblyFileVersion("3.14.1910.1")]
[assembly: InternalsVisibleTo("SharePointPnP.PowerShell.Tests")]
\ No newline at end of file
diff --git a/Commands/Provisioning/Site/GetProvisioningTemplate.cs b/Commands/Provisioning/Site/GetProvisioningTemplate.cs
index 11d3eac74..a84fa35dd 100644
--- a/Commands/Provisioning/Site/GetProvisioningTemplate.cs
+++ b/Commands/Provisioning/Site/GetProvisioningTemplate.cs
@@ -358,6 +358,7 @@ private void ExtractTemplate(XMLPnPSchemaVersion schema, string path, string pac
var percentage = Convert.ToInt32((100 / Convert.ToDouble(total)) * Convert.ToDouble(step));
WriteProgress(new ProgressRecord(0, $"Extracting Template from {SelectedWeb.Url}", message) { PercentComplete = percentage });
+ WriteProgress(new ProgressRecord(1, " ", " ") { RecordType = ProgressRecordType.Completed });
};
creationInformation.MessagesDelegate = (message, type) =>
{
diff --git a/Tests/FilesTest.cs b/Tests/FilesTest.cs
index 085a85c80..d1c1d5e06 100644
--- a/Tests/FilesTest.cs
+++ b/Tests/FilesTest.cs
@@ -44,10 +44,14 @@ private string Site2RelativeFolderUrl
}
}
+ private const string SourceFolderWithFolders = "SourceFolderWithFoldersAndFilesAndEmptyFolder";
+ private const string SourceFolderName = "SourceFolder";
private const string TargetFileName = "Testfile.txt";
private const string TargetFileContents = "Some random file contents";
private const string TargetCopyFolderName = "CopyDestination";
+ private const string EmptyFolderName = "EmptyFolder";
private const string TargetFileNameWithAmpersand = "Test & file.txt";
+ private const string TargetFileNameWithHashtag = "Test & file.txt";
[TestInitialize]
public void Initialize()
@@ -87,10 +91,34 @@ public void Initialize()
fileToUpload = folder.Files.Add(fci);
site1Ctx.Load(fileToUpload);
- site1Ctx.ExecuteQueryRetry();
+ fci.Url = TargetFileNameWithHashtag;
+ fci.Overwrite = true;
+ fileToUpload = folder.Files.Add(fci);
+ site1Ctx.Load(fileToUpload);
folder.EnsureFolder(TargetCopyFolderName);
+ // Prereq for CopyFile_EmptyFolderBetweenSiteCollections_Test
+ folder.EnsureFolder(EmptyFolderName);
+
+ // Prereq for CopyFile_FolderWithSkipSourceFolderNameBetweenSiteCollections_Test
+ var sourceFolder = folder.EnsureFolder(SourceFolderName);
+ fileToUpload = sourceFolder.Files.Add(fci);
+ site1Ctx.Load(fileToUpload);
+
+
+ // Prereq for CopyFile_FolderWithFoldersAndEmptyFolderBetweenSiteCollections_Test
+ var folderHirachyFolder0 = folder.EnsureFolder(SourceFolderWithFolders);
+ var folderHirachyFolder1 = folderHirachyFolder0.EnsureFolder(TargetCopyFolderName);
+
+ var folderHirachyFile0 = folderHirachyFolder0.Files.Add(fci);
+ var folderHirachyFile1 = folderHirachyFolder1.Files.Add(fci);
+ site1Ctx.Load(folderHirachyFile0);
+ site1Ctx.Load(folderHirachyFile1);
+
+ folderHirachyFolder1.EnsureFolder(EmptyFolderName);
+
+ site1Ctx.ExecuteQueryRetry();
}
OfficeDevPnP.Core.Sites.SiteCollection.CreateAsync(ctx, new OfficeDevPnP.Core.Sites.CommunicationSiteCollectionCreationInformation()
{
@@ -144,7 +172,7 @@ public void GetFile_AsFile_Test()
var results = scope.ExecuteCommand("Get-PnPFile",
new CommandParameter("Url", siteRelativeFileUrl),
new CommandParameter("AsFile"));
-
+
Assert.IsFalse(results.Any());
}
}
@@ -158,7 +186,7 @@ public void GetFile_AsObject_Test()
var results = scope.ExecuteCommand("Get-PnPFile",
new CommandParameter("Url", siteRelativeFileUrl));
-
+
Assert.IsTrue(results.Any());
Assert.IsTrue(results[0].BaseObject.GetType() == typeof(Microsoft.SharePoint.Client.File));
}
@@ -235,6 +263,33 @@ public void CopyFile_WithAmpersand_Test()
}
}
+ [TestMethod]
+ public void CopyFile_WithHashtag_Test()
+ {
+ using (var scope = new PSTestScope(_site1Url, true))
+ {
+ var sourceUrl = $"{Site1RelativeFolderUrl}/{TargetFileNameWithHashtag}";
+ var destinationUrl = $"{Site1RelativeFolderUrl}/{TargetCopyFolderName}";
+ var destinationFileUrl = $"{destinationUrl}/{TargetFileNameWithHashtag}";
+
+ var results = scope.ExecuteCommand("Copy-PnPFile",
+ new CommandParameter("SourceUrl", sourceUrl),
+ new CommandParameter("TargetUrl", destinationUrl),
+ new CommandParameter("Force"));
+
+ using (var ctx = TestCommon.CreateClientContext(_site1Url))
+ {
+ File initialFile = ctx.Web.GetFileByServerRelativeUrl(destinationFileUrl);
+ ctx.Load(initialFile);
+ ctx.ExecuteQueryRetry();
+ if (!initialFile.Exists)
+ {
+ Assert.Fail("Copied file cannot be found");
+ }
+ }
+ }
+ }
+
[TestMethod]
public void CopyFile_BetweenSiteCollections_Test()
{
@@ -288,6 +343,135 @@ public void CopyFile_BetweenSiteCollectionsWithAmpersand_Test()
}
}
}
+
+ [TestMethod]
+ public void CopyFile_BetweenSiteCollectionsWithHashtag_Test()
+ {
+ using (var scope = new PSTestScope(_site1Url, true))
+ {
+ var sourceUrl = $"{Site1RelativeFolderUrl}/{TargetFileNameWithHashtag}";
+ var destinationFolderUrl = $"{Site2RelativeFolderUrl}";
+ string destinationFileUrl = $"{destinationFolderUrl}/{TargetFileNameWithHashtag}";
+
+ var results = scope.ExecuteCommand("Copy-PnPFile",
+ new CommandParameter("SourceUrl", sourceUrl),
+ new CommandParameter("TargetUrl", destinationFolderUrl),
+ new CommandParameter("Force"));
+
+ using (var ctx = TestCommon.CreateClientContext(_site2Url))
+ {
+ File initialFile = ctx.Web.GetFileByServerRelativeUrl(destinationFileUrl);
+ ctx.Load(initialFile);
+ ctx.ExecuteQuery();
+ if (!initialFile.Exists)
+ {
+ Assert.Fail("Copied file cannot be found");
+ }
+ }
+ }
+ }
+
+ [TestMethod]
+ public void CopyFile_EmptyFolder_Test()
+ {
+ using (var scope = new PSTestScope(_site1Url, true))
+ {
+ var sourceUrl = $"{Site1RelativeFolderUrl}/{EmptyFolderName}";
+ var destinationUrl = $"{Site1RelativeFolderUrl}/{TargetCopyFolderName}/{EmptyFolderName}";
+
+ var results = scope.ExecuteCommand("Copy-PnPFile",
+ new CommandParameter("SourceUrl", sourceUrl),
+ new CommandParameter("TargetUrl", destinationUrl),
+ new CommandParameter("Force"));
+
+ using (var ctx = TestCommon.CreateClientContext(_site1Url))
+ {
+ Folder initialFolder = ctx.Web.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(destinationUrl));
+ initialFolder.EnsureProperties(f => f.Name, f => f.Exists);
+ ctx.Load(initialFolder);
+ ctx.ExecuteQuery();
+ if (!initialFolder.Exists)
+ {
+ Assert.Fail("Copied folder cannot be found");
+ }
+ }
+ }
+ }
+
+ [TestMethod]
+ public void CopyFile_EmptyFolderBetweenSiteCollections_Test()
+ {
+ using (var scope = new PSTestScope(_site1Url, true))
+ {
+ var sourceUrl = $"{Site1RelativeFolderUrl}/{EmptyFolderName}";
+ var destinationUrl = $"{Site2RelativeFolderUrl}/{EmptyFolderName}";
+
+ var results = scope.ExecuteCommand("Copy-PnPFile",
+ new CommandParameter("SourceUrl", sourceUrl),
+ new CommandParameter("TargetUrl", destinationUrl),
+ new CommandParameter("Force"));
+
+ using (var ctx = TestCommon.CreateClientContext(_site2Url))
+ {
+ Folder initialFolder = ctx.Web.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(destinationUrl));
+ initialFolder.EnsureProperties(f => f.Name, f => f.Exists);
+ ctx.Load(initialFolder);
+ ctx.ExecuteQuery();
+ if (!initialFolder.Exists)
+ {
+ Assert.Fail("Copied folder cannot be found");
+ }
+ }
+ }
+ }
+
+ [TestMethod]
+ public void CopyFile_FolderWithSkipSourceFolderNameBetweenSiteCollections_Test()
+ {
+ using (var scope = new PSTestScope(_site1Url, true))
+ {
+ var sourceUrl = $"{Site1RelativeFolderUrl}/{SourceFolderName}";
+ var destinationUrl = $"{Site2RelativeFolderUrl}";
+
+ var results = scope.ExecuteCommand("Copy-PnPFile",
+ new CommandParameter("SourceUrl", sourceUrl),
+ new CommandParameter("TargetUrl", destinationUrl),
+ new CommandParameter(name: "SkipSourceFolderName"),
+ new CommandParameter("Force"));
+
+ using (var ctx = TestCommon.CreateClientContext(_site2Url))
+ {
+ Folder initialFolder = ctx.Web.GetFolderByServerRelativePath(ResourcePath.FromDecodedUrl(destinationUrl));
+ initialFolder.EnsureProperties(f => f.Name, f => f.Exists, f => f.Files);
+ ctx.Load(initialFolder);
+ ctx.ExecuteQuery();
+ Assert.AreEqual(1, initialFolder.Files.Count);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void CopyFile_FolderWithFoldersAndEmptyFolderBetweenSiteCollections_Test()
+ {
+ using (var scope = new PSTestScope(_site1Url, true))
+ {
+ var sourceUrl = $"{Site1RelativeFolderUrl}/{SourceFolderWithFolders}";
+ var destinationUrl = $"{Site2RelativeFolderUrl}";
+
+ var results = scope.ExecuteCommand("Copy-PnPFile",
+ new CommandParameter("SourceUrl", sourceUrl),
+ new CommandParameter("TargetUrl", destinationUrl),
+ new CommandParameter("Force"));
+
+ using (var ctx = TestCommon.CreateClientContext(_site2Url))
+ {
+ List list = ctx.Web.GetListUsingPath(ResourcePath.FromDecodedUrl(destinationUrl));
+ ctx.Load(list);
+ ctx.ExecuteQuery();
+ Assert.AreEqual(5, list.ItemCount);
+ }
+ }
+ }
}
}
#endif
\ No newline at end of file
diff --git a/version.txt b/version.txt
index 8f80374bc..764245439 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-3.14.1910.0
\ No newline at end of file
+3.14.1910.1
\ No newline at end of file