Public/Tests/Builder.XmlWellFormed.Tests.ps1
|
BeforeAll { $env:TCS_CONFIG_ROOT = Join-Path -Path $TestDrive -ChildPath 'config' $env:TCS_SKIP_UPDATE_CHECK = '1' $env:TCS_TELEMETRY_OPTOUT = '1' $ModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'tcs.confluence.psd1') -Force } AfterAll { Remove-Module -Name tcs.confluence -Force -ErrorAction SilentlyContinue } # Every builder must return well-formed storage format (XHTML), whatever text it is given. Describe 'Builder output is well-formed XML' { BeforeAll { $hostile = "R&D <draft> `"quoted`" it's ]]> & more" $rows = @( [pscustomobject]@{ Name = $hostile; File = 'report.pdf'; Mail = 'me@contoso.com'; Link = 'https://x.com/?a=1&b=2'; Nested = [pscustomobject]@{ A = $hostile; B = 1 } } ) function Test-StorageFormat([string]$Markup) { # Confluence storage format uses the ac: and ri: namespaces $document = New-Object -TypeName System.Xml.XmlDocument $document.LoadXml("<root xmlns:ac=`"http://atlassian.com/content`" xmlns:ri=`"http://atlassian.com/resource/identifier`">$Markup</root>") return $true } } It '<Name> output parses as XML' -ForEach @( @{ Name = 'New-ConfluenceContentHeader'; Build = { New-ConfluenceContentHeader -Header $hostile -Level 2 -StringFormatting Bold, Italic } } @{ Name = 'New-ConfluenceContentTable'; Build = { New-ConfluenceContentTable -TableData $rows -HeaderStringFormatting Bold -VerticalHeader -FirstCellHeaderFormat 3 } } @{ Name = 'New-ConfluenceContentTable (hashtable rows)'; Build = { New-ConfluenceContentTable -TableData @(@{ Key = $hostile }, @{ Key = 'b' }) } } @{ Name = 'New-ConfluenceContentTable -Raw with builder fragments'; Build = { New-ConfluenceContentTable -TableData @([pscustomobject]@{ A = (New-ConfluenceContentStatus -Text $hostile); B = (New-ConfluenceContentLink -Url 'https://x.com/?a&b' -LinkText $hostile) }) -Raw } } @{ Name = 'New-ConfluenceContentLink -Url'; Build = { New-ConfluenceContentLink -Url "https://x.com/?a=1&b=it's" -LinkText $hostile } } @{ Name = 'New-ConfluenceContentLink -TextBlock'; Build = { New-ConfluenceContentLink -TextBlock "$hostile see https://x.com/?a=1&b=2 and mailto:me@x.com." } } @{ Name = 'New-ConfluenceContentDivider (line)'; Build = { New-ConfluenceContentDivider } } @{ Name = 'New-ConfluenceContentDivider (space)'; Build = { New-ConfluenceContentDivider -Type space } } @{ Name = 'New-ConfluenceContentDivider (dotted)'; Build = { New-ConfluenceContentDivider -Type dotted } } @{ Name = 'New-ConfluenceContentInfo'; Build = { New-ConfluenceContentInfo -Title $hostile -Content $hostile -Type error } } @{ Name = 'New-ConfluenceContentInfo -Raw'; Build = { New-ConfluenceContentInfo -Title 't' -Content (New-ConfluenceContentCodeBlock -Content $hostile) -Raw } } @{ Name = 'New-ConfluenceContentCodeBlock'; Build = { New-ConfluenceContentCodeBlock -Content $hostile -Language "a<b'" } } @{ Name = 'New-ConfluenceContentTOC'; Build = { New-ConfluenceContentTOC -IncludeSectionNumbers } } @{ Name = 'New-ConfluenceContentInternalLink'; Build = { New-ConfluenceContentInternalLink -PageTitle $hostile -SpaceKey 'A&B' -HeadingLink $hostile -LinkText $hostile } } @{ Name = 'New-ConfluenceContentInternalLink -InternalLinkURL'; Build = { New-ConfluenceContentInternalLink -InternalLinkURL 'https://x.com/wiki/spaces/A/pages/1/R&D' -PageTitle $hostile -HeadingLink 'x' } } @{ Name = 'New-ConfluenceContentStatus'; Build = { New-ConfluenceContentStatus -Text $hostile -Colour Red -Subtle } } @{ Name = 'New-ConfluenceContentExpand'; Build = { New-ConfluenceContentExpand -Title $hostile -Content $hostile } } @{ Name = 'New-ConfluenceContentJiraIssue'; Build = { New-ConfluenceContentJiraIssue -JqlQuery $hostile -Columns 'key', 'a&b' -Server $hostile } } @{ Name = 'ConvertTo-ConfluenceHTML'; Build = { ConvertTo-ConfluenceHTML -InputFormat Markdown -InputContent "# $hostile`n| a | b |`n|---|---|`n| $hostile | 2 |`n- $hostile`n**$hostile**" } } @{ Name = 'Join-ConfluenceContent'; Build = { foreach ($separator in 'HorizontalRule', 'NewLine', 'Space', 'Tab') { Join-ConfluenceContent -ContentBlocks '<p>a</p>', '<p>b</p>' -Separator $separator } } } @{ Name = 'New-ConfluencePageLayout'; Build = { New-ConfluencePageLayout -Section @{ LayoutType = 'single'; Cells = (New-ConfluenceContentHeader -Header $hostile -Level 1) }, @{ LayoutType = 'three_equal'; Cells = (New-ConfluenceContentDivider), (New-ConfluenceContentInfo -Title $hostile -Content $hostile), '' } } } ) { $markup = (& $Build) -join '' $markup | Should -Not -BeNullOrEmpty { Test-StorageFormat -Markup $markup } | Should -Not -Throw } It 'Covers every exported New-ConfluenceContent* builder' { $tested = @('New-ConfluenceContentHeader', 'New-ConfluenceContentTable', 'New-ConfluenceContentLink', 'New-ConfluenceContentDivider', 'New-ConfluenceContentInfo', 'New-ConfluenceContentCodeBlock', 'New-ConfluenceContentTOC', 'New-ConfluenceContentInternalLink', 'New-ConfluenceContentStatus', 'New-ConfluenceContentExpand', 'New-ConfluenceContentJiraIssue') $builders = (Get-Command -Module tcs.confluence -Name 'New-ConfluenceContent*').Name foreach ($builder in $builders) { $tested | Should -Contain $builder } } } |