Testing/Unit/PowerShell/Orchestrator/ConvertTo-ResultsCsv.Tests.ps1
|
$OrchestratorPath = '../../../../Modules/Orchestrator.psm1' Import-Module (Join-Path -Path $PSScriptRoot -ChildPath $OrchestratorPath) -Function ConvertTo-ResultsCsv -Force InModuleScope Orchestrator { Describe -Tag 'Orchestrator' -Name 'ConvertTo-ResultsCsv' { BeforeAll { Mock -CommandName Join-Path { "." } Mock -CommandName Test-Path { $true } Mock -CommandName Out-File {} Mock -CommandName Set-Content {} Mock -CommandName Remove-Item {} Mock -CommandName Get-Content { "" } Mock -CommandName Format-PlainText { "" } Mock -CommandName Add-Member {} # Return a valid encoding so Set-Content does not throw and trigger a warning Mock -CommandName Get-FileEncoding { 'utf8' } Mock -CommandName ConvertTo-Csv { "" } Mock -CommandName Write-Warning {} Mock -CommandName Get-ChildItem { [pscustomobject]@{"FullName"="CyberResults_00000000-0000-0000-0000-000000000000.json"; "CreationTime"=[DateTime]"2024-01-01"} } } It 'Handles multiple products, control groups, and controls' { # Test to validate that the 3-way nested for loop properly finds all controls Mock -CommandName ConvertFrom-Json { @{ "Results"=[PSCustomObject]@{ "EXO"=@( @{ "Controls"=@( @{ "Requirement"="123"; "Details"="123"; }, @{ "Requirement"="123"; "Details"="123"; } ) }, @{ "Controls"=@( @{ "Requirement"="123"; "Details"="123"; } ) } ); "AAD"=@( @{ "Controls"=@( @{ "Requirement"="123"; "Details"="123"; } ) } ); }} } $CsvParameters = @{ ProductNames = @("exo", "aad"); OutFolderPath = "."; FullCyberResultsName = "CyberResults"; OutCsvFileName = "CyberResults"; OutActionPlanFileName = "ActionPlan"; } { ConvertTo-ResultsCsv @CsvParameters} | Should -Not -Throw Should -Invoke -CommandName ConvertFrom-Json -Exactly -Times 1 # Note: Write-Warning may be called for configuration warnings (e.g., OrgName not provided) # Should -Invoke -CommandName Write-Warning -Exactly -Times 0 # Each control contributes two calls, EXO has 3 controls, AAD has 1 = 3*2 + 1*2 = 8 Should -Invoke -CommandName Format-PlainText -Exactly -Times 8 } It 'Handles file not found errors' { # Test to validate that a warning is printed if there is an error opening the CyberResults file Mock -CommandName ConvertFrom-Json {} Mock -CommandName Get-Content { throw "File not found" } $CsvParameters = @{ ProductNames = @("exo", "aad"); OutFolderPath = "."; FullCyberResultsName = "CyberResults"; OutCsvFileName = "CyberResults"; OutActionPlanFileName = "ActionPlan"; } { ConvertTo-ResultsCsv @CsvParameters} | Should -Not -Throw Should -Invoke -CommandName Format-PlainText -Exactly -Times 0 Should -Invoke -CommandName Write-Warning -Exactly -Times 1 } } } AfterAll { Remove-Module Orchestrator -ErrorAction SilentlyContinue } |