Functions/Get-FileFromUrl.Tests.ps1
describe "BitTitan.Runbooks.Common/Get-FileFromUrl" -Tags "module", "unit" { # Import the function to test . "$($PSScriptRoot)\Get-FileFromUrl.ps1" context "when there are no issues" { # Set up the function inputs $fileUrl = "https://website.com/file.txt" $destinationPath = "Z:\SomeFolder\downloadedFile.txt" # Mock Split-Path to return the same path mock Split-Path { return "Z:\SomeFolder" } # Mock Test-Path to always return true (valid) mock Test-Path { return $true } # Mock New-Object to return a mock of System.Net.WebClient $Script:calledFileUrl = "" $Script:calledDestinationPath = "" mock New-Object { class WebClientMock { [Void]DownloadFile($fileUrl, $destinationPath) { $Script:calledFileUrl = $fileUrl $Script:calledDestinationPath = $destinationPath } } return [WebClientMock]::new() } # Mock Get-Item to return our own value mock Get-Item { return "Get-Item success" } it "downloads the file and returns the downloaded file object" { # Call the function $output = Get-FileFromUrl -FileUrl $fileUrl -DestinationPath $destinationPath # Verify the mocks Assert-MockCalled Split-Path -Times 1 -Exactly -ParameterFilter { $Path -eq $destinationPath -and $Parent } Assert-MockCalled Test-Path -Times 2 -Exactly -ParameterFilter { $Path -eq "Z:\SomeFolder" -or $Path -eq $destinationPath } Assert-MockCalled New-Object -Times 1 -Exactly -ParameterFilter { $TypeName -eq "System.Net.WebClient" } $Script:calledFileUrl | Should Be $fileUrl $Script:calledDestinationPath | Should Be $destinationPath Assert-MockCalled Get-Item -Times 1 -Exactly -ParameterFilter { $Path -eq $destinationPath } # Verify the output $output | Should Be "Get-Item success" } } context "when the destination directory does not exist" { # Set up the function inputs $fileUrl = "https://website.com/file.txt" $destinationPath = "Z:\SomeFolder\downloadedFile.txt" # Mock Split-Path to return the same path mock Split-Path { return "Z:\SomeFolder" } # Mock Test-Path to fail mock Test-Path { return $false } # Mock New-Object to return a mock of System.Net.WebClient $Script:calledFileUrl = "" $Script:calledDestinationPath = "" mock New-Object { class WebClientMock { [Void]DownloadFile($fileUrl, $destinationPath) { $Script:calledFileUrl = $fileUrl $Script:calledDestinationPath = $destinationPath } } return [WebClientMock]::new() } # Mock Get-Item to return our own value mock Get-Item { return "Get-Item success" } it "returns null" { # Call the function $output = Get-FileFromUrl -FileUrl $fileUrl -DestinationPath $destinationPath -ErrorAction SilentlyContinue # Verify the mocks Assert-MockCalled Split-Path -Times 1 -Exactly -ParameterFilter { $Path -eq $destinationPath -and $Parent } Assert-MockCalled Test-Path -Times 1 -Exactly -ParameterFilter { $Path -eq "Z:\SomeFolder" -or $Path -eq $destinationPath } Assert-MockCalled New-Object -Times 0 -Exactly $Script:calledFileUrl | Should Be "" $Script:calledDestinationPath | Should Be "" Assert-MockCalled Get-Item -Times 0 # Verify the output $output | Should Be $null } } context "when there is an issue with the download process" { # Set up the function inputs $fileUrl = "https://website.com/file.txt" $destinationPath = "Z:\SomeFolder\downloadedFile.txt" # Mock Split-Path to return the same path mock Split-Path { return "Z:\SomeFolder" } # Mock Test-Path to always return true (valid) mock Test-Path { return $true } # Mock New-Object to return a mock of System.Net.WebClient $Script:calledFileUrl = "" $Script:calledDestinationPath = "" mock New-Object { class WebClientMock { [Void]DownloadFile($fileUrl, $destinationPath) { throw "throwing download exception" } } return [WebClientMock]::new() } # Mock Get-Item to return our own value mock Get-Item { return "Get-Item success" } it "returns null" { # Call the function $output = Get-FileFromUrl -FileUrl $fileUrl -DestinationPath $destinationPath -ErrorAction SilentlyContinue # Verify the mocks Assert-MockCalled Split-Path -Times 1 -Exactly -ParameterFilter { $Path -eq $destinationPath -and $Parent } Assert-MockCalled Test-Path -Times 1 -Exactly -ParameterFilter { $Path -eq "Z:\SomeFolder" -or $Path -eq $destinationPath } Assert-MockCalled New-Object -Times 1 -Exactly -ParameterFilter { $TypeName -eq "System.Net.WebClient" } $Script:calledFileUrl | Should Be "" $Script:calledDestinationPath | Should Be "" Assert-MockCalled Get-Item -Times 0 -Exactly # Verify the output $output | Should Be $null } } context "when the file was not saved correctly after download" { # Set up the function inputs $fileUrl = "https://website.com/file.txt" $destinationPath = "Z:\SomeFolder\downloadedFile.txt" # Mock Split-Path to return the same path mock Split-Path { return "Z:\SomeFolder" } # Mock Test-Path to only return true when checking for the directory # This will fail when checking for the downloaded file mock Test-Path { return $Path -eq "Z:\SomeFolder" } # Mock New-Object to return a mock of System.Net.WebClient $Script:calledFileUrl = "" $Script:calledDestinationPath = "" mock New-Object { class WebClientMock { [Void]DownloadFile($fileUrl, $destinationPath) { $Script:calledFileUrl = $fileUrl $Script:calledDestinationPath = $destinationPath } } return [WebClientMock]::new() } # Mock Get-Item to return our own value mock Get-Item { return "Get-Item success" } it "returns null" { # Call the function $output = Get-FileFromUrl -FileUrl $fileUrl -DestinationPath $destinationPath -ErrorAction SilentlyContinue # Verify the mocks Assert-MockCalled Split-Path -Times 1 -Exactly -ParameterFilter { $Path -eq $destinationPath -and $Parent } Assert-MockCalled Test-Path -Times 2 -Exactly -ParameterFilter { $Path -eq "Z:\SomeFolder" -or $Path -eq $destinationPath } Assert-MockCalled New-Object -Times 1 -Exactly -ParameterFilter { $TypeName -eq "System.Net.WebClient" } $Script:calledFileUrl | Should Be $fileUrl $Script:calledDestinationPath | Should Be $destinationPath Assert-MockCalled Get-Item -Times 0 -Exactly # Verify the output $output | Should Be $null } } } |