import { test, expect } from '@playwright/test'; test.describe('OAuth Callback Pages', () => { test.describe('Google callback', () => { test('shows loading state while processing', async ({ page }) => { // Intercept token exchange to keep it pending await page.route('**/auth/google/callback**', (_route) => new Promise(() => { // Never resolve — keeps loading state visible }), ); await page.goto('/auth/callback/google?code=test-code'); // Should show a loading/spinner state await expect(page.locator('.animate-spin').first()).toBeVisible({ timeout: 5000 }); }); test('redirects to login with error on failure', async ({ page }) => { await page.route('**/auth/google/callback**', (route) => route.fulfill({ status: 401, contentType: 'application/json', body: JSON.stringify({ message: 'OAuth failed' }), }), ); await page.goto('/auth/callback/google?code=bad-code'); await expect(page).toHaveURL(/\/login\?error=/, { timeout: 10000 }); }); }); test.describe('Zalo callback', () => { test('shows loading state while processing', async ({ page }) => { await page.route('**/auth/zalo/callback**', (_route) => new Promise(() => { // Never resolve }), ); await page.goto('/auth/callback/zalo?code=test-code'); await expect(page.locator('.animate-spin').first()).toBeVisible({ timeout: 5000 }); }); test('redirects to login with error on failure', async ({ page }) => { await page.route('**/auth/zalo/callback**', (route) => route.fulfill({ status: 401, contentType: 'application/json', body: JSON.stringify({ message: 'OAuth failed' }), }), ); await page.goto('/auth/callback/zalo?code=bad-code'); await expect(page).toHaveURL(/\/login\?error=/, { timeout: 10000 }); }); }); });