tests/Invoke-BykaDrBackup.Integration.Tests.ps1
|
# End-to-end integration tests for Invoke-BykaDrBackup against $TestDrive. # # These tests run the full backup function (writing into TestDrive, NOT a real # desktop location) and assert observable side effects: backup folder created, # RESTORE-INSTRUCTIONS.md written, cleanup loop honors -KeepDays, -ProjectRoot # explicit pass short-circuits auto-detect. # # Added 2026-05-27 in M-13 Phase 3 Wave E [G4] panel-followup. Per operator # instruction, no Tier-3 deferrals -- the panel's code-reviewer F15 + qa F2 # specifically called out the missing happy-path integration coverage. BeforeAll { $script:ManifestPath = Join-Path $PSScriptRoot '..' 'BykaDrBackup.psd1' Import-Module $script:ManifestPath -Force } AfterAll { Remove-Module BykaDrBackup -ErrorAction SilentlyContinue } Describe 'Invoke-BykaDrBackup happy path' { It 'creates a backup-<timestamp> directory containing RESTORE-INSTRUCTIONS.md' { $dest = Join-Path $TestDrive 'happy-dest' # Suppress noisy console output during test. Invoke-BykaDrBackup -Destination $dest -KeepDays 365 6>$null $backupFolders = @(Get-ChildItem -LiteralPath $dest -Directory -Filter 'backup-*' -ErrorAction SilentlyContinue) $backupFolders.Count | Should -Be 1 $restoreFile = Join-Path $backupFolders[0].FullName 'RESTORE-INSTRUCTIONS.md' Test-Path $restoreFile | Should -BeTrue $content = Get-Content -LiteralPath $restoreFile -Raw $content | Should -Match '# BYKA Emergency Restore Instructions' $content | Should -Match 'Install-PSResource -Name BykaDrBackup' } } Describe 'Invoke-BykaDrBackup cleanup loop' { It 'deletes folders older than -KeepDays and preserves the current run' { $dest = Join-Path $TestDrive 'cleanup-dest' New-Item -ItemType Directory -Path $dest -Force | Out-Null # Seed: one old (10 days ago) + one ineligible-by-name folder. $oldFolder = Join-Path $dest 'backup-2026-05-15_120000' New-Item -ItemType Directory -Path $oldFolder -Force | Out-Null $unparseable = Join-Path $dest 'backup-not-a-date' New-Item -ItemType Directory -Path $unparseable -Force | Out-Null Invoke-BykaDrBackup -Destination $dest -KeepDays 7 6>$null # Old folder should be DELETED; unparseable should be PRESERVED (date-parse # guard skips it); current-run folder should EXIST. Test-Path $oldFolder | Should -BeFalse Test-Path $unparseable | Should -BeTrue @(Get-ChildItem -LiteralPath $dest -Directory -Filter 'backup-*' -ErrorAction SilentlyContinue).Count | Should -BeGreaterOrEqual 1 } It 'preserves a fresh-named folder under -KeepDays' { $dest = Join-Path $TestDrive 'keep-fresh-dest' New-Item -ItemType Directory -Path $dest -Force | Out-Null $todayStamp = Get-Date -Format 'yyyy-MM-dd_HHmmss' $freshOld = Join-Path $dest "backup-$todayStamp" New-Item -ItemType Directory -Path $freshOld -Force | Out-Null Invoke-BykaDrBackup -Destination $dest -KeepDays 1 6>$null Test-Path $freshOld | Should -BeTrue } } Describe 'Invoke-BykaDrBackup -ProjectRoot handling' { It 'accepts an explicit -ProjectRoot that exists' { $dest = Join-Path $TestDrive 'pr-dest' $pr = Join-Path $TestDrive 'fake-project' New-Item -ItemType Directory -Path $pr -Force | Out-Null # Should not throw despite no CLAUDE.md (-ProjectRoot bypasses auto-detect). { Invoke-BykaDrBackup -Destination $dest -KeepDays 365 -ProjectRoot $pr 6>$null } | Should -Not -Throw } It 'warns but does not throw when -ProjectRoot does not exist' { $dest = Join-Path $TestDrive 'pr-missing-dest' $missingPr = Join-Path $TestDrive 'no-such-dir' { Invoke-BykaDrBackup -Destination $dest -KeepDays 365 -ProjectRoot $missingPr 6>$null } | Should -Not -Throw } } Describe 'Invoke-BykaDrBackup -Destination deny-list' { It 'rejects -Destination inside the Windows system root' { # ValidateScript should throw with the deny-list message. { Invoke-BykaDrBackup -Destination "$env:WINDIR\BYKA-EVIL" } | Should -Throw '*protected system path*' } } |