DataTalksClub / DataTalksClub/website
Make event timeline tests deterministic when the upcoming catalogue is empty
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Parent/reference: #228 (scheduled/full-regression recovery)
Related release evidence: #253, #261, #295
Related Event contracts: #45, #289
Problem
The event timeline tests assume that the checked projection always contains an upcoming
Event. That assumption is false once the wall clock passes the latest checked event. On the
current release base origin/main at
face8e4808d65afbf0374d1ced7a88079950d663, the newest checked Event starts at
2026-08-31T17:00:00+02:00. With the current date at or after that instant,
event_groups() correctly returns an empty upcoming tuple, but several tests index
upcoming[0] or require an explanation pill to be present.
The focused reproduction on this base is:
uv run --frozen pytest content/tests/test_events_timeline.py -q
9 failed, 30 passed, 455 subtests passed
The same deterministic-test defect is visible in scheduled full regression
run 33441614182. The
parallel Django traceback/pickle error is a secondary reporting effect; this issue owns only
the event-timeline test assumptions.
Exact affected tests
All affected tests are in content/tests/test_events_timeline.py:
EventTimelineRouteTests.test_clean_hub_is_upcoming_and_past_filter_is_paginated
(indexesgroups.upcoming[0]after rendering with an uncontrolled clock);EventIndexDesignSystemTests.test_rows_are_built_from_the_shared_design_system_primitives;EventKindsExplainerTests.test_both_views_explain_every_kind_a_row_can_carry;EventKindsExplainerTests.test_every_kind_pill_is_bound_to_its_own_explanation;EventDetailDesignSystemTests.test_a_live_podcast_recording_keeps_the_mint_pill_the_index_gives_it;EventDetailDesignSystemTests.test_an_event_without_speakers_or_links_draws_neither_of_them;EventDetailDesignSystemTests.test_detail_carries_its_own_stylesheet_and_loads_no_legacy_css;EventDetailDesignSystemTests.test_the_kind_pill_and_the_state_word_match_the_index; andEventDetailDesignSystemTests.test_the_page_is_built_from_the_shared_design_system_primitives.
Some failures are reported as parametrized subfailures or as follow-on errors after the first
empty-catalogue assumption; the complete list above is the affected contract surface.
Normative authority
_docs/PROCESS.md,
for independent engineer/tester/PM gates and evidence reuse;- Specification 05 — Events, registration, and email,
for the read-only Event projection and event lifecycle boundary; and - Specification 10 — Verification strategy,
for deterministic synthetic fixtures, isolated test databases, and release-critical test
coverage.
Scope
Repair only the event-timeline test fixtures/clock control and add explicit empty-upcoming
coverage. The implementation must make the tests describe the public contract independently of
the calendar date.
The non-empty assertions may use an injected aware instant and a deterministic checked record
or test projection. The route request and the expected EventGroups must use the same instant;
tests must not depend on whichever Event happens to be upcoming on the day they run. Tests that
need a representative event must select one from the controlled fixture rather than indexing a
wall-clock-derived production tuple.
Add an explicit empty-upcoming scenario that supplies EventGroups((), recent) (or an
equivalent deterministic test seam) to the public events view and verifies the existing public
empty state is a successful, bounded response containing No upcoming events. and no fabricated
event/kind assertions. The scenario must also prove that the past archive remains independently
renderable when the upcoming side is empty, if that behavior is exercised by the fixture.
Production event grouping, projection data, templates, URL patterns, cache policy, SEO metadata,
event ordering, lifecycle behavior, and all non-test source files remain unchanged. Do not alter
the latest event date merely to keep a test green.
Explicit non-goals
- No change to
content/public_data.event_groups, Event projection JSON, Event model, route,
template, CSS, JavaScript, or public copy. - No synthetic future production record, date extension, clock shim in application code, or
weakening/removal of an assertion. - No fix for #253 projection/source attestation, #261 collection-hub pagination, #295 migration
inventory, or the secondary multiprocessing traceback/pickle reporting behavior. - No browser/provider/network, database migration, deployment, source-repository, commit, push,
or issue-closure action outside the normal lifecycle.
Dependencies and ordering
- Implementation dependency: none. This test-only correction can be engineered from the
clean currentorigin/mainbase without waiting for #253; the content-source repair is not
part of this issue. - Release relationship: #253, #261, and #295 remain separate release gates. Their status may
keep the aggregate pipeline red, but must not be used to excuse a failing #299 criterion. - Event ownership: #289 owns the future non-activating Event domain core and #45 owns the
eventual public Event lifecycle/pages/calendar contract. This issue changes neither.
Acceptance criteria
- The nine affected tests above pass on the current
origin/mainbase at a clock after
2026-08-31T17:00:00+02:00and at a clock before the newest checked event, without changing
production event grouping or checked projection data. - Every assertion requiring an upcoming record obtains it from a deterministic aware clock
and fixture/projection seam; no affected test indexes a tuple whose membership depends on the
host wall clock. - The route test uses one controlled instant for grouping and requests, and still verifies
upcoming/past separation, pagination, escaped titles, canonical output, and status codes. - An explicit empty-upcoming test verifies
GET /eventsis a 200 response with the existing
No upcoming events.state and no exception, fabricated kind explanation, or invalid item
access; the past archive remains covered independently where applicable. - The focused suite passes with an exact recorded command and count:
uv run --frozen pytest content/tests/test_events_timeline.py -q. - The engineer generates and freezes the versioned verification plan for the exact base/head,
with all component dispositions recorded. The independent tester recomputes that plan and
validates the focused result plus the graph-selected shared checks; no required check is
silently skipped. - Because this is test-only and has no product-page render change, screenshots are marked
not_applicablewith the graph/render-impact proof. The tester still verifies the Django route
scenarios and runs the graph-selected Playwright tier if required by the plan. - Engineer, independent tester, and PM reports are posted to this issue before any commit;
only the orchestrator may merge/push after PM acceptance, and on-call alone observes the
resulting CI run.
Required verification scenarios
- Run the affected tests with an injected aware
nowbefore the newest checked event and prove
the representative upcoming record and all kind/detail assertions remain meaningful. - Run the same tests with an injected aware
nowafter the newest checked event and prove the
empty-upcoming path is intentional and bounded rather than an accidentalIndexError. - Exercise the public
/eventsview with controlled non-empty and emptyEventGroups; verify
200 status, the existing empty copy, no invalid controls, and no cross-view leakage. - Run the exact focused command, the generated graph-selected Django/CI checks, and any
required Playwright tier from the frozen verification plan. Report the known independent
#253/#261/#295 failures separately if they remain on the shared base.
Lifecycle
This is a groomed P0 testing/bug issue. The engineer works in an isolated uncommitted worktree
from the exact current base and posts a frozen handoff. A separate tester reviews the diff,
recomputes the plan, runs the controlled before/after-clock and empty-upcoming scenarios, and
records screenshot not_applicable evidence. PM accepts only after all criteria and evidence
are complete. The engineer then commits with Closes #299; the orchestrator locally merges with
--no-ff, pushes main, and dispatches on-call. No pull request is created.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with content/tests/test_events_timeline.py and run uv run --frozen pytest content/tests/test_events_timeline.py -q to observe the affected failures. Read the event timeline tests and the public /events route, then make the fixtures and clock deterministic so both non-empty and empty-upcoming cases pass without changing production event behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- backend, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100