86 lines
2.7 KiB
TypeScript
86 lines
2.7 KiB
TypeScript
/**
|
|
* SmartAuth E2E — Account Linking
|
|
* Tests OAuth provider linking/unlinking flows in admin dashboard.
|
|
*/
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('SmartAuth: Account Linking', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/login');
|
|
await page.evaluate(() => {
|
|
localStorage.setItem('admin_access_token', 'mock-token');
|
|
localStorage.setItem('admin_refresh_token', 'mock-refresh');
|
|
localStorage.setItem(
|
|
'admin_auth_user',
|
|
JSON.stringify({
|
|
email: 'admin@acme.com',
|
|
name: 'Test Admin',
|
|
role: 'super_admin',
|
|
})
|
|
);
|
|
});
|
|
|
|
// Mock auth state — logged in as admin
|
|
await page.route('**/api/auth/me', route =>
|
|
route.fulfill({
|
|
status: 200,
|
|
body: JSON.stringify({
|
|
id: 'usr_test',
|
|
email: 'admin@acme.com',
|
|
role: 'admin',
|
|
displayName: 'Test Admin',
|
|
providers: [{ provider: 'google', email: 'admin@acme.com', linkedAt: '2026-01-01' }],
|
|
mfaEnabled: false,
|
|
}),
|
|
})
|
|
);
|
|
});
|
|
|
|
test('should display linked providers', async ({ page }) => {
|
|
await page.route('**/api/auth/providers', route =>
|
|
route.fulfill({
|
|
status: 200,
|
|
body: JSON.stringify([
|
|
{ provider: 'google', email: 'admin@acme.com', linkedAt: '2026-01-01T00:00:00Z' },
|
|
]),
|
|
})
|
|
);
|
|
await page.goto('/settings/security');
|
|
await expect(page.getByRole('main')).toContainText('Google');
|
|
await expect(page.getByRole('main')).toContainText('admin@acme.com');
|
|
});
|
|
|
|
test('should show link provider button', async ({ page }) => {
|
|
await page.route('**/api/auth/providers', route =>
|
|
route.fulfill({ status: 200, body: JSON.stringify([]) })
|
|
);
|
|
await page.goto('/settings/security');
|
|
await expect(page.getByRole('button', { name: /link provider/i })).toBeVisible();
|
|
});
|
|
|
|
test('should prevent unlinking last provider', async ({ page }) => {
|
|
await page.route('**/api/auth/providers', route =>
|
|
route.fulfill({
|
|
status: 200,
|
|
body: JSON.stringify([
|
|
{ provider: 'google', email: 'admin@acme.com', linkedAt: '2026-01-01T00:00:00Z' },
|
|
]),
|
|
})
|
|
);
|
|
await page.route('**/api/auth/providers/google', route =>
|
|
route.fulfill({
|
|
status: 400,
|
|
body: JSON.stringify({ error: 'Cannot unlink last auth method' }),
|
|
})
|
|
);
|
|
await page.goto('/settings/security');
|
|
// Attempt unlink
|
|
const unlinkButton = page.getByRole('button', { name: /unlink/i });
|
|
if (await unlinkButton.isVisible()) {
|
|
await unlinkButton.click();
|
|
await expect(page.getByText(/cannot unlink/i)).toBeVisible();
|
|
}
|
|
});
|
|
});
|