Functions/Upload-FileToOneDrive.Tests.ps1

describe "BitTitan.Runbooks.OneDrive/Upload-FileToOneDrive" -Tag "module", "unit" {

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

    # Declare external functions
    function Test-Path {
        return $true
    }
    function Get-Item {
        return [PSCustomObject]@{
            Length = 1111
        }
    }
    function Get-MicrosoftGraphAuthenticationToken {
        param($endpoint)
        return "This is the token!"
    }
    function Get-OneDriveFileDownloadLink {
        param($filePath, $userPrincipalName, $token)
        return $null
    }
    function Upload-SmallFileToOneDrive {
        param($FilePath, $DestinationFilePath, $UserPrincipalName, $Token)
        return $true
    }
    function Upload-LargeFileToOneDrive {
        param($FilePath, $DestinationFilePath, $UserPrincipalName, $Token)
        return $true
    }

    # Declare the function inputs
    $filePath = "folder/file.extension"
    $destinationFilePath = "\destination\file.extension"
    $endpoint = "endpoint"
    $userPrincipalName = "userPrincipalName@domain.com"
    $outputStream = "Warning"

    context "when there are no issues" {
        # Declare mocks
        mock Get-OneDriveFileDownloadLink {
            param($filePath, $userPrincipalName, $token)
            return $null
        }

        mock Upload-SmallFileToOneDrive {
            param($FilePath, $DestinationFilePath, $UserPrincipalName, $Token)
            return $true
        }
        mock Upload-LargeFileToOneDrive {
            param($FilePath, $DestinationFilePath, $UserPrincipalName, $Token)
            return $true
        }

        it "uploads a small file" {
            # Declare mocks
            mock Get-Item {
                return [PSCustomObject]@{
                    Length = 1000
                }
            }

            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName

            # Verify the mocks
            Assert-MockCalled Get-OneDriveFileDownloadLink -Times 1 -Exactly -ParameterFilter {
                $filePath -eq "destination\file.extension" -and
                $userPrincipalName -eq "userPrincipalName@domain.com" -and
                $token -eq "This is the token!"
            } -Scope it
            Assert-MockCalled Upload-SmallFileToOneDrive -Times 1 -Exactly -ParameterFilter {
                $FilePath -eq "folder/file.extension" -and
                $DestinationFilePath -eq "destination\file.extension" -and
                $UserPrincipalName -eq "userPrincipalName@domain.com" -and
                $Token -eq "This is the token!"
            } -Scope it

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

        it "uploads a large file" {
            # Declare mocks
            mock Get-Item {
                return [PSCustomObject]@{
                    Length = 60000000
                }
            }

            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName

            # Verify the mocks
            Assert-MockCalled Get-OneDriveFileDownloadLink -Times 1 -Exactly -ParameterFilter {
                $filePath -eq "destination\file.extension" -and
                $userPrincipalName -eq "userPrincipalName@domain.com" -and
                $token -eq "This is the token!"
            } -Scope it
            Assert-MockCalled Upload-LargeFileToOneDrive -Times 1 -Exactly -ParameterFilter {
                $FilePath -eq "folder/file.extension" -and
                $DestinationFilePath -eq "destination\file.extension" -and
                $UserPrincipalName -eq "userPrincipalName@domain.com" -and
                $Token -eq "This is the token!"
            } -Scope it

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

    context "when the token cannot be retrieved" {
        # Declare mocks
        mock Get-MicrosoftGraphAuthenticationToken {
            param($endpoint)
            return " "
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -OutputStream $outputStream -WarningVariable warningVariable

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

    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-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when the UserPrincipalName is not valid" {
        # Declare the function inputs
        $userPrincipalName = "userPrincipalName"

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when the file already exists on OneDrive" {
        # Declare mocks
        mock Get-OneDriveFileDownloadLink {
            param($Uri, $Method, $Headers)
            return $true
        }
        mock Upload-SmallFileToOneDrive {
            param($FilePath, $DestinationFilePath, $UserPrincipalName, $Token)
            return $true
        }
        mock Get-Item {
            return [PSCustomObject]@{
                Length = 1000
            }
        }

        # Declare function input variable
        $destinationFilePath = "/folder/file.extension"

        it "outputs a warning and returns false, when the -Overwrite switch is set to false" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -Overwrite:$false -OutputStream $outputStream -WarningVariable warningVariable

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

        it "proceeds with the upload if the -Overwrite switch is set, but outputs a warning" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -UserPrincipalName $userPrincipalName -Overwrite -OutputStream $outputStream -WarningVariable warningVariable

            # Verify the mocks
            Assert-MockCalled Get-OneDriveFileDownloadLink -Times 1 -Exactly -ParameterFilter {
                $filePath -eq "folder/file.extension" -and
                $userPrincipalName -eq "userPrincipalName@domain.com" -and
                $token -eq "This is the token!"
            } -Scope it
            Assert-MockCalled Upload-SmallFileToOneDrive -Times 1 -Exactly -ParameterFilter {
                $FilePath -eq "folder/file.extension" -and
                $DestinationFilePath -eq "folder/file.extension" -and
                $UserPrincipalName -eq "userPrincipalName@domain.com" -and
                $Token -eq "This is the token!"
            } -Scope it

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

    context "when Upload-SmallFileToOneDrive returns false" {
        # Declare mocks
        mock Upload-SmallFileToOneDrive {
            return $false
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when Upload-LargeFileToOneDrive returns false" {
        # Declare mocks
        mock Upload-LargeFileToOneDrive {
            return $false
        }
        mock Get-Item {
            return [PSCustomObject]@{
                Length = 60000000
            }
        }

        it "outputs a warning and returns false" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -OutputStream $outputStream -WarningVariable warningVariable

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

    context "when the file size is larger than 60 MB" {
        # Declare mocks
        mock Get-Item {
            return [PSCustomObject]@{
                Length = 100000000
            }
        }

        it "returns false" {
            # Call the function
            $output = Upload-FileToOneDrive -filePath $filePath -destinationFilePath $destinationFilePath -Endpoint $endpoint -userPrincipalName $userPrincipalName -OutputStream $outputStream

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