"""The DCA Schedule page's shape. This page is what its name says: a **schedule** you follow, with the plan that generates it behind a button. Two sections went — "Up next" and "History" — because the calendar already showed both, and the only things they carried that the calendar cannot (Record buy, Skip) moved onto the row they act on. These tests pin that arrangement, because it is the part a later edit undoes without noticing. """ from __future__ import annotations import re from freezegun import freeze_time import factories as fac from test_routes import make_login HTML = {"accept": "text/html"} TODAY = "2026-08-08" def _plan(client, session_factory, *, tickers="ALPHA", amount="500"): make_login(client, session_factory) with session_factory() as s: fac.hold(s, fac.make_instrument(s, "ALPHA")) s.commit() token = re.search( r'name="_csrf" value="([^"]+)"', client.get("/schedule", headers=HTML).text).group(1) client.post("/schedule/save", data={"_csrf": token, "name": "Regular buys", "interval_days": "28", "amount": amount, "brokerage": "9.50", "start_date": "2026-01-05", "tickers": tickers}, headers=HTML, follow_redirects=True) return client.get("/schedule", headers=HTML).text @freeze_time(TODAY) def test_the_page_is_called_the_dca_schedule(client, session_factory): """'Plan' on its own said nothing about what the page was for.""" make_login(client, session_factory) page = client.get("/schedule", headers=HTML).text assert "DCA Schedule" in page @freeze_time(TODAY) def test_the_redundant_sections_are_gone(client, session_factory): """Both restated the calendar. If either comes back, so does the argument for why the calendar is not enough.""" page = _plan(client, session_factory) assert "

Up next

" not in page assert "

History

" not in page @freeze_time(TODAY) def test_record_buy_and_skip_survived_the_sections_that_held_them(client, session_factory): """The one thing that had to be kept when Up next went.""" page = _plan(client, session_factory) assert "/schedule/complete" in page, "Record buy is gone" assert 'action="/schedule/skip"' in page, "Skip is gone" @freeze_time(TODAY) def test_they_appear_once_not_on_every_row(client, session_factory): """The rotation has ONE next step. Offering Record buy on every row implies you can record the third buy before the first.""" page = _plan(client, session_factory) assert page.count('action="/schedule/skip"') == 1 @freeze_time(TODAY) def test_the_calendar_comes_before_coming_up(client, session_factory): """65/35, calendar on the left — so in source order the calendar is first. On a narrow screen that is also the stacking order, which is the reason it matters beyond aesthetics.""" page = _plan(client, session_factory) assert page.index('class="calendar"') < page.index("Coming up") @freeze_time(TODAY) def test_the_plan_editor_is_a_dialog_holding_the_preview(client, session_factory): page = _plan(client, session_factory) found = re.search(r'', page, re.S) assert found, "the plan editor is not a dialog" dialog = found.group(0) assert 'action="/schedule/save"' in dialog, "the form is not in the dialog" assert "Preview plan" in dialog, "the preview is not in the dialog" @freeze_time(TODAY) def test_the_preview_shows_dates_against_tickers(client, session_factory): """A rotation of tickers with no dates does not answer "when do I next buy ALPHA".""" page = _plan(client, session_factory) preview = re.search(r'
(.*?)
', page, re.S).group(1) assert "Date" in preview assert "Ticker" in preview assert re.search(r"\d{4}-\d{2}-\d{2}", preview), "no dates in the preview" @freeze_time(TODAY) def test_the_preview_is_long_enough_to_be_worth_scrolling(client, session_factory): """A preview you cannot scroll is a list, not a preview.""" page = _plan(client, session_factory) preview = re.search(r'
(.*?)
', page, re.S).group(1) assert len(re.findall(r"\d{4}-\d{2}-\d{2}", preview)) >= 12 @freeze_time(TODAY) def test_the_deep_link_opens_the_editor_without_script(client, session_factory): """`` with no `open` is display:none, so with scripting off the form would be unreachable — the same trap the instruments page hit.""" page = _plan(client, session_factory) assert "