tests/DeviceCleanup.Tests.ps1

Import-Module Pester -MinimumVersion 5.0 -ErrorAction Stop
Import-Module "$PSScriptRoot/../DeviceCleanup.psd1" -Force

Describe 'DeviceCleanup module' {
    Context 'Get-StaleIntuneDevice' {
        It 'returns devices older than cutoff and in Autopilot' {
            # Mocks for Graph
            Mock -CommandName Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -ModuleName 'DeviceCleanup' -MockWith {
                @(
                    [pscustomobject]@{ SerialNumber='ABC123'; ManagedDeviceId='x-keep' }
                    [pscustomobject]@{ SerialNumber='DEF456'; ManagedDeviceId=$null }
                )
            }
            Mock -CommandName Get-MgDeviceManagementManagedDevice -ModuleName 'DeviceCleanup' -MockWith {
                @(
                    [pscustomobject]@{ Id='x-keep'; SerialNumber='ABC123'; DeviceName='KeepPC'; LastSyncDateTime = (Get-Date) } # fresh
                    [pscustomobject]@{ Id='y-stale'; SerialNumber='DEF456'; DeviceName='StalePC'; LastSyncDateTime = (Get-Date).AddDays(-120) } # stale
                )
            }

            $result = Get-StaleIntuneDevice -InactiveDays 30
            $names = $result.DeviceName
            $names | Should -Contain 'StalePC'
            $names | Should -Not -Contain 'KeepPC'

            Assert-MockCalled -CommandName Get-MgDeviceManagementWindowsAutopilotDeviceIdentity -ModuleName 'DeviceCleanup' -Times 1
            Assert-MockCalled -CommandName Get-MgDeviceManagementManagedDevice -ModuleName 'DeviceCleanup' -Times 1
        }
    }

    Context 'Remove-IntuneDevice WhatIf' {
        It 'does not call Remove-MgDeviceManagementManagedDevice when WhatIf' {
            Mock -CommandName Remove-MgDeviceManagementManagedDevice -ModuleName 'DeviceCleanup'
            $md = [pscustomobject]@{ Id='y-stale'; DeviceName='StalePC' }
            { $md | Remove-IntuneDevice -WhatIf } | Should -Not -Throw
            Assert-MockCalled -CommandName Remove-MgDeviceManagementManagedDevice -ModuleName 'DeviceCleanup' -Times 0
        }
    }

    Context 'Remove-EntraDevice resolves from managed devices' {
        It 'resolves and attempts removal (suppressed by WhatIf)' {
            Mock -CommandName Get-MgDevice -ModuleName 'DeviceCleanup' -MockWith {
                @(
                    [pscustomobject]@{ Id='guid-1'; DeviceId='AADA-1'; DisplayName='PC1' },
                    [pscustomobject]@{ Id='guid-2'; DeviceId='AADA-2'; DisplayName='PC2' }
                )
            }
            Mock -CommandName Remove-MgDevice -ModuleName 'DeviceCleanup'

            $md = @(
                [pscustomobject]@{ AzureAdDeviceId='AADA-2' }
            )
            { Remove-EntraDevice -FromManagedDevice $md -WhatIf } | Should -Not -Throw
            Assert-MockCalled -CommandName Remove-MgDevice -ModuleName 'DeviceCleanup' -Times 0
        }
    }

    Context 'Remove-AdComputer targeting' {
        It 'builds search bases and filters by name (WhatIf)' -Skip:(!(Get-Module -ListAvailable ActiveDirectory)) {
            Mock -CommandName Get-ADComputer -ModuleName 'DeviceCleanup' -MockWith {
                @(
                    [pscustomobject]@{ Name='StalePC'; DistinguishedName='CN=StalePC,OU=Clients,OU=Computers,DC=contoso,DC=com' },
                    [pscustomobject]@{ Name='KeepPC'; DistinguishedName='CN=KeepPC,OU=Clients,OU=Computers,DC=contoso,DC=com' }
                )
            }
            Mock -CommandName Microsoft.ActiveDirectory.Management.Commands.RemoveADComputer -ModuleName 'DeviceCleanup'

            { Remove-AdComputer -ComputerNames 'StalePC' -AdBaseDn 'DC=contoso,DC=com' -AdOuNames 'Clients' -WhatIf } | Should -Not -Throw
            Assert-MockCalled -CommandName Microsoft.ActiveDirectory.Management.Commands.RemoveADComputer -ModuleName 'DeviceCleanup' -Times 0
        }
    }
}