Open Meet Display

Version 1.0. A minor version only adds; only a major breaks. Comments to [email protected].

OMD Conformance Tests

These tests check an Open Meet Display receiver or producer against the specification. A receiver runs groups A, B, and C; a producer runs group D. Each test has a check and an observable pass condition, so the list doubles as a test plan. A test marked must is required for conformance. One marked should is a strong recommendation, and one marked may is optional: if you do it, do it this way. A test’s id never changes, and an id the list skips is never reused.

Tools for running them:

  • The message schema and the probe reply schema check shapes with any JSON Schema 2020-12 validator. They allow fields and kinds they do not define, as receivers must, so a misspelled key passes them: check your field names against the field reference.
  • omd-check.mjs checks a message, or a probe reply with --probe, and names the test each problem fails.
  • Each test that needs a crafted message names a fixture. The fixture index lists them all with what a conforming receiver answers: accept (200 or 204, and shown), ignore (200 or 204, and the board unchanged, which only you can see), refuse-400, refuse-422 (with accepts), or accept-or-422 (either is conforming). The test page sends them to your receiver from your browser, as a browser-based producer does.

You can run every test without us. If a test is ambiguous, that is a bug in the format: write to [email protected].


A. Messages

What a receiver does with the messages it is sent.

OMD-C1 — Every example is accepted (must)

  • Check: send each example message to your receiver.
  • Pass: each is answered 200 or 204. Each kind you show appears on the board as the message describes it; each kind you do not show changes nothing.

OMD-C2 — A message replaces what its target shows (must)

  • Check: send results-track-heat.json, then c2-fewer-rows.omd.json, the same heat with its last row gone.
  • Pass: the board shows only the rows of the second message. The row that disappeared is gone from the board; rows are never merged across messages.

OMD-C3 — A kind you do not show is accepted and changes nothing (must)

  • Check: send c3-unknown-kind.omd.json, whose omd.kind is schedule.
  • Pass: 200 or 204, and the board keeps what it showed. Refusing it would show the operator an error on every send.

OMD-C4 — A mode other than replace is accepted and changes nothing (must)

  • Check: send c4-unknown-mode.omd.json, whose display.mode is append.
  • Pass: 200 or 204, and the board keeps what it showed.

OMD-C5 — Fields you do not know are ignored (must)

OMD-C6 — A null field is treated as missing (must)

  • Check: send c6-nulls.omd.json, which sends null for optional fields a producer would leave out.
  • Pass: 200 or 204, and the board shows what it shows when those fields are missing: no null, None, or blank label printed.

OMD-C7 — Unknown values in open lists are shown or ignored (must)

  • Check: send c7-unknown-values.omd.json: a sport, gender, entry type, status, and scoring role this version does not define.
  • Pass: 200 or 204. Each unknown value is shown as text or ignored, and the row with the unknown status is shown without a place of its own. See Open and closed lists.

OMD-C8 — Names in any script are shown whole (must)

  • Check: send c8-utf8-names.omd.json, with names in accented Latin, Chinese, Malay, and Arabic script.
  • Pass: 200 or 204, and every name is shown as sent, without replacement characters. A name too wide for the board may be cut, never garbled.

OMD-C9 — Rows are shown in the order sent, as written (must)

  • Check: send results-xc-race.json and start-list.json.
  • Pass: rows appear in the order of rows, and every value (place, mark, wind, points) appears as written. The receiver does not sort, re-place, add up, or reformat them.

OMD-C10 — A later minor version is read (must)

  • Check: send c10-later-minor.omd.json, version 1.7 with a field 1.0 does not define.
  • Pass: 200 or 204, and the board shows it as the 1.0 message it would otherwise be.

OMD-C11 — A target you do not know is shown or refused by name (should)

  • Check: send c11-unknown-target.omd.json, whose display.target is no-such-board.
  • Pass: either 200 or 204 and the message appears on your default surface, or 422 with errors naming /display/target. Never a refusal that does not say which target.

B. HTTP POST

How a receiver answers over HTTP. The test page runs these from a browser on another origin, exactly as a browser-based producer does, so passing there proves CORS too.

OMD-C12 — The preflight is answered (must)

  • Check: send OPTIONS to your URL with Origin, Access-Control-Request-Method: POST, and Access-Control-Request-Headers: content-type.
  • Pass: 204 (or 200) with Access-Control-Allow-Origin, Access-Control-Allow-Methods listing GET, POST, and OPTIONS, and Access-Control-Allow-Headers listing Content-Type.

OMD-C13 — Every reply carries the CORS header (must)

  • Check: from a web page on another origin, send a message you accept, one you refuse (c16-not-json.txt), and the probe.
  • Pass: every reply, success or error, carries Access-Control-Allow-Origin, so the browser shows the producer the status. Without it the operator sees “could not connect” for a message you received.

