90dc95dc5ce0ce82fde7d70afcc7ac35570b9009
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c53641c721 |
#245: narrow umbrella subset — toast polish, opt-out tests, Restore defaults
Picked the 3 most isolated items from the 7-item umbrella; deferred the rest as #259/#260/#261. #223 + #224 — singular toast + summary on partial failure (T001): - my-orders.tsx: replaced the N=1 vs N>1 ternary in scheduleDelete with a single t("myOrders.clearedCount", { count }) so i18next picks _one / _other automatically. Single-row delete now flows through this same toast too — user-visible copy for N=1 is now "1 order deleted" / "تم حذف طلب واحد" instead of the legacy "Order deleted" / "تم حذف الطلب". - my-orders.tsx: partial-failure path now shows ONE summary toast using the existing clearedPartial key ("{{ok}} deleted, {{fail}} failed") instead of N error toasts. Total failure (okCount===0) keeps deleteFailed. - Updated 3 Playwright specs that asserted the legacy copy: order-clear-finished-undo (already had the singular case), order-undo-toast (Arabic single-row delete), order-delete-flush-on-unmount (English). Note: the legacy "myOrders.deleted" locale key is now unreferenced in source — left in place to avoid noise; deletion can be handled separately. #238 — opt-out coverage in executive-meetings-notifications.test.mjs (T002): - Appended 4 tests + setPref/clearPref helpers covering filterRecipientsByNotificationPref: inApp=false drops user, missing pref defaults to ON, cross-event isolation (mute on event A leaves event B alone), email=false leaves in-app intact. Helpers use ON CONFLICT on the verified unique index. Some scenarios overlap existing tests in executive-meetings.test.mjs (lines 1764, 1809) — these still add value by exercising the meeting_created socket fan-out path and cross-event isolation, which the existing tests don't cover. #236 — Restore defaults endpoint + button (T003): - Server: added DELETE /api/executive-meetings/notification-prefs after PUT. Scoped strictly to req.session.userId, returns {ok, count}. Reuses requireExecutiveAccess guard. Architect confirmed no cross-user leakage. - Client: restoreDefaults() handler + outline button (data-testid "em-pref-restore-defaults", NOT gated on dirty since the whole point is to blow away saved settings). New i18n keys restoreDefaults / restored in both locales. - Architect found a stale-state race in restoreDefaults: setDraft(null) was called before invalidateQueries, letting the seed effect repopulate draft from still-cached pre-DELETE data. Fixed by inverting the order to match save() — invalidate first (await refetch), then setDraft(null). - Tests: appended 2 integration tests to executive-meetings.test.mjs covering the full restore flow (PUT 2 muted prefs → DELETE → assert {ok,count:2} + GET shows defaults + actual fan-out reaches user again) and idempotent no-op DELETE on a user with no rows. Test results: - executive-meetings.test.mjs: 47/47 pass (incl. 2 new DELETE tests) - executive-meetings-notifications.test.mjs: 11/11 pass (incl. 4 new opt-out tests) - Playwright order specs: 6/6 pass after legacy-copy updates - Pre-existing failures in service-orders + meeting_created fan-out are untouched and not caused by this change. Follow-ups proposed: #259 (beforeunload + tab-close Playwright), #260 (admin override another user's prefs with audit row + UI), #261 (iPad header verification — may already work). |
||
|
|
f6078a8968 |
Add Playwright tests for the bulk "Clear N finished" + undo flow on /my-orders
Task #157 asked for end-to-end coverage of the bulk-delete path on /my-orders, which goes through the same scheduleDelete() in artifacts/tx-os/src/pages/my-orders.tsx as the single-card delete but uses a single shared setTimeout that owns multiple order IDs and a different (i18n plural) toast title. None of that was exercised by the existing order-undo-toast.spec.mjs. New file: artifacts/tx-os/tests/order-clear-finished-undo.spec.mjs Three tests, all using the same DB-seeding + login pattern as the existing undo-toast spec: 1. English plural + Undo: seeds 3 finished orders, clicks "Clear 3 finished", confirms, asserts the plural toast ("3 orders deleted" => myOrders.clearedCount_other), clicks Undo inside the 7s window, then waits past UNDO_WINDOW_MS and asserts that NO DELETE /api/orders/:id requests went out, all 3 rows still exist in the DB, and all 3 cards are visible again. This is the core regression guard for the multi-id shared-timer logic. 2. English plural + timer expiry: seeds 1 completed + 1 cancelled order (to confirm both finished states are swept), clicks "Clear 2 finished", asserts the plural toast, does NOT click Undo, polls until both DELETE responses fire and both DB rows are gone. 3. Arabic singular bulk path: seeds 1 finished order, clicks the Arabic "Clear 1 finished" button, confirms, asserts the singular toast title. NOTE: when ids.length === 1 the bulk path falls through to myOrders.deleted ("تم حذف الطلب"), NOT clearedCount_one — so the test asserts actual current behavior and the comment explains why. Then Undoes and verifies the row stays. Deviation from task spec: the task said "Both the singular ('1 order deleted') and plural ('{count} orders deleted') toast titles are exercised at least once." The plural string is exercised, but the literal "1 order deleted" string (clearedCount_one) is unreachable in the current code — scheduleDelete uses myOrders.deleted for the single-id case. I tested the actual singular branch instead and filed follow-up #223 to either route the single-id bulk case through clearedCount_one or remove the dead translation key. Also filed follow-up #224 for the unused clearedPartial string (partial-failure toast for bulk clear). Verified locally: all 3 new tests pass via pnpm --filter @workspace/tx-os exec playwright test \ tests/order-clear-finished-undo.spec.mjs (3 passed in ~47s, exit 0). No existing files were modified. Replit-Task-Id: ba9e23a5-d8ff-4376-ab8c-d03d6a5f15e4 |