PrivateFunctions/Upload-LargeFileToSharePointOnline.Tests.ps1

describe "BitTitan.Runbooks.SharePointOnline/Upload-LargeFileToSharePointOnline" -Tag "module", "unit" {

    # Import the function to test
    . "$($PSScriptRoot)\Upload-LargeFileToSharePointOnline.ps1"

    # Declare external functions
    function Test-Path {
        return $true
    }
    function Invoke-RestMethod {
        param($Uri, $Method, $Body, $Headers)
        return [PSCustomObject]@{
            ID = 'id'
            uploadUrl = "url"
        }
    }

    # Declare the function inputs
    $filePath = "$($PSScriptRoot)\file.extension"
    $destination = "/hello/world.exe"
    $token = "This is the token!"
    $siteUrl = "site.sharepoint.com"
    $outputStream = "Warning"

    # Create the test file
    New-Item -Path $filePath -ItemType "file" -Value "This is a text string."

    context "when there are no issues" {
        # Declare mocks
        mock Invoke-RestMethod {
            param($Uri, $Method, $Body, $Headers)
            return [PSCustomObject]@{
                ID = 'id'
                uploadUrl = "url"
            }
        }

        it "uploads a large file to SharePoint Online" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl

            # Verify the mocks
            Assert-MockCalled Invoke-RestMethod -Times 1 -Exactly -ParameterFilter {
                $Uri -eq "https://graph.microsoft.com/v1.0/sites/site.sharepoint.com/drive/root:/hello/world.exe:/createUploadSession" -and
                $Method -eq "POST" -and
                $Headers.Accept -eq "application/json" -and
                $Headers.Authorization -eq "bearer This is the token!"
            } -Scope it
            Assert-MockCalled Invoke-RestMethod -Times 1 -Exactly -ParameterFilter {
                $Uri -eq "url" -and
                $Method -eq "PUT"
            } -Scope it

            # Verify the output
            $output | Should Be $true
        }
    }

    context "when the file does not exist on the local machine" {
        # Declare mocks
        mock Test-Path {
            return $false
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when the siteUrl is not valid" {
        # Declare the function inputs
        $siteUrl = "siteUrl"
        $destination = "\hello\world.exe"

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when Invoke-RestMethod throws an exception while retrieving the upload link" {
        # Declare mocks
        mock Invoke-RestMethod{
            throw "error"
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when Invoke-RestMethod throws an exception while uploading the file" {
        # Declare mocks
        mock Invoke-RestMethod{
            param($Uri, $Method, $Body)
            if($Method -eq "PUT"){
                throw "error"
            }
            return [PSCustomObject]@{
                ID = 'id'
                uploadUrl = "url"
            }
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when Invoke-RestMethod does not return the upload url" {
        # Declare mocks
        mock Invoke-RestMethod{
            return [PSCustomObject]@{
                ID = 'id'
            }
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when Invoke-RestMethod does not return the id" {
        # Declare mocks
        mock Invoke-RestMethod{
            return [PSCustomObject]@{
                uploadUrl = "url"
            }
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-LargeFileToSharePointOnline -filePath $filePath -destinationFilePath $destination -Token $token -siteUrl $siteUrl -OutputStream $outputStream -WarningVariable warningVariable

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

    # Remove the test file
    Remove-Item -Path $filePath
}