singleloginsystem/tests/Feature/OidcAppViewTest.php
= 9c9e3ca43c Feat: Update App details from view page
- Implemented the `show` page for managing URL apps with functionalities like updating name, logo, access URL, and connection status.
- Added `UrlAppViewTest` for feature testing, ensuring role-based access, and validation of edit actions.
- Updated navigation to route URL apps to their respective management views.
- Enhanced `OidcService` to handle updated app settings and redirect URIs.
2026-06-22 11:20:49 +00:00

163 lines
5.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Models\{ConnectedApp, ConnectionProtocol, ConnectionStatus, User};
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Laravel\Passport\Client;
use Livewire\Livewire;
beforeEach(function (): void {
$this->seed(Database\Seeders\PermissionSeeder::class);
$this->seed(Database\Seeders\DefaultRoleWithPermissionSeeder::class);
$this->seed(Database\Seeders\ConnectionProtocolSeeder::class);
$this->seed(Database\Seeders\ConnectionProviderSeeder::class);
$this->seed(Database\Seeders\ConnectionStatusSeeder::class);
$this->oidcProtocol = ConnectionProtocol::query()->where('name', 'oidc')->firstOrFail();
$this->status = ConnectionStatus::query()->where('name', 'connected')->firstOrFail();
// Create a mock OIDC application in database
$this->connectedApp = ConnectedApp::query()->create([
'name' => 'Test OIDC App',
'slug' => 'test-oidc-app',
'connection_protocol_id' => $this->oidcProtocol->id,
'connection_provider_id' => 0,
'connection_status_id' => $this->status->id,
'settings' => [
'access_url' => 'https://test-oidc-app.example.com',
'signOutUris' => ['https://test-oidc-app.example.com/logout'],
],
]);
// Create corresponding Passport Client
$this->passportClient = Client::query()->create([
'id' => (string) Str::uuid(),
'name' => 'Test OIDC App',
'secret' => bcrypt('old-secret-value'),
'provider' => 'users',
'redirect_uris' => ['https://test-oidc-app.example.com/callback'],
'grant_types' => ['authorization_code'],
'revoked' => false,
]);
});
it('authorizes only admin users to access the OIDC view page', function (): void {
$user = User::factory()->create();
$user->assignRole('user'); // standard user
$this->actingAs($user);
// Should fail with 403 Forbidden
Livewire::actingAs($user)
->test('pages::apps.oidc.show', ['id' => $this->connectedApp->id])
->assertForbidden();
$admin = User::factory()->create();
$admin->assignRole('admin'); // admin user
$this->actingAs($admin);
// Should load successfully
Livewire::actingAs($admin)
->test('pages::apps.oidc.show', ['id' => $this->connectedApp->id])
->assertOk();
});
it('displays client credentials and allows generating a new client secret', function (): void {
$admin = User::factory()->create();
$admin->assignRole('admin');
$this->actingAs($admin);
$component = Livewire::test('pages::apps.oidc.show', ['id' => $this->connectedApp->id])
->assertSet('appId', $this->connectedApp->id)
->assertSet('passportClient.id', $this->passportClient->id);
// Call generateNewSecret
$component->call('generateNewSecret');
// Get plain secret set in component
$newSecretPlain = $component->get('newSecretPlain');
expect($newSecretPlain)->toBeString()
->and(mb_strlen($newSecretPlain))->toBe(40);
// Verify it is updated in DB
$this->passportClient->refresh();
expect(Hash::check($newSecretPlain, $this->passportClient->secret))->toBeTrue();
});
it('allows updating app name and logo', function (): void {
$admin = User::factory()->create();
$admin->assignRole('admin');
$this->actingAs($admin);
$logo = Illuminate\Http\UploadedFile::fake()->image('logo.png');
Livewire::test('pages::apps.oidc.show', ['id' => $this->connectedApp->id])
->call('openEditGeneralModal')
->assertSet('editName', 'Test OIDC App')
->set('editName', 'Updated OIDC App Name')
->set('editLogo', $logo)
->call('saveGeneralInfo')
->assertHasNoErrors();
// Verify it updated in Database
$this->connectedApp->refresh();
expect($this->connectedApp->name)->toBe('Updated OIDC App Name')
->and($this->connectedApp->logo)->not->toBeNull();
// Verify Passport client name was updated
$this->passportClient->refresh();
expect($this->passportClient->name)->toBe('Updated OIDC App Name');
});
it('allows updating connection status via changeStatus', function (): void {
$admin = User::factory()->create();
$admin->assignRole('admin');
$this->actingAs($admin);
// Initial status should be 'connected'
expect($this->connectedApp->status->name)->toBe('connected');
Livewire::test('pages::apps.oidc.show', ['id' => $this->connectedApp->id])
->call('changeStatus', 'disconnected')
->assertHasNoErrors();
// Verify status updated in DB
$this->connectedApp->refresh();
expect($this->connectedApp->status->name)->toBe('disconnected');
});
it('allows updating redirect URIs', function (): void {
$admin = User::factory()->create();
$admin->assignRole('admin');
$this->actingAs($admin);
Livewire::test('pages::apps.oidc.show', ['id' => $this->connectedApp->id])
->call('startEditRedirects')
->assertSet('editSignInUris', ['https://test-oidc-app.example.com/callback'])
->assertSet('editSignOutUris', ['https://test-oidc-app.example.com/logout'])
// Add a new sign-in URI
->call('addRepeaterItem', 'editSignInUris')
->set('editSignInUris.1', 'https://test-oidc-app.example.com/callback2')
// Remove a sign-out URI
->call('removeRepeaterItem', 'editSignOutUris', 0)
->call('saveRedirectUris')
->assertHasNoErrors();
// Verify changes in Passport Client and Connected App settings
$this->passportClient->refresh();
expect($this->passportClient->redirect_uris)->toBe([
'https://test-oidc-app.example.com/callback',
'https://test-oidc-app.example.com/callback2',
]);
$this->connectedApp->refresh();
expect($this->connectedApp->settings['signOutUris'] ?? [])->toBe([]);
});