TenantAtlas/tests/Unit/PolicyNormalizerSettingsCatalogFlattenTest.php
Ahmed Darrazi 58e6a4e980 feat(settings-catalog): Add category display and definition caching
- Add SettingsCatalogCategoryResolver service with 3-tier caching
- Add SettingsCatalogCategory model and migration
- Add warm-cache commands for definitions and categories
- Update PolicyNormalizer to display categories in settings table
- Fix extraction of nested children in choiceSettingValue
- Add category inheritance from parent settings
- Skip template IDs with {tenantid} placeholder in Graph API calls
- Update Livewire table with Category, Data Type, and Description columns

Related tests updated and passing.
2025-12-21 00:40:20 +01:00

235 lines
10 KiB
PHP

<?php
use App\Models\SettingsCatalogCategory;
use App\Models\SettingsCatalogDefinition;
use App\Services\Intune\PolicyNormalizer;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
uses(TestCase::class);
uses(RefreshDatabase::class);
beforeEach(function () {
$this->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');
});