69 lines
4.6 KiB
PowerShell
69 lines
4.6 KiB
PowerShell
#Requires -Version 5.1
|
|
Set-StrictMode -Version Latest
|
|
$ErrorActionPreference='Stop'
|
|
$root=[IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
|
|
$scratch=Join-Path ([IO.Path]::GetTempPath()) ('ms-private-cleanup-test-'+[guid]::NewGuid().ToString('N'))
|
|
$module=Import-Module (Join-Path $root 'src/Wind.Cleanup.psm1') -Force -PassThru
|
|
$script:passed=0
|
|
function Assert-Cleanup([bool]$Condition,[string]$Message){if(-not$Condition){throw $Message};$script:passed++}
|
|
try{
|
|
$files=Join-Path $scratch 'files';[IO.Directory]::CreateDirectory($files)|Out-Null
|
|
# Use the production allowlist and an exact one-file plan; never scan or select other Temp files.
|
|
$tempRoot=[IO.Path]::GetFullPath([IO.Path]::GetTempPath()).TrimEnd('\')
|
|
$file=Join-Path $files 'sample.txt';$report=Join-Path $scratch 'report.json'
|
|
function New-TestCleanupPlan {
|
|
[IO.File]::WriteAllText($file,'original')
|
|
[IO.File]::SetLastWriteTimeUtc($file,[DateTime]::UtcNow.AddDays(-30))
|
|
$item=Get-Item -LiteralPath $file
|
|
[pscustomobject]@{
|
|
Schema=2;AgeDays=7;CutoffUtc=[DateTime]::UtcNow.AddDays(-7).ToString('o');Categories=@('Temp')
|
|
Files=@([pscustomobject]@{Path=$item.FullName;Root=$tempRoot;Category='Temp';Length=$item.Length;LastWriteUtc=$item.LastWriteTimeUtc.ToString('o')})
|
|
}
|
|
}
|
|
|
|
$plan=New-TestCleanupPlan
|
|
$result=Invoke-WindCleanup -Plan $plan -ReportPath $report -WhatIf
|
|
Assert-Cleanup ($result.Status-eq'Preview'-and(Test-Path -LiteralPath $file)-and-not(Test-Path -LiteralPath $report)) 'WhatIf changed files or wrote a cleanup report.'
|
|
|
|
$result=Invoke-WindCleanup -Plan $plan -ReportPath $report -Confirm:$false
|
|
Assert-Cleanup ($result.Deleted-eq1-and$result.FreedBytes-eq8-and-not(Test-Path -LiteralPath $file)) 'Unchanged planned file was not deleted and accounted for.'
|
|
|
|
$plan=New-TestCleanupPlan
|
|
[IO.File]::SetLastWriteTimeUtc($file,[DateTime]::UtcNow.AddDays(-20))
|
|
$result=Invoke-WindCleanup -Plan $plan -ReportPath $report -Confirm:$false
|
|
Assert-Cleanup ($result.Skipped-eq1-and$result.Deleted-eq0-and(Test-Path -LiteralPath $file)) 'File changed after planning was deleted because it was still older than the cutoff.'
|
|
|
|
$plan=New-TestCleanupPlan;$originalWrite=[IO.File]::GetLastWriteTimeUtc($file)
|
|
[IO.File]::WriteAllText($file,'different size');[IO.File]::SetLastWriteTimeUtc($file,$originalWrite)
|
|
$result=Invoke-WindCleanup -Plan $plan -ReportPath $report -Confirm:$false
|
|
Assert-Cleanup ($result.Skipped-eq1-and(Test-Path -LiteralPath $file)) 'Changed file size was ignored when the timestamp was preserved.'
|
|
|
|
$plan=New-TestCleanupPlan;$handle=[IO.File]::Open($file,[IO.FileMode]::Open,[IO.FileAccess]::ReadWrite,[IO.FileShare]::None)
|
|
try{$result=Invoke-WindCleanup -Plan $plan -ReportPath $report -Confirm:$false}finally{$handle.Dispose()}
|
|
Assert-Cleanup ($result.Skipped-eq1-and$result.Deleted-eq0-and(Test-Path -LiteralPath $file)) 'Locked file was not recorded as skipped.'
|
|
|
|
$plan=New-TestCleanupPlan;$plan.Files[0].LastWriteUtc='invalid'
|
|
$result=Invoke-WindCleanup -Plan $plan -ReportPath $report -Confirm:$false
|
|
Assert-Cleanup ($result.Skipped-eq1-and(Test-Path -LiteralPath $file)) 'Invalid planned timestamp did not preserve the file.'
|
|
|
|
# Exercise the real entry script with mock dependencies; never read or clear the real clipboard.
|
|
$wrapper=Join-Path $scratch 'wrapper';$src=Join-Path $wrapper 'src';[IO.Directory]::CreateDirectory($src)|Out-Null
|
|
Copy-Item -LiteralPath (Join-Path $root 'Cleanup.ps1') -Destination $wrapper
|
|
[IO.File]::WriteAllText((Join-Path $src 'Wind.Core.psm1'),'function Assert-WindMutationAllowed {}')
|
|
$mock=@'
|
|
function Get-WindCleanupPlan { [pscustomobject]@{Files=@()} }
|
|
function Invoke-WindCleanup { throw 'Unexpected cleanup mutation during WhatIf.' }
|
|
function Clear-WindCurrentClipboard { throw 'Unexpected clipboard mutation during WhatIf.' }
|
|
'@
|
|
[IO.File]::WriteAllText((Join-Path $src 'Wind.Cleanup.psm1'),$mock)
|
|
& (Join-Path $wrapper 'Cleanup.ps1') -Mode Run -ClearClipboard -WhatIf
|
|
Assert-Cleanup $true 'Cleanup entry script WhatIf did not return before mutations.'
|
|
}finally{
|
|
Remove-Module $module -ErrorAction SilentlyContinue
|
|
$resolved=[IO.Path]::GetFullPath($scratch)
|
|
$temp=[IO.Path]::GetFullPath([IO.Path]::GetTempPath()).TrimEnd('\')+'\'
|
|
if(-not$resolved.StartsWith($temp,[StringComparison]::OrdinalIgnoreCase)){throw 'Unsafe test cleanup directory.'}
|
|
if([IO.Directory]::Exists($resolved)){[IO.Directory]::Delete($resolved,$true)}
|
|
}
|
|
Write-Output "$script:passed cleanup tests passed. Only disposable files and a mocked clipboard were used."
|