Skip to content

Give the date code one clock a test can freeze - #751

Open
mircealungu wants to merge 1 commit into
masterfrom
freezable-clock-for-date-tests
Open

mircealungu wants to merge 1 commit into
masterfrom
freezable-clock-for-date-tests

Conversation

@mircealungu

Copy link
Copy Markdown
Member

Salvaged from a stale Claude worktree (.claude/worktrees/eloquent-lovelace-9b32b4, Aug 29). The rest of that worktree was superseded by master; this part never landed.

The problem

Every "is this today?" question in util/time.py read the wall clock directly, in two separate places:

def user_local_today(user):
    return datetime.now(user_zone(user)).date()

def server_now():
    return datetime.now(SERVER_TZ).replace(tzinfo=None)

The streak code's answers depend on the relationship between the server's date and the user's — that's the whole subject of the comment block at the top of the file, and of issue #587. But a test that builds its fixtures from the machine's own clock can only exercise whichever relationship happens to hold at the moment it runs. So the suite is green all afternoon and fails after local midnight, for reasons unrelated to the change under test. f162c541 ("Make the streak tests and the streak code agree on which day it is") went in for exactly that, and fixed the fixtures without removing the dependency on when you run them.

The change

Both functions now derive from a single _now_utc(), so patching that one function moves them together and a test can name the instant it means:

with clock_at("2026-03-01 12:00"):   # UTC
    ...

zeeguu/core/test/frozen_clock.py holds clock_at plus server_time_at, which gives the naive SERVER_TZ value the DB would hold for a given UTC instant.

The added friend-streak test runs one scenario at two pinned instants. Auckland is UTC+13 on that date, so at 06:00 UTC it is still the 1st there and at 12:00 UTC it is already the 2nd, while the server is on the 1st either way — the streak has to come out the same. Verified the seam actually bites:

2026-03-01 06:00 -> server_now: 2026-03-01 06:00:00 | auckland today: 2026-03-01
2026-03-01 12:00 -> server_now: 2026-03-01 12:00:00 | auckland today: 2026-03-02

Not included

The same worktree also reworked compute_current_streak to expire a streak only when it is stale in both friends' local calendars. Deliberately dropped: friend_streak_last_updated is written with server_now() and update_streak's continuation check (last_updated_date == server_yesterday) is server-frame, so reading it in two user calendars would let the UI show a streak that the increment path then resets to 1. Master's single-frame treatment is the correct one.

Behaviour

None changed — datetime.now(TZ) and datetime.now(utc).astimezone(TZ) are the same reading. get_server_time_utc() is left alone; it documents itself as unused.

zeeguu/core/test: 368 passed, 12 subtests passed.

🤖 Generated with Claude Code

Every "is this today?" question in util/time.py read the wall clock
directly, in two separate places. That makes a whole class of behaviour
untestable: the streak code's answers depend on the relationship between
the server's date and the user's, and a test built from the machine's own
clock exercises only whichever relationship happens to hold when it runs.
A suite can be green all afternoon and fail after local midnight for
reasons that have nothing to do with the change under test -- f162c54
went in for exactly that.

server_now() and user_local_today() now both derive from one _now_utc(),
so a test can pin an instant and move them together. frozen_clock.clock_at
does the pinning; the added friend-streak test names two UTC moments that
straddle an Auckland midnight while the server stays on the previous day,
and asserts the streak comes out the same at both.

No behaviour change: datetime.now(TZ) and datetime.now(utc).astimezone(TZ)
are the same reading. get_server_time_utc() is left alone -- it documents
itself as unused.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

ArchLens - No architecturally relevant changes to the existing views

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant