From 78bb0c6076405d07eed5114818e295356ea9d2bc Mon Sep 17 00:00:00 2001 From: bryan cook <3217452+bryanbcook@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:12:32 -0400 Subject: [PATCH 1/3] Add -PassThru to Get-BloggerPost #26 --- README.md | 14 +++++--- src/public/Get-BloggerPost.ps1 | 30 ++++++++++++---- src/tests/Get-BloggerPost.Tests.ps1 | 53 +++++++++++++++++++++++++---- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ff15082..2d25fb8 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,11 @@ A PowerShell library for publishing markdown files authored in markdown to Blogg 1. Fetch an individual post from your blog ``` - Get-BloggerPost -PostId + $post = Get-BloggerPost -PostId ``` - - You can also persist the post to disk as HTML or markdown in the current directory. - + + You can also persist the post to disk as HTML or markdown in the current directory. + When using `HTML` format, files are saved as `.html` When using `Markdown` format, files are saved as `.md` @@ -84,6 +84,12 @@ A PowerShell library for publishing markdown files authored in markdown to Blogg Get-BloggerPost -PostId <postId> -OutDirectory ".\Blog" -FolderDateFormat "YYYY\\MM" -Format Markdown ``` + When persisting to disk, the post object is not returned unless `-PassThru` is specified. + + ``` + $post = Get-BloggerPost -PostId <postid> -Format Markdown -PassThru + ``` + 1. Publish a markdown file to your blog as draft ``` diff --git a/src/public/Get-BloggerPost.ps1 b/src/public/Get-BloggerPost.ps1 index 9fdad7a..e13b099 100644 --- a/src/public/Get-BloggerPost.ps1 +++ b/src/public/Get-BloggerPost.ps1 @@ -18,14 +18,28 @@ .PARAMETER OutDirectory The directory where the HTML file will be saved. If not specified, uses the current directory. +.PARAMETER PassThru + If specified, the function will return the post object instead of just saving it to a file + .EXAMPLE - Get-BloggerPost -PostId "1234567890123456789" + # obtain a post from the blog defined in the user preferences + $post = Get-BloggerPost -PostId "1234567890123456789" .EXAMPLE + # obtain a post from a specified blog and save it as HTML in a specific directory Get-BloggerPost -BlogId "9876543210987654321" -PostId "1234567890123456789" -Format HTML -OutDirectory "C:\temp" .EXAMPLE + # obtain a post from a specified blog and save it as Markdown in a specific directory with a date-based folder structure Get-BloggerPost -BlogId "9876543210987654321" -PostId "1234567890123456789" -Format Markdown -DateFormat "YYYY\\MM" -OutDirectory "C:\blogposts" + +.EXAMPLE + # obtain a post from a specified blog and save it as JSON in the current directory + Get-BloggerPost -BlogId "9876543210987654321" -PostId "1234567890123456789" -Format JSON + +.EXAMPLE + # obtain a post from a specified blog, write it to disk and return the post object + $post = Get-BloggerPost -BlogId "9876543210987654321" -PostId "1234567890123456789" -Format Markdown -PassThru #> Function Get-BloggerPost { [CmdletBinding()] @@ -46,7 +60,10 @@ Function Get-BloggerPost { [string]$FolderDateFormat, [Parameter(ParameterSetName = "Persist")] - [string]$OutDirectory = (Get-Location).Path + [string]$OutDirectory = (Get-Location).Path, + + [Parameter(ParameterSetName = "Persist")] + [switch]$PassThru ) if (!$PSBoundParameters.ContainsKey("BlogId")) { @@ -56,10 +73,6 @@ Function Get-BloggerPost { } } - if ([string]::IsNullOrEmpty($PostId)) { - throw "PostId is required." - } - try { $uri = "https://www.googleapis.com/blogger/v3/blogs/$BlogId/posts/$PostId" @@ -144,7 +157,10 @@ Function Get-BloggerPost { } # Return the post object for further processing if needed - return $result + if (!($PSCmdlet.ParameterSetName -eq "Persist") -or ($PassThru.IsPresent -and $PassThru)) { + Write-Verbose "Returning blog post object" + return $result + } } catch { throw "Failed to save post content: $($_.Exception.Message)" diff --git a/src/tests/Get-BloggerPost.Tests.ps1 b/src/tests/Get-BloggerPost.Tests.ps1 index c16aacb..331c238 100644 --- a/src/tests/Get-BloggerPost.Tests.ps1 +++ b/src/tests/Get-BloggerPost.Tests.ps1 @@ -40,16 +40,16 @@ Describe "Get-BloggerPost" { # setup blog post retrieval Mock Invoke-GAPi { - return [pscustomobject]@{ content = "<html>Test content</html>" } + return [pscustomobject]@{ content = "<p>Test content</p>" } } } # act - $result = Get-BloggerPost -PostId "123" -Format HTML -OutDirectory $OutDirectory + Get-BloggerPost -PostId "123" -Format HTML -OutDirectory $OutDirectory # assert - $result | Should -Not -BeNullOrEmpty - Test-Path -Path (Join-Path -Path $OutDirectory -ChildPath "123.html") | Should -BeTrue + $outputFile = Join-Path -Path $OutDirectory -ChildPath "123.html" + Test-Path -Path $outputFile | Should -BeTrue } } @@ -64,7 +64,7 @@ Describe "Get-BloggerPost" { It "Should call correct API endpoint" { InModuleScope PSBlogger { Mock Invoke-GApi { - return [pscustomobject]@{ content = "<html>Test content</html>" } + return [pscustomobject]@{ content = "<p>Test content</p>" } } -ParameterFilter { $uri -eq "https://www.googleapis.com/blogger/v3/blogs/test-blog-id/posts/123" } -Verifiable @@ -131,7 +131,7 @@ Describe "Get-BloggerPost" { # mock post retrieval Mock Invoke-GApi { - return @{ content = "<html>Test content</html>" } + return @{ content = "<p>Test content</p>" } } } } @@ -367,4 +367,45 @@ Describe "Get-BloggerPost" { Test-Path "TestDrive:\123.html" | Should -BeTrue } } + + Context "PassThru" { + + BeforeEach { + InModuleScope PSBlogger { + # Mock the session to return a test blog ID + $BloggerSession.BlogId = "test-blog-id" + + # mock post retrieval + Mock Invoke-GApi { + return @{ content = "<p>Test content</p>" } + } + } + } + + It "Should return post object when not persisting output to disk" { + # act + $result = Get-BloggerPost -PostId "123" + + # assert + $result | Should -Not -BeNullOrEmpty + } + + It "Should not return a post object when persisting to disk" { + # act + $result = Get-BloggerPost -PostId "123" -Format HTML -OutDirectory TestDrive:\ + + # assert + $result | Should -BeNullOrEmpty + } + + It "Should return post object when persisting to disk with PassThru specified" { + # act + $result = Get-BloggerPost -PostId "123" -Format HTML -OutDirectory TestDrive:\ -PassThru + + # assert + $result | Should -Not -BeNullOrEmpty + } + + + } } From c2e9657acc9749b721932fea22eac807912b9bb4 Mon Sep 17 00:00:00 2001 From: bryan cook <3217452+bryanbcook@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:46:13 -0400 Subject: [PATCH 2/3] Added -PassThru to ConvertTo-HtmlFromMarkdown and tests --- src/public/ConvertTo-HtmlFromMarkdown.ps1 | 41 ++++++++++-- .../ConvertTo-HtmlFromMarkdown.Tests.ps1 | 64 +++++++++++++++++++ src/tests/_TestHelpers.ps1 | 2 +- 3 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 src/tests/ConvertTo-HtmlFromMarkdown.Tests.ps1 diff --git a/src/public/ConvertTo-HtmlFromMarkdown.ps1 b/src/public/ConvertTo-HtmlFromMarkdown.ps1 index c0a9623..271aa87 100644 --- a/src/public/ConvertTo-HtmlFromMarkdown.ps1 +++ b/src/public/ConvertTo-HtmlFromMarkdown.ps1 @@ -8,20 +8,38 @@ .PARAMETER OutFile The resulting html. If this parameter is not specified an HTML file with the same name of the markdown file will be created. +.PARAMETER PassThru + If specified, the content of the HTML file will be returned as well as written to disk. + +.EXAMPLE + # obtain an HTML representation of the markdown file + $html = ConvertTo-HtmlFromMarkdown -File "C:\path\to\file.md" + +.EXAMPLE + # write the HTML representation of the markdown file to disk + ConvertTo-HtmlFromMarkdown -File "C:\path\to\file.md" -OutFile "C:\path\to\file.html" + +.EXAMPLE + # write the HTML representation of the markdown file to disk and return the content + $html = ConvertTo-HtmlFromMarkdown -File "C:\path\to\file.md" -OutFile "C:\path\to\file.html" -PassThru #> function ConvertTo-HtmlFromMarkdown { + [CmdletBinding(DefaultParameterSetName = "Default")] param( - [Parameter(Mandatory = $true, HelpMessage = "Path to Markdown file")] + [Parameter(Mandatory = $true, ParameterSetName = "Default")] + [Parameter(Mandatory = $true, ParameterSetName = "Persist")] [ValidateScript({ Test-Path $_ -PathType Leaf })] [string]$File, - [Parameter(HelpMessage = "File path to create")] - #[ValidateScript({ Test-Path $_ -Include "*.html" -PathType Container})] - [string]$OutFile + [Parameter(ParameterSetName = "Persist")] + [string]$OutFile, + + [Parameter(ParameterSetName = "Persist")] + [switch]$PassThru ) # ensure that the file is an absolute path because pandoc.exe doesn't like powershell relative paths - $File = (Resolve-Path $File).Path + $File = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($File) # Use pandoc to convert the markdown to Html $pandocArgs = "`"{0}`" " -f $File @@ -41,8 +59,10 @@ function ConvertTo-HtmlFromMarkdown { if (!($OutFile)) { $OutFile = Join-Path (Split-Path $File -Parent) ((Split-Path $File -LeafBase) + ".html") + # ensure that the file is an absolute path because pandoc.exe doesn't like powershell relative paths Write-Verbose "Using OutFile: $OutFile" } + $OutFile = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutFile) $pandocArgs += "-o `"{0}`" " -f $OutFile @@ -60,7 +80,14 @@ function ConvertTo-HtmlFromMarkdown { Set-Content -Path $OutFile -Value $content - Remove-Item $OutFile + if (!($PSCmdlet.ParameterSetName -eq "Persist")) { + Write-Verbose "Removing temporary file: $OutFile" + Remove-Item $OutFile - return $content + return $content + } + + if ($PassThru.IsPresent -and $PassThru) { + return $content + } } \ No newline at end of file diff --git a/src/tests/ConvertTo-HtmlFromMarkdown.Tests.ps1 b/src/tests/ConvertTo-HtmlFromMarkdown.Tests.ps1 new file mode 100644 index 0000000..e1b714d --- /dev/null +++ b/src/tests/ConvertTo-HtmlFromMarkdown.Tests.ps1 @@ -0,0 +1,64 @@ +Describe "ConvertTo-HtmlFromMarkdown" { + BeforeAll { + Import-Module $PSScriptRoot\_TestHelpers.ps1 -Force + + $script:InFile = "TestDrive:\123.md" + $script:OutFile = "TestDrive:\123.html" + + Set-MarkdownFile -Path $script:InFile -Content "# Hello World" + } + + BeforeEach { + Import-Module $PSScriptRoot\..\PSBlogger.psm1 -Force + } + + AfterEach { + if (Test-Path $script:OutFile) { + Remove-Item $script:OutFile -Force + } + } + + It "Should convert Markdown file to HTML" { + # act + $result = ConvertTo-HtmlFromMarkdown -File $script:InFile + + # assert + $result | Should -Not -BeNullOrEmpty + $result | Should -BeLike "<h1*>Hello World</h1>*" + } + + It "Should not produce an HTML file if OutFile is not specified" { + # act + $result = ConvertTo-HtmlFromMarkdown -File $script:InFile + + # assert + $result | Should -Not -BeNullOrEmpty + Test-Path $script:OutFile | Should -BeFalse + } + + It "Should create an HTML file when OutFile is specified" { + # act + ConvertTo-HtmlFromMarkdown -File $script:InFile -OutFile $script:OutFile + + # assert + Test-Path $script:OutFile | Should -BeTrue + } + + It "Should not return content if OutFile is specified without PassThru" { + # act + $result = ConvertTo-HtmlFromMarkdown -File $script:InFile -OutFile $script:OutFile + + # assert + $result | Should -BeNullOrEmpty + Test-Path $script:OutFile | Should -BeTrue + } + + It "Should return content if PassThru is specified with OutFile" { + # act + $result = ConvertTo-HtmlFromMarkdown -File $script:InFile -OutFile $script:OutFile -PassThru + + # assert + $result | Should -Not -BeNullOrEmpty + Test-Path $script:OutFile | Should -BeTrue + } +} \ No newline at end of file diff --git a/src/tests/_TestHelpers.ps1 b/src/tests/_TestHelpers.ps1 index 1e95eea..b4f1943 100644 --- a/src/tests/_TestHelpers.ps1 +++ b/src/tests/_TestHelpers.ps1 @@ -11,7 +11,7 @@ function New-BlogPost($id) { .SYNOPSIS Blogger Blog post #> - @{ id=$id } + [pscustomobject]@{ id=$id } } From 0e92b4b98167a65fe8f8c38c6e00822e683ea80f Mon Sep 17 00:00:00 2001 From: bryan cook <3217452+bryanbcook@users.noreply.github.com> Date: Thu, 24 Jul 2025 18:21:29 -0400 Subject: [PATCH 3/3] Add -PassThru to ConvertTo-MarkdownFromHtml --- src/public/ConvertTo-MarkdownFromHtml.ps1 | 40 +++++++++- src/public/Get-BloggerPost.ps1 | 2 +- .../ConvertTo-MarkdownFromHtml.Tests.ps1 | 77 +++++++++++-------- 3 files changed, 82 insertions(+), 37 deletions(-) diff --git a/src/public/ConvertTo-MarkdownFromHtml.ps1 b/src/public/ConvertTo-MarkdownFromHtml.ps1 index 0d4b431..fb019f7 100644 --- a/src/public/ConvertTo-MarkdownFromHtml.ps1 +++ b/src/public/ConvertTo-MarkdownFromHtml.ps1 @@ -11,6 +11,32 @@ .PARAMETER OutFile The resulting markdown file, if specified. +.PARAMETER PassThru + Return markdown content as output, in addition to writing it to disk. + +.EXAMPLE + # Convert HTML content to Markdown and save to a file + ConvertTo-MarkdownFromHtml -Content "<h1>Hello World</h1>" -OutFile "C:\path\to\file.md" + +.EXAMPLE + # Convert a HTML file to Markdown and save to a file + ConvertTo-MarkdownFromHtml -File "C:\path\to\file.html" -OutFile "C:\path\to\file.md" + +.EXAMPLE + # Convert a HTML file to Markdown and return the content + $content = ConvertTo-MarkdownFromHtml -File "C:\path\to\file.html" + +.EXAMPLE + # Convert HTML content to Markdown and return the content + $content = ConvertTo-MarkdownFromHtml -Content "<h1>Hello World</h1>" + +.EXAMPLE + # Convert HTML content to Markdown and save to a file, returning the content + $content = ConvertTo-MarkdownFromHtml -Content "<h1>Hello World</h1>" -OutFile "C:\path\to\file.md" -PassThru + +.EXAMPLE + # Convert a HTML file to Markdown and save to a file, returning the content + $content = ConvertTo-MarkdownFromHtml -File "C:\path\to\file.html" -OutFile "C:\path\to\file.md" -PassThru #> function ConvertTo-MarkdownFromHtml { param( @@ -22,8 +48,12 @@ function ConvertTo-MarkdownFromHtml { [string]$Content, [Parameter(ParameterSetName = "FromFile")] - [Parameter(Mandatory=$false, ParameterSetName = "FromContent")] - [string]$OutFile + [Parameter(ParameterSetName = "FromContent")] + [string]$OutFile, + + [Parameter(ParameterSetName = "FromFile")] + [Parameter(ParameterSetName = "FromContent")] + [switch]$PassThru ) # when FromContent is specified, write the content to a temporary file @@ -69,5 +99,9 @@ function ConvertTo-MarkdownFromHtml { Remove-Item $OutFile } - return $content + # return output if not persisting to disk or PassThru is specified + if (!$PSBoundParameters.ContainsKey("OutFile") -or ($PassThru.IsPresent -and $PassThru)) { + Write-Verbose "Returning content" + return $content + } } \ No newline at end of file diff --git a/src/public/Get-BloggerPost.ps1 b/src/public/Get-BloggerPost.ps1 index e13b099..d563434 100644 --- a/src/public/Get-BloggerPost.ps1 +++ b/src/public/Get-BloggerPost.ps1 @@ -143,7 +143,7 @@ Function Get-BloggerPost { $file = "$title.md" $filePath = Join-Path -Path $OutDirectory -ChildPath $file - ConvertTo-MarkdownFromHtml -Content $result.content -OutFile $filePath > $null + ConvertTo-MarkdownFromHtml -Content $result.content -OutFile $filePath Set-MarkdownFrontMatter -File $filePath -Replace $frontMatter Write-Verbose "Post content saved to: $filePath" } diff --git a/src/tests/ConvertTo-MarkdownFromHtml.Tests.ps1 b/src/tests/ConvertTo-MarkdownFromHtml.Tests.ps1 index 3dcc672..9befefb 100644 --- a/src/tests/ConvertTo-MarkdownFromHtml.Tests.ps1 +++ b/src/tests/ConvertTo-MarkdownFromHtml.Tests.ps1 @@ -1,79 +1,90 @@ Describe "ConvertTo-MarkdownFromHtml" { BeforeAll { Import-Module $PSScriptRoot\_TestHelpers.ps1 -Force - + $script:inFile = "TestDrive:\123.html" + $script:outFile = "TestDrive:\123.md" + $script:htmlContent = "<h1>Hello World</h1>" + Set-Content -Path $script:inFile -Value $script:htmlContent } BeforeEach { Import-Module $PSScriptRoot\..\PSBlogger.psm1 -Force } - Context "Using Content" { - - BeforeEach { - $outFile = "TestDrive:\123.md" - $htmlContent = "<h1>Hello World</h1>" + AfterEach { + if (Test-Path $outFile) { + Remove-Item $outFile -Force } + } - AfterEach { - if (Test-Path $outFile) { - Remove-Item $outFile -Force - } - } + Context "Using Content" { - It "Should save HTML content to a markdown file" { + It "Should convert HTML content to Markdown file" { # act - ConvertTo-MarkdownFromHtml -Content $htmlContent -OutFile $outFile + ConvertTo-MarkdownFromHtml -Content $script:htmlContent -OutFile $script:outFile # assert - Test-Path $outFile | Should -BeTrue + Test-Path $script:outFile | Should -BeTrue + $content = (Get-Content -Path $script:outFile -Raw).Split("`r") + $content[0] | Should -Be "# Hello World" } - It "Should convert HTML content to Markdown file" { + It "Should not persist to disk if OutFile is not specified" { # act - $content = ConvertTo-MarkdownFromHtml -Content $htmlContent -OutFile $outFile + $content = ConvertTo-MarkdownFromHtml -Content $script:htmlContent # assert - $content = (Get-Content -Path $outFile -Raw).Split("`r") - $content[0] | Should -Be "# Hello World" + $content | Should -Not -BeNullOrEmpty + Test-Path $script:outFile | Should -BeFalse } - It "Should not persist to disk if OutFile is not specified" { + It "Should return content when writing to disk if PassThru is specified" { # act - $content = ConvertTo-MarkdownFromHtml -Content $htmlContent + $content = ConvertTo-MarkdownFromHtml -Content $script:htmlContent -OutFile $script:outFile -PassThru # assert $content | Should -Not -BeNullOrEmpty - Test-Path $outFile | Should -BeFalse + Test-Path $script:outFile | Should -BeTrue } } Context "Using File" { - BeforeEach { - $htmlContent = "<h1>Hello World</h1>" - $htmlFile = "TestDrive:\123.html" - $markdownFile = "TestDrive:\123.md" - Set-Content -Path $htmlFile -Value $htmlContent + It "Should convert HTML content to Markdown and persist to OutFile" { + # act + ConvertTo-MarkdownFromHtml -File $script:inFile -OutFile $script:outFile + + # assert + Test-Path $script:outFile | Should -BeTrue + $content = (Get-Content -Path $script:outFile -Raw).Split("`r") + $content[0] | Should -Be "# Hello World" } It "Should convert HTML file to Markdown" { # act - $content = ConvertTo-MarkdownFromHtml -File $htmlFile -OutFile $markdownFile + $content = ConvertTo-MarkdownFromHtml -File $script:inFile # assert - Test-Path $markdownFile | Should -BeTrue - $content = (Get-Content -Path $markdownFile -Raw).Split("`r") - $content[0] | Should -Be "# Hello World" + $content | Should -Not -BeNullOrEmpty + $content | Should -BeLike "# Hello World*" + } + + It "Should delete temporary OutFile if OutFile is not specified" { + # act + $content = ConvertTo-MarkdownFromHtml -File $script:inFile + + # assert + $content | Should -Not -BeNullOrEmpty + Test-Path $script:outFile | Should -BeFalse } - It "Should delete temporary file" { + It "Should return content when writing to disk if PassThru is specified" { # act - $content = ConvertTo-MarkdownFromHtml -File $htmlFile + $content = ConvertTo-MarkdownFromHtml -File $script:inFile -OutFile $script:outFile -PassThru # assert $content | Should -Not -BeNullOrEmpty - Test-Path $markdownFile | Should -BeFalse + Test-Path $script:outFile | Should -BeTrue } } } \ No newline at end of file