# Invoke-GiteaFileDownload.Tests.ps1 # Import the module under test $modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\PS-GiteaUtilities.psm1' Import-Module -Name $modulePath -Force Describe 'Invoke-GiteaFileDownload' { BeforeEach { # Always mock Get-GiteaConfiguration to avoid needing real config Mock -CommandName Get-GiteaConfiguration -ModuleName PS-GiteaUtilities -MockWith { return @{ token = 'mocktoken' } } # Correct webClient Mock: headers, download, dispose Mock -CommandName New-Object -ModuleName PS-GiteaUtilities -MockWith { $headers = New-Object System.Net.WebHeaderCollection # Create a real object $webClient = New-Object PSObject # Add Headers Add-Member -InputObject $webClient -MemberType NoteProperty -Name Headers -Value $headers # Add a DownloadFile method Add-Member -InputObject $webClient -MemberType ScriptMethod -Name DownloadFile -Value { param($url, $path) # Fake download (do nothing) } # Add a Dispose method Add-Member -InputObject $webClient -MemberType ScriptMethod -Name Dispose -Value { # Fake dispose (do nothing) } return $webClient } # Mock filesystem behavior Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $false } Mock -CommandName New-Item -ModuleName PS-GiteaUtilities -MockWith { } # Clean captured download data before each test $script:LastDownloadUrl = $null $script:LastDownloadPath = $null } Context 'When all parameters are valid' { It 'Should download a file successfully' { $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' -token 'abc123' $result | Should -Not -BeNullOrEmpty $result.Success | Should -Be $true $result.Path | Should -Match 'file\.txt$' } } Context 'When preserving relative paths' { It 'Should create a path based on filePath with PreserveRelativePath' { $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/file.txt' ` -filePath 'docs/manual/file.txt' -PreserveRelativePath -token 'abc123' $result.Path | Should -Match 'docs[\\/]+manual[\\/]+file\.txt$' $result.Success | Should -Be $true } } Context 'When skipping directories' { It 'Should skip items with type = dir' { $result = Invoke-GiteaFileDownload -filePath 'docs/' -type 'dir' -token 'abc123' $result.Success | Should -Be $true $result.Error | Should -Match 'Skipped' } } Context 'When file exists and -Force is not used' { BeforeEach { # Simulate file already exists Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { param($Path, $PathType) if ($PathType -eq 'Leaf') { return $true } else { return $false } } Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { } } It 'Should not overwrite existing file without Force' { $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/existingfile.txt' -token 'abc123' $result.Success | Should -Be $false $result.Error | Should -Match 'already exists' } } Context 'When download fails' { BeforeEach { Mock -CommandName New-Object -ModuleName PS-GiteaUtilities -MockWith { $headers = New-Object System.Net.WebHeaderCollection $webClient = New-Object PSObject Add-Member -InputObject $webClient -MemberType NoteProperty -Name Headers -Value $headers Add-Member -InputObject $webClient -MemberType ScriptMethod -Name DownloadFile -Value { throw "Download failed intentionally" } Add-Member -InputObject $webClient -MemberType ScriptMethod -Name Dispose -Value { return $true } return $webClient } Mock -CommandName Test-Path -ModuleName PS-GiteaUtilities -MockWith { $false } Mock -CommandName New-Item -ModuleName PS-GiteaUtilities -MockWith { } Mock -CommandName Write-Error -ModuleName PS-GiteaUtilities -MockWith { } } It 'Should capture error and mark download as failed' { $result = Invoke-GiteaFileDownload -downloadURL 'https://gitea.example.com/raw/path/to/badfile.txt' -token 'abc123' $result.Success | Should -Be $false $result.Error | Should -Match 'Failed to download' } } }