Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions .githooks/pre-commit.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,31 @@
$ErrorActionPreference = 'Stop'
$testScript = 'PowerShell/system-administration/maintenance/system-maintenance.ps1'
$testPath = 'tests/unit/PowerShell/system-maintenance.Tests.ps1'
$resultsPath = 'tests/results/system-maintenance.json'
$resultsPath = 'tests/results/system-maintenance.xml'

if (Test-Path $testPath) {
Write-Host "Running Pester tests for $testScript..."
Invoke-Pester -Script $testPath -OutputFormat NUnitXml -OutputFile $resultsPath

# Set SCRIPTS_ROOT environment variable for tests
$env:SCRIPTS_ROOT = (Get-Location).Path

# Use Pester v5 configuration syntax
$config = New-PesterConfiguration
$config.Run.Path = $testPath
$config.Run.PassThru = $true
$config.TestResult.Enabled = $true
$config.TestResult.OutputPath = $resultsPath
$config.TestResult.OutputFormat = 'JUnitXml'

$result = Invoke-Pester -Configuration $config

if ($result.FailedCount -gt 0) {
Write-Host "Tests failed. Aborting commit."
exit 1
}

if (Test-Path $resultsPath) {
git add $resultsPath
Write-Host "Test results saved and staged: $resultsPath"
Write-Host "Test results saved to: $resultsPath"
}
else {
Write-Host "Test results not found, aborting commit."
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ jobs:
id: check_results
shell: pwsh
run: |
$resultsPath = 'tests/results/system-maintenance.json'
$resultsPath = 'tests/results/system-maintenance.xml'
if (Test-Path $resultsPath) {
$fileAge = (Get-Date) - (Get-Item $resultsPath).LastWriteTime
if ($fileAge.TotalDays -lt 2) {
Write-Host "::set-output name=found::true"
echo "found=true" >> $env:GITHUB_OUTPUT
} else {
Write-Host "Test results are too old."
Write-Host "::set-output name=found::false"
echo "found=false" >> $env:GITHUB_OUTPUT
}
} else {
Write-Host "No local test results found."
Write-Host "::set-output name=found::false"
echo "found=false" >> $env:GITHUB_OUTPUT
}

- name: Use local test results if available
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

#Ignore vscode AI rules
.github\instructions\codacy.instructions.md

# Test results
tests/results/
36 changes: 16 additions & 20 deletions tests/unit/PowerShell/system-maintenance.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,26 @@ Describe "system-maintenance.ps1" {
}
$scriptPathCandidate = Join-Path $scriptsRoot "PowerShell/system-administration/maintenance/system-maintenance.ps1"
if (-not (Test-Path $scriptPathCandidate)) {
# Try absolute path as fallback
$scriptPathCandidate = "F:\April\Scripts\PowerShell\system-administration\maintenance\system-maintenance.ps1"
if (-not (Test-Path $scriptPathCandidate)) {
throw "Script not found at: $scriptPathCandidate"
}
throw "Script not found at: $scriptPathCandidate. Ensure SCRIPTS_ROOT is set correctly or run from repository root."
}
$script:scriptPath = Resolve-Path $scriptPathCandidate | Select-Object -ExpandProperty Path
}
Context "Basic Script Validation" {
It "should be a valid script file" {
Test-Path -Path $scriptPath | Should Be $true
Test-Path -Path $scriptPath | Should -Be $true
}

It "should have comment-based help" {
$help = Get-Help $scriptPath -ErrorAction SilentlyContinue
$notNull = $false
if ($help -and $help.Name -eq 'system-maintenance.ps1') { $notNull = $true }
$notNull | Should Be $true
$notNull | Should -Be $true
}

It "should support -WhatIf" {
# For scripts, -WhatIf is not a formal parameter, but script logic should handle it
$content = Get-Content -Path $scriptPath -Raw
($content -like '*WhatIf*') | Should Be $true
($content -like '*WhatIf*') | Should -Be $true
}
}

Expand All @@ -71,7 +67,7 @@ Describe "system-maintenance.ps1" {
$threw = $false
}
catch { $threw = $true }
$threw | Should Be $true
$threw | Should -Be $true
}

It "should reject MaxTempFileAgeDays above maximum (> 3650)" {
Expand All @@ -81,7 +77,7 @@ Describe "system-maintenance.ps1" {
$threw = $false
}
catch { $threw = $true }
$threw | Should Be $true
$threw | Should -Be $true
}

It "should reject non-numeric MaxTempFileAgeDays" {
Expand All @@ -91,7 +87,7 @@ Describe "system-maintenance.ps1" {
$threw = $false
}
catch { $threw = $true }
$threw | Should Be $true
$threw | Should -Be $true
}
}

Expand All @@ -100,7 +96,7 @@ Describe "system-maintenance.ps1" {
Context "Permissions and Prerequisites" {
It "should have #Requires -RunAsAdministrator directive" {
$content = Get-Content -Path $scriptPath -Raw
$content -match '#Requires\s+-RunAsAdministrator' | Should Be $true
$content -match '#Requires\s+-RunAsAdministrator' | Should -Be $true
}

# Note: Testing actual permission failures requires running in a non-admin context,
Expand All @@ -118,7 +114,7 @@ Describe "system-maintenance.ps1" {
foreach ($attr in $command.Parameters['MaxTempFileAgeDays'].Attributes) {
if ($attr -is [System.Management.Automation.ParameterAttribute]) { $count++ }
}
($count -gt 0) | Should Be $true
($count -gt 0) | Should -Be $true
}
}

Expand All @@ -128,38 +124,38 @@ Describe "system-maintenance.ps1" {
$cmdletBinding = $command.ScriptBlock.Attributes | Where-Object { $_ -is [System.Management.Automation.CmdletBindingAttribute] }
$hasImpact = $false
if ($cmdletBinding -and $cmdletBinding.ConfirmImpact) { $hasImpact = $true }
$hasImpact | Should Be $true
$hasImpact | Should -Be $true
}
}

Context "Logging and Output" {
It "should create log file path using Get-LogFilePath function" {
$content = Get-Content -Path $scriptPath -Raw
($content -like '*function Get-LogFilePath*') | Should Be $true
($content -like '*function Get-LogFilePath*') | Should -Be $true
}

It "should handle environment where MyDocuments is not available" {
$content = Get-Content -Path $scriptPath -Raw
($content -like '*IsNullOrWhiteSpace*userDocs*') | Should Be $true
($content -like '*GetTempPath*') | Should Be $true
($content -like '*IsNullOrWhiteSpace*userDocs*') | Should -Be $true
($content -like '*GetTempPath*') | Should -Be $true
}
}

Context "Error Handling" {
It "should use StrictMode" {
$content = Get-Content -Path $scriptPath -Raw
($content -like '*Set-StrictMode*Latest*') | Should Be $true
($content -like '*Set-StrictMode*Latest*') | Should -Be $true
}

It "should set ErrorActionPreference appropriately" {
$content = Get-Content -Path $scriptPath -Raw
($content -like '*$ErrorActionPreference*Stop*') | Should Be $true
($content -like '*$ErrorActionPreference*Stop*') | Should -Be $true
}

It "should include try-catch blocks for error handling" {
$content = Get-Content -Path $scriptPath -Raw
$tryCount = ($content -split 'try\s*\{').Count
($tryCount -gt 5) | Should Be $true
($tryCount -gt 5) | Should -Be $true
}
}
}
Loading