Testing/Unit/PowerShell/Orchestrator/Connect-Tenant.Tests.ps1

$ModuleRootPath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\..\..\Modules'
Import-Module (Join-Path -Path $ModuleRootPath -ChildPath 'Orchestrator.psm1') -Force

InModuleScope Orchestrator {
    Describe -Tag 'Orchestrator' -Name 'Invoke-Connection' {
        Context 'When LogIn is true' {
            BeforeEach {
                # Fresh config & mock per test to avoid state leakage
                $script:CyberConfig = [PSCustomObject]@{
                    ProductNames    = @('aad')  # default, overridden in tests
                    LogIn           = $true
                    M365Environment = 'commercial'
                }
                function Connect-Tenant { throw 'this will be mocked' }
                Mock -ModuleName Orchestrator Connect-Tenant { @() }
            }

            It 'connects to aad (single product)' {
                $FailedAuthList = Invoke-Connection -CyberConfig $CyberConfig
                Should -Invoke -CommandName Connect-Tenant -Times 1 -Exactly
                $FailedAuthList | Should -BeNullOrEmpty
            }
            It 'connects to defender' {
                $CyberConfig.ProductNames = @('defender')
                $FailedAuthList = Invoke-Connection -CyberConfig $CyberConfig
                Should -Invoke -CommandName Connect-Tenant -Times 1 -Exactly
                $FailedAuthList | Should -BeNullOrEmpty
            }
            It 'connects to all products in one call' {
                $CyberConfig.ProductNames = @('aad','defender','exo','powerplatform','sharepoint','teams')
                $FailedAuthList = Invoke-Connection -CyberConfig $CyberConfig
                # Still only one Connect-Tenant invocation expected (array passed)
                Should -Invoke -CommandName Connect-Tenant -Times 1 -Exactly
                $FailedAuthList | Should -BeNullOrEmpty
            }
            It 'passes service principal parameters when provided' {
                $CyberConfig = [PSCustomObject]@{
                    ProductNames = @('aad')
                    LogIn = $true
                    M365Environment = 'commercial'
                    AppID = 'a'
                    CertificateThumbprint = 'b'
                    Organization = 'c'
                }
                $FailedAuthList = Invoke-Connection -CyberConfig $CyberConfig
                Should -Invoke -CommandName Connect-Tenant -Times 1 -Exactly
                $FailedAuthList | Should -BeNullOrEmpty
            }
        }

        Context 'When LogIn is false' {
            BeforeEach {
                $script:CyberConfig = [PSCustomObject]@{
                    ProductNames    = @('aad')
                    LogIn           = $false
                    M365Environment = 'commercial'
                }
                function Connect-Tenant { throw 'this will be mocked' }
                Mock -ModuleName Orchestrator Connect-Tenant { @() }
            }
            It 'does not attempt authentication' {
                Invoke-Connection -CyberConfig $CyberConfig | Should -BeNullOrEmpty
                Should -Invoke -CommandName Connect-Tenant -Times 0 -Exactly
            }
        }
    }
}

AfterAll {
    Remove-Module Orchestrator -ErrorAction SilentlyContinue
}