#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 # Replace only the catalog in this module instance: all deletions stay in this test's directory. & $module { param($TestRoot) $script:cleanupTestRoot=$TestRoot function script:Get-WindPrivacyCleanupCatalog { [pscustomobject]@{Category='Temp';Root=$script:cleanupTestRoot;Patterns=@('*');Recurse=$true} } } $files $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)) Get-WindCleanupPlan -AgeDays 7 -Category Temp } $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."