"""Small things the pages said wrong, each checked where a person reads it. A count of reports that was never true, a verb that did not agree, "(s)" on every count, one financial year written two ways, slugs where words belong, a title that was not the heading, two primary buttons, a tick for a feed that had not run, a promise that a rate nobody provides would arrive, and AUD written in where the reporting currency belongs. """ from __future__ import annotations import re from pathlib import Path import pytest from test_imports_web import upload_csv import factories as fac from app import exports from test_routes import bind_to_only_portfolio, make_login HTML = {"accept": "text/html"} TEMPLATES = Path(__file__).resolve().parent.parent / "app" / "templates" def _text(html: str) -> str: return re.sub(r"\s+", " ", re.sub(r"<[^>]+>", " ", html)) def test_everything_is_as_many_reports_as_there_are(client, session_factory): make_login(client, session_factory) page = _text(client.get("/imports-exports", headers=HTML).text) assert f"“Everything” is {len(exports.TITLES)} reports" in page assert "nine" not in page def test_a_password_alone_still_signs_you_in(client, session_factory): make_login(client, session_factory) page = _text(client.get("/profile/passkeys", headers=HTML).text) assert "Your password still signs you in." in page @pytest.mark.parametrize("count, word, said", [ (1, "trade", "1 trade"), (2, "trade", "2 trades"), (0, "row", "0 rows"), ("3", "duplicate", "3 duplicates"), ]) def test_a_count_agrees_with_its_noun(app_module, count, word, said): assert app_module.templates.env.filters["plural"](count, word) == said def test_no_count_is_written_with_an_s_in_brackets(): found = [f"{path.name}: {line.strip()}" for path in sorted(TEMPLATES.glob("*.html")) for line in path.read_text(encoding="utf-8").splitlines() if "(s)" in line] assert found == [] def test_a_one_trade_file_offers_to_commit_one_trade(client, session_factory): make_login(client, session_factory) with session_factory() as s: bind_to_only_portfolio(s) fac.hold(s, fac.make_instrument(s, "ACME")) s.commit() page = upload_csv(client, session_factory, b"Trade Date,Buy/Sell,Code,Units,Price,Brokerage\n" b"06/01/2025,Buy,ACME,100,5.00,9.50\n").text assert ">Commit 1 trade" in page def test_a_financial_year_is_written_one_way(client, session_factory): make_login(client, session_factory) with session_factory() as s: bind_to_only_portfolio(s) fac.add_trade(s, fac.make_instrument(s, "ACME"), "2025-01-06", "buy", 1, "1.00") s.commit() page = client.get("/imports-exports", headers=HTML).text assert ">FY24/25" in page assert not re.search(r"FY20[0-9]{2}/20[0-9]{2}", page) def test_a_class_and_a_status_read_as_words(client, session_factory): make_login(client, session_factory) with session_factory() as s: bind_to_only_portfolio(s) acme = fac.make_instrument(s, "ACME", asset_class="share") fac.add_trade(s, acme, "2025-01-06", "buy", 100, "5.00", brokerage="9.50") s.commit() holding = client.get("/holding/ACME", headers=HTML).text preview = upload_csv(client, session_factory, b"Trade Date,Buy/Sell,Code,Units,Price,Brokerage\n" b"06/01/2025,Buy,ACME,100,5.00,9.50\n").text assert "ASX · Share · AUD" in _text(holding) assert ">already recorded" in preview and ">duplicate" not in preview def test_the_admin_page_is_titled_as_it_is_headed(client, session_factory): make_login(client, session_factory) page = client.get("/admin", headers=HTML).text assert "Admin — Stocktake" in page def test_a_first_run_offers_recording_a_trade_once(client, session_factory): make_login(client, session_factory) page = client.get("/", headers=HTML).text assert "Nothing recorded yet" in page assert len(re.findall(r']*class="primary"', page)) == 1 def test_a_feed_that_has_not_run_is_not_shown_as_fine(client, session_factory, app_module, monkeypatch): monkeypatch.setitem(app_module.feed_status, "finished", None) monkeypatch.setitem(app_module.feed_status, "running", False) make_login(client, session_factory) with session_factory() as s: bind_to_only_portfolio(s) fac.add_trade(s, fac.make_instrument(s, "ACME"), "2025-01-06", "buy", 1, "1.00") s.commit() page = client.get("/", headers=HTML).text summary = re.search(r'
\s*]*)>(.*?)', page, re.S) assert summary, "no feed status on the page" assert "✓" not in summary.group(2) and 'class="ok"' not in summary.group(1) def test_a_missing_rate_is_not_promised_to_arrive(): """A pair no provider has is never filled, and a promise that it will be sends nobody to fix it.""" found = [path.name for path in sorted(TEMPLATES.glob("*.html")) if "refresh fills it in" in " ".join(path.read_text(encoding="utf-8").split())] assert found == [] def test_the_reporting_currency_is_not_written_in_as_aud(): found = [f"{path.name}: {line.strip()}" for path in sorted(TEMPLATES.glob("*.html")) for line in path.read_text(encoding="utf-8").splitlines() if "'AUD'" in line] assert found == []