Tests/AD-LinuxInventory.Tests.ps1
|
BeforeAll { $modulePath = Split-Path -Parent $PSScriptRoot Import-Module "$modulePath\AD-LinuxInventory.psd1" -Force } Describe 'AD-LinuxInventory Module' { Context 'Module Loading' { It 'Should import without errors' { { Import-Module "$PSScriptRoot\..\AD-LinuxInventory.psd1" -Force } | Should -Not -Throw } It 'Should export exactly 5 public functions' { $commands = Get-Command -Module AD-LinuxInventory $commands.Count | Should -Be 5 } It 'Should export all expected functions' { $expected = @('Register-LinuxServer', 'Import-LinuxInventory', 'Get-LinuxInventory', 'Update-LinuxServer', 'Sync-LinuxInventory') foreach ($func in $expected) { Get-Command -Module AD-LinuxInventory -Name $func | Should -Not -BeNullOrEmpty } } It 'Should not export private functions' { { Get-Command -Module AD-LinuxInventory -Name Initialize-LinuxOU -ErrorAction Stop } | Should -Throw { Get-Command -Module AD-LinuxInventory -Name New-HtmlDashboard -ErrorAction Stop } | Should -Throw } } Context 'Register-LinuxServer Parameter Validation' { It 'Should have mandatory Name parameter' { (Get-Command Register-LinuxServer).Parameters['Name'].Attributes.Mandatory | Should -Contain $true } It 'Should have mandatory IPAddress parameter' { (Get-Command Register-LinuxServer).Parameters['IPAddress'].Attributes.Mandatory | Should -Contain $true } It 'Should default OperatingSystem to Linux' { $default = (Get-Command Register-LinuxServer).Parameters['OperatingSystem'].Attributes | Where-Object { $_ -is [System.Management.Automation.PSDefaultValueAttribute] -or $_.TypeId.Name -eq 'ParameterAttribute' } # The default is set in code, not via attribute -- verify the param exists (Get-Command Register-LinuxServer).Parameters.ContainsKey('OperatingSystem') | Should -BeTrue } It 'Should support -WhatIf' { (Get-Command Register-LinuxServer).Parameters.ContainsKey('WhatIf') | Should -BeTrue } It 'Should support -Confirm' { (Get-Command Register-LinuxServer).Parameters.ContainsKey('Confirm') | Should -BeTrue } It 'Should have Force switch' { (Get-Command Register-LinuxServer).Parameters['Force'].SwitchParameter | Should -BeTrue } It 'Should validate IPAddress format' { $validatePattern = (Get-Command Register-LinuxServer).Parameters['IPAddress'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidatePatternAttribute] } $validatePattern | Should -Not -BeNullOrEmpty } } Context 'Import-LinuxInventory Parameter Validation' { It 'Should have mandatory CsvPath parameter' { (Get-Command Import-LinuxInventory).Parameters['CsvPath'].Attributes.Mandatory | Should -Contain $true } It 'Should validate CsvPath with ValidateScript' { $validateScript = (Get-Command Import-LinuxInventory).Parameters['CsvPath'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidateScriptAttribute] } $validateScript | Should -Not -BeNullOrEmpty } It 'Should have Force switch' { (Get-Command Import-LinuxInventory).Parameters['Force'].SwitchParameter | Should -BeTrue } } Context 'Get-LinuxInventory Parameter Validation' { It 'Should have Online switch' { (Get-Command Get-LinuxInventory).Parameters['Online'].SwitchParameter | Should -BeTrue } It 'Should accept OutputPath parameter' { (Get-Command Get-LinuxInventory).Parameters.ContainsKey('OutputPath') | Should -BeTrue } It 'Should accept OrganizationalUnit parameter' { (Get-Command Get-LinuxInventory).Parameters.ContainsKey('OrganizationalUnit') | Should -BeTrue } } Context 'Update-LinuxServer Parameter Validation' { It 'Should have mandatory Name parameter' { (Get-Command Update-LinuxServer).Parameters['Name'].Attributes.Mandatory | Should -Contain $true } It 'Should accept pipeline input for Name' { (Get-Command Update-LinuxServer).Parameters['Name'].Attributes.ValueFromPipeline | Should -Contain $true } It 'Should support -WhatIf' { (Get-Command Update-LinuxServer).Parameters.ContainsKey('WhatIf') | Should -BeTrue } It 'Should validate IPAddress format' { $validatePattern = (Get-Command Update-LinuxServer).Parameters['IPAddress'].Attributes | Where-Object { $_ -is [System.Management.Automation.ValidatePatternAttribute] } $validatePattern | Should -Not -BeNullOrEmpty } } Context 'Sync-LinuxInventory Parameter Validation' { It 'Should have UpdateDescription switch' { (Get-Command Sync-LinuxInventory).Parameters['UpdateDescription'].SwitchParameter | Should -BeTrue } It 'Should have TimeoutMs parameter with default 1000' { (Get-Command Sync-LinuxInventory).Parameters.ContainsKey('TimeoutMs') | Should -BeTrue } It 'Should accept OrganizationalUnit parameter' { (Get-Command Sync-LinuxInventory).Parameters.ContainsKey('OrganizationalUnit') | Should -BeTrue } } Context 'Register-LinuxServer Mocked Execution' { BeforeAll { Mock -ModuleName AD-LinuxInventory Import-Module { } Mock -ModuleName AD-LinuxInventory Get-ADDomain { [PSCustomObject]@{ DistinguishedName = 'DC=contoso,DC=com' DNSRoot = 'contoso.com' } } Mock -ModuleName AD-LinuxInventory Get-ADOrganizationalUnit { $true } Mock -ModuleName AD-LinuxInventory New-ADOrganizationalUnit { } Mock -ModuleName AD-LinuxInventory Get-ADComputer { throw [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]::new('Not found') } Mock -ModuleName AD-LinuxInventory New-ADComputer { } Mock -ModuleName AD-LinuxInventory Set-ADComputer { } Mock -ModuleName AD-LinuxInventory Remove-ADComputer { } } It 'Should call New-ADComputer with correct name' { Register-LinuxServer -Name 'test-srv-01' -IPAddress '10.0.0.1' -OperatingSystem 'Ubuntu 22.04' Should -Invoke -ModuleName AD-LinuxInventory -CommandName New-ADComputer -Times 1 -ParameterFilter { $Name -eq 'TEST-SRV-01' } } It 'Should call Set-ADComputer to set OS and IP properties' { Register-LinuxServer -Name 'test-srv-02' -IPAddress '10.0.0.2' -OperatingSystem 'RHEL 9' Should -Invoke -ModuleName AD-LinuxInventory -CommandName Set-ADComputer -Times 1 } It 'Should return an object with Registered status' { $result = Register-LinuxServer -Name 'test-srv-03' -IPAddress '10.0.0.3' $result.Status | Should -Be 'Registered' $result.Name | Should -Be 'TEST-SRV-03' $result.IPv4Address | Should -Be '10.0.0.3' } It 'Should set ManagedBy when specified' { Register-LinuxServer -Name 'test-srv-04' -IPAddress '10.0.0.4' -ManagedBy 'jsmith' Should -Invoke -ModuleName AD-LinuxInventory -CommandName Set-ADComputer -Times 1 -ParameterFilter { $ManagedBy -eq 'jsmith' } } } Context 'Get-LinuxInventory Mocked Execution' { BeforeAll { Mock -ModuleName AD-LinuxInventory Import-Module { } Mock -ModuleName AD-LinuxInventory Get-ADDomain { [PSCustomObject]@{ DistinguishedName = 'DC=contoso,DC=com' DNSRoot = 'contoso.com' } } Mock -ModuleName AD-LinuxInventory Get-ADOrganizationalUnit { $true } Mock -ModuleName AD-LinuxInventory Get-ADComputer { @( [PSCustomObject]@{ Name = 'WEB-PROD-01' DNSHostName = 'web-prod-01.contoso.com' IPv4Address = '10.1.2.50' OperatingSystem = 'Ubuntu 22.04 LTS' OperatingSystemVersion = '22.04' Description = 'Production web server' ManagedBy = 'CN=John Smith,OU=Users,DC=contoso,DC=com' Created = (Get-Date).AddMonths(-6) Modified = (Get-Date).AddDays(-1) Enabled = $true }, [PSCustomObject]@{ Name = 'DB-PROD-01' DNSHostName = 'db-prod-01.contoso.com' IPv4Address = '10.1.3.10' OperatingSystem = 'RHEL 9' OperatingSystemVersion = '9.3' Description = 'Production database' ManagedBy = $null Created = (Get-Date).AddMonths(-3) Modified = (Get-Date).AddDays(-7) Enabled = $true } ) } } It 'Should return all servers from the OU' { $results = Get-LinuxInventory @($results).Count | Should -Be 2 } It 'Should include expected properties on output objects' { $results = Get-LinuxInventory $first = $results[0] $first.Name | Should -Be 'WEB-PROD-01' $first.IPv4Address | Should -Be '10.1.2.50' $first.OperatingSystem | Should -Be 'Ubuntu 22.04 LTS' $first.Description | Should -Be 'Production web server' } It 'Should have Online property as null when -Online is not specified' { $results = Get-LinuxInventory $results[0].Online | Should -BeNullOrEmpty } } Context 'Sync-LinuxInventory Mocked Execution' { BeforeAll { Mock -ModuleName AD-LinuxInventory Import-Module { } Mock -ModuleName AD-LinuxInventory Get-ADDomain { [PSCustomObject]@{ DistinguishedName = 'DC=contoso,DC=com' DNSRoot = 'contoso.com' } } Mock -ModuleName AD-LinuxInventory Get-ADOrganizationalUnit { $true } Mock -ModuleName AD-LinuxInventory Set-ADComputer { } Mock -ModuleName AD-LinuxInventory Get-ADComputer { @( [PSCustomObject]@{ Name = 'WEB-PROD-01' DNSHostName = 'web-prod-01.contoso.com' IPv4Address = '10.1.2.50' Description = 'Production web server' OperatingSystem = 'Ubuntu 22.04 LTS' }, [PSCustomObject]@{ Name = 'DB-OFFLINE-01' DNSHostName = 'db-offline-01.contoso.com' IPv4Address = '10.1.3.99' Description = 'Decommissioned DB' OperatingSystem = 'CentOS 7' } ) } Mock -ModuleName AD-LinuxInventory Test-Connection { param($ComputerName) if ($ComputerName -eq '10.1.2.50') { [PSCustomObject]@{ ResponseTime = 2 } } else { $null } } } It 'Should return results for all servers' { $results = Sync-LinuxInventory @($results).Count | Should -Be 2 } It 'Should detect online server correctly' { $results = Sync-LinuxInventory $online = $results | Where-Object { $_.Name -eq 'WEB-PROD-01' } $online.Online | Should -BeTrue } It 'Should detect offline server correctly' { $results = Sync-LinuxInventory $offline = $results | Where-Object { $_.Name -eq 'DB-OFFLINE-01' } $offline.Online | Should -BeFalse } It 'Should include IPAddress in results' { $results = Sync-LinuxInventory $results[0].IPAddress | Should -Be '10.1.2.50' } } Context 'Manifest Validation' { BeforeAll { $manifest = Test-ModuleManifest -Path "$PSScriptRoot\..\AD-LinuxInventory.psd1" } It 'Should have version 1.0.0' { $manifest.Version.ToString() | Should -Be '1.0.0' } It 'Should have correct author' { $manifest.Author | Should -Be 'Larry Roberts' } It 'Should have correct GUID' { $manifest.GUID.ToString() | Should -Be 'd2e8f3a1-5b49-4c7d-ae12-9f3c6d8b7e45' } It 'Should have ProjectUri pointing to GitHub' { $manifest.PrivateData.PSData.ProjectUri | Should -Be 'https://github.com/larro1991/AD-LinuxInventory' } It 'Should have LicenseUri pointing to GitHub' { $manifest.PrivateData.PSData.LicenseUri | Should -Be 'https://github.com/larro1991/AD-LinuxInventory/blob/master/LICENSE' } It 'Should include expected tags' { $tags = $manifest.PrivateData.PSData.Tags $tags | Should -Contain 'ActiveDirectory' $tags | Should -Contain 'Linux' $tags | Should -Contain 'Inventory' $tags | Should -Contain 'CrossPlatform' $tags | Should -Contain 'ServerManagement' } It 'Should require PowerShell 5.1' { $manifest.PowerShellVersion.ToString() | Should -Be '5.1' } It 'Should export exactly 5 functions in manifest' { $manifest.ExportedFunctions.Count | Should -Be 5 } } } |