Update configs.Tests.ps1

This commit is contained in:
Chris Titus 2024-08-28 16:40:38 -05:00
parent bf56639572
commit 44521776ba

View File

@ -3,114 +3,129 @@ $VerbosePreference = "Continue"
# Import Config Files
$global:importedConfigs = @{}
$configFiles = Get-ChildItem .\config -Filter *.json -ErrorAction SilentlyContinue
if ($configFiles) {
foreach ($file in $configFiles) {
try {
$global:importedConfigs[$file.BaseName] = Get-Content $file.FullName | ConvertFrom-Json
Write-Verbose "Successfully imported config file: $($file.FullName)"
} catch {
Write-Error "Failed to import config file: $($file.FullName). Error: $_"
}
Get-ChildItem .\config -Filter *.json | ForEach-Object {
try {
$global:importedConfigs[$_.BaseName] = Get-Content $_.FullName | ConvertFrom-Json
Write-Verbose "Successfully imported config file: $($_.FullName)"
} catch {
Write-Error "Failed to import config file: $($_.FullName). Error: $_"
}
} else {
Write-Warning "No config files found in the .\config directory"
}
Describe "Config Files Validation" {
$configSchemas = @{
applications = @{
Type = "Object"
Properties = @{
winget = @{ Type = "String" }
choco = @{ Type = "String" }
category = @{ Type = "String" }
content = @{ Type = "String" }
description = @{ Type = "String" }
link = @{ Type = "String" }
BeforeAll {
$script:configSchemas = @{
applications = @{
Type = "Object"
Properties = @{
winget = @{ Type = "String" }
choco = @{ Type = "String" }
category = @{ Type = "String" }
content = @{ Type = "String" }
description = @{ Type = "String" }
link = @{ Type = "String" }
}
Required = @("winget", "choco", "category", "content", "description", "link")
}
tweaks = @{
Type = "Object"
Properties = @{
registry = @{
Type = "Object"
Properties = @{
Path = @{ Type = "String" }
Name = @{ Type = "String" }
Type = @{ Type = "String" }
Value = @{ Type = "String" }
OriginalValue = @{ Type = "String" }
}
Required = @("Path", "Name", "Type", "Value", "OriginalValue")
}
service = @{
Type = "Object"
Properties = @{
Name = @{ Type = "String" }
StartupType = @{ Type = "String" }
OriginalType = @{ Type = "String" }
}
Required = @("Name", "StartupType", "OriginalType")
}
ScheduledTask = @{
Type = "Object"
Properties = @{
Name = @{ Type = "String" }
State = @{ Type = "String" }
OriginalState = @{ Type = "String" }
}
Required = @("Name", "State", "OriginalState")
}
}
}
Required = @("winget", "choco", "category", "content", "description", "link")
}
tweaks = @{
Type = "Object"
Properties = @{
registry = @{
Type = "Object"
Properties = @{
Path = @{ Type = "String" }
Name = @{ Type = "String" }
Type = @{ Type = "String" }
Value = @{ Type = "String" }
OriginalValue = @{ Type = "String" }
}
Required = @("Path", "Name", "Type", "Value", "OriginalValue")
function Test-Schema {
param (
$Object,
$Schema
)
$errors = @()
$Object.PSObject.Properties | ForEach-Object {
$propName = $_.Name
$propValue = $_.Value
$propSchema = $Schema.Properties[$propName]
if (-not $propSchema) {
$errors += "Property '$propName' is not defined in the schema"
return
}
service = @{
Type = "Object"
Properties = @{
Name = @{ Type = "String" }
StartupType = @{ Type = "String" }
OriginalType = @{ Type = "String" }
switch ($propSchema.Type) {
"String" {
if ($propValue -isnot [string]) {
$errors += "Property '$propName' should be a string but is $($propValue.GetType())"
}
}
Required = @("Name", "StartupType", "OriginalType")
}
ScheduledTask = @{
Type = "Object"
Properties = @{
Name = @{ Type = "String" }
State = @{ Type = "String" }
OriginalState = @{ Type = "String" }
"Object" {
if ($propValue -isnot [PSCustomObject]) {
$errors += "Property '$propName' should be an object but is $($propValue.GetType())"
} else {
$errors += Test-Schema -Object $propValue -Schema $propSchema
}
}
Required = @("Name", "State", "OriginalState")
}
}
foreach ($requiredProp in $Schema.Required) {
if (-not $Object.PSObject.Properties.Name.Contains($requiredProp)) {
$errors += "Required property '$requiredProp' is missing"
}
}
return $errors
}
}
Context "Config File Structure" {
It "Should import all config files without errors" {
$global:importedConfigs | Should -Not -BeNullOrEmpty -Because "No config files were imported successfully"
Write-Verbose "Imported configs: $($global:importedConfigs.Keys -join ', ')"
}
foreach ($configName in $configSchemas.Keys) {
It "Should have the correct structure for $configName" {
$global:importedConfigs | Should -Not -BeNullOrEmpty
$global:importedConfigs.ContainsKey($configName) | Should -BeTrue -Because "Config file '$configName' is missing"
$config = $global:importedConfigs[$configName]
$config | Should -Not -BeNullOrEmpty -Because "Config file '$configName' is empty"
$schema = $configSchemas[$configName]
It "Should have the correct structure for all configs" {
$results = $configSchemas.Keys | ForEach-Object -Parallel {
$configName = $_
$config = $using:global:importedConfigs[$configName]
$schema = $using:configSchemas[$configName]
function Test-Schema {
param (
$Object,
$Schema
)
$Object.PSObject.Properties | ForEach-Object {
$propName = $_.Name
$propValue = $_.Value
$propSchema = $Schema.Properties[$propName]
$propSchema | Should -Not -BeNullOrEmpty -Because "Property '$propName' is not defined in the schema"
switch ($propSchema.Type) {
"String" { $propValue | Should -BeOfType [string] }
"Object" {
$propValue | Should -BeOfType [PSCustomObject]
Test-Schema -Object $propValue -Schema $propSchema
}
}
}
foreach ($requiredProp in $Schema.Required) {
$Object.PSObject.Properties.Name | Should -Contain $requiredProp -Because "Required property '$requiredProp' is missing"
}
if (-not $config) {
return "Config file '$configName' is missing or empty"
}
Test-Schema -Object $config -Schema $schema
}
& $using:Test-Schema -Object $config -Schema $schema
} -ThrottleLimit 4
$results | Should -BeNullOrEmpty -Because "The following schema violations were found: $($results -join '; ')"
}
}
}