TenantAtlas/tests/Unit/EntraAdminRolesReportServiceTest.php
2026-02-26 00:48:25 +01:00

119 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\Tenant;
use App\Services\EntraAdminRoles\EntraAdminRolesReportService;
use App\Services\Graph\GraphClientInterface;
use App\Services\Graph\GraphResponse;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
it('requests principal expansion and uses principal display name when present', function () {
$tenant = Tenant::factory()->create();
ensureDefaultProviderConnection($tenant, 'microsoft');
$roleDefinitions = [
[
'id' => 'role-def-1',
'templateId' => '62e90394-69f5-4237-9190-012177145e10',
'displayName' => 'Global Administrator',
'isBuiltIn' => true,
],
];
$roleAssignments = [
[
'id' => 'role-assign-1',
'roleDefinitionId' => 'role-def-1',
'principalId' => 'principal-1',
'directoryScopeId' => '/',
'principal' => [
'@odata.type' => '#microsoft.graph.user',
'displayName' => 'Ada Lovelace',
],
],
];
$calls = [];
$this->mock(GraphClientInterface::class, function ($mock) use (&$calls, $roleDefinitions, $roleAssignments) {
$mock->shouldReceive('listPolicies')
->twice()
->andReturnUsing(function (string $policyType, array $options) use (&$calls, $roleDefinitions, $roleAssignments): GraphResponse {
$calls[] = [$policyType, $options];
if ($policyType === 'entraRoleDefinitions') {
return new GraphResponse(true, $roleDefinitions);
}
return new GraphResponse(true, $roleAssignments);
});
});
$result = app(EntraAdminRolesReportService::class)->generate($tenant);
expect($calls)->toHaveCount(2);
expect($calls[0][0])->toBe('entraRoleDefinitions');
expect($calls[0][1])->not->toHaveKey('expand');
expect($calls[1][0])->toBe('entraRoleAssignments');
expect($calls[1][1]['expand'] ?? null)->toBe('principal');
expect($calls[1][1])->toMatchArray(array_merge($calls[0][1], [
'expand' => 'principal',
]));
expect($result->payload['high_privilege'])->toHaveCount(1);
expect($result->payload['high_privilege'][0]['principal_display_name'])->toBe('Ada Lovelace');
});
it('falls back to Unknown when principal details are missing upstream', function () {
$tenant = Tenant::factory()->create();
ensureDefaultProviderConnection($tenant, 'microsoft');
$roleDefinitions = [
[
'id' => 'role-def-1',
'templateId' => '62e90394-69f5-4237-9190-012177145e10',
'displayName' => 'Global Administrator',
'isBuiltIn' => true,
],
];
$roleAssignments = [
[
'id' => 'role-assign-1',
'roleDefinitionId' => 'role-def-1',
'principalId' => 'principal-1',
'directoryScopeId' => '/',
],
];
$calls = [];
$this->mock(GraphClientInterface::class, function ($mock) use (&$calls, $roleDefinitions, $roleAssignments) {
$mock->shouldReceive('listPolicies')
->twice()
->andReturnUsing(function (string $policyType, array $options) use (&$calls, $roleDefinitions, $roleAssignments): GraphResponse {
$calls[] = [$policyType, $options];
if ($policyType === 'entraRoleDefinitions') {
return new GraphResponse(true, $roleDefinitions);
}
return new GraphResponse(true, $roleAssignments);
});
});
$result = app(EntraAdminRolesReportService::class)->generate($tenant);
expect($calls)->toHaveCount(2);
expect($calls[0][0])->toBe('entraRoleDefinitions');
expect($calls[0][1])->not->toHaveKey('expand');
expect($calls[1][0])->toBe('entraRoleAssignments');
expect($calls[1][1]['expand'] ?? null)->toBe('principal');
expect($result->payload['high_privilege'])->toHaveCount(1);
expect($result->payload['high_privilege'][0]['principal_display_name'])->toBe('Unknown');
});