tests/Get-MsecIntuneReusableSetting.Tests.ps1

#Requires -Module Pester
#
# Tests for Get-MsecIntuneReusableSetting.
#
# Each covers something found against a live tenant:
# - referencingConfigurationPolicyCount and settingInstance are ABSENT from the response
# unless explicitly $select'd. Not null - absent. Without the select every setting reads
# as unreferenced and empty, which could get an in-use allow-list deleted.
# - A missing count must be $null, never 0: unknown and orphaned are different, and only
# one of them justifies deletion.
# - Entries are nested at varying depths, so the walker must not assume a fixed shape.

BeforeAll {
    Import-Module (Join-Path $PSScriptRoot '..' 'Msec.psm1') -Force -ErrorAction Stop
}
AfterAll { Remove-Module Msec -Force -ErrorAction SilentlyContinue }

Describe 'Get-MsecIntuneReusableSetting' {
    BeforeEach {
        InModuleScope Msec { Mock Assert-MsecSession -MockWith { } }
    }

    It 'asks for the reference count and contents explicitly, because they are absent otherwise' {
        $path = InModuleScope Msec {
            $script:asked = $null
            Mock Invoke-MsecGraphRequest -MockWith { $script:asked = $Path; @() }
            Get-MsecIntuneReusableSetting | Out-Null
            $script:asked
        }

        $path | Should -Match 'referencingConfigurationPolicyCount'
        $path | Should -Match 'settingInstance'
    }

    It 'projects a Device Control group with its entries and reference count' {
        $row = InModuleScope Msec {
            Mock Invoke-MsecGraphRequest -MockWith {
                @([pscustomobject]@{
                    id = '97a61128-1736-4808-a766-6bdc27deb519'
                    displayName = 'Authorized USBs '
                    description = ''
                    settingDefinitionId = 'device_vendor_msft_defender_configuration_devicecontrol_policygroups_{groupid}_groupdata'
                    lastModifiedDateTime = '2026-09-11T12:30:04Z'
                    referencingConfigurationPolicyCount = 1
                    settingInstance = [pscustomobject]@{
                        groupSettingCollectionValue = @(
                            [pscustomobject]@{ children = @(
                                [pscustomobject]@{
                                    settingDefinitionId = 'x_groupdata_descriptors_name'
                                    simpleSettingValue = [pscustomobject]@{ value = 'SanDisk - 1903' }
                                }
                                # Deliberately nested one level deeper than its sibling: the
                                # real payload varies in depth and a fixed-depth reader misses rows.
                                [pscustomobject]@{ groupSettingCollectionValue = @(
                                    [pscustomobject]@{ children = @(
                                        [pscustomobject]@{
                                            settingDefinitionId = 'x_groupdata_descriptors_name'
                                            simpleSettingValue = [pscustomobject]@{ value = "Feng's USB STICK" }
                                        }
                                        [pscustomobject]@{
                                            settingDefinitionId = 'x_groupdata_descriptors_serialnumberid'
                                            simpleSettingValue = [pscustomobject]@{ value = '9D0400034040' }
                                        }
                                    ) }
                                ) }
                            ) }
                        )
                    }
                })
            }
            Get-MsecIntuneReusableSetting
        }

        $row.DisplayName | Should -Be 'Authorized USBs'      # trailing space trimmed
        $row.Kind | Should -Be 'DeviceControlGroup'
        $row.ReferencingPolicyCount | Should -Be 1
        $row.IsUnreferenced | Should -BeFalse
        $row.EntryCount | Should -Be 2
        $row.Entries | Should -Contain 'SanDisk - 1903'
        $row.Entries | Should -Contain "Feng's USB STICK"
        $row.EntryIdentifiers | Should -Contain '9D0400034040'
        # The join back to a Device Control policy's `groupid`.
        $row.Id | Should -Be '97a61128-1736-4808-a766-6bdc27deb519'
    }

    It 'reports an unknown reference count as null, never as zero' {
        $rows = InModuleScope Msec {
            Mock Invoke-MsecGraphRequest -MockWith {
                @(
                    [pscustomobject]@{ id='a'; displayName='Known orphan'; settingDefinitionId='x'
                                       referencingConfigurationPolicyCount = 0; settingInstance = $null }
                    # Property absent entirely - what the API returns without the $select.
                    [pscustomobject]@{ id='b'; displayName='Count unknown'; settingDefinitionId='x'
                                       settingInstance = $null }
                )
            }
            , @(Get-MsecIntuneReusableSetting)
        }

        $known = $rows | Where-Object Id -eq 'a'
        $unknown = $rows | Where-Object Id -eq 'b'

        $known.ReferencingPolicyCount | Should -Be 0
        $known.IsUnreferenced | Should -BeTrue

        # Unknown is not orphaned. Reporting it as orphaned invites deleting an in-use allow-list.
        $unknown.ReferencingPolicyCount | Should -BeNullOrEmpty
        $unknown.IsUnreferenced | Should -BeNullOrEmpty
    }

    It 'returns only genuine orphans under -UnreferencedOnly, excluding unknown counts' {
        $rows = InModuleScope Msec {
            Mock Invoke-MsecGraphRequest -MockWith {
                @(
                    [pscustomobject]@{ id='orphan'; displayName='Orphan'; settingDefinitionId='x'
                                       referencingConfigurationPolicyCount = 0; settingInstance = $null }
                    [pscustomobject]@{ id='used';   displayName='In use'; settingDefinitionId='x'
                                       referencingConfigurationPolicyCount = 2; settingInstance = $null }
                    [pscustomobject]@{ id='unknown'; displayName='Unknown'; settingDefinitionId='x'
                                       settingInstance = $null }
                )
            }
            , @(Get-MsecIntuneReusableSetting -UnreferencedOnly)
        }

        @($rows | ForEach-Object Id) | Should -Be @('orphan')
    }

    It 'rewrites a 403 to name the permission' {
        $err = InModuleScope Msec {
            Mock Invoke-MsecGraphRequest -MockWith { throw 'Response status code does not indicate success: 403 (Forbidden).' }
            try { Get-MsecIntuneReusableSetting; $null } catch { "$($_.Exception.Message)" }
        }
        $err | Should -Match 'DeviceManagementConfiguration\.Read\.All'
    }
}