"""The top bar: what is a destination, and what is an app-level control. Four things are deliberately NOT in the nav — Charts, Record trade, Holdings and Admin — on one principle: **a control belongs beside the thing it acts on**, not in a list of destinations repeated at the top of every page. What is left is the three things that are genuinely places. These tests pin the *shape*, not the styling, because the shape is the part that carries the reasoning and the part a later edit undoes without noticing. A test that asserted colours would fail on every visual change and teach us to stop reading it. """ from __future__ import annotations import re from app import navigation def test_the_nav_holds_only_the_three_destinations(): """Anything added back here should be a *place*, not an action. If a fourth genuinely is one, change this test deliberately — that is the point of it.""" assert [item.key for item in navigation.NAV] == ["portfolio", "plan", "imports"] def test_the_four_moved_items_are_not_in_the_nav(): """Named individually so a failure says which one crept back.""" keys = {item.key for item in navigation.NAV} for gone in ("charts", "trade", "holdings", "admin"): assert gone not in keys, ( f"{gone!r} is back in the top nav. It belongs next to the thing it " "acts on; putting it back makes the bar a toolbar again.") def test_the_plan_nav_entry_says_dca_schedule(): """'Plan' on its own did not say what the page was for — you edit a plan, you follow a schedule.""" plan = next(item for item in navigation.NAV if item.key == "plan") assert plan.label == "DCA Schedule" assert plan.href == "/schedule", "the route stays; it is in bookmarks" def test_admin_is_a_top_bar_control_with_an_icon(): assert navigation.ADMIN_ITEM.key == "admin" assert navigation.ADMIN_ITEM.href == "/admin" assert navigation.ADMIN_ITEM.path, "the cog needs an icon — it renders icon-only" def _page(client, session_factory) -> str: """Signed in, on the dashboard. `make_login` lives in test_routes because that is where the login flow is exercised; importing it beats a second implementation that could drift from the real form.""" from test_routes import make_login make_login(client, session_factory) response = client.get("/", headers={"accept": "text/html"}) assert response.status_code == 200 return response.text def test_the_top_bar_carries_the_admin_cog_and_the_account_menu(client, session_factory): page = _page(client, session_factory) assert 'class="iconbtn"' in page, "no admin cog in the top bar" assert "usermenu" in page, "no account menu in the top bar" def test_the_account_menu_holds_the_switcher_account_link_and_log_out(client, session_factory): """Exactly these three belong behind the profile icon. Asserted against the menu's own markup rather than the whole page, or a stray 'Log out' anywhere would satisfy it.""" page = _page(client, session_factory) found = re.search(r'