Functions/Connect-PartnerCenterAdminAccount.Tests.ps1

describe "BitTitan.Runbooks.PartnerCenter/Connect-PartnerCenterAdminAccount" -Tags "module", "unit" {

    # Import the function to test
    . "$($PSScriptRoot)\Connect-PartnerCenterAdminAccount.ps1"

    # Declare external functions and mocks
    function Connect-PartnerCenter {
        param ($ApplicationId, [PSCredential]$Credential, [Switch]$ServicePrincipal, $TenantId)
    }
    function Test-EmailAddressValidity {
        param ($EmailAddress)
        return $emailAddress -eq "username@domain.com"
    }
    function Write-OutputMessage {
        param ($Message, $OutputStream)
    }

    # Declare shared variables
    $username = "username@domain.com"
    $password = "password" | ConvertTo-SecureString -AsPlainText -Force

    context "when there are no issues" {
        # Mock Connect-PartnerCenter
        mock Connect-PartnerCenter {}

        it "connects to Partner Center with app + user authentication and outputs a warning." {
            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Username $username -Password $password `
                -ApplicationId ([Guid]::empty) `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Connect-PartnerCenter -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq "username@domain.com" -and `
                $Credential.GetNetworkCredential().Password -eq "password" -and `
                $ApplicationId -eq ([Guid]::empty)
            } -Scope it

            # Verify the output
            $errorVariable | Should BeNullOrEmpty
            $warningVariable | Should Not BeNullOrEmpty
            $output | Should Be $true
        }

        it "connects to Partner Center with app + user authentication using an endpoint and outputs a warning." {
            # Declare the endpoint stub
            $endpoint = [PSCustomObject]@{
                Name                = "Stub endpoint"
                Credential          = [PSCredential]::new($username, $password)
                ExtendedProperties  = @{
                    ApplicationId = ([Guid]::empty).Guid
                }
            }

            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Endpoint $endpoint `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Connect-PartnerCenter -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq "username@domain.com" -and $Credential.GetNetworkCredential().Password -eq "password" -and $ApplicationId -eq ([Guid]::empty).Guid
            } -Scope it

            # Verify the output
            $errorVariable | Should BeNullOrEmpty
            $warningVariable | Should Not BeNullOrEmpty
            $output | Should Be $true
        }

        it "connects to Partner Center with app authentication." {
            # Call the function
            $output = Connect-PartnerCenterAdminAccount -ApplicationId ([Guid]::empty) `
                -ApplicationSecret $password `
                -TenantId ([Guid]::empty) `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Connect-PartnerCenter -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq ([Guid]::empty) -and `
                $Credential.GetNetworkCredential().Password -eq "password" -and `
                $TenantId -eq ([Guid]::empty) -and `
                $ServicePrincipal
            } -Scope it

            # Verify the output
            $errorVariable | Should BeNullOrEmpty
            $warningVariable | Should BeNullOrEmpty
            $output | Should Be $true
        }

        it "connects to Partner Center with app authentication using an endpoint." {
            # Declare the endpoint stub
            $endpoint = [PSCustomObject]@{
                Name                = "Stub endpoint"
                Credential          = [PSCredential]::new(([Guid]::empty).Guid, $password)
                ExtendedProperties  = @{
                    TenantId = ([Guid]::empty).Guid
                }
            }

            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Endpoint $endpoint `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Connect-PartnerCenter -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq ([Guid]::empty) -and `
                $Credential.GetNetworkCredential().Password -eq "password" -and `
                $TenantId -eq ([Guid]::empty) -and `
                $ServicePrincipal
            } -Scope it

            # Verify the output
            $errorVariable | Should BeNullOrEmpty
            $warningVariable | Should BeNullOrEmpty
            $output | Should Be $true
        }
    }

    context "when an exception occurs while connecting to Partner Center" {
        # Declare mocks
        mock Connect-PartnerCenter {
            throw "throws exception"
        }
        mock Write-OutputMessage {}

        it "fails to connect to Partner Center using app + user authentication and outputs an error message" {
            # Declare the endpoint stub
            $endpoint = [PSCustomObject]@{
                Name                = "Stub endpoint"
                Credential          = [PSCredential]::new($username, $password)
                ExtendedProperties  = @{
                    ApplicationId = ([Guid]::empty).Guid
                }
            }

            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Endpoint $endpoint `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Write-OutputMessage -Times 1 -Exactly -ParameterFilter {
                $OutputStream -eq "Error"
            } -Scope it
            Assert-MockCalled Connect-PartnerCenter -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq "username@domain.com" -and `
                $Credential.GetNetworkCredential().Password -eq "password" -and `
                $ApplicationId -eq ([Guid]::empty)
            } -Scope it

            # Verify the output
            $warningVariable | Should Not BeNullOrEmpty
            $output | Should Be $false
        }

        it "fails to connect to Partner Center using app authentication and outputs an error message" {
            # Declare the endpoint stub
            $endpoint = [PSCustomObject]@{
                Name                = "Stub endpoint"
                Credential          = [PSCredential]::new(([Guid]::empty).Guid, $password)
                ExtendedProperties  = @{
                    TenantId = ([Guid]::empty).Guid
                }
            }

            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Endpoint $endpoint `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Write-OutputMessage -Times 1 -Exactly -ParameterFilter {
                $OutputStream -eq "Error"
            } -Scope it
            Assert-MockCalled Connect-PartnerCenter -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq ([Guid]::empty) -and `
                $Credential.GetNetworkCredential().Password -eq "password" -and `
                $TenantId -eq ([Guid]::empty) -and `
                $ServicePrincipal
            } -Scope it

            # Verify the output
            $warningVariable | Should BeNullOrEmpty
            $output | Should Be $false
        }
    }

    context "when the endpoint does not contain the 'ApplicationId' extended property for app + user authentication" {
        # Mock Connect-PartnerCenter
        mock Connect-PartnerCenter {}
        mock Write-OutputMessage {}

        it "fails to connect to Partner Center and outputs an error message" {
            # Declare the endpoint stub
            $endpoint = [PSCustomObject]@{
                Name                = "Stub endpoint"
                Credential          = [PSCredential]::new($username, $password)
                ExtendedProperties  = @{}
            }

            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Endpoint $endpoint `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Write-OutputMessage -Times 1 -Exactly -ParameterFilter {
                $OutputStream -eq "Error"
            } -Scope it
            Assert-MockCalled Connect-PartnerCenter -Times 0 -Exactly -Scope it

            # Verify the output
            $warningVariable | Should BeNullOrEmpty
            $output | Should Be $false
        }
    }

    context "when the endpoint does not contain the 'TenantId' extended property for app authentication" {
        # Mock Connect-PartnerCenter
        mock Connect-PartnerCenter {}
        mock Write-OutputMessage {}

        it "fails to connect to Partner Center and outputs an error message" {
            # Declare the endpoint stub
            $endpoint = [PSCustomObject]@{
                Name                = "Stub endpoint"
                Credential          = [PSCredential]::new(([Guid]::empty).Guid, $password)
                ExtendedProperties  = @{}
            }

            # Call the function
            $output = Connect-PartnerCenterAdminAccount -Endpoint $endpoint `
                -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Write-OutputMessage -Times 1 -Exactly -ParameterFilter {
                $OutputStream -eq "Error"
            } -Scope it
            Assert-MockCalled Connect-PartnerCenter -Times 0 -Exactly -Scope it

            # Verify the output
            $warningVariable | Should BeNullOrEmpty
            $output | Should Be $false
        }
    }
}