diff --git a/deploy/compose.yaml b/deploy/compose.yaml index e034cbf..0a1a2c5 100644 --- a/deploy/compose.yaml +++ b/deploy/compose.yaml @@ -36,6 +36,20 @@ services: # No username or password: the broker allows anonymous connections, because a credential # this project invented is still a credential to store and keep out of a commit (ADR-0002). OPENF1_MQTT_NO_TLS: "true" + # A switch spelled as a credential, and the value is deliberately not one. + # + # Formula 1 has closed the legacy SignalR endpoint the recorder used to reach: a negotiate + # against `livetiming.formula1.com/signalr` now answers 401 with `WWW-Authenticate: Basic` + # and `Bearer`, so the live path receives nothing at all. The replacement, + # `livetiming.formula1.com/signalrcore`, still negotiates and subscribes anonymously. + # + # Upstream chooses between the two by whether `F1_TOKEN` is *set*, not by whether its value + # authenticates: unset omits `--auth` and takes the dead endpoint, set passes `--auth` and + # takes the live one (`real_time/recording.py`). It is then sent as a bearer, which Formula 1 + # is expected to ignore — this project holds no F1TV token and is not becoming a system that + # does (ADR-0002). Whether the free subset arrives on an unauthenticated connection is the + # measurement ADR-0002 leaves outstanding, and #42 settles it against a live Session. + F1_TOKEN: unauthenticated depends_on: - api diff --git a/test/timing-screen.test.sh b/test/timing-screen.test.sh index ef4591b..a24abf5 100755 --- a/test/timing-screen.test.sh +++ b/test/timing-screen.test.sh @@ -666,4 +666,53 @@ print(counter.columns) assert_equals "a row is twenty-five columns, the whole track list the design system lays out" \ "25" "$(cells_in_a_row <<<"$spark_screen")" +# --- The header names those columns (#70) ----------------------------------------------------- +# +# Twenty-five figures a viewer cannot read is twenty-five figures they cannot use. The header is +# the design system's (docs/adr/0010) and is laid on the same grid as the rows, so the assertion +# that matters is that it has a cell for every cell a row has: one short, and every label right of +# the gap names the wrong column while still looking perfectly plausible. + +cells_in_the_header() { + python3 -c ' +import re, sys +from html.parser import HTMLParser + +class Columns(HTMLParser): + def __init__(self): + super().__init__() + self.depth = 0 + self.columns = 0 + + def handle_starttag(self, tag, attrs): + if self.depth == 1: + self.columns += 1 + self.depth += 1 + + def handle_endtag(self, tag): + self.depth -= 1 + +header = re.search(r"