Functions/Connect-SharePointOnlineAdminAccount.Tests.ps1

describe "BitTitan.Runbooks.SharePointOnline/Connect-SharePointOnlineAdminAccount" -Tag "module", "unit" {

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

    # Declare mocks and external functions
    function Connect-SPOService {
        param ([PSCredential]$Credential, $Url)
    }

    context "when there are no issues" {
        # Declare mocks
        mock Connect-SPOService {}

        it "connects to SharePoint Online with the provided username and password" {
            # Call the function
            $output = Connect-SharePointOnlineAdminAccount -Username "username" -Password ("password" | ConvertTo-SecureString -AsPlainText -Force) `
                -OrganizationName "organizationName"

            # Verify the mocks
            Assert-MockCalled Connect-SPOService -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq "username" -and $Credential.GetNetworkCredential().Password -eq "password" -and
                $Url -eq "https://organizationName-admin.sharepoint.com"
            } -Scope it

            # Verify the output
            $Global:SharePointOnlineConnectionEstablished | Should Be $true
            $output | Should Be $true
        }

        # Reset the connection
        $Global:SharePointOnlineConnectionEstablished = $false

        it "connects to SharePoint Online with the provided endpoint" {
            # Mock the endpoint
            $endpoint = [PSCustomObject]@{
                Credential          = [PSCredential]::new(
                    "username",
                    ("password" | ConvertTo-SecureString -AsPlainText -Force)
                )
                ExtendedProperties = @{
                    OrganizationName = "organizationName"
                }
            }

            # Call the function
            $output = Connect-SharePointOnlineAdminAccount -Endpoint $endpoint

            # Verify the mocks
            Assert-MockCalled Connect-SPOService -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq "username" -and $Credential.GetNetworkCredential().Password -eq "password" -and
                $Url -eq "https://organizationName-admin.sharepoint.com"
            } -Scope it

            # Verify the output
            $Global:SharePointOnlineConnectionEstablished | Should Be $true
            $output | Should Be $true
        }

        # Reset the connection
        $Global:SharePointOnlineConnectionEstablished = $false
    }

    context "when the connection has already been established" {
        # Declare mocks
        mock Connect-SPOService {}

        # Set the connection
        $Global:SharePointOnlineConnectionEstablished = $true

        it "does not re-connect and outputs a warning" {
            # Call the function
            $output = Connect-SharePointOnlineAdminAccount -Username "username" -Password ("password" | ConvertTo-SecureString -AsPlainText -Force) `
                -OrganizationName "organizationName" -WarningAction SilentlyContinue -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Connect-SPOService -Times 0 -Exactly -Scope it

            # Verify the output
            $warningVariable | Should Not BeNullOrEmpty
            $Global:SharePointOnlineConnectionEstablished | Should Be $true
            $output | Should Be $true
        }

        # Reset the connection
        $Global:SharePointOnlineConnectionEstablished = $false
    }

    context "when the endpoint does not contain an 'OrganizationName' extended property" {
        # Declare mocks
        mock Connect-SPOService {}

        it "outputs an error" {
            # Mock the endpoint
            $endpoint = [PSCustomObject]@{
                Credential          = [PSCredential]::new(
                    "username",
                    ("password" | ConvertTo-SecureString -AsPlainText -Force)
                )
                ExtendedProperties = @{}
            }

            # Call the function
            $output = Connect-SharePointOnlineAdminAccount -Endpoint $endpoint -ErrorAction SilentlyContinue -ErrorVariable errorVariable

            # Verify the mocks
            Assert-MockCalled Connect-SPOService -Times 0 -Exactly -Scope it

            # Verify the output
            $errorVariable | Should Not BeNullOrEmpty
            $Global:SharePointOnlineConnectionEstablished | Should Be $false
            $output | Should Be $false
        }
    }

    context "when there is an exception while connecting to SharePoint Online" {
        # Declare mocks
        mock Connect-SPOService {
            throw "throws exception"
        }

        it "fails to connect to SharePoint Online and outputs an error message" {
            # Call the function
            $output = Connect-SharePointOnlineAdminAccount -Username "username" -Password ("password" | ConvertTo-SecureString -AsPlainText -Force) `
                -OrganizationName "organizationName" -ErrorAction SilentlyContinue -ErrorVariable errorVariable

            # Verify the mocks
            Assert-MockCalled Connect-SPOService -Times 1 -Exactly -ParameterFilter {
                $Credential.Username -eq "username" -and $Credential.GetNetworkCredential().Password -eq "password" -and
                $Url -eq "https://organizationName-admin.sharepoint.com"
            } -Scope it

            # Verify the output
            $Global:SharePointOnlineConnectionEstablished | Should Be $false
            $errorVariable | Should Not BeNullOrEmpty
            $output | Should Be $false
        }

        # Reset the connection
        $Global:SharePointOnlineConnectionEstablished = $false
    }
}