groupe-meditation/frontend/e2e/public.spec.js

156 lines
6 KiB
JavaScript
Raw Normal View History

import { expect, test } from '@playwright/test';
const groupes = [
{
id: 'groupe-alpha',
nom: 'Groupe Alpha',
district: '87-16',
adresse_local: '123 rue Principale, Saint-Bruno',
jour_reunion: 'mardi',
heure_reunion: '19:30',
assemblee_affaires_ordre: 'premiere',
format_reunion: 'Discussion ouverte',
},
{
id: 'groupe-demo',
nom: 'Groupe Démonstration',
district: '87-16',
adresse_local: 'Salle de démonstration',
jour_reunion: 'samedi',
heure_reunion: '20:00',
assemblee_affaires_ordre: 'derniere',
format_reunion: 'Formation',
},
];
async function mockPublicApi(page) {
await page.route('**/api/auth/groupes', async (route) => {
await route.fulfill({ json: groupes });
});
}
async function mockSysadminApi(page) {
await page.route('**/api/admin/sysadmin-login', async (route) => {
const body = route.request().postDataJSON();
if (body.pin !== '0000') {
await route.fulfill({ status: 401, json: { detail: 'PIN Sysadmin invalide' } });
return;
}
await route.fulfill({
json: {
access_token: 'instance-admin-token',
token_type: 'bearer',
sysadmin_instance: true,
membre: {
id: 'admin-id',
prenom: 'Sysadmin',
courriel: 'sysadmin',
groupe_id: null,
date_abstinence: null,
is_sysadmin: true,
},
},
});
});
await page.route('**/api/admin/groupes', async (route) => {
await route.fulfill({
json: groupes.map((groupe, index) => ({
...groupe,
lien_aa87: 'https://aa87.org',
tenant_schema: `grp_${index}`,
cree_le: '2026-01-01T00:00:00Z',
membres: index === 0 ? 12 : 14,
reunions: index === 0 ? 52 : 52,
traces: index === 0 ? 120 : 180,
demo: groupe.nom === 'Groupe Démonstration',
protege: groupe.nom === 'Groupe Démonstration',
})),
});
});
await page.route('**/api/admin/sysadmin-pin', async (route) => {
const body = route.request().postDataJSON();
if (body.pin_actuel !== '0000') {
await route.fulfill({ status: 401, json: { detail: 'PIN actuel invalide' } });
return;
}
await route.fulfill({ json: { message: 'PIN sysadmin mis à jour' } });
});
}
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
localStorage.clear();
sessionStorage.clear();
});
await mockPublicApi(page);
});
test('la page publique liste les groupes en tuiles fermées et expose les liens publics', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { name: 'Choisir un groupe' })).toBeVisible();
await expect(page.getByRole('button', { name: /Groupe Alpha/ })).toBeVisible();
await expect(page.getByText('123 rue Principale')).toBeHidden();
await expect(page.getByRole('button', { name: 'Sysadmin' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Charte' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Confidentialité' })).toBeVisible();
await expect(page.getByRole('link', { name: 'Découvrir' })).toBeVisible();
await page.getByRole('button', { name: /Groupe Alpha/ }).click();
await expect(page.getByText('123 rue Principale')).toBeVisible();
await expect(page.getByPlaceholder('Adresse courriel ou identifiant')).toBeVisible();
await expect(page.getByPlaceholder('PIN')).toHaveAttribute('type', 'password');
});
test('les pages publiques Charte et Confidentialité restent accessibles sans connexion', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: 'Charte' }).click();
await expect(page.getByRole('heading', { name: /Charte|Principes/ })).toBeVisible();
await page.goto('/');
await page.getByRole('button', { name: 'Confidentialité' }).click();
await expect(page.getByRole('heading', { name: /Confidentialité/ })).toBeVisible();
});
test('le sysadmin d’instance ouvre la gestion des groupes sans contexte de groupe', async ({ page }) => {
await mockSysadminApi(page);
await page.goto('/');
await page.getByRole('button', { name: 'Sysadmin' }).click();
await page.getByPlaceholder('PIN sysadmin').fill('0000');
await page.getByRole('button', { name: 'Ouvrir' }).click();
await expect(page.getByRole('heading', { name: 'Gestion des groupes' })).toBeVisible();
await expect(page.getByRole('button', { name: 'Créer un groupe' })).toBeVisible();
await expect(page.getByRole('button', { name: /Groupe Alpha/ })).toBeVisible();
await expect(page.getByRole('button', { name: /Groupe Démonstration/ })).toBeVisible();
await expect(page.getByText('Instance · Bonjour Sysadmin')).toBeVisible();
await expect(page.getByText(/Groupe Alpha · Bonjour Sysadmin/)).not.toBeVisible();
});
test('le changement de PIN sysadmin masque les saisies et exige une confirmation', async ({ page }) => {
await mockSysadminApi(page);
await page.goto('/');
await page.getByRole('button', { name: 'Sysadmin' }).click();
await page.getByPlaceholder('PIN sysadmin').fill('0000');
await page.getByRole('button', { name: 'Ouvrir' }).click();
await page.getByRole('button', { name: 'Changer le PIN sysadmin' }).click();
await expect(page.getByPlaceholder('PIN actuel')).toHaveAttribute('type', 'password');
await expect(page.getByPlaceholder('Nouveau PIN', { exact: true })).toHaveAttribute('type', 'password');
await expect(page.getByPlaceholder('Confirmer le nouveau PIN')).toHaveAttribute('type', 'password');
await page.getByPlaceholder('PIN actuel').fill('0000');
await page.getByPlaceholder('Nouveau PIN', { exact: true }).fill('1234');
await page.getByPlaceholder('Confirmer le nouveau PIN').fill('4321');
await page.getByRole('button', { name: 'Enregistrer' }).click();
await expect(page.getByText('La confirmation ne correspond pas')).toBeVisible();
await page.getByPlaceholder('Confirmer le nouveau PIN').fill('1234');
await page.getByRole('button', { name: 'Enregistrer' }).click();
await expect(page.getByText('PIN sysadmin mis à jour')).toBeVisible();
});