TenantAtlas/tests/Unit/GraphContractRegistryTest.php
2025-12-14 20:23:18 +01:00

107 lines
4.0 KiB
PHP

<?php
use App\Services\Graph\GraphContractRegistry;
use App\Services\Graph\GraphResponse;
use Tests\TestCase;
uses(TestCase::class);
beforeEach(function () {
config()->set('graph_contracts.types.deviceConfiguration', [
'resource' => 'deviceManagement/deviceConfigurations',
'allowed_select' => ['id', 'displayName'],
'allowed_expand' => ['assignments'],
'type_family' => [
'#microsoft.graph.deviceConfiguration',
'#microsoft.graph.windows10CustomConfiguration',
],
]);
config()->set('graph_contracts.types.settingsCatalogPolicy', [
'resource' => 'deviceManagement/configurationPolicies',
'allowed_select' => ['id'],
'allowed_expand' => [],
'type_family' => ['#microsoft.graph.deviceManagementConfigurationPolicy'],
'update_whitelist' => ['name', 'description'],
'update_map' => ['displayName' => 'name'],
'update_strip_keys' => ['platforms', 'technologies', 'templateReference', 'assignments'],
'settings_write' => [
'path_template' => 'deviceManagement/configurationPolicies/{id}/settings/{settingId}',
'method' => 'PATCH',
],
]);
$this->registry = app(GraphContractRegistry::class);
});
it('sanitizes disallowed select and expand values', function () {
$result = $this->registry->sanitizeQuery('deviceConfiguration', [
'$select' => ['id', 'displayName', 'unsupported'],
'$expand' => ['assignments', 'badExpand'],
]);
$query = $result['query'];
$warnings = $result['warnings'];
expect($query['$select'])->toBe(['id', 'displayName']);
expect($query['$expand'])->toBe(['assignments']);
expect($warnings)->not->toBeEmpty();
});
it('matches derived types within family', function () {
expect($this->registry->matchesTypeFamily('deviceConfiguration', '#microsoft.graph.windows10CustomConfiguration'))->toBeTrue();
expect($this->registry->matchesTypeFamily('deviceConfiguration', '#microsoft.graph.androidCompliancePolicy'))->toBeFalse();
});
it('detects capability errors for downgrade', function () {
$response = new GraphResponse(
success: false,
data: [],
status: 400,
errors: [['message' => 'Request is invalid due to $select']]
);
$shouldDowngrade = $this->registry->shouldDowngradeOnCapabilityError($response, ['$select' => ['displayName']]);
expect($shouldDowngrade)->toBeTrue();
});
it('provides contract for settings catalog policies', function () {
$contract = config('graph_contracts.types.settingsCatalogPolicy');
expect($contract)->not->toBeEmpty();
expect($contract['resource'])->toBe('deviceManagement/configurationPolicies');
expect($this->registry->matchesTypeFamily('settingsCatalogPolicy', '#microsoft.graph.deviceManagementConfigurationPolicy'))->toBeTrue();
});
it('sanitizes update payloads for settings catalog policies', function () {
$payload = [
'id' => 'scp-1',
'@odata.type' => '#microsoft.graph.deviceManagementConfigurationPolicy',
'displayName' => 'Config',
'Description' => 'desc',
'version' => 5,
'createdDateTime' => '2024-01-01T00:00:00Z',
'settings' => [
[
'id' => 'setting-1',
'settingInstance' => [
'@odata.type' => '#microsoft.graph.deviceManagementConfigurationSimpleSettingInstance',
'settingDefinitionId' => 'setting_definition',
'simpleSettingValue' => ['value' => 'bar'],
],
],
],
'Platforms' => ['windows'],
'unknown' => 'drop-me',
];
$sanitized = $this->registry->sanitizeUpdatePayload('settingsCatalogPolicy', $payload);
expect($sanitized)->toHaveKeys(['name', 'description']);
expect($sanitized)->not->toHaveKey('id');
expect($sanitized)->not->toHaveKey('@odata.type');
expect($sanitized)->not->toHaveKey('version');
expect($sanitized)->not->toHaveKey('platforms');
expect($sanitized)->not->toHaveKey('settings');
});