Phase A of #161: ships the smoke script and README before the maximus-api prices-proxy endpoint is live in prod. The script will fail on case 1 (HTTP 404) until /v1/prices is implemented and deployed — that is expected; running it is gated to Phase B (after prices-proxy ships, before cutting v0.9.0). Script covers 4 cases: 1. Stock happy path (AAPL) — HTTP 200, .price > 0 2. Crypto happy path (BTC) — HTTP 200, .price > 0 3. Invalid symbol — HTTP 404, error.code=symbol_not_found 4. Missing auth — HTTP 401, error.code=missing_token `set -euo pipefail`, exits non-zero on first failure. Reads token from MAXIMUS_API_TEST_TOKEN env var (never committed). README documents env vars and the two paths for obtaining a premium test token (admin endpoint TODO in maximus-api, manual JWT signing as current workaround). CSP whitelist for https://api.lacompagniemaximus.com is already in place in src-tauri/tauri.conf.json — verified, no change needed. No application code touched; npm test (492) and cargo test --lib (69) remain green. Phase A only (#161)
3.8 KiB
Smoke tests
End-to-end smoke scripts that hit the deployed maximus-api from outside
the simpl-resultat process. They are run manually as part of the ship checklist
before each release tag, and serve as a reproducible witness that the
production /v1/prices endpoint matches the contract in
docs/api-contract-prices.md.
These are not run by npm test or cargo test — they would either depend on
network reachability or leak a real license token into CI. Keep them as a
manual gate, owned by the person cutting the release.
prices.sh
Issue: #161 (price-fetching production wiring + release smoke).
Hits /v1/prices on the deployed maximus-api with four cases:
| # | Case | Expected |
|---|---|---|
| 1 | Stock happy path (AAPL) | HTTP 200 with .price > 0 |
| 2 | Crypto happy path (BTC) | HTTP 200 with .price > 0 |
| 3 | Invalid symbol | HTTP 404 with error.code = "symbol_not_found" |
| 4 | Missing Authorization |
HTTP 401 with error.code = "missing_token" |
The script exits non-zero on the first failure (set -euo pipefail). It
needs bash, curl, jq, and GNU date (Linux). On macOS, override
SMOKE_DATE manually.
Run
export MAXIMUS_API_TEST_TOKEN=<premium-test-license-token>
./tests/smoke/prices.sh
Environment variables
| Variable | Default | Purpose |
|---|---|---|
MAXIMUS_API_TEST_TOKEN |
(required) | Bearer token issued for a premium test license |
MAXIMUS_API_URL |
https://api.lacompagniemaximus.com |
Override target — useful for hitting a staging host |
SMOKE_DATE |
yesterday (date -d 'yesterday') |
YYYY-MM-DD; pick a weekday for stock data availability |
Obtaining MAXIMUS_API_TEST_TOKEN
The token must be a premium-tier license (the free tier returns 403 from
/v1/prices). Two paths:
-
Admin endpoint (preferred, post maximus-api implementation) —
POST /admin/licenseson maximus-api, gated byADMIN_SECRET, returns a freshly minted premium license token. This endpoint is not yet implemented; tracked as a follow-up issue in the maximus-api repo. -
Manual provisioning (current workaround) — until the admin endpoint ships, issue the token by hand:
- Generate an Ed25519-signed JWT with the same private key the production
maximus-api uses (
MAXIMUS_API_LICENSE_PRIVATE_KEYon the server). - Set
tier: "premium",iat: now,exp: now + 30 days,license_id: "smoke-test-<date>",machine_id: "smoke-test". - Sign with the private key, base64url-encode the result.
- Store it locally in your shell (do not commit it).
The
dist/scripts/issue-test-token.mjshelper inside the maximus-api repo can do this in one shot once it lands; see that repo'sdocs/for usage. - Generate an Ed25519-signed JWT with the same private key the production
maximus-api uses (
Never commit the token. .gitignore does not need an entry — the script reads
it from the env, and there is nothing that writes the value to disk.
Status (2026-04-28)
/v1/prices is not yet deployed in prod (see issue #161 Phase A). The
smoke script will fail on case 1 with HTTP 404 until the maximus-api
prices-proxy milestone ships. That is expected. Once unblocked, the same
script becomes the gate for Phase B (cut v0.9.0 release).
To verify the script's shape today against the live host:
$ curl -i https://api.lacompagniemaximus.com/healthz
HTTP/2 200
{"status":"ok"}
$ curl -i https://api.lacompagniemaximus.com/v1/prices?symbol=AAPL
HTTP/2 404
{"error":"Not found"} # expected during Phase A