Files

87 lines
7.0 KiB
TypeScript

import { test, expect } from '@playwright/test';
import { testAccount } from '../helpers/account';
test('local recovery settings, masked secret, SSO greeting and offline re-entry', async ({ page, context }) => {
const request = context.request;
const state = await (await request.get('/api/local-admin/status')).json();
if (state.setupRequired) {
expect((await request.post('/api/local-admin/setup', { headers: { 'x-model-request': '1' }, data: { ...testAccount, setupToken: 'isolated-test-bootstrap' } })).ok()).toBe(true);
await request.post('/api/auth/logout', { headers: { 'x-model-request': '1' } });
}
await page.goto('/');
await expect(page.getByRole('button', { name: 'כניסה עם חשבון המעבדה' })).toBeVisible();
await expect(page.locator('a[href="/local-admin"]')).toHaveCount(0);
await page.goto('/local-admin');
await page.getByLabel('שם משתמש', { exact: true }).fill(testAccount.username);
await page.getByLabel('סיסמה', { exact: true }).fill(testAccount.password);
await page.getByRole('button', { name: 'כניסה מקומית', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Synology SSO Server' })).toBeVisible();
await page.getByLabel('כתובת המנפיק (Issuer)', { exact: true }).fill('http://localhost:4005');
await page.getByLabel('כתובת גילוי (Well-known URL)').fill('http://localhost:4005/.well-known/openid-configuration');
await page.getByLabel('מזהה לקוח (Application ID)', { exact: true }).fill('model-test');
await page.getByLabel('סוד לקוח (Application Secret)').fill('mock-test-secret');
await page.getByLabel('כתובת חזרה (Redirect URI)').fill('http://localhost:4174/api/auth/callback');
await page.getByLabel('הרשאות (Scopes)').fill('openid profile email groups');
await page.getByLabel('הגבלת הכניסה לפי קבוצות Synology / AD').check();
await page.getByLabel('שם שדה הקבוצות').fill('groups');
await page.getByLabel('קבוצות מורשות — קבוצה בכל שורה').fill('model-delivery-users');
await page.getByLabel('הפעלת כניסה ארגונית').check();
await page.getByLabel('בקשת offline_access לחידוש הכניסה').check();
await page.getByRole('button', { name: 'שמירת הגדרות', exact: true }).click();
await expect(page.getByRole('status')).toContainText('ההגדרות נשמרו');
await expect(page.getByLabel('סוד לקוח (Application Secret)')).toHaveValue('');
await page.getByRole('button', { name: 'בדיקת ההגדרות השמורות' }).click();
await expect(page.getByRole('status')).toContainText('החיבור לשרת אומת');
const directory = page.locator('.directory-settings');
await expect(directory.getByRole('heading', { name: 'שמות מתוך Active Directory' })).toBeVisible();
await directory.getByLabel('קריאת שמות מהספרייה', { exact: true }).uncheck();
await directory.getByLabel('כתובת הספרייה (LDAPS)').fill('ldaps://directory.example.invalid:636');
await directory.getByLabel('חשבון קריאה (Bind DN / UPN)').fill('reader@example.invalid');
await directory.getByLabel('סיסמת חשבון הקריאה').fill('browser-test-directory-secret');
await directory.getByRole('button', { name: 'שמירת הגדרות הספרייה' }).click();
await expect(directory.getByRole('status')).toContainText('הגדרות הספרייה נשמרו');
await expect(directory.getByLabel('סיסמת חשבון הקריאה')).toHaveValue('');
await directory.getByLabel('מזהה SSO לבדיקה').fill('REZNIK\\test.sso');
await directory.getByRole('button', { name: 'בדיקת שם מהספרייה' }).click();
await expect(directory.getByRole('alert')).toContainText('קריאת השמות כבויה');
await page.setViewportSize({ width: 390, height: 844 });
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe(true);
await page.screenshot({ path: 'test-results/model-delivery-local-admin.png', fullPage: true });
await page.getByRole('link', { name: 'פתיחת האפליקציה' }).click();
await expect(page.locator('.greeting')).toHaveText(`שלום, ${testAccount.displayName}`);
await page.getByRole('button', { name: 'החשבון שלי' }).click();
await page.getByRole('button', { name: 'יציאה מהחשבון' }).click();
await page.getByRole('button', { name: 'כניסה עם חשבון המעבדה' }).click();
await expect(page.locator('.greeting')).toHaveText('שלום, טום בדיקה');
await page.getByRole('button', { name: 'החשבון שלי' }).click();
await page.getByLabel('שם לתצוגה', { exact: true }).fill('תום רוף בדיקה');
await page.getByRole('button', { name: 'שמירת השם', exact: true }).click();
await expect(page.locator('.greeting')).toHaveText('שלום, תום רוף בדיקה');
const session = await (await request.get('/api/auth/session')).json();
expect(session.user.authProvider).toBe('oidc');
expect(session.user.groups).toEqual(['model-delivery-users']);
expect(Object.keys(session).sort()).toEqual(['expiresAt', 'user']);
expect(await page.evaluate(() => Object.keys(localStorage).some(key => /token|secret/i.test(key)))).toBe(false);
await page.evaluate(async () => { await navigator.serviceWorker.ready; });
await page.reload();
await expect.poll(() => page.evaluate(() => Boolean(navigator.serviceWorker.controller))).toBe(true);
await context.setOffline(true);
await page.reload();
await expect(page.locator('.greeting')).toHaveText('שלום, תום רוף בדיקה');
await context.setOffline(false);
await page.getByRole('button', { name: 'החשבון שלי' }).click();
await page.getByRole('button', { name: 'שימוש בשם הארגוני' }).click();
await expect(page.locator('.greeting')).toHaveText('שלום, טום בדיקה');
// Restore this reusable test user's preference after checking offline persistence.
expect((await request.post('/api/auth/profile', { headers: { 'x-model-request': '1', 'x-model-user': session.user.id }, data: { displayName: 'טום בדיקה' } })).ok()).toBe(true);
await page.goto('/local-admin');
await expect(page.getByRole('button', { name: 'כניסה מקומית', exact: true })).toBeVisible();
await expect(page.getByLabel('סוד לקוח (Application Secret)')).toHaveCount(0);
await expect(page.locator('.directory-settings')).toHaveCount(0);
// Only the isolated test database is configured by this test. Disable its test provider afterwards.
const local = await request.post('/api/local-admin/login', { headers: { 'x-model-request': '1' }, data: { username: testAccount.username, password: testAccount.password } });
expect(local.ok()).toBe(true);
const { secretConfigured: _, ...settings } = await (await request.get('/api/local-admin/settings')).json();
expect((await request.post('/api/local-admin/settings', { headers: { 'x-model-request': '1' }, data: { ...settings, enabled: false } })).ok()).toBe(true);
});