Tests/ntp/Sync-NTPTime.Tests.ps1
|
#Requires -Version 5.1 BeforeAll { . "$PSScriptRoot/../../Public/ntp/Sync-NTPTime.ps1" } Describe -Name 'Sync-NTPTime' -Fixture { BeforeAll { # Mock data: successful w32tm /resync output (English) $script:successOutput = [PSCustomObject]@{ Output = "Sending resync command to local computer`r`nThe command completed successfully." ExitCode = 0 } # Mock data: failed w32tm /resync output $script:failureOutput = [PSCustomObject]@{ Output = 'The computer did not resync because no time data was available.' ExitCode = 1 } } Context -Name 'When resyncing the local machine (happy path)' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:successOutput } } It -Name 'Should return a success result for the local machine' -Test { $result = Sync-NTPTime $result | Should -Not -BeNullOrEmpty $result.ComputerName | Should -Be $env:COMPUTERNAME $result.Success | Should -BeTrue $result.ServiceRestarted | Should -BeFalse $result.Message | Should -Match 'The command completed successfully' $result.Timestamp | Should -Not -BeNullOrEmpty } It -Name 'Should call Invoke-Command exactly once' -Test { Sync-NTPTime Should -Invoke -CommandName 'Invoke-Command' -Times 1 -Exactly } } Context -Name 'When resyncing a remote machine (happy path)' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:successOutput } } It -Name 'Should return a success result for the remote machine' -Test { $result = Sync-NTPTime -ComputerName 'REMOTE-SRV01' $result | Should -Not -BeNullOrEmpty $result.ComputerName | Should -Be 'REMOTE-SRV01' $result.Success | Should -BeTrue $result.ServiceRestarted | Should -BeFalse } It -Name 'Should invoke Invoke-Command with the remote ComputerName' -Test { Sync-NTPTime -ComputerName 'REMOTE-SRV01' Should -Invoke -CommandName 'Invoke-Command' -Times 1 -Exactly -ParameterFilter { $ComputerName -eq 'REMOTE-SRV01' } } } Context -Name 'When pipeline input provides multiple machines' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:successOutput } } It -Name 'Should return one result per machine' -Test { $result = 'SRV01', 'SRV02', 'SRV03' | Sync-NTPTime $result.Count | Should -Be 3 $result[0].ComputerName | Should -Be 'SRV01' $result[1].ComputerName | Should -Be 'SRV02' $result[2].ComputerName | Should -Be 'SRV03' } It -Name 'Should report success for all machines' -Test { $result = 'SRV01', 'SRV02' | Sync-NTPTime $result | ForEach-Object { $_.Success | Should -BeTrue } } } Context -Name 'When -RestartService is specified' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:successOutput } } It -Name 'Should set ServiceRestarted to true and still succeed' -Test { $result = Sync-NTPTime -ComputerName 'REMOTE-SRV01' -RestartService $result.ServiceRestarted | Should -BeTrue $result.Success | Should -BeTrue $result.ComputerName | Should -Be 'REMOTE-SRV01' } It -Name 'Should call Invoke-Command twice (restart + resync)' -Test { Sync-NTPTime -ComputerName 'REMOTE-SRV01' -RestartService Should -Invoke -CommandName 'Invoke-Command' -Times 2 -Exactly } } Context -Name 'When w32tm resync reports failure' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:failureOutput } } It -Name 'Should return Success = false with the failure message' -Test { $result = Sync-NTPTime -ComputerName 'REMOTE-SRV01' $result.Success | Should -BeFalse $result.Message | Should -Match 'did not resync' $result.ComputerName | Should -Be 'REMOTE-SRV01' } } Context -Name 'When per-machine failure occurs' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:successOutput } Mock -CommandName 'Invoke-Command' -ParameterFilter { $ComputerName -eq 'BADSERVER' } -MockWith { throw 'Connection refused' } } It -Name 'Should continue processing other machines after one fails' -Test { $result = Sync-NTPTime -ComputerName 'SRV01', 'BADSERVER', 'SRV02' -ErrorVariable syncError -ErrorAction SilentlyContinue $result.Count | Should -Be 2 $result[0].ComputerName | Should -Be 'SRV01' $result[0].Success | Should -BeTrue $result[1].ComputerName | Should -Be 'SRV02' $result[1].Success | Should -BeTrue } It -Name 'Should write an error for the failing machine' -Test { $null = Sync-NTPTime -ComputerName 'SRV01', 'BADSERVER', 'SRV02' -ErrorVariable syncError -ErrorAction SilentlyContinue $syncError | Should -Not -BeNullOrEmpty "$syncError" | Should -Match 'BADSERVER' } } Context -Name 'When ShouldProcess is respected (-WhatIf)' -Fixture { BeforeAll { Mock -CommandName 'Invoke-Command' -MockWith { return $script:successOutput } } It -Name 'Should NOT invoke any command with -WhatIf' -Test { Sync-NTPTime -ComputerName 'SRV01' -WhatIf Should -Invoke -CommandName 'Invoke-Command' -Times 0 -Exactly } It -Name 'Should NOT invoke any command with -WhatIf and -RestartService' -Test { Sync-NTPTime -ComputerName 'SRV01' -RestartService -WhatIf Should -Invoke -CommandName 'Invoke-Command' -Times 0 -Exactly } } Context -Name 'When parameter validation fails' -Fixture { It -Name 'Should throw on empty string ComputerName' -Test { { Sync-NTPTime -ComputerName '' } | Should -Throw } It -Name 'Should throw on null ComputerName' -Test { { Sync-NTPTime -ComputerName $null } | Should -Throw } } } |