diff --git a/app/Services/Intune/PolicySnapshotService.php b/app/Services/Intune/PolicySnapshotService.php index 6ad2a60..5caa176 100644 --- a/app/Services/Intune/PolicySnapshotService.php +++ b/app/Services/Intune/PolicySnapshotService.php @@ -39,12 +39,18 @@ public function fetch(Tenant $tenant, Policy $policy, ?string $actorEmail = null $this->graphLogger->logRequest('get_policy', $context); try { - $response = $this->graphClient->getPolicy($policy->policy_type, $policy->external_id, [ + $options = [ 'tenant' => $tenantIdentifier, 'client_id' => $tenant->app_client_id, 'client_secret' => $tenant->app_client_secret, 'platform' => $policy->platform, - ]); + ]; + + if ($policy->policy_type === 'deviceCompliancePolicy') { + $options['expand'] = ['scheduledActionsForRule']; + } + + $response = $this->graphClient->getPolicy($policy->policy_type, $policy->external_id, $options); } catch (Throwable $throwable) { $mapped = GraphErrorMapper::fromThrowable($throwable, $context); @@ -191,6 +197,14 @@ private function hydrateSettingsCatalog(string $tenantIdentifier, Tenant $tenant */ private function hydrateComplianceActions(string $tenantIdentifier, Tenant $tenant, string $policyId, array $payload, array $metadata): array { + $existingActions = $payload['scheduledActionsForRule'] ?? null; + + if (is_array($existingActions) && $existingActions !== []) { + $metadata['compliance_actions_hydration'] = 'embedded'; + + return [$payload, $metadata]; + } + $path = sprintf('deviceManagement/deviceCompliancePolicies/%s/scheduledActionsForRule', urlencode($policyId)); $options = [ 'tenant' => $tenantIdentifier, diff --git a/config/graph_contracts.php b/config/graph_contracts.php index b181301..3e86656 100644 --- a/config/graph_contracts.php +++ b/config/graph_contracts.php @@ -15,7 +15,7 @@ 'deviceConfiguration' => [ 'resource' => 'deviceManagement/deviceConfigurations', 'allowed_select' => ['id', 'displayName', 'description', '@odata.type', 'version', 'lastModifiedDateTime'], - 'allowed_expand' => [], + 'allowed_expand' => ['scheduledActionsForRule'], 'type_family' => [ '#microsoft.graph.deviceConfiguration', '#microsoft.graph.windows10CustomConfiguration', diff --git a/tests/Unit/PolicySnapshotServiceTest.php b/tests/Unit/PolicySnapshotServiceTest.php index eaa9a02..aaee4b0 100644 --- a/tests/Unit/PolicySnapshotServiceTest.php +++ b/tests/Unit/PolicySnapshotServiceTest.php @@ -22,7 +22,7 @@ public function listPolicies(string $policyType, array $options = []): GraphResp public function getPolicy(string $policyType, string $policyId, array $options = []): GraphResponse { - $this->requests[] = ['getPolicy', $policyType, $policyId]; + $this->requests[] = ['getPolicy', $policyType, $policyId, $options]; return new GraphResponse(success: true, data: [ 'payload' => [ @@ -101,5 +101,8 @@ public function request(string $method, string $path, array $options = []): Grap expect($result['payload']['scheduledActionsForRule'][0]['scheduledActionConfigurations'][0]['notificationTemplateId']) ->toBe('template-123'); expect($result['metadata']['compliance_actions_hydration'])->toBe('complete'); - expect($client->requests)->toContain(['getPolicy', 'deviceCompliancePolicy', 'compliance-123']); + expect($client->requests[0][0])->toBe('getPolicy'); + expect($client->requests[0][1])->toBe('deviceCompliancePolicy'); + expect($client->requests[0][2])->toBe('compliance-123'); + expect($client->requests[0][3]['expand'] ?? [])->toBe(['scheduledActionsForRule']); });