Files
TX/artifacts/api-server/tests
riyadhafraa 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).
2026-05-01 07:30:00 +00:00
..