BitTitan.Runbooks.MSPComplete.Tests.ps1

####################################################################################################
# Declarations
####################################################################################################

# Set InformationPreference
$InformationPreference = "Continue"

####################################################################################################
# Functions
####################################################################################################

# Add modules folder to path if not already added
if (!$env:PSModulePath.EndsWith(";$(Get-Location)\Modules")) {
    $env:PSModulePath += ";$(Get-Location)\Modules"
}

# Import functions from BitTitan.Runbooks.Modules
Import-Module BitTitan.Runbooks.MSPComplete -Force

<#
.SYNOPSIS
    This function returns the requested endpoint in the MSPComplete test environment.
.PARAMETER endpointType
    The type of the Endpoint.
.PARAMETER endpointExists
    Whether the Endpoint currently exists in the test environment.
.PARAMETER environment
    The BitTitan environment where the Endpoint is stored.
#>

function Get-MSPCompleteTestEnvironmentEndpoint {
    param (
        # The type of the Endpoint.
        [Parameter(Mandatory=$true)]
        [ValidateSet("Generic", "Office365")]
        [String]$endpointType,

        # Whether the Endpoint currently exists in the test environment.
        [Parameter(Mandatory=$false)]
        [Switch]$endpointExists,

        # The BitTitan environment where the Endpoint is stored.
        [Parameter(Mandatory=$false)]
        [ValidateSet("BT", "Beta")]
        [String]$environment = "Beta"
    )

    # Return the requested endpoint
    # Endpoint doesn't exist, return immediately
    if (!$endpointExists) {
        return @{
            EndpointID  = New-Guid
            Endpoint    = $null
            Username    = "invalidendpointusername"
            Password    = "invalidendpointpassword"
        }
    }

    # Return endpoint which exists
    if ($environment -eq "BT") {
        if ($endpointType -eq "Generic") {
            $endpointId = "8ac179cb-c401-11e8-a943-000d3af74645"
            return @{
                EndpointID  = $endpointId
                Endpoint    = Get-BT_Endpoint -Ticket $mspcBT.Ticket -Id $endpointId
                Username    = "btgenericendpointusername"
                Password    = "btgenericendpointpassword"
            }
        }
        elseif ($endpointType -eq "Office365") {
            $endpointId = "1e37d35d-c401-11e8-a943-000d3af74645"
            return @{
                EndpointID  = $endpointId
                Endpoint    = Get-BT_Endpoint -Ticket $mspcBT.Ticket -Id $endpointId
                Username    = "btoffice365endpointusername"
                Password    = "btoffice365endpointpassword"
            }
        }
    }
    elseif ($environment -eq "Beta") {
        if ($endpointType -eq "Generic") {
            $endpointId = "91a37333-c405-11e8-a945-000d3af9f695"
            return @{
                EndpointID  = $endpointId
                Endpoint    = Get-BT_Endpoint -Ticket $mspcBeta.Ticket -Id $endpointId -Environment "Beta"
                Username    = "betagenericendpointusername"
                Password    = "betagenericendpointpassword"
            }
        }
        elseif ($endpointType -eq "Office365") {
            $endpointId = "a4417af9-c405-11e8-a945-000d3af9f695"
            return @{
                EndpointID  = $endpointId
                Endpoint    = Get-BT_Endpoint -Ticket $mspcBeta.Ticket -Id $endpointId -Environment "Beta"
                Username    = "betaoffice365endpointusername"
                Password    = "betaoffice365endpointpassword"
            }
        }
    }
    Write-Error "Unsupported combination of parameters."
    return $null
}

####################################################################################################
# The tests
####################################################################################################

