feat: Permettre aux parents de consulter l'emploi du temps de leurs enfants
Les parents avaient accès au lien "Emploi du temps" dans la navigation,
mais le dashboard n'affichait aucune donnée réelle : la section EDT
restait un placeholder vide ("L'emploi du temps sera disponible...").
Cette implémentation connecte le dashboard parent aux vrais endpoints API
(GET /api/me/children/{childId}/schedule/day|week/{date} et le résumé
multi-enfants), affiche le ScheduleWidget avec le prochain cours mis en
évidence (AC1), permet de cliquer sur chaque enfant dans le résumé pour
voir son EDT détaillé (AC2), et met en cache les endpoints parent dans le
Service Worker pour le mode offline (AC5).
Le handler backend est optimisé pour ne résoudre que l'enfant demandé
(via childId optionnel dans la query) au lieu de tous les enfants à chaque
appel, et les fonctions utilitaires dupliquées (formatSyncDate, timezone)
sont factorisées.
This commit is contained in:
@@ -59,7 +59,7 @@ function resolveDeterministicIds(): { schoolId: string; academicYearId: string }
|
||||
*/
|
||||
function currentWeekdayIso(): number {
|
||||
const jsDay = new Date().getDay(); // 0=Sun, 1=Mon...6=Sat
|
||||
if (jsDay === 0) return 1; // Sunday → use Monday
|
||||
if (jsDay === 0) return 5; // Sunday → use Friday
|
||||
if (jsDay === 6) return 5; // Saturday → use Friday
|
||||
return jsDay;
|
||||
}
|
||||
@@ -101,14 +101,13 @@ async function navigateToSeededDay(page: import('@playwright/test').Page) {
|
||||
const prevBtn = page.getByLabel('Précédent');
|
||||
await expect(prevBtn).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Retry clicking — on webkit, Svelte 5 event delegation needs time to hydrate
|
||||
const deadline = Date.now() + 15000;
|
||||
// Navigate one day at a time, waiting for each load to complete before clicking again
|
||||
const deadline = Date.now() + 20000;
|
||||
let navigated = false;
|
||||
while (Date.now() < deadline && !navigated) {
|
||||
for (let i = 0; i < back; i++) {
|
||||
await prevBtn.click();
|
||||
}
|
||||
await page.waitForTimeout(500);
|
||||
await prevBtn.click();
|
||||
// Wait for the schedule API call to complete before checking/clicking again
|
||||
await page.waitForTimeout(1500);
|
||||
const title = await page.locator('.day-title').textContent();
|
||||
if (title && targetPattern.test(title)) {
|
||||
navigated = true;
|
||||
@@ -118,6 +117,9 @@ async function navigateToSeededDay(page: import('@playwright/test').Page) {
|
||||
await expect(page.locator('.day-title').getByText(targetPattern)).toBeVisible({
|
||||
timeout: 5000
|
||||
});
|
||||
|
||||
// Wait for any in-flight schedule loads to settle after reaching target day
|
||||
await page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
async function loginAsStudent(page: import('@playwright/test').Page) {
|
||||
@@ -134,6 +136,16 @@ test.describe('Student Schedule Consultation (Story 4.3)', () => {
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.beforeAll(async () => {
|
||||
// Clear caches to prevent stale data from previous runs
|
||||
try {
|
||||
execSync(
|
||||
`docker compose -f "${composeFile}" exec -T php php bin/console cache:pool:clear cache.rate_limiter users.cache --env=dev 2>&1`,
|
||||
{ encoding: 'utf-8' }
|
||||
);
|
||||
} catch {
|
||||
// Cache pools may not exist
|
||||
}
|
||||
|
||||
// Create student user
|
||||
execSync(
|
||||
`docker compose -f "${composeFile}" exec -T php php bin/console app:dev:create-test-user --tenant=ecole-alpha --email=${STUDENT_EMAIL} --password=${STUDENT_PASSWORD} --role=ROLE_ELEVE 2>&1`,
|
||||
@@ -316,9 +328,9 @@ test.describe('Student Schedule Consultation (Story 4.3)', () => {
|
||||
timeout: 15000
|
||||
});
|
||||
|
||||
// Navigate to next day
|
||||
// Navigate to next day — wait for the load to settle before navigating back
|
||||
await page.getByLabel('Suivant').click();
|
||||
await page.waitForTimeout(300);
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
// Then navigate back
|
||||
await page.getByLabel('Précédent').click();
|
||||
|
||||
Reference in New Issue
Block a user