"""The models page has to be usable at 446 rows, not just at 45. It shipped as one ungrouped table of every routable model with a single "Show deprecated / stale" switch. That is workable while the catalog is NeuralWatt-only; with OpenRouter allowlisted the table is 440 rows and the switch is an all-or-nothing control over the only axis it offers. Static checks on the source, as with the allowlist filter tests -- this repo has no DOM harness. Behaviour was verified in a browser: filters compose (45 routable -> 14 neuralwatt -> 7 at tier 3), search types forward with the caret intact, paging walks 9 pages of 50, and changing a filter returns to page 1. """ from __future__ import annotations import re from pathlib import Path import pytest SRC = (Path(__file__).resolve().parent.parent / "admin" / "frontend" / "models.html").read_text(encoding="utf-8") def _function_body(name: str) -> str: match = re.search(rf"^(?:async )?function {re.escape(name)}\(.*?^\}}", SRC, re.S | re.M) assert match, f"{name}() not found in models.html" return match.group(0) def _strip_comments(text: str) -> str: text = re.sub(r"/\*.*?\*/", "", text, flags=re.S) return "\n".join(ln for ln in text.split("\n") if not ln.strip().startswith("//")) @pytest.mark.parametrize("control", [ "mf-search", "mf-provider", "mf-tier", "mf-availability", "mf-page-size", "mf-clear", "mf-prev", "mf-next", ]) def test_every_filter_control_exists(control): assert f'id="{control}"' in SRC def test_the_old_all_or_nothing_toggle_is_gone(): """Availability is a select now -- 'show deprecated' could not express 'show me only the stale ones', which is what auditing an override needs.""" assert 'id="show-deprecated-toggle"' not in _strip_comments(SRC) def test_filters_compose_rather_than_override(): """Each axis narrows independently; matchesModelFilters returns false on the first miss rather than picking a winner.""" body = _function_body("matchesModelFilters") for axis in ("f.availability", "f.provider", "f.tier", "f.q"): assert axis in body, f"{axis} is not consulted" def test_routable_is_the_default_view(): """The page is usually open to answer 'what can the router pick now'.""" assert '' in SRC body = _function_body("matchesModelFilters") assert "'routable'" in body def test_the_page_is_paginated(): render = _function_body("renderModels") assert "_modelPageSize" in render assert "slice(start, start + _modelPageSize)" in render def test_changing_a_filter_returns_to_page_one(): """Otherwise a narrowed result can land on an empty page.""" bind = _function_body("bindModelFilters") assert "_modelPage = 1" in bind def test_the_count_names_the_window_and_the_whole(): """'31 of 446' is a filter result; '446' alone is a claim about the catalog. Same rule as the decisions page.""" render = _function_body("renderModels") assert "of ${eligible.length} models" in render def test_the_pager_hides_itself_on_a_single_page(): render = _function_body("renderModels") assert "totalPages > 1" in render def test_filter_controls_are_bound_once_not_re_rendered(): """The providers page reversed typed text by rebuilding the input on every keystroke and re-focusing it, which reset the caret to 0. These controls are static markup, bound once at init.""" init = _function_body("init") assert "bindModelFilters()" in init render = _strip_comments(_function_body("renderModels")) for control in ("mf-search", "mf-provider", "mf-tier", "mf-availability"): assert f'"{control}"' not in render, ( f"renderModels rebuilds {control}; a keystroke would destroy it" ) def test_the_provider_list_is_derived_from_the_catalog(): """Hard-coding provider names would go stale the moment one is added.""" body = _function_body("refreshProviderOptions") assert "new Set(models.map" in body @pytest.mark.parametrize("column", ["Ctx", "$/1M out", "Prof", "Caps"]) def test_the_decision_relevant_columns_are_present(column): """The four facts a routing decision actually turns on: the context ceiling that produces a 422, the completion price profiles filter on, the proficiency term that is the only category-dependent part of the ranking, and the capability gates that hard-filter a request. All four already ship in /admin/api/models -- none needed an API change.""" assert f">{column}<" in SRC def test_proficiency_shows_a_mean_and_keeps_the_breakdown_reachable(): """A bare mean would imply uniform competence, which is the exact thing the proficiency table disproves -- deepseek-v4-flash is 1.00 on coding and 0.33 on tool use. The per-category detail stays in the title.""" body = _function_body("proficiencyCell") assert "title=" in body assert "entries.length" in body, "the sample count must be visible too" def test_row_density_matches_the_decisions_table_approach(): """Both are scanning surfaces over hundreds of rows, so both trade card-table's comfortable spacing for smaller type AND tighter padding. Measured: 57px before, 31px after, against decisions' 36px.""" assert "#model-tbody td, thead th{padding-top:.2rem!important" in SRC assert "#model-tbody{font-size:.72rem}" in SRC # The override select was 32px and set the floor on row height; shrinking # only the padding would have moved the row by almost nothing. assert "#model-tbody .model-override{height:24px" in SRC def test_empty_states_span_every_column(): """A stale colspan leaves the empty-state message boxed into part of the row, which reads as a broken table rather than an empty one.""" assert 'colspan="5"' not in SRC assert SRC.count('colspan="9"') >= 2 def test_the_page_still_requests_the_unfiltered_catalog(): """The availability filter needs the deprecated rows present to show them; this is the one caller that passes include_unroutable.""" assert "include_unroutable=true" in _function_body("loadModels")