OMD-C14 — Allowed producers are named, with Vary: Origin (should)

  • Check: set your receiver to allow https://manager.2timer.app only, then send the preflight and a message from that origin and from another.
  • Pass: the allowed origin gets Access-Control-Allow-Origin: https://manager.2timer.app and Vary: Origin; the other gets no Access-Control-Allow-Origin. * is for testing only. See Security.

OMD-C15 — Accepted messages are answered within 5 seconds (must)

  • Check: time the reply to each example and to c3-unknown-kind.omd.json.
  • Pass: 200 or 204 within 5 seconds, including for a kind you ignore. Draw after you answer, not before.

OMD-C16 — A body that is not JSON gets 400 (must)

  • Check: send c16-not-json.txt with Content-Type: application/json.
  • Pass: 400, optionally with { "errors": [{ "path": "", "message": "…" }] }, and the board keeps what it showed.

OMD-C17 — A message with no omd block gets 422 naming what you read (must)

  • Check: send c17-no-omd.omd.json, a message in the shape of a draft of this format: "format": "meet.display.v1" and no omd block.
  • Pass: 422 with a body whose accepts lists the versions you read, such as ["1.0"], and the board keeps what it showed.

OMD-C18 — A major you do not read gets 422 naming what you read (must)

  • Check: send c18-major-2.omd.json, version 2.0.
  • Pass: 422 with accepts, and errors naming /omd/version. The board keeps what it showed: never show half of a message from a version you do not read.

OMD-C19 — The receiver is reachable where the operator runs it (must)

  • Check: run your receiver on another computer on the network, and send from a browser-based producer in Chrome at that computer’s address.
  • Pass: the message arrives after the operator allows Chrome’s local-network prompt once. The receiver listens on the network interface, not only 127.0.0.1, and its port is open in the firewall. Your documentation says the address, port, and path to enter.

C. Probe

How a receiver answers the probe: a GET on the URL it takes messages on, which a producer sends before its first message.

OMD-C20 — The probe is answered (must)

  • Check: send GET to the URL you take messages on, from a web page on another origin.
  • Pass: 200 with JSON that validates against probe-reply-v1: accepts lists 1.0 (or a later 1.x), and generator has your id and name. The reply carries Access-Control-Allow-Origin. node omd-check.mjs --probe reply.json finds nothing.

OMD-C21 — A probe changes nothing (must)

  • Check: with a message on the board, send the probe three times.
  • Pass: the board keeps what it showed, and the probes are not recorded as messages.

OMD-C22 — A receiver that is not ready says so (may)

  • Check: start your receiver before its board or output is ready, and send the probe.
  • Pass: 503 with Retry-After, and 200 once it is ready. A receiver that is ready as soon as it answers never needs 503.

OMD-C23 — Listed targets are ones you show (may)

  • Check: read targets in your probe reply, and send announcement.json to each, changing display.target.
  • Pass: each listed target shows the message on the surface it names. A target you take but do not list still works.

OMD-C24 — Your generator id never changes (should)

  • Check: compare generator.id in your probe reply across a restart and an upgrade of your product.
  • Pass: the same id, a short name you picked once. name and version may change; id does not.

D. Producer

What meet software that sends Open Meet Display does.

OMD-C25 — Every message validates (must)

  • Check: capture what you send with the reference receiver (node omd-test-receiver.mjs --json), and run node omd-check.mjs on each message.
  • Pass: zero errors, for every kind you send, including a relay, a field event, and a non-finisher.

OMD-C26 — The producer probes and sends the newest version both read (must)

  • Check: point your producer at the reference receiver, which answers the probe with ["1.0"], and send.
  • Pass: your producer sent GET before its first message, and the message says omd.version 1.0. Pointed at a receiver that answers accepts: ["2.0"] only, it sends nothing and tells the operator the receiver needs a newer version.

OMD-C27 — A receiver that does not answer the probe still gets messages (should)

  • Check: run the reference receiver with --draft, which answers the probe 404, and send.
  • Pass: your producer still sends: the draft message that receiver was built against, or 1.0. It never refuses to send because the probe went unanswered.

OMD-C28 — Fields with no value are left out (should)

  • Check: send a start list and look at the message.
  • Pass: no result, place, status, or points keys in a start list row, and no null anywhere a producer has nothing to say.

OMD-C29 — Rows arrive in display order, paged to the board (must)

  • Check: send results for a heat larger than the board’s rows per page.
  • Pass: each message carries the rows that should be on screen now, sorted as they should appear, and no more than the board shows; the next page arrives as its own message.

OMD-C30 — The operator sets the destination (must)

  • Check: open your producer’s display settings.
  • Pass: the operator can enter the receiver’s address, port, path, and display target, and can test the connection. The test probes and says what answered, in words the operator understands.