create(); $app = Application::factory()->create(['name' => 'Test Application']); $this->actingAs($user); // Set up session data session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); expect($component->get('client')->id)->toBe($app->id); expect($component->get('client')->name)->toBe('Test Application'); expect($component->get('redirectUrl'))->toBe('https://example.com/callback'); }); it('displays client application name', function () { $user = User::factory()->create(['name' => 'John Doe']); $app = Application::factory()->create(['name' => 'My OAuth App']); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); $component->assertSeeText('My OAuth App') ->assertSeeText('John Doe') ->assertSeeText('about to log into') ->assertSeeText('Logging in as:'); }); it('approves and redirects to redirect URL', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback?code=123']); Livewire::test(ConsentScreen::class) ->call('approve') ->assertRedirect('https://example.com/callback?code=123'); // Check that session data is cleared expect(session('app_id'))->toBeNull(); expect(session('redirect_on_confirm'))->toBeNull(); }); it('denies and redirects to dashboard', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); Livewire::test(ConsentScreen::class) ->call('deny') ->assertRedirect(route('dashboard')); }); it('clears session data on approval', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); // Verify session data exists before approval expect(session('app_id'))->toBe($app->id); expect(session('redirect_on_confirm'))->toBe('https://example.com/callback'); Livewire::test(ConsentScreen::class) ->call('approve'); // Verify session data is cleared after approval expect(session('app_id'))->toBeNull(); expect(session('redirect_on_confirm'))->toBeNull(); }); it('handles different redirect URL formats', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); $redirectUrls = [ 'https://example.com/oauth/callback', 'http://localhost:3000/auth/callback?state=xyz', 'https://app.example.com:8080/callback?code=abc&state=def' ]; foreach ($redirectUrls as $redirectUrl) { session(['app_id' => $app->id, 'redirect_on_confirm' => $redirectUrl]); Livewire::test(ConsentScreen::class) ->call('approve') ->assertRedirect($redirectUrl); // Reset session for next iteration session()->flush(); } }); it('can be rendered with valid session data', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); $component->assertStatus(200); }); it('requires redirect URL in session', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); // Set only app_id, missing redirect_on_confirm session(['app_id' => $app->id]); // This should fail because redirectUrl is typed as string and session('redirect_on_confirm') returns null expect(fn() => Livewire::test(ConsentScreen::class)) ->toThrow(\Illuminate\View\ViewException::class); }); it('displays confirm and cancel buttons', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); $component->assertSeeText('Confirm') ->assertSeeText('Cancel'); }); it('shows user name in consent message', function () { $user = User::factory()->create(['name' => 'Alice Smith']); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); $component->assertSeeText('Alice Smith'); }); it('requires session data to mount', function () { $user = User::factory()->create(); $this->actingAs($user); // No session data set - should fail due to strict typing expect(fn() => Livewire::test(ConsentScreen::class)) ->toThrow(\Illuminate\View\ViewException::class); }); it('handles application with special characters in name', function () { $user = User::factory()->create(); $app = Application::factory()->create(['name' => "O'Reilly's OAuth & API Service!"]); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); $component->assertSeeText("O'Reilly's OAuth & API Service!"); }); it('preserves URL parameters in redirect URL', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); $complexRedirectUrl = 'https://example.com/callback?code=xyz&state=abc123&scope=read%20write'; session(['app_id' => $app->id, 'redirect_on_confirm' => $complexRedirectUrl]); Livewire::test(ConsentScreen::class) ->call('approve') ->assertRedirect($complexRedirectUrl); }); it('does not redirect when denying without clearing app session data', function () { $user = User::factory()->create(); $app = Application::factory()->create(); $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); Livewire::test(ConsentScreen::class) ->call('deny') ->assertRedirect(route('dashboard')); // Note: deny() doesn't clear session data, only approve() does // This might be intentional behavior for security reasons }); it('works with different user types', function () { $adminUser = User::factory()->create(['is_admin' => true, 'name' => 'Admin User']); $regularUser = User::factory()->create(['is_admin' => false, 'name' => 'Regular User']); $app = Application::factory()->create(['name' => 'Test App']); foreach ([$adminUser, $regularUser] as $user) { $this->actingAs($user); session(['app_id' => $app->id, 'redirect_on_confirm' => 'https://example.com/callback']); $component = Livewire::test(ConsentScreen::class); expect($component->get('client')->id)->toBe($app->id); $component->assertSeeText($user->name); // Clean up for next iteration auth()->logout(); session()->flush(); } });