What Changed Removed per-file uses(TestCase::class ...) bindings in Unit tests to avoid Pest v4 “folder already uses the test case” discovery failure (kept RefreshDatabase where needed). Updated the backup scheduling job test to pass the newly required BulkOperationService when manually calling RunBackupScheduleJob::handle(). Where Unit (bulk cleanup across 56 files) RunBackupScheduleJobTest.php Verification ./vendor/bin/sail test → 443 passed, 5 skipped Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local> Reviewed-on: #45
140 lines
4.6 KiB
PHP
140 lines
4.6 KiB
PHP
<?php
|
|
|
|
use App\Models\Tenant;
|
|
use App\Services\Graph\GraphLogger;
|
|
use App\Services\Graph\GraphResponse;
|
|
use App\Services\Graph\MicrosoftGraphClient;
|
|
use App\Services\Graph\ScopeTagResolver;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
uses(RefreshDatabase::class);
|
|
beforeEach(function () {
|
|
Cache::flush();
|
|
});
|
|
|
|
test('resolves scope tag IDs to objects with id and displayName', function () {
|
|
$tenant = Tenant::factory()->create();
|
|
|
|
$mockGraphClient = Mockery::mock(MicrosoftGraphClient::class);
|
|
$mockGraphClient->shouldReceive('request')
|
|
->with('GET', '/deviceManagement/roleScopeTags', Mockery::on(function ($options) use ($tenant) {
|
|
return $options['query']['$select'] === 'id,displayName'
|
|
&& $options['tenant'] === $tenant->external_id
|
|
&& $options['client_id'] === $tenant->app_client_id
|
|
&& $options['client_secret'] === $tenant->app_client_secret;
|
|
}))
|
|
->once()
|
|
->andReturn(new GraphResponse(
|
|
success: true,
|
|
data: [
|
|
'value' => [
|
|
['id' => '0', 'displayName' => 'Default'],
|
|
['id' => '1', 'displayName' => 'Verbund-1'],
|
|
['id' => '2', 'displayName' => 'Verbund-2'],
|
|
],
|
|
]
|
|
));
|
|
|
|
$mockLogger = Mockery::mock(GraphLogger::class);
|
|
|
|
$resolver = new ScopeTagResolver($mockGraphClient, $mockLogger);
|
|
$result = $resolver->resolve(['0', '1', '2'], $tenant);
|
|
|
|
expect($result)->toBe([
|
|
['id' => '0', 'displayName' => 'Default'],
|
|
['id' => '1', 'displayName' => 'Verbund-1'],
|
|
['id' => '2', 'displayName' => 'Verbund-2'],
|
|
]);
|
|
});
|
|
|
|
test('caches scope tag objects for 1 hour', function () {
|
|
$tenant = Tenant::factory()->create();
|
|
|
|
$mockGraphClient = Mockery::mock(MicrosoftGraphClient::class);
|
|
$mockGraphClient->shouldReceive('request')
|
|
->once() // Only called once due to caching
|
|
->andReturn(new GraphResponse(
|
|
success: true,
|
|
data: [
|
|
'value' => [
|
|
['id' => '0', 'displayName' => 'Default'],
|
|
],
|
|
]
|
|
));
|
|
|
|
$mockLogger = Mockery::mock(GraphLogger::class);
|
|
|
|
$resolver = new ScopeTagResolver($mockGraphClient, $mockLogger);
|
|
|
|
// First call - fetches from API
|
|
$result1 = $resolver->resolve(['0'], $tenant);
|
|
|
|
// Second call - should use cache
|
|
$result2 = $resolver->resolve(['0'], $tenant);
|
|
|
|
expect($result1)->toBe([['id' => '0', 'displayName' => 'Default']]);
|
|
expect($result2)->toBe([['id' => '0', 'displayName' => 'Default']]);
|
|
});
|
|
|
|
test('returns empty array for empty input', function () {
|
|
$tenant = Tenant::factory()->create();
|
|
$mockGraphClient = Mockery::mock(MicrosoftGraphClient::class);
|
|
$mockLogger = Mockery::mock(GraphLogger::class);
|
|
|
|
$resolver = new ScopeTagResolver($mockGraphClient, $mockLogger);
|
|
$result = $resolver->resolve([], $tenant);
|
|
|
|
expect($result)->toBe([]);
|
|
});
|
|
|
|
test('handles 403 forbidden gracefully', function () {
|
|
$tenant = Tenant::factory()->create();
|
|
|
|
$mockGraphClient = Mockery::mock(MicrosoftGraphClient::class);
|
|
$mockGraphClient->shouldReceive('request')
|
|
->once()
|
|
->andReturn(new GraphResponse(
|
|
success: false,
|
|
status: 403,
|
|
data: []
|
|
));
|
|
|
|
$mockLogger = Mockery::mock(GraphLogger::class);
|
|
|
|
$resolver = new ScopeTagResolver($mockGraphClient, $mockLogger);
|
|
$result = $resolver->resolve(['0', '1'], $tenant);
|
|
|
|
// Should return empty array when 403
|
|
expect($result)->toBe([]);
|
|
});
|
|
|
|
test('filters returned scope tags to requested IDs', function () {
|
|
$tenant = Tenant::factory()->create();
|
|
|
|
$mockGraphClient = Mockery::mock(MicrosoftGraphClient::class);
|
|
$mockGraphClient->shouldReceive('request')
|
|
->once()
|
|
->andReturn(new GraphResponse(
|
|
success: true,
|
|
data: [
|
|
'value' => [
|
|
['id' => '0', 'displayName' => 'Default'],
|
|
['id' => '1', 'displayName' => 'Verbund-1'],
|
|
['id' => '2', 'displayName' => 'Verbund-2'],
|
|
],
|
|
]
|
|
));
|
|
|
|
$mockLogger = Mockery::mock(GraphLogger::class);
|
|
|
|
$resolver = new ScopeTagResolver($mockGraphClient, $mockLogger);
|
|
// Request only IDs 0 and 2
|
|
$result = $resolver->resolve(['0', '2'], $tenant);
|
|
|
|
expect($result)->toHaveCount(2);
|
|
// Note: array_filter preserves keys, so result will be [0 => ..., 2 => ...]
|
|
expect($result[0])->toBe(['id' => '0', 'displayName' => 'Default']);
|
|
expect($result[2])->toBe(['id' => '2', 'displayName' => 'Verbund-2']);
|
|
});
|