Files
6krrt/tests/test_models_page_structure.py
adlee-was-taken 3c0100d08e fix(admin): tighten the models table and show what routing turns on
Rows were 57px against the decisions table's 36px, which is the other
scanning surface over hundreds of rows. Two things set that height and
only fixing one would have moved it barely: 24px of td padding, and a
32px override <select>. Both come down; the row is now 31px.

The space that buys is spent on the four facts a routing decision
actually turns on, all already in /admin/api/models -- no API change:

  Ctx       effective_context_window, the hard filter that 422s
  $/1M out  the completion price profiles filter on
  Prof      mean proficiency, with /N and the per-category breakdown
            in the title -- a bare mean would imply uniform competence,
            which is the one thing the table disproves
  Caps      T/V/J/R chips, reusing the decisions page's flag language

The Ctx column earned its place immediately: 12 of 30 active OpenRouter
rows read 0 and have never been selected across 23,000+ decisions.
Fixed separately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRQXz5SYZYVWscxS1QqF6U
2026-09-08 22:26:39 -04:00

152 lines
6.1 KiB
Python

"""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 '<option value="routable">Routable only</option>' 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")