tests/UnipharSecurityAuthHelpers.Tests.ps1
|
<#
.SYNOPSIS Pester tests for the Workday synchronization helper functions in UnipharSecurityAuth. .DESCRIPTION Covers the pure helper functions used by the Invoke-WorkdayUserSync runbook: ConvertTo-E164PhoneNumber, Get-CleanManagerName, Get-UserAttributeDiff, and Get-OrphanedEmployeeId. .NOTES Author: Security Team Requires: Pester v5 #> BeforeAll { $modulePath = Join-Path (Split-Path $PSScriptRoot -Parent) 'UnipharSecurityAuth.psm1' Import-Module $modulePath -Force } AfterAll { Remove-Module UnipharSecurityAuth -Force -ErrorAction SilentlyContinue } Describe 'ConvertTo-E164PhoneNumber' -Tags 'Unit' { Context 'When the value is a valid international number' { It 'Normalizes "<Value>" to "<Expected>"' -ForEach @( @{ Value = '+353 (86) 1687760'; Expected = '+353 861687760' } @{ Value = '+44 (7801) 930577'; Expected = '+44 7801930577' } @{ Value = '+1 (619) 3792154'; Expected = '+1 6193792154' } @{ Value = '+31 (6) 84790375'; Expected = '+31 684790375' } @{ Value = '+966 (54) 0055577'; Expected = '+966 540055577' } @{ Value = '+353 861687760'; Expected = '+353 861687760' } @{ Value = ' +353 86 168 7760 '; Expected = '+353 861687760' } ) { ConvertTo-E164PhoneNumber -PhoneNumber $Value | Should -BeExactly $Expected } } Context 'When the value has a trailing extension' { It 'Preserves the extension for "<Value>"' -ForEach @( @{ Value = '+353 (89) 7050141 x1'; Expected = '+353 897050141x1' } @{ Value = '+1 (619) 3792154 ext 123'; Expected = '+1 6193792154x123' } @{ Value = '+1 (619) 3792154 extension 5'; Expected = '+1 6193792154x5' } ) { ConvertTo-E164PhoneNumber -PhoneNumber $Value | Should -BeExactly $Expected } } Context 'When the value cannot be normalized' { It 'Returns $null for "<Value>"' -ForEach @( @{ Value = $null } @{ Value = '' } @{ Value = ' ' } @{ Value = '0861687760' } @{ Value = '(086) 1687760' } @{ Value = '+353 12' } ) { ConvertTo-E164PhoneNumber -PhoneNumber $Value | Should -BeNullOrEmpty } } It 'Accepts pipeline input' { '+353 (86) 1687760' | ConvertTo-E164PhoneNumber | Should -BeExactly '+353 861687760' } } Describe 'Get-CleanManagerName' -Tags 'Unit' { Context 'When the name has a trailing parenthetical' { It 'Strips the parenthetical from "<Value>"' -ForEach @( @{ Value = 'Tara McGuinness (On Leave)'; Expected = 'Tara McGuinness' } @{ Value = 'John Smith (Contractor)'; Expected = 'John Smith' } @{ Value = 'Jane Doe (A) (B)'; Expected = 'Jane Doe' } @{ Value = 'Jane Doe (On Leave) '; Expected = 'Jane Doe' } ) { Get-CleanManagerName -ManagerName $Value | Should -BeExactly $Expected } } Context 'When the name has no parenthetical' { It 'Returns the trimmed name for "<Value>"' -ForEach @( @{ Value = 'ROBERTA KANCIAUSKAITE'; Expected = 'ROBERTA KANCIAUSKAITE' } @{ Value = ' Sarah Connor '; Expected = 'Sarah Connor' } ) { Get-CleanManagerName -ManagerName $Value | Should -BeExactly $Expected } } Context 'When the value is empty' { It 'Returns $null for "<Value>"' -ForEach @( @{ Value = $null } @{ Value = '' } @{ Value = ' ' } @{ Value = '(On Leave)' } ) { Get-CleanManagerName -ManagerName $Value | Should -BeNullOrEmpty } } } Describe 'Get-UserAttributeDiff' -Tags 'Unit' { It 'Returns only the changed attributes' { $current = @{ DisplayName = 'Jane Doe'; Department = 'Sales' } $desired = @{ DisplayName = 'Jane Doe'; Department = 'Marketing'; Company = 'Uniphar' } $diff = Get-UserAttributeDiff -Current $current -Desired $desired $diff.Keys | Should -HaveCount 2 $diff['Department'] | Should -BeExactly 'Marketing' $diff['Company'] | Should -BeExactly 'Uniphar' $diff.ContainsKey('DisplayName') | Should -BeFalse } It 'Ignores case and surrounding whitespace when comparing' { $current = @{ Department = 'sales ' } $desired = @{ Department = 'SALES' } (Get-UserAttributeDiff -Current $current -Desired $desired).Keys | Should -HaveCount 0 } It 'Never blanks an existing attribute from an empty desired value' { $current = @{ Department = 'Sales' } $desired = @{ Department = ''; Company = $null } (Get-UserAttributeDiff -Current $current -Desired $desired).Keys | Should -HaveCount 0 } It 'Treats a missing current key as a change when desired is non-empty' { $current = @{} $desired = @{ Company = 'Uniphar' } $diff = Get-UserAttributeDiff -Current $current -Desired $desired $diff['Company'] | Should -BeExactly 'Uniphar' } It 'Handles a null current hashtable' { $desired = @{ Company = 'Uniphar' } $diff = Get-UserAttributeDiff -Current $null -Desired $desired $diff['Company'] | Should -BeExactly 'Uniphar' } It 'Returns an empty hashtable when nothing changed' { $current = @{ DisplayName = 'Jane Doe' } $desired = @{ DisplayName = 'Jane Doe' } (Get-UserAttributeDiff -Current $current -Desired $desired).Keys | Should -HaveCount 0 } } Describe 'Get-OrphanedEmployeeId' -Tags 'Unit' { It 'Returns current IDs that are not in the valid set' { $result = Get-OrphanedEmployeeId -CurrentEmployeeIds @('100', '200', '300') -ValidEmployeeIds @('100', '300') $result | Should -Be @('200') } It 'Compares case-insensitively and ignores whitespace' { $result = Get-OrphanedEmployeeId -CurrentEmployeeIds @(' ABC ', 'def') -ValidEmployeeIds @('abc') $result | Should -Be @('def') } It 'De-duplicates orphaned IDs' { $result = Get-OrphanedEmployeeId -CurrentEmployeeIds @('200', '200', '201') -ValidEmployeeIds @('100') $result | Should -Be @('200', '201') } It 'Skips null and empty current IDs' { $result = Get-OrphanedEmployeeId -CurrentEmployeeIds @('', $null, ' ', '999') -ValidEmployeeIds @('100') $result | Should -Be @('999') } It 'Returns an empty array when all current IDs are valid' { $result = @(Get-OrphanedEmployeeId -CurrentEmployeeIds @('100', '200') -ValidEmployeeIds @('100', '200')) $result | Should -HaveCount 0 } It 'Returns all current IDs when the valid set is empty' { $result = Get-OrphanedEmployeeId -CurrentEmployeeIds @('100', '200') -ValidEmployeeIds @() $result | Should -Be @('100', '200') } } |