TenantAtlas/tests/Unit/TenantPermissionServiceTest.php
Ahmed Darrazi 58e6a4e980 feat(settings-catalog): Add category display and definition caching
- Add SettingsCatalogCategoryResolver service with 3-tier caching
- Add SettingsCatalogCategory model and migration
- Add warm-cache commands for definitions and categories
- Update PolicyNormalizer to display categories in settings table
- Fix extraction of nested children in choiceSettingValue
- Add category inheritance from parent settings
- Skip template IDs with {tenantid} placeholder in Graph API calls
- Update Livewire table with Category, Data Type, and Description columns

Related tests updated and passing.
2025-12-21 00:40:20 +01:00

124 lines
3.8 KiB
PHP

<?php
use App\Models\Tenant;
use App\Models\TenantPermission;
use App\Services\Graph\GraphClientInterface;
use App\Services\Graph\GraphResponse;
use App\Services\Intune\TenantPermissionService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
uses(TestCase::class, RefreshDatabase::class);
function requiredPermissions(): array
{
$service = app(TenantPermissionService::class);
$required = $service->getRequiredPermissions();
if (empty($required)) {
test()->markTestSkipped('No required permissions configured.');
}
return $required;
}
it('returns ok when all permissions exist', function () {
// Mock GraphClient to return all permissions as granted
$this->mock(GraphClientInterface::class, function ($mock) {
$mock->shouldReceive('getServicePrincipalPermissions')
->andReturn(new GraphResponse(true, [
'value' => collect(config('intune_permissions.permissions', []))
->map(fn ($p) => ['value' => $p['key']])
->toArray(),
]));
});
$tenant = Tenant::create([
'tenant_id' => 'tenant-ok',
'name' => 'Tenant OK',
]);
foreach (requiredPermissions() as $permission) {
TenantPermission::create([
'tenant_id' => $tenant->id,
'permission_key' => $permission['key'],
'status' => 'ok',
]);
}
$result = app(TenantPermissionService::class)->compare($tenant);
expect($result['overall_status'])->toBe('ok');
expect(TenantPermission::where('tenant_id', $tenant->id)->where('status', 'ok')->count())
->toBe(count(requiredPermissions()));
});
it('marks missing permissions when not granted', function () {
$permissions = requiredPermissions();
// Mock GraphClient to return only first permission as granted
$this->mock(GraphClientInterface::class, function ($mock) use ($permissions) {
$mock->shouldReceive('getServicePrincipalPermissions')
->andReturn(new GraphResponse(true, [
'permissions' => [$permissions[0]['key']],
]));
});
$tenant = Tenant::create([
'tenant_id' => 'tenant-missing',
'name' => 'Tenant Missing',
]);
$first = $permissions[0]['key'];
TenantPermission::create([
'tenant_id' => $tenant->id,
'permission_key' => $first,
'status' => 'ok',
]);
// Use liveCheck=true to trigger Graph API call
$result = app(TenantPermissionService::class)->compare($tenant, null, true, true);
expect($result['overall_status'])->toBe('missing');
$missingKey = $permissions[1]['key'] ?? null;
if ($missingKey) {
$this->assertDatabaseHas('tenant_permissions', [
'tenant_id' => $tenant->id,
'permission_key' => $missingKey,
'status' => 'missing',
]);
}
});
it('reports error statuses from graph comparison', function () {
// Mock GraphClient to return an error
$this->mock(GraphClientInterface::class, function ($mock) {
$mock->shouldReceive('getServicePrincipalPermissions')
->andReturn(new GraphResponse(false, [], 500, ['Graph API error']));
});
$tenant = Tenant::create([
'tenant_id' => 'tenant-error',
'name' => 'Tenant Error',
]);
$permissions = requiredPermissions();
$first = $permissions[0]['key'];
$result = app(TenantPermissionService::class)->compare($tenant, [
$first => [
'status' => 'error',
'details' => ['message' => 'forbidden'],
],
]);
expect($result['overall_status'])->toBe('error');
$this->assertDatabaseHas('tenant_permissions', [
'tenant_id' => $tenant->id,
'permission_key' => $first,
'status' => 'error',
]);
});