describe "Modules/BitTitan.Runbooks.MSPComplete/Get-CredentialFromMSPCompleteEndpoint" -Tags "module", "MSPComplete" {

    # Verify that required global variables are present
    if ($null -eq $mspcBT) {
        throw "`$Global:mspcBT is null. `$Global:mspcBT is a required global variable for this test, and should be a MSPComplete context object in the 'BT' environment."
    }
    if ($null -eq $mspcBeta) {
        throw "`$Global:mspcBeta is null. `$Global:mspcBeta is a required global variable for this test, and should be a MSPComplete context object in the 'Beta' environment."
    }

    context "when the Endpoint ID is invalid" {
        # Get endpoint information
        $endpointInformation = Get-MSPCompleteTestEnvironmentEndpoint -EndpointType "Generic" -Environment "BT" -EndpointExists:$false

        # Verify endpoint information
        $endpointInformation.Endpoint   | Should Be $null
        $endpointInformation.EndpointID | Should Not Be $null
        $endpointInformation.Username   | Should Not Be $null
        $endpointInformation.Password   | Should Not Be $null

        it "returns a null credential object" {
            # Call the function
            $credential = Get-CredentialFromMSPCompleteEndpoint -EndpointID $endpointInformation.EndpointID -Ticket $mspcBT.Ticket -Environment "BT"

            # Verify the retrieved credential
            $credential | Should Be $null
        }
    }

    context "when the ID of the provided Endpoint is invalid" {
        # Get endpoint information
        $endpointInformation = Get-MSPCompleteTestEnvironmentEndpoint -EndpointType "Generic" -Environment "BT" -EndpointExists:$false

        # Verify endpoint information
        $endpointInformation.Endpoint   | Should Be $null
        $endpointInformation.EndpointID | Should Not Be $null
        $endpointInformation.Username   | Should Not Be $null
        $endpointInformation.Password   | Should Not Be $null

        # Prepare the endpoint with invalid ID
        $endpointInformation.Endpoint = [PSCustomObject]@{
            Id = $endpointInformation.EndpointID
        }

        it "returns a null credential object" {
            # Call the function
            $credential = Get-CredentialFromMSPCompleteEndpoint -Endpoint $endpointInformation.Endpoint -Ticket $mspcBT.Ticket -Environment "BT"

            # Verify the retrieved credential
            $credential | Should Be $null
        }
    }

    # Test for retrieving credentials from all possible types of endpoints
    $environments = @("BT", "Beta")
    $endpointTypes = @("Generic", "Office365")
    $endpointIdentifiers = @("Endpoint ID", "Endpoint without credential", "Endpoint with credential")

    # Loop through environments
    foreach ($environment in $environments) {
        # Set correct ticket
        if ($environment -eq "BT") {
            $ticket = $mspcBT.Ticket
        }
        else {
            $ticket = $mspcBeta.Ticket
        }

        # Loop through endpoint types
        foreach ($endpointType in $endpointTypes) {

            # Loop through endpoint identifiers
            foreach ($endpointIdentifier in $endpointIdentifiers) {

                context "when given a $($endpointType) $($endpointIdentifier) in the '$($environment)' environment" {
                    # Get endpoint information
                    $endpointInformation = Get-MSPCompleteTestEnvironmentEndpoint -EndpointType $endpointType -Environment $environment -EndpointExists

                    # Verify endpoint information
                    $endpointInformation.Endpoint   | Should Not Be $null
                    $endpointInformation.EndpointID | Should Not Be $null
                    $endpointInformation.Username   | Should Not Be $null
                    $endpointInformation.Password   | Should Not Be $null

                    # Prepare for the test
                    $itStatement = "retrieves the credential"
                    if ($endpointIdentifier -eq "Endpoint with credential") {
                        $itStatement += " directly from the Endpoint"

                        # Create the credential in the endpoint
                        $endpointInformation.Endpoint | Add-Member -NotePropertyName "Credential" -NotePropertyValue (New-Object System.Management.Automation.PSCredential(
                            $endpointInformation.Username,
                            ($endpointInformation.Password | ConvertTo-SecureString -AsPlainText -Force)
                        )) -Force

                        # Get-MSPCompleteEndpointWithCredential should not be called
                        # Mock Get-MSPCompleteEndpointWithCredential to return null
                        # This ensures that if it is called, the test will fail
                        mock Get-MSPCompleteEndpointWithCredential { return $null }
                    }

                    # Execute the test
                    it $itStatement {
                        # Create hash table for params
                        $getCredentialFromMSPCompleteEndpointParams = @{
                            Environment = $environment
                            Ticket      = $ticket
                        }
                        if ($endpointIdentifier -eq "Endpoint ID") {
                            $getCredentialFromMSPCompleteEndpointParams.Add("EndpointID", $endpointInformation.EndpointID)
                        }
                        else {
                            $getCredentialFromMSPCompleteEndpointParams.Add("Endpoint", $endpointInformation.Endpoint)
                        }

                        # Call the function
                        $credential = Get-CredentialFromMSPCompleteEndpoint @getCredentialFromMSPCompleteEndpointParams

                        # Verify the retrieved credential
                        $credential                                 | Should Not Be $null
                        $credential.Username                        | Should Be $endpointInformation.Username
                        $credential.GetNetworkCredential().Password | Should Be $endpointInformation.Password
                    }
                }
            }
        }
    }
}

