Pest v4 discovery fails when unit tests re-bind the test case with uses(TestCase::class). Remove per-file bindings and keep RefreshDatabase where needed. Also update RunBackupScheduleJobTest to pass BulkOperationService when calling handle() manually.
159 lines
5.3 KiB
PHP
159 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Services\Graph\GraphContractRegistry;
|
|
use App\Services\Graph\GraphLogger;
|
|
use App\Services\Graph\MicrosoftGraphClient;
|
|
use Illuminate\Http\Client\Request;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
it('includes contract select fields when listing policies', function () {
|
|
Http::fake([
|
|
'graph.microsoft.com/*' => Http::response(['value' => []], 200),
|
|
]);
|
|
|
|
$logger = mock(GraphLogger::class);
|
|
$logger->shouldReceive('logRequest')->zeroOrMoreTimes()->andReturnNull();
|
|
$logger->shouldReceive('logResponse')->zeroOrMoreTimes()->andReturnNull();
|
|
|
|
$client = new MicrosoftGraphClient(
|
|
logger: $logger,
|
|
contracts: app(GraphContractRegistry::class),
|
|
);
|
|
|
|
$client->listPolicies('endpointSecurityPolicy', [
|
|
'access_token' => 'test-token',
|
|
]);
|
|
|
|
$client->listPolicies('securityBaselinePolicy', [
|
|
'access_token' => 'test-token',
|
|
]);
|
|
|
|
$client->listPolicies('settingsCatalogPolicy', [
|
|
'access_token' => 'test-token',
|
|
]);
|
|
|
|
Http::assertSent(function (Request $request) {
|
|
$url = $request->url();
|
|
|
|
if (! str_contains($url, '/deviceManagement/configurationPolicies')) {
|
|
return false;
|
|
}
|
|
|
|
parse_str((string) parse_url($url, PHP_URL_QUERY), $query);
|
|
|
|
expect($query)->toHaveKey('$select');
|
|
|
|
$select = (string) $query['$select'];
|
|
|
|
expect($select)->toContain('technologies')
|
|
->and($select)->toContain('templateReference')
|
|
->and($select)->toContain('name')
|
|
->and($select)->not->toContain('@odata.type');
|
|
|
|
expect($select)->not->toContain('displayName');
|
|
expect($select)->not->toContain('version');
|
|
|
|
return true;
|
|
});
|
|
});
|
|
|
|
it('retries list policies without $select on select/expand parsing errors', function () {
|
|
Http::fake([
|
|
'graph.microsoft.com/*' => Http::sequence()
|
|
->push([
|
|
'error' => [
|
|
'code' => 'BadRequest',
|
|
'message' => "Parsing OData Select and Expand failed: Could not find a property named 'version' on type 'microsoft.graph.deviceManagementConfigurationPolicy'.",
|
|
],
|
|
], 400)
|
|
->push([
|
|
'error' => [
|
|
'code' => 'BadRequest',
|
|
'message' => "Parsing OData Select and Expand failed: Could not find a property named 'version' on type 'microsoft.graph.deviceManagementConfigurationPolicy'.",
|
|
],
|
|
], 400)
|
|
->push(['value' => [['id' => 'policy-1', 'name' => 'Policy One']]], 200),
|
|
]);
|
|
|
|
$logger = mock(GraphLogger::class);
|
|
$logger->shouldReceive('logRequest')->zeroOrMoreTimes()->andReturnNull();
|
|
$logger->shouldReceive('logResponse')->zeroOrMoreTimes()->andReturnNull();
|
|
|
|
$client = new MicrosoftGraphClient(
|
|
logger: $logger,
|
|
contracts: app(GraphContractRegistry::class),
|
|
);
|
|
|
|
$response = $client->listPolicies('settingsCatalogPolicy', [
|
|
'access_token' => 'test-token',
|
|
]);
|
|
|
|
expect($response->successful())->toBeTrue();
|
|
expect($response->data)->toHaveCount(1);
|
|
expect($response->warnings)->toContain('Capability fallback applied: removed $select for compatibility.');
|
|
|
|
$recorded = Http::recorded();
|
|
|
|
expect($recorded)->toHaveCount(3);
|
|
|
|
[$firstRequest] = $recorded[0];
|
|
[$secondRequest] = $recorded[1];
|
|
[$thirdRequest] = $recorded[2];
|
|
|
|
parse_str((string) parse_url($firstRequest->url(), PHP_URL_QUERY), $firstQuery);
|
|
parse_str((string) parse_url($secondRequest->url(), PHP_URL_QUERY), $secondQuery);
|
|
parse_str((string) parse_url($thirdRequest->url(), PHP_URL_QUERY), $thirdQuery);
|
|
|
|
expect($firstQuery)->toHaveKey('$select');
|
|
expect($secondQuery)->toHaveKey('$select');
|
|
expect($thirdQuery)->not->toHaveKey('$select');
|
|
});
|
|
|
|
it('paginates list policies when nextLink is present', function () {
|
|
$nextLink = 'https://graph.microsoft.com/beta/deviceManagement/configurationPolicies?$skiptoken=page2';
|
|
|
|
Http::fake([
|
|
'graph.microsoft.com/*' => Http::sequence()
|
|
->push([
|
|
'value' => [
|
|
['id' => 'policy-1', 'name' => 'Policy One'],
|
|
],
|
|
'@odata.nextLink' => $nextLink,
|
|
], 200)
|
|
->push([
|
|
'value' => [
|
|
['id' => 'policy-2', 'name' => 'Policy Two'],
|
|
],
|
|
], 200),
|
|
]);
|
|
|
|
$logger = mock(GraphLogger::class);
|
|
$logger->shouldReceive('logRequest')->zeroOrMoreTimes()->andReturnNull();
|
|
$logger->shouldReceive('logResponse')->zeroOrMoreTimes()->andReturnNull();
|
|
|
|
$client = new MicrosoftGraphClient(
|
|
logger: $logger,
|
|
contracts: app(GraphContractRegistry::class),
|
|
);
|
|
|
|
$response = $client->listPolicies('settingsCatalogPolicy', [
|
|
'access_token' => 'test-token',
|
|
]);
|
|
|
|
expect($response->successful())->toBeTrue();
|
|
expect($response->data)->toHaveCount(2);
|
|
expect(collect($response->data)->pluck('id')->all())->toMatchArray(['policy-1', 'policy-2']);
|
|
|
|
$recorded = Http::recorded();
|
|
|
|
expect($recorded)->toHaveCount(2);
|
|
|
|
[$firstRequest] = $recorded[0];
|
|
[$secondRequest] = $recorded[1];
|
|
|
|
expect($firstRequest->url())->toContain('/deviceManagement/configurationPolicies');
|
|
expect($secondRequest->url())->toBe($nextLink);
|
|
});
|