Tests/Unit/Disconnect-SPCTenant.Tests.ps1
|
#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '5.0.0' } BeforeAll { $moduleRoot = Resolve-Path (Join-Path $PSScriptRoot '..\..') $publicDir = Join-Path $moduleRoot 'Public' $privateDir = Join-Path $moduleRoot 'Private' . (Join-Path $privateDir 'Test-SPCConnection.ps1') . (Join-Path $publicDir 'Auth\Disconnect-SPCTenant.ps1') # Standardized mock module context schema $script:FakeConnectedContext = [PSCustomObject]@{ TenantName = 'contoso' AuthMethod = 'Interactive' ConnectedAt = (Get-Date).ToUniversalTime() GraphTokenRefreshedAt = (Get-Date).ToUniversalTime() PnPContext = [PSCustomObject]@{ Url = 'https://contoso-admin.sharepoint.com' } GraphAccessToken = 'fake-token' _ClientId = 'fake-client-id' _CertificateThumbprint = $null _CertificatePath = $null _CertificatePassword = $null _ClientSecret = $null } } Describe 'Disconnect-SPCTenant' { BeforeEach { $script:SPCContext = $script:FakeConnectedContext $script:SPCLicenseCache = @{ Key = 'test-key'; Tier = 'PRO' } Mock Disconnect-PnPOnline {} Mock Disconnect-MgGraph {} } Context 'AC-TEST-02 / AC-STD-05: Session Context Cleanup' { It 'AC-TEST-02: Clears $script:SPCContext and license cache on disconnect' { $script:SPCContext | Should -Not -BeNullOrEmpty Disconnect-SPCTenant $script:SPCContext | Should -BeNullOrEmpty $script:SPCLicenseCache | Should -BeNullOrEmpty } It 'AC-TEST-02: Calls Disconnect-PnPOnline and Disconnect-MgGraph' { Disconnect-SPCTenant Should -Invoke Disconnect-PnPOnline -Times 1 -Exactly Should -Invoke Disconnect-MgGraph -Times 1 -Exactly } } Context 'NFR-REL-02: Idempotency & Error Handling' { It 'NFR-REL-02: Safely executes when already disconnected ($script:SPCContext is null) without throwing' { $script:SPCContext = $null { Disconnect-SPCTenant } | Should -Not -Throw $script:SPCContext | Should -BeNullOrEmpty } It 'NFR-REL-02: Silently suppresses underlying Disconnect-PnPOnline exceptions' { Mock Disconnect-PnPOnline { throw 'PnP session fault' } { Disconnect-SPCTenant } | Should -Not -Throw $script:SPCContext | Should -BeNullOrEmpty } It 'NFR-REL-02: Silently suppresses underlying Disconnect-MgGraph exceptions' { Mock Disconnect-MgGraph { throw 'Graph disconnect fault' } { Disconnect-SPCTenant } | Should -Not -Throw $script:SPCContext | Should -BeNullOrEmpty } } Context 'ShouldProcess & WhatIf Support' { It 'AC-TEST-02: Respects -WhatIf by leaving session context intact and skipping disconnect calls' { Disconnect-SPCTenant -WhatIf $script:SPCContext | Should -Not -BeNullOrEmpty Should -Invoke Disconnect-PnPOnline -Times 0 -Exactly Should -Invoke Disconnect-MgGraph -Times 0 -Exactly } } Context 'Security & Stream Isolation' { It 'AC-SEC-02: Does not leak tokens or credentials into Verbose stream' { $script:verboseLog = @() Mock Write-Verbose { param($Message) $script:verboseLog += $Message } Disconnect-SPCTenant -Verbose $leak = $script:verboseLog | Where-Object { $_ -match 'password|secret|token|bearer|ey[A-Za-z0-9_-]+' } $leak | Should -BeNullOrEmpty } } } |