diet-guard/app/test
Krzysztof kuhy Rudnicki 3d82ddefd4 feat: let the phone fetch and bank the catering delivery itself
The phone now walks the panel on its own -- login, active order, delivery,
menu -- parses the dishes and banks them, so the feature works with the PC
switched off. Read-only: nothing here logs a meal.

`package:http` has no cookie jar, so the `SESSION` cookie is read off the login
response and replayed by hand. `Response.headers` folds duplicate `set-cookie`
values into one comma-joined string, so the parser splits on both `,` and `;`
and looks for the named cookie rather than assuming the header holds only it --
tested against both orderings and against a panel that sets no session cookie
at all.

Android-only, as decided: the panel sends no CORS headers, so a browser cannot
call it. `refreshDelivery` checks `kIsWeb` first and returns the unsupported
reason without touching the network. No `dart:io` anywhere -- `package:http`
compiles for web, it is the panel that refuses, not the toolchain, so this
needs no `_io`/`_web` seam.

The idempotency guard is ported with its teeth: `addManualEntry` restamps
`editedAt` unconditionally, so re-banking an unchanged dish republishes the
whole curated bank to every peer. `bankDishes` compares the nutritional fields
first and returns a write *count*, which is what the tests assert on -- "the
entry exists" passes while this misbehaves. The comparison is numeric, not
string, so `270 == 270.0` is a match exactly as in Python's `_matches`.

Every failure becomes a reason string, never a throw, so a catering outage
cannot break the caller: a rejected login, a delivery whose dishes all fail
the unit check, and missing credentials each have a test.

One test bug worth noting: the assertion that nothing is logged was missing an
`await` and so was comparing a Future against `isEmpty` -- the single most
important guarantee in this file was passing vacuously until the split forced
it to run.

Test files split three ways for the 250-line cap; block counts checked against
the pre-split file (16 either side), not just a green suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQpCiPaSbyRpwsLkH3dgsX
2026-08-23 08:30:21 +02:00
..
desktop Split the remaining seven Dart test files 2026-08-15 20:53:55 +02:00
models Read the meal schedule from a forward-only history (Dart) 2026-08-16 14:41:37 +02:00
screens Rebuild the slot row when settings changes the schedule 2026-08-16 15:12:57 +02:00
services feat: let the phone fetch and bank the catering delivery itself 2026-08-23 08:30:21 +02:00
widgets Read the meal schedule from a forward-only history (Dart) 2026-08-16 14:41:37 +02:00
fake_notifications.dart Add OAuth device flow, background notifications, and fix AGP9 release crash (Milestones 3–4) 2026-06-25 17:29:23 +02:00
fake_secure_storage.dart Add Flutter half of cross-device sync (Milestone 3) 2026-06-22 22:42:27 +02:00
firebase_backend_google_test.dart Split the last four Dart lib files; file-length gate now reports zero 2026-08-15 21:07:24 +02:00
google_platform_test.dart Add Google sign-in support for the Firebase sync account 2026-08-12 23:36:10 +02:00
google_sign_in_backend_test.dart Add Google sign-in support for the Firebase sync account 2026-08-12 23:36:10 +02:00
keyboard_operability_test.dart Stop two keyboard tests hanging, and make the CI mirror mirror CI 2026-08-04 21:50:15 +02:00
kuchnia_bank_interop_test.dart fix: keep the catering dish queue alive across a submit 2026-08-22 23:36:53 +02:00
kuchnia_parity_test.dart feat: mirror the catering parser and slot spread in Dart, gated by one fixture 2026-08-23 08:00:54 +02:00
repo_invariants_test.dart Automate CLAUDE.md's structural rules, then cut it to 189 lines 2026-08-15 16:39:57 +02:00
sync_merge_kuchnia_test.dart feat: carry the catering credential to the phone 2026-08-23 08:25:27 +02:00
widget_test.dart app: run the companion app's desktop target as a web build 2026-07-20 16:31:32 +02:00