Tests/WinslopFix.Module.Tests.ps1

Describe 'WinslopFix Module' {

    BeforeAll {
        $modulePath = Join-Path (Join-Path $PSScriptRoot '..') 'WinslopFix.psd1'
        Import-Module $modulePath -Force -ErrorAction Stop
    }

    AfterAll {
        Remove-Module WinslopFix -Force -ErrorAction SilentlyContinue
    }

    Context 'Module Manifest' {

        BeforeAll {
            $manifestPath = Join-Path (Join-Path $PSScriptRoot '..') 'WinslopFix.psd1'
            $manifest = Test-ModuleManifest -Path $manifestPath -ErrorAction Stop
        }

        It 'has a valid module manifest' {
            $manifest | Should -Not -BeNullOrEmpty
        }

        It 'has a valid root module' {
            $manifest.RootModule | Should -Be 'WinslopFix.psm1'
        }

        It 'has a valid version' {
            $manifest.Version | Should -Not -BeNullOrEmpty
        }

        It 'has a valid GUID' {
            $manifest.Guid | Should -Not -BeNullOrEmpty
        }

        It 'has a valid description' {
            $manifest.Description | Should -Not -BeNullOrEmpty
            $manifest.Description.Length | Should -BeGreaterThan 20
        }

        It 'has an author' {
            $manifest.Author | Should -Not -BeNullOrEmpty
        }

        It 'targets PowerShell 5.1 or later' {
            $manifest.PowerShellVersion | Should -Be '5.1'
        }

        It 'supports Desktop and Core editions' {
            $manifest.CompatiblePSEditions | Should -Contain 'Desktop'
            $manifest.CompatiblePSEditions | Should -Contain 'Core'
        }

        It 'has a ProjectUri' {
            $manifest.PrivateData.PSData.ProjectUri | Should -Not -BeNullOrEmpty
        }

        It 'has a LicenseUri' {
            $manifest.PrivateData.PSData.LicenseUri | Should -Not -BeNullOrEmpty
        }

        It 'has tags for PSGallery discovery' {
            $manifest.PrivateData.PSData.Tags | Should -Not -BeNullOrEmpty
            $manifest.PrivateData.PSData.Tags.Count | Should -BeGreaterThan 3
        }
    }

    Context 'Exported Functions' {

        It 'exports exactly the expected functions' {
            $expectedFunctions = @(
                'Disable-CopilotAIFeature'
                'Enable-CopilotAIFeature'
                'Get-WinslopFixLog'
                'Get-WorkloadSessionStatus'
                'Install-WinslopFix'
                'Start-WinslopFix'
                'Stop-WorkloadSession'
                'Uninstall-WinslopFix'
            )

            $exported = (Get-Command -Module WinslopFix).Name | Sort-Object
            $exported | Should -Be $expectedFunctions
        }

        It 'does not export private functions' {
            $exported = (Get-Command -Module WinslopFix).Name
            $exported | Should -Not -Contain 'Assert-Administrator'
            $exported | Should -Not -Contain 'Get-WinslopFixConfig'
            $exported | Should -Not -Contain 'Write-WinslopFixLog'
            $exported | Should -Not -Contain 'Test-CopilotPlatform'
        }

        It 'exports <_>' -ForEach @(
            'Get-WorkloadSessionStatus'
            'Stop-WorkloadSession'
            'Start-WinslopFix'
            'Install-WinslopFix'
            'Uninstall-WinslopFix'
            'Get-WinslopFixLog'
            'Disable-CopilotAIFeature'
            'Enable-CopilotAIFeature'
        ) {
            Get-Command -Module WinslopFix -Name $_ -ErrorAction SilentlyContinue |
                Should -Not -BeNullOrEmpty
        }
    }

    Context 'Function Quality' {

        It '<_.BaseName> uses CmdletBinding' -ForEach (
            Get-ChildItem -Path (Join-Path (Join-Path $PSScriptRoot '..') 'Public') -Filter *.ps1
        ) {
            $ast = [System.Management.Automation.Language.Parser]::ParseFile(
                $_.FullName, [ref]$null, [ref]$null
            )
            $cmdletBinding = $ast.FindAll({
                $args[0] -is [System.Management.Automation.Language.AttributeAst] -and
                $args[0].TypeName.Name -eq 'CmdletBinding'
            }, $true)
            $cmdletBinding.Count | Should -BeGreaterThan 0
        }

        It '<_.BaseName> has comment-based help' -ForEach (
            Get-ChildItem -Path (Join-Path (Join-Path $PSScriptRoot '..') 'Public') -Filter *.ps1
        ) {
            $fileContent = Get-Content $_.FullName -Raw
            $fileContent | Should -Match '\.SYNOPSIS'
        }
    }
}