Functions/New-TemporaryFolder.Tests.ps1

describe "BitTitan.Runbooks.Common/New-TemporaryFolder" -Tag "module", "unit" {

    # Import the function to test
    . "$($PSScriptRoot)\New-TemporaryFolder.ps1"

    # Declare our own external functions
    function Join-Path {
        param ($Path, $ChildPath)
        return "JoinedPath"
    }
    function Test-Path {
        return $true
    }
    function New-Item {
        return "newItem"
    }
    function Get-Item {
        return "item"
    }

    # Set up the function inputs
    $folderName = "tempFolderName"
    $folderPath = "Z:\tempFolderPath"

    context "when there are no issues" {
        # Mock Join-Path
        mock Join-Path {
            return "JoinedPath"
        }

        # Mock Test-Path
        mock Test-Path { return $false }

        # Mock New-Item
        mock New-Item { return "newFolder" }

        # Mock Get-Item
        mock Get-Item { return "folder" }

        it "creates the folder in the env TEMP directory" {
            # Call the function
            $output = New-TemporaryFolder -FolderName $folderName

            # Verify the mocks
            Assert-MockCalled Join-Path -Times 1 -Exactly -ParameterFilter {
                $ChildPath -eq $folderName
            }
            Assert-MockCalled Test-Path -Times 1 -Exactly
            Assert-MockCalled New-Item -Times 1 -Exactly
            Assert-MockCalled Get-Item -Times 0 -Exactly

            # Verify the output
            $output | Should Be "newFolder"
        }
    }

    context "when the temporary folder already exists" {
        # Mock Join-Path
        mock Join-Path {
            return "JoinedPath"
        }

        # Mock Test-Path
        mock Test-Path { return $true }

        # Mock New-Item
        mock New-Item { return "newFolder" }

        # Mock Get-Item
        mock Get-Item { return "folder" }

        it "retrieves the existing folder" {
            # Call the function
            $output = New-TemporaryFolder -FolderName $folderName -WarningAction SilentlyContinue

            # Verify the mocks
            Assert-MockCalled Join-Path -Times 1 -Exactly -ParameterFilter {
                $ChildPath -eq $folderName
            }
            Assert-MockCalled Test-Path -Times 1 -Exactly
            Assert-MockCalled New-Item -Times 0 -Exactly
            Assert-MockCalled Get-Item -Times 1 -Exactly

            # Verify the output
            $output | Should Be "folder"
        }
    }

    context "when New-Item throws an exception" {
        # Mock Join-Path
        mock Join-Path {
            return "JoinedPath"
        }

        # Mock Test-Path
        mock Test-Path { return $false }

        # Mock New-Item
        mock New-Item { throw "throwing exception" }

        # Mock Get-Item
        mock Get-Item { return "folder" }

        it "outputs an error and returns null" {
            # Call the function
            $output = New-TemporaryFolder -FolderName $folderName -WarningAction SilentlyContinue `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable

            # Verify the mocks
            Assert-MockCalled Join-Path -Times 1 -Exactly -ParameterFilter {
                $ChildPath -eq $folderName
            }
            Assert-MockCalled Test-Path -Times 1 -Exactly
            Assert-MockCalled New-Item -Times 1 -Exactly
            Assert-MockCalled Get-Item -Times 0 -Exactly

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

    context "when the folder cannot be created" {
        # Mock Join-Path
        mock Join-Path {
            return "JoinedPath"
        }

        # Mock Test-Path
        mock Test-Path { return $false }

        # Mock New-Item
        mock New-Item {}

        # Mock Get-Item
        mock Get-Item { return "folder" }

        it "outputs an error and returns null" {
            # Call the function
            $output = New-TemporaryFolder -FolderName $folderName -WarningAction SilentlyContinue `
                -ErrorAction SilentlyContinue -ErrorVariable errorVariable

            # Verify the mocks
            Assert-MockCalled Join-Path -Times 1 -Exactly -ParameterFilter {
                $ChildPath -eq $folderName
            }
            Assert-MockCalled Test-Path -Times 1 -Exactly
            Assert-MockCalled New-Item -Times 1 -Exactly
            Assert-MockCalled Get-Item -Times 0 -Exactly

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