diet-guard/diet_guard/tests
Krzysztof kuhy Rudnicki 8905d072d0 feat: carry the catering credential to the phone
The Dart half of the credential sync: a `KuchniaCredentialService` that owns
the value locally, a `sync_merge_kuchnia.dart` adapter mirroring the Python
one, and a `_syncKuchniaCredential` tick alongside the banks and budget. The
phone can now receive the panel password, which is the prerequisite for it
fetching anything itself.

One source of truth, per the answered question: the value lives in the synced
document store and nowhere else. Deliberately *not* mirrored into
`flutter_secure_storage` -- two homes for one value is how a stale password
survives a change made on the other device, and the credential has to be
readable synchronously at merge time anyway.

Gated by a second shared fixture, `tests/fixtures/kuchnia_credential.json`,
asserted by both suites. Two cases carry the weight:

- an **unparsable** edit time must fall back to the same clock on both sides
  (Python catches `ValueError` from `fromisoformat`, Dart's `tryParse` returns
  null). Verified they agree on `wall_time_ms == 0`; mutating that expectation
  fails both suites.
- a **blank half** contributes nothing, so a half-filled settings form cannot
  push an empty-string password that wins LWW against a real one.

`KuchniaCredentialService.init()` is called in the WorkManager isolate as well
as `main()`. A fresh isolate has its own static state and `_syncKuchniaCredential`
no-ops when the singleton is missing, so without it a background tick would
neither publish this device's credential nor receive a peer's -- and on the
phone the background tick is most of the syncing there is. Same class of trap
as the `initSyncDeviceId()` one already documented there.

`.toDouble()` came off the bank record: the fields are already `double`, so it
was a no-op the analyzer flags. The field *types* are what keep the encoding
byte-identical to Python's, and `kuchnia_parity_test.dart` asserts that.

654 Dart tests, 1040 Python tests, 100% Python branch coverage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QQpCiPaSbyRpwsLkH3dgsX
2026-08-23 08:25:27 +02:00
..
__init__.py feat(diet_guard): add meal-logging screen-lock gate with trigger fix 2026-06-10 22:32:39 +02:00
_gate_fixtures.py Let the PC gate set the eating window and meal count 2026-08-16 15:02:35 +02:00
_gate_focus_probe.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_gate_keyboard_probe.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
_gate_layout_probe.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
_gate_measurement.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
_kuchnia_fakes.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
_sync_fakes.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
_tk_fakes_canvas.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
_tk_fakes_containers.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
_tk_fakes.py Make _FakeTclError subclass the real tkinter.TclError 2026-08-15 20:24:11 +02:00
conftest.py feat: sync the catering credential as its own document 2026-08-23 08:12:30 +02:00
test_averages_report.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_averages.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_budget_history_io.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_budget_history.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_budget.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_calendar_averages.py Show weekly and monthly average intake on both devices 2026-08-09 14:59:40 +02:00
test_calendar_view.py Migrate diet_guard to gatelock v0.2.0 per-output locking 2026-07-25 16:56:13 +02:00
test_cli_averages.py Show weekly and monthly average intake on both devices 2026-08-09 14:59:40 +02:00
test_cli_gate.py perf(gate): narrow the pre-lock pull and defer the heavy imports 2026-08-21 12:58:44 +02:00
test_cli_sync.py Migrate sync to shared crdt_sync library (Python + Dart) 2026-07-10 23:49:43 +02:00
test_cli.py perf(cli): publish off-thread so logging a meal returns immediately 2026-08-21 13:22:26 +02:00
test_daystatus.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
test_estimator.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_foodbank_manual.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_foodbank_rebuild.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_foodbank.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_fuzzy.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
test_gate_layout_fits.py Fit the meal gate on 1366x768 with a full day logged, and stop the auto-scroll 2026-08-03 16:00:13 +02:00
test_gate_tk_modules.py Make _FakeTclError subclass the real tkinter.TclError 2026-08-15 20:24:11 +02:00
test_gate.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
test_gatelock_calendar.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_gatelock_dashboard.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_gatelock_fanout.py Split the three gate test files; assert fake_tk really swaps tkinter 2026-08-15 20:12:13 +02:00
test_gatelock_form.py Split the three gate test files; assert fake_tk really swaps tkinter 2026-08-15 20:12:13 +02:00
test_gatelock_groups.py Split the three gate test files; assert fake_tk really swaps tkinter 2026-08-15 20:12:13 +02:00
test_gatelock_keyboard.py Split the six Python gate files; guard the fake-tk patch set 2026-08-15 20:08:03 +02:00
test_gatelock_mealflow.py Split the three gate test files; assert fake_tk really swaps tkinter 2026-08-15 20:12:13 +02:00
test_gatelock_scheduleedit.py Let the PC gate set the eating window and meal count 2026-08-16 15:02:35 +02:00
test_gatelock.py Split the three gate test files; assert fake_tk really swaps tkinter 2026-08-15 20:12:13 +02:00
test_kuchnia_autoload.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_cli.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_client.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_credential_store.py feat: sync the catering credential as its own document 2026-08-23 08:12:30 +02:00
test_kuchnia_credential_sync.py feat: carry the catering credential to the phone 2026-08-23 08:25:27 +02:00
test_kuchnia_gate.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_import.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_orders.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_parity.py feat: mirror the catering parser and slot spread in Dart, gated by one fixture 2026-08-23 08:00:54 +02:00
test_kuchnia_parse.py feat: import Kuchnia Wikinga catering deliveries into the food bank 2026-08-22 23:04:22 +02:00
test_kuchnia_queue.py fix: keep the catering dish queue alive across a submit 2026-08-22 23:36:53 +02:00
test_main.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
test_mcp_averages.py Make PC sync event-driven; retire the 15-min timer 2026-08-15 19:21:30 +02:00
test_mcp.py Make PC sync event-driven; retire the 15-min timer 2026-08-15 19:21:30 +02:00
test_meal_schedule_store.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
test_meal_schedule.py Derive meal slots from an eating window and a meal count 2026-08-16 14:21:12 +02:00
test_portions.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
test_prune_peers.py fix(sync): prune the revision marker too, not just the device directory 2026-08-21 13:38:34 +02:00
test_resolve.py Extract diet_guard from testsAndMisc as a standalone repo 2026-06-22 12:18:39 +02:00
test_slots.py Read the meal schedule from a forward-only history (Python) 2026-08-16 14:28:22 +02:00
test_state_redirect.py Register the _hmac_key fixture; guard the redirect so it fails locally 2026-08-15 21:19:35 +02:00
test_state_sync.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
test_state_today.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
test_state.py Split _state.py and _tk_fakes.py; make the food-log redirect fail closed 2026-08-15 20:21:26 +02:00
test_sync_backend.py perf(gate): unfreeze "Fetch from sync" and bound the interactive timeout 2026-08-21 13:07:37 +02:00
test_sync_banks_mirror.py perf(sync): hoist the device listing and stop the curated-bank 404 storm 2026-08-21 13:16:08 +02:00
test_sync_banks.py Split the last seven Python files; extend the redirect guard to all five paths 2026-08-15 20:37:05 +02:00
test_sync_budget.py Sync the meal schedule as sched: fields on the budget record 2026-08-16 14:49:08 +02:00
test_sync_device_id.py perf(sync): hoist the device listing and stop the curated-bank 404 storm 2026-08-21 13:16:08 +02:00
test_sync_events.py perf(cli): publish off-thread so logging a meal returns immediately 2026-08-21 13:22:26 +02:00
test_sync_kuchnia.py fix: stop a touched credentials file clobbering a newer peer edit 2026-08-23 08:15:40 +02:00
test_sync_merge_banks.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
test_sync_merge_budget.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
test_sync_merge_schedule.py Sync the meal schedule as sched: fields on the budget record 2026-08-16 14:49:08 +02:00
test_sync_merge.py Split _sync.py and its tests; extract the gate fixtures from conftest 2026-08-15 18:51:18 +02:00
test_sync_pull.py perf(sync): hoist the device listing and stop the curated-bank 404 storm 2026-08-21 13:16:08 +02:00
test_sync_refresh.py perf(gate): narrow the pre-lock pull and defer the heavy imports 2026-08-21 12:58:44 +02:00
test_sync.py feat: sync the catering credential as its own document 2026-08-23 08:12:30 +02:00
test_test_guard.py Remove unused features; fix reminder false alarms; share all state 2026-07-26 16:39:52 +02:00