*/ public array $applyPolicyCalls = []; public function listPolicies(string $policyType, array $options = []): GraphResponse { return new GraphResponse(true, []); } public function getPolicy(string $policyType, string $policyId, array $options = []): GraphResponse { return new GraphResponse(true, ['payload' => []]); } public function getOrganization(array $options = []): GraphResponse { return new GraphResponse(true, []); } public function applyPolicy(string $policyType, string $policyId, array $payload, array $options = []): GraphResponse { $this->applyPolicyCalls[] = [ 'policyType' => $policyType, 'policyId' => $policyId, 'payload' => $payload, 'options' => $options, ]; return new GraphResponse(true, []); } public function request(string $method, string $path, array $options = []): GraphResponse { return new GraphResponse(true, []); } public function getServicePrincipalPermissions(array $options = []): GraphResponse { return new GraphResponse(true, []); } } test('restore execution applies windows feature update profile with sanitized payload', function () { $client = new WindowsUpdateProfilesRestoreGraphClient; app()->instance(GraphClientInterface::class, $client); $tenant = Tenant::create([ 'tenant_id' => 'tenant-1', 'name' => 'Tenant One', 'metadata' => [], ]); $policy = Policy::create([ 'tenant_id' => $tenant->id, 'external_id' => 'policy-feature', 'policy_type' => 'windowsFeatureUpdateProfile', 'display_name' => 'Feature Updates A', 'platform' => 'windows', ]); $backupSet = BackupSet::create([ 'tenant_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupPayload = [ 'id' => 'policy-feature', '@odata.type' => '#microsoft.graph.windowsFeatureUpdateProfile', 'displayName' => 'Feature Updates A', 'featureUpdateVersion' => 'Windows 11, version 23H2', 'deployableContentDisplayName' => 'Some Content', 'endOfSupportDate' => '2026-01-01T00:00:00Z', 'roleScopeTagIds' => ['0'], ]; $backupItem = BackupItem::create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, 'policy_type' => $policy->policy_type, 'platform' => $policy->platform, 'payload' => $backupPayload, ]); $user = User::factory()->create(['email' => 'tester@example.com']); $this->actingAs($user); $service = app(RestoreService::class); $run = $service->execute( tenant: $tenant, backupSet: $backupSet, selectedItemIds: [$backupItem->id], dryRun: false, actorEmail: $user->email, actorName: $user->name, ); expect($run->status)->toBe('completed'); expect($run->results[0]['status'])->toBe('applied'); expect(PolicyVersion::where('policy_id', $policy->id)->count())->toBe(1); expect($client->applyPolicyCalls)->toHaveCount(1); expect($client->applyPolicyCalls[0]['policyType'])->toBe('windowsFeatureUpdateProfile'); expect($client->applyPolicyCalls[0]['policyId'])->toBe('policy-feature'); expect($client->applyPolicyCalls[0]['options']['method'] ?? null)->toBe('PATCH'); expect($client->applyPolicyCalls[0]['payload']['featureUpdateVersion'])->toBe('Windows 11, version 23H2'); expect($client->applyPolicyCalls[0]['payload']['roleScopeTagIds'])->toBe(['0']); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('id'); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('@odata.type'); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('deployableContentDisplayName'); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('endOfSupportDate'); }); test('restore execution applies windows quality update profile with sanitized payload', function () { $client = new WindowsUpdateProfilesRestoreGraphClient; app()->instance(GraphClientInterface::class, $client); $tenant = Tenant::create([ 'tenant_id' => 'tenant-1', 'name' => 'Tenant One', 'metadata' => [], ]); $policy = Policy::create([ 'tenant_id' => $tenant->id, 'external_id' => 'policy-quality', 'policy_type' => 'windowsQualityUpdateProfile', 'display_name' => 'Quality Updates A', 'platform' => 'windows', ]); $backupSet = BackupSet::create([ 'tenant_id' => $tenant->id, 'name' => 'Backup', 'status' => 'completed', 'item_count' => 1, ]); $backupPayload = [ 'id' => 'policy-quality', '@odata.type' => '#microsoft.graph.windowsQualityUpdateProfile', 'displayName' => 'Quality Updates A', 'qualityUpdateCveIds' => ['CVE-2025-0001'], 'deployableContentDisplayName' => 'Some Content', 'releaseDateDisplayName' => 'January 2026', 'roleScopeTagIds' => ['0'], ]; $backupItem = BackupItem::create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => $policy->id, 'policy_identifier' => $policy->external_id, 'policy_type' => $policy->policy_type, 'platform' => $policy->platform, 'payload' => $backupPayload, ]); $user = User::factory()->create(['email' => 'tester@example.com']); $this->actingAs($user); $service = app(RestoreService::class); $run = $service->execute( tenant: $tenant, backupSet: $backupSet, selectedItemIds: [$backupItem->id], dryRun: false, actorEmail: $user->email, actorName: $user->name, ); expect($run->status)->toBe('completed'); expect($run->results[0]['status'])->toBe('applied'); expect(PolicyVersion::where('policy_id', $policy->id)->count())->toBe(1); expect($client->applyPolicyCalls)->toHaveCount(1); expect($client->applyPolicyCalls[0]['policyType'])->toBe('windowsQualityUpdateProfile'); expect($client->applyPolicyCalls[0]['policyId'])->toBe('policy-quality'); expect($client->applyPolicyCalls[0]['options']['method'] ?? null)->toBe('PATCH'); expect($client->applyPolicyCalls[0]['payload']['qualityUpdateCveIds'])->toBe(['CVE-2025-0001']); expect($client->applyPolicyCalls[0]['payload']['roleScopeTagIds'])->toBe(['0']); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('id'); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('@odata.type'); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('deployableContentDisplayName'); expect($client->applyPolicyCalls[0]['payload'])->not->toHaveKey('releaseDateDisplayName'); });