# 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 ```bash export MAXIMUS_API_TEST_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: 1. **Admin endpoint (preferred, post maximus-api implementation)** — `POST /admin/licenses` on maximus-api, gated by `ADMIN_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. 2. **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_KEY` on the server). - Set `tier: "premium"`, `iat: now`, `exp: now + 30 days`, `license_id: "smoke-test-"`, `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.mjs` helper inside the maximus-api repo can do this in one shot once it lands; see that repo's `docs/` for usage. 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: ```bash $ 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 ```