create($attributes + [ 'status' => 'active', 'app_client_id' => null, 'app_client_secret' => null, ]); $connection = ProviderConnection::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'is_default' => true, 'status' => 'connected', 'entra_tenant_id' => (string) ($tenant->tenant_id ?: 'tenant-'.$tenant->getKey()), ]); ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $connection->getKey(), 'type' => 'client_secret', 'payload' => [ 'client_id' => 'provider-client-'.$tenant->getKey(), 'client_secret' => 'provider-secret-'.$tenant->getKey(), ], ]); return $tenant; } it('returns a report with failures when policy list calls fail', function () { $tenant = tenantWithDefaultMicrosoftConnectionForPolicySyncReport(); $logger = mock(GraphLogger::class); $logger->shouldReceive('logRequest')->zeroOrMoreTimes()->andReturnNull(); $logger->shouldReceive('logResponse')->zeroOrMoreTimes()->andReturnNull(); mock(GraphClientInterface::class) ->shouldReceive('listPolicies') ->andReturnUsing(function (string $policyType) { return match ($policyType) { 'endpointSecurityPolicy' => new GraphResponse( success: false, data: [], status: 403, errors: [['message' => 'Forbidden']], meta: ['path' => '/deviceManagement/configurationPolicies'], ), default => new GraphResponse( success: true, data: [ ['id' => 'scp-1', 'displayName' => 'Settings Catalog', 'technologies' => ['mdm']], ], status: 200, ), }; }); $service = app(PolicySyncService::class); $result = $service->syncPoliciesWithReport($tenant, [ ['type' => 'endpointSecurityPolicy', 'platform' => 'windows'], ['type' => 'settingsCatalogPolicy', 'platform' => 'windows'], ]); expect($result)->toHaveKeys(['synced', 'failures']); expect($result['synced'])->toBeArray(); expect($result['failures'])->toBeArray(); expect(count($result['synced']))->toBe(1); expect(Policy::query()->where('tenant_id', $tenant->id)->count())->toBe(1); expect(count($result['failures']))->toBe(1); expect($result['failures'][0]['policy_type'])->toBe('endpointSecurityPolicy'); expect($result['failures'][0]['status'])->toBe(403); });