normalizer = app(PolicyNormalizer::class); }); it('flattens settings catalog setting instances into a table', function () { $snapshot = [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationPolicy', 'settings' => [ [ 'id' => 's1', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance', 'settingDefinitionId' => 'device_vendor_msft_policy_config_system_minimumpinlength', 'simpleSettingValue' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationIntegerSettingValue', 'value' => 12, ], ], ], [ 'id' => 's2', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance', 'settingDefinitionId' => 'device_vendor_msft_policy_config_system_usebiometrics', 'choiceSettingValue' => [ 'value' => 'device_vendor_msft_policy_config_system_usebiometrics_true', ], ], ], [ 'id' => 'group', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationGroupSettingCollectionInstance', 'settingDefinitionId' => 'device_vendor_msft_policy_config_system_group', 'groupSettingCollectionValue' => [ [ 'children' => [ [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance', 'settingDefinitionId' => 'device_vendor_msft_policy_config_system_child', 'simpleSettingValue' => [ 'value' => true, ], ], ], ], ], ], ], [ 'id' => 'unknown', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.someUnknownSettingInstance', 'settingDefinitionId' => 'unknown_definition', 'foo' => 'bar', ], ], ], ]; $result = $this->normalizer->normalize($snapshot, 'settingsCatalogPolicy', 'windows'); expect($result['status'])->toBe('success'); expect($result)->toHaveKey('settings_table'); $rows = collect($result['settings_table']['rows']); // Use definition_id field for lookup (raw ID), definition field now contains display name $minimumPinLength = $rows->firstWhere('definition_id', 'device_vendor_msft_policy_config_system_minimumpinlength'); expect($minimumPinLength)->not->toBeNull(); expect($minimumPinLength['definition'])->toContain('Minimum'); // Display name expect($minimumPinLength['data_type'])->toBe('Number'); // User-friendly type expect($minimumPinLength['value'])->toBe('12'); expect($minimumPinLength)->toHaveKey('category'); expect($minimumPinLength)->toHaveKey('description'); $useBiometrics = $rows->firstWhere('definition_id', 'device_vendor_msft_policy_config_system_usebiometrics'); expect($useBiometrics)->not->toBeNull(); expect($useBiometrics['definition'])->toContain('Usebiometrics'); // Display name (prettified) expect($useBiometrics['value'])->toBe('Enabled'); // Formatted from "usebiometrics_true" -> "Enabled" $child = $rows->firstWhere('definition_id', 'device_vendor_msft_policy_config_system_child'); expect($child)->not->toBeNull(); expect($child['definition'])->toContain('Child'); // Display name (prettified) expect($child['value'])->toBe('Enabled'); // Formatted from boolean true -> "Enabled" expect($child['path'])->toContain('group'); // Path contains parent definition IDs $unknown = $rows->firstWhere('definition_id', 'unknown_definition'); expect($unknown)->not->toBeNull(); expect($unknown['definition'])->toBe('Unknown Definition'); // Prettified fallback expect($unknown['value'])->toContain('foo'); }); it('inherits category from nearest ancestor when child categories are missing', function () { $categoryId = 'cat-windows-hello'; $parentDefinitionId = 'device_vendor_msft_passportforwork_biometrics_usebiometrics'; $groupDefinitionId = 'device_vendor_msft_passportforwork_{tenantid}'; $childDefinitionId = 'device_vendor_msft_passportforwork_{tenantid}_policies_pincomplexity_expiration'; SettingsCatalogCategory::create([ 'category_id' => $categoryId, 'display_name' => 'Windows Hello For Business', 'description' => 'Windows Hello settings', ]); SettingsCatalogDefinition::create([ 'definition_id' => $parentDefinitionId, 'display_name' => 'Allow Use of Biometrics', 'description' => 'Enable biometrics', 'category_id' => $categoryId, 'raw' => ['id' => $parentDefinitionId], ]); $snapshot = [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationPolicy', 'settings' => [ [ 'id' => '0', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance', 'settingDefinitionId' => $parentDefinitionId, 'choiceSettingValue' => [ 'value' => "{$parentDefinitionId}_true", 'children' => [ [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationGroupSettingInstance', 'settingDefinitionId' => $groupDefinitionId, 'groupSettingValue' => [ 'children' => [ [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance', 'settingDefinitionId' => $childDefinitionId, 'simpleSettingValue' => [ 'value' => 0, ], ], ], ], ], ], ], ], ], ], ]; $result = $this->normalizer->normalize($snapshot, 'settingsCatalogPolicy', 'windows'); $rows = collect($result['settings_table']['rows']); $group = $rows->firstWhere('definition_id', $groupDefinitionId); $child = $rows->firstWhere('definition_id', $childDefinitionId); expect($group)->not->toBeNull(); expect($child)->not->toBeNull(); expect($group['category'])->toBe('Windows Hello For Business'); expect($child['category'])->toBe('Windows Hello For Business'); }); it('uses the only known category for template settings without ancestors', function () { $categoryId = 'cat-windows-hello'; $rootDefinitionId = 'device_vendor_msft_passportforwork_biometrics_usebiometrics'; $groupDefinitionId = 'device_vendor_msft_passportforwork_{tenantid}'; $childDefinitionId = 'device_vendor_msft_passportforwork_{tenantid}_policies_pincomplexity_expiration'; SettingsCatalogCategory::create([ 'category_id' => $categoryId, 'display_name' => 'Windows Hello For Business', 'description' => 'Windows Hello settings', ]); SettingsCatalogDefinition::create([ 'definition_id' => $rootDefinitionId, 'display_name' => 'Allow Use of Biometrics', 'description' => 'Enable biometrics', 'category_id' => $categoryId, 'raw' => ['id' => $rootDefinitionId], ]); $snapshot = [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationPolicy', 'settings' => [ [ 'id' => 'root', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationChoiceSettingInstance', 'settingDefinitionId' => $rootDefinitionId, 'choiceSettingValue' => [ 'value' => "{$rootDefinitionId}_true", ], ], ], [ 'id' => 'group', 'settingInstance' => [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationGroupSettingInstance', 'settingDefinitionId' => $groupDefinitionId, 'groupSettingValue' => [ 'children' => [ [ '@odata.type' => '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance', 'settingDefinitionId' => $childDefinitionId, 'simpleSettingValue' => [ 'value' => 0, ], ], ], ], ], ], ], ]; $result = $this->normalizer->normalize($snapshot, 'settingsCatalogPolicy', 'windows'); $rows = collect($result['settings_table']['rows']); $group = $rows->firstWhere('definition_id', $groupDefinitionId); $child = $rows->firstWhere('definition_id', $childDefinitionId); expect($group)->not->toBeNull(); expect($child)->not->toBeNull(); expect($group['category'])->toBe('Windows Hello For Business'); expect($child['category'])->toBe('Windows Hello For Business'); });