diff --git a/windows/collector/Test-SmInput.ps1 b/windows/collector/Test-SmInput.ps1 new file mode 100644 index 0000000..a464f25 --- /dev/null +++ b/windows/collector/Test-SmInput.ps1 @@ -0,0 +1,36 @@ +#Requires -Version 5.1 +# Pure validation helpers for the WinPE collector. No WinForms dependency so they +# are unit-testable headless. Each returns [pscustomobject]@{ Ok=[bool]; Message=[string] }. + +function New-SmResult([bool]$ok, [string]$msg = '') { [pscustomobject]@{ Ok = $ok; Message = $msg } } + +$script:SmReserved = @('administrator','guest','system','defaultaccount','wdagutilityaccount','sm-bootstrap') + +function Test-SmUsername([string]$name) { + if ([string]::IsNullOrWhiteSpace($name)) { return New-SmResult $false 'Username is required.' } + if ($name.Length -gt 20) { return New-SmResult $false 'Username must be 20 characters or fewer.' } + if ($script:SmReserved -contains $name.ToLower()) { return New-SmResult $false 'That username is reserved.' } + if ($name -notmatch '^[A-Za-z0-9][A-Za-z0-9 ._-]*$') { return New-SmResult $false 'Username has illegal characters.' } + New-SmResult $true +} + +function Test-SmPassword([string]$pw, [string]$confirm) { + if ([string]::IsNullOrEmpty($pw)) { return New-SmResult $false 'Password is required.' } + if ($pw.Length -lt 8) { return New-SmResult $false 'Password must be at least 8 characters.' } + if ($pw -ne $confirm) { return New-SmResult $false 'Passwords do not match.' } + New-SmResult $true +} + +function Test-SmPin([string]$pin, [string]$confirm) { + if ($pin -notmatch '^[0-9]+$') { return New-SmResult $false 'PIN must be numeric.' } + if ($pin.Length -lt 6) { return New-SmResult $false 'PIN must be at least 6 digits.' } + if ($pin -ne $confirm) { return New-SmResult $false 'PINs do not match.' } + New-SmResult $true +} + +function Test-SmComputerName([string]$name) { + if ([string]::IsNullOrWhiteSpace($name)) { return New-SmResult $false 'Computer name is required.' } + if ($name.Length -gt 15) { return New-SmResult $false 'Computer name must be 15 characters or fewer.' } + if ($name -notmatch '^[A-Za-z0-9-]+$') { return New-SmResult $false 'Computer name: letters, digits, hyphens only.' } + New-SmResult $true +} diff --git a/windows/tests/Collector.Tests.ps1 b/windows/tests/Collector.Tests.ps1 new file mode 100644 index 0000000..8a84196 --- /dev/null +++ b/windows/tests/Collector.Tests.ps1 @@ -0,0 +1,32 @@ +#Requires -Version 5.1 +BeforeAll { + . (Join-Path $PSScriptRoot '..\collector\Test-SmInput.ps1') +} + +Describe 'Test-SmUsername' { + It 'accepts a simple username' { (Test-SmUsername 'jamie').Ok | Should -BeTrue } + It 'rejects empty' { (Test-SmUsername '').Ok | Should -BeFalse } + It 'rejects reserved name' { (Test-SmUsername 'Administrator').Ok | Should -BeFalse } + It 'rejects illegal chars' { (Test-SmUsername 'a\b').Ok | Should -BeFalse } + It 'rejects > 20 chars' { (Test-SmUsername ('x'*21)).Ok| Should -BeFalse } +} + +Describe 'Test-SmPassword' { + It 'accepts matching 8+ char password' { (Test-SmPassword 'Sup3rPass!' 'Sup3rPass!').Ok | Should -BeTrue } + It 'rejects mismatch' { (Test-SmPassword 'a' 'b').Ok | Should -BeFalse } + It 'rejects < 8 chars' { (Test-SmPassword 'short' 'short').Ok | Should -BeFalse } +} + +Describe 'Test-SmPin' { + It 'accepts 6-digit matching pin' { (Test-SmPin '246810' '246810').Ok | Should -BeTrue } + It 'rejects < 6 digits' { (Test-SmPin '123' '123').Ok | Should -BeFalse } + It 'rejects non-numeric' { (Test-SmPin 'abcdef' 'abcdef').Ok | Should -BeFalse } + It 'rejects mismatch' { (Test-SmPin '246810' '999999').Ok | Should -BeFalse } +} + +Describe 'Test-SmComputerName' { + It 'accepts a valid name' { (Test-SmComputerName 'SILVER-01').Ok | Should -BeTrue } + It 'rejects empty' { (Test-SmComputerName '').Ok | Should -BeFalse } + It 'rejects > 15 chars' { (Test-SmComputerName ('A'*16)).Ok | Should -BeFalse } + It 'rejects illegal chars' { (Test-SmComputerName 'bad name').Ok | Should -BeFalse } +}