describe "Modules/BitTitan.Runbooks.MSPComplete/Get-MSPCompleteEndpointWithCredential" -Tags "module", "MSPComplete" {

    # Verify that required global variables are present
    if ($null -eq $mspcBT -or $null -eq $mspcBT.Ticket) {
        throw "`$Global:mspcBT or `$Global:mspcBT.Ticket is null. `$Global:mspcBT.Ticket is a required global variable for this test, and should be a MSPComplete ticket in the 'BT' environment."
    }
    if ($null -eq $mspcBeta -or $null -eq $mspcBeta.Ticket) {
        throw "`$Global:mspcBeta or `$Global:mspcBeta.Ticket is null. `$Global:mspcBeta.Ticket is a required global variable for this test, and should be a MSPComplete ticket in the 'Beta' environment."
    }

    context "when the Endpoint ID is invalid" {
        # Get endpoint information
        $endpointInformation = Get-MSPCompleteTestEnvironmentEndpoint -EndpointType "Generic" -Environment "BT" -EndpointExists:$false

        # Verify endpoint information
        $endpointInformation.Endpoint   | Should Be $null
        $endpointInformation.EndpointID | Should Not Be $null
        $endpointInformation.Username   | Should Not Be $null
        $endpointInformation.Password   | Should Not Be $null

        it "returns a null endpoint object" {
            # Call the function
            $endpoint = Get-MSPCompleteEndpointWithCredential -EndpointID $endpointInformation.EndpointID -Ticket $mspcBT.Ticket -Environment "BT"

            # Verify the retrieved endpoint
            $endpoint | Should Be $null
        }
    }

    context "when the ID of the provided Endpoint is invalid" {
        # Get endpoint information
        $endpointInformation = Get-MSPCompleteTestEnvironmentEndpoint -EndpointType "Generic" -Environment "BT" -EndpointExists:$false

        # Verify endpoint information
        $endpointInformation.Endpoint   | Should Be $null
        $endpointInformation.EndpointID | Should Not Be $null
        $endpointInformation.Username   | Should Not Be $null
        $endpointInformation.Password   | Should Not Be $null

        # Prepare the endpoint with invalid ID
        $endpointInformation.Endpoint = [PSCustomObject]@{
            Id = $endpointInformation.EndpointID
        }

        it "returns a null endpoint object" {
            # Call the function
            $endpoint = Get-MSPCompleteEndpointWithCredential -Endpoint $endpointInformation.Endpoint -Ticket $mspcBT.Ticket -Environment "BT"

            # Verify the retrieved endpoint
            $endpoint | Should Be $null
        }
    }

    # Test for retrieving endpoints with credentials for all possible types of endpoints
    $environments = @("BT", "Beta")
    $endpointTypes = @("Generic", "Office365")
    $endpointIdentifiers = @("Endpoint ID", "Endpoint")

    # Loop through environments
    foreach ($environment in $environments) {
        # Set correct ticket
        if ($environment -eq "BT") {
            $ticket = $mspcBT.Ticket
        }
        else {
            $ticket = $mspcBeta.Ticket
        }

        # Loop through endpoint types
        foreach ($endpointType in $endpointTypes) {

            # Loop through endpoint identifiers
            foreach ($endpointIdentifier in $endpointIdentifiers) {

                context "when given a $($endpointType) $($endpointIdentifier) in the '$($environment)' environment" {
                    # Get endpoint information
                    $endpointInformation = Get-MSPCompleteTestEnvironmentEndpoint -EndpointType $endpointType -Environment $environment -EndpointExists

                    # Verify endpoint information
                    $endpointInformation.Endpoint   | Should Not Be $null
                    $endpointInformation.EndpointID | Should Not Be $null
                    $endpointInformation.Username   | Should Not Be $null
                    $endpointInformation.Password   | Should Not Be $null

                    # Execute the test
                    it "retrieves the Endpoint with credential" {
                        # Create hash table for params
                        $getMSPCompleteEndpointWithCredentialParams = @{
                            Environment = $environment
                            Ticket      = $ticket
                        }
                        if ($endpointIdentifier -eq "Endpoint ID") {
                            $getMSPCompleteEndpointWithCredentialParams.Add("EndpointID", $endpointInformation.EndpointID)
                        }
                        else {
                            $getMSPCompleteEndpointWithCredentialParams.Add("Endpoint", $endpointInformation.Endpoint)
                        }

                        # Call the function
                        $endpoint = Get-MSPCompleteEndpointWithCredential @getMSPCompleteEndpointWithCredentialParams

                        # Verify the retrieved endpoint
                        $endpoint                                               | Should Not Be $null
                        $endpoint.Credential                                    | Should Not Be $null
                        $endpoint.Credential.Username                           | Should Be $endpointInformation.Username
                        $endpoint.Credential.GetNetworkCredential().Password    | Should Be $endpointInformation.Password
                    }
                }
            }
        }
    }
}