DataTalksClub / DataTalksClub/website

Make event timeline tests deterministic when the upcoming catalogue is empty

Open
#299 16 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug events P0 testing
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
    (indexes groups.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; and
  • EventDetailDesignSystemTests.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

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 current origin/main base 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/main base at a clock after
    2026-08-31T17:00:00+02:00 and 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 /events is 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_applicable with 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

  1. Run the affected tests with an injected aware now before the newest checked event and prove
    the representative upcoming record and all kind/detail assertions remain meaningful.
  2. Run the same tests with an injected aware now after the newest checked event and prove the
    empty-upcoming path is intentional and bounded rather than an accidental IndexError.
  3. Exercise the public /events view with controlled non-empty and empty EventGroups; verify
    200 status, the existing empty copy, no invalid controls, and no cross-view leakage.
  4. 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.