tests/Search-GPO.Tests.ps1

BeforeAll {
    . (Join-Path $PSScriptRoot '..\Public\Search-GPO.ps1')
    $script:OriginalUserDnsDomain = $env:USERDNSDOMAIN
    $env:USERDNSDOMAIN = 'example.test'
}

AfterAll {
    $env:USERDNSDOMAIN = $script:OriginalUserDnsDomain
}

Describe 'Search-GPO' {
    BeforeEach {
        $script:TestGpo = [pscustomobject]@{
            DisplayName      = 'Test GPO'
            Id               = [guid]'11111111-1111-1111-1111-111111111111'
            ModificationTime = [datetime]'2026-01-01T00:00:00Z'
        }

        Mock Import-Module {}
        Mock Get-GPO { @($script:TestGpo) }
        Mock Test-Path { $false }
        Mock Get-GPOReport {
            '<GPO><Name>Literal * Match</Name><LinksTo><SOMPath>example.test/Workstations</SOMPath><Enabled>true</Enabled></LinksTo></GPO>'
        }
    }

    It 'treats wildcard characters in SearchTerm as literal text' {
        $results = @(Search-GPO -SearchTerm '*')

        $results | Should -HaveCount 1
        $results[0].Source | Should -Be 'GPO Settings'
        $results[0].MatchDetails | Should -BeLike 'XML Snippet: *Literal * Match*'
        $results[0].PSObject.TypeNames | Should -Contain 'SearchGPO.Result'
    }

    It 'returns objects with the detail view type when ShowDetails is specified' {
        $results = @(Search-GPO -SearchTerm 'Literal' -ShowDetails)

        $results | Should -HaveCount 1
        $results[0].PSObject.TypeNames | Should -Contain 'SearchGPO.Result.Detail'
        $results[0].PSObject.Properties.Name | Should -Contain 'ScanFailures'
    }

    It 'records metadata failures and continues the scan' {
        Mock Get-GPOReport { throw 'Access denied' }
        $warnings = @()

        $results = @(Search-GPO -SearchTerm 'Literal' -WarningVariable +warnings)

        $results | Should -BeNullOrEmpty
        ($warnings -join "`n") | Should -Match 'could not read metadata'
        ($warnings -join "`n") | Should -Match 'completed with 1 failed scan step'
    }

    It 'captures matching SYSVOL script evidence' {
        $scriptFile = Join-Path $TestDrive 'startup.ps1'
        Set-Content -LiteralPath $scriptFile -Value 'Write-Output "literal * script marker"'
        Mock Get-GPOReport {
            '<GPO><Name>Unrelated</Name><LinksTo><SOMPath>example.test/Workstations</SOMPath><Enabled>true</Enabled></LinksTo></GPO>'
        }
        Mock Test-Path {
            param($LiteralPath)
            $LiteralPath -match 'Machine\\Scripts\\Startup$'
        }
        Mock Get-ChildItem { Get-Item -LiteralPath $scriptFile }

        $results = @(Search-GPO -SearchTerm 'literal * script marker')

        $results | Should -HaveCount 1
        $results[0].Source | Should -Be 'Script Code'
        $results[0].MatchDetails | Should -Match 'startup.ps1'
    }
}

Describe 'Module manifest' {
    It 'declares its Windows and GroupPolicy runtime requirements' {
        $manifest = Test-ModuleManifest -Path (Join-Path $PSScriptRoot '..\Search-GPO.psd1')

        $manifest.RequiredModules.Name | Should -Contain 'GroupPolicy'
        $manifest.CompatiblePSEditions | Should -Be @('Desktop')
        ($manifest.ExportedFormatFiles | Split-Path -Leaf) | Should -Contain 'Search-GPO.format.ps1xml'
    }
}