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([]); });