Commit Graph

2 Commits

Author SHA1 Message Date
c21d6f5668 fix(tests): fix fasting custom threshold tests using Django ORM cache
The user_with_custom_thresholds fixture used UserProfile.objects.get_or_create()
which returns a separate Python instance from the one cached in
user._state.fields_cache['profile']. When the fixture modified and saved
the get_or_create instance, the cached instance on the user object still
held default values (periodic=16, full=24). compute_fasting() accessed
u.profile which returned the stale cached object.

Fixed by modifying through u.profile directly, which operates on the
same cached instance. Also applied black formatting to fasting.py.
2026-07-19 13:50:54 -04:00
29fc493cc2 Rewrite fasting trend algorithm and add comprehensive tests
- Replace day-iteration algorithm with pair-based approach for fasting
  detection. Iterate consecutive food scrobble pairs and mark foodless
  days between them as fasting days.

- Handle consecutive-day periodic fasting: when two food scrobbles are on
  consecutive days with a gap >= periodic_threshold but < full_threshold,
  mark the later day as a periodic fast (user's original bug fix).

- Fix _dt test helper to use replace() instead of subtracting hours,
  producing correct timestamps (e.g., '3 days ago at 18:46' instead of
  '3 days + 18h46m ago').

- Fix total_days off-by-one: removed +1 from inclusive day count so a
  'last_30' period correctly reports 30 days.

- Add _drinks_on_day() for per-day drink detection (replaces whole-
  window _drinks_in_window for more accurate liquid fasting detection).

- Fix Beer test fixture to use styles M2M field instead of non-existent
  beer_style attribute.

- Add 26 test cases covering: classification, short gaps, periodic/
  full/liquid fasting, multi-day gaps, vacation exemptions, custom
  thresholds, streaks, mixed types, edge cases.

Reasoning:
The original day-iteration algorithm had fundamental issues: it marked
days with food as fasting (since it only checked prev/next food times),
it didn't filter out normal (< periodic) gaps, and the _dt helper was
misinterpreting hour parameters. The new pair-based approach is cleaner:
for each consecutive food scrobble pair, we mark the foodless days
between them. This naturally handles multi-day fasts and correctly
avoids marking food-eating days as fasting. The consecutive-day periodic
rule preserves the user's original intent of detecting overnight fasts
between meals.
2026-07-19 13:11:29 -04:00