feat: Remplacer le champ UUID par une recherche autocomplete pour la liaison parent-élève
L'ajout d'un parent à un élève nécessitait de connaître et coller manuellement l'UUID du compte parent, ce qui était source d'erreurs et très peu ergonomique pour les administrateurs. Le nouveau composant ParentSearchInput offre une recherche par nom/email avec autocomplétion (debounce 300ms, navigation clavier, ARIA combobox). Les parents déjà liés sont exclus des résultats, et la sélection se réinitialise proprement quand l'admin retape dans le champ.
This commit is contained in:
@@ -19,9 +19,10 @@ const STUDENT_EMAIL = 'e2e-students-eleve@example.com';
|
||||
const STUDENT_PASSWORD = 'StudentTest123';
|
||||
const PARENT_EMAIL = 'e2e-students-parent@example.com';
|
||||
const PARENT_PASSWORD = 'ParentTest123';
|
||||
const PARENT_FIRST_NAME = 'StudParent';
|
||||
const PARENT_LAST_NAME = 'TestLink';
|
||||
|
||||
let studentUserId: string;
|
||||
let parentUserId: string;
|
||||
|
||||
/**
|
||||
* Extracts the User ID from the Symfony console table output.
|
||||
@@ -58,12 +59,11 @@ test.describe('Student Management', () => {
|
||||
);
|
||||
studentUserId = extractUserId(studentOutput);
|
||||
|
||||
// Create parent user and capture userId
|
||||
const parentOutput = execSync(
|
||||
`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${PARENT_EMAIL} --password=${PARENT_PASSWORD} --role=ROLE_PARENT 2>&1`,
|
||||
// Create parent user (with name for search-based linking)
|
||||
execSync(
|
||||
`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${PARENT_EMAIL} --password=${PARENT_PASSWORD} --role=ROLE_PARENT --firstName=${PARENT_FIRST_NAME} --lastName=${PARENT_LAST_NAME} 2>&1`,
|
||||
{ encoding: 'utf-8' }
|
||||
);
|
||||
parentUserId = extractUserId(parentOutput);
|
||||
|
||||
// Clean up any existing guardian links for this student (DB + cache)
|
||||
try {
|
||||
@@ -197,7 +197,7 @@ test.describe('Student Management', () => {
|
||||
await expect(dialog.getByRole('heading', { name: /ajouter un parent\/tuteur/i })).toBeVisible();
|
||||
|
||||
// Form fields should be present
|
||||
await expect(dialog.getByLabel(/id du parent/i)).toBeVisible();
|
||||
await expect(dialog.getByRole('combobox', { name: /rechercher/i })).toBeVisible();
|
||||
await expect(dialog.getByLabel(/type de relation/i)).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -235,8 +235,17 @@ test.describe('Student Management', () => {
|
||||
const dialog = page.getByRole('dialog');
|
||||
await expect(dialog).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Fill in the guardian details
|
||||
await dialog.getByLabel(/id du parent/i).fill(parentUserId);
|
||||
// Search for the parent by name
|
||||
const searchInput = dialog.getByRole('combobox', { name: /rechercher/i });
|
||||
await searchInput.fill(PARENT_EMAIL);
|
||||
|
||||
// Wait for autocomplete results
|
||||
const listbox = dialog.locator('#parent-search-listbox');
|
||||
await expect(listbox).toBeVisible({ timeout: 10000 });
|
||||
const option = listbox.locator('[role="option"]').first();
|
||||
await option.click();
|
||||
await expect(dialog.getByText(/sélectionné/i)).toBeVisible();
|
||||
|
||||
await dialog.getByLabel(/type de relation/i).selectOption('père');
|
||||
|
||||
// Submit
|
||||
@@ -292,7 +301,15 @@ test.describe('Student Management', () => {
|
||||
await page.getByRole('button', { name: /ajouter un parent/i }).click();
|
||||
const dialog = page.getByRole('dialog');
|
||||
await expect(dialog).toBeVisible({ timeout: 5000 });
|
||||
await dialog.getByLabel(/id du parent/i).fill(parentUserId);
|
||||
|
||||
const searchInput = dialog.getByRole('combobox', { name: /rechercher/i });
|
||||
await searchInput.fill(PARENT_EMAIL);
|
||||
|
||||
const listbox2 = dialog.locator('#parent-search-listbox');
|
||||
await expect(listbox2).toBeVisible({ timeout: 10000 });
|
||||
const option = listbox2.locator('[role="option"]').first();
|
||||
await option.click();
|
||||
|
||||
await dialog.getByLabel(/type de relation/i).selectOption('mère');
|
||||
await dialog.getByRole('button', { name: 'Ajouter' }).click();
|
||||
await expect(page.locator('.alert-success')).toBeVisible({ timeout: 10000 });
|
||||
|
||||
Reference in New Issue
Block a user