#!/usr/bin/env bash # Smoke test — /v1/prices end-to-end against the deployed maximus-api. # # Issue #161 (Phase A): committed for reproducibility before each release. # Issue #161 (Phase B): runnable once maximus-api/prices-proxy ships. # Until then, /v1/prices returns 404 in prod and this script will exit 1 # on the first happy-path call. That is expected during Phase A. # # Usage: # MAXIMUS_API_TEST_TOKEN= ./tests/smoke/prices.sh # # Optional overrides: # MAXIMUS_API_URL (default: https://api.lacompagniemaximus.com) # SMOKE_DATE (default: yesterday — pick a weekday for stocks) # # Dependencies: bash 4+, curl, jq, GNU `date -d` (Linux). On macOS, set # SMOKE_DATE manually instead of relying on the default. # # Exit codes: # 0 all 4 cases pass # 1 any single case fails (the script is set -e; first failure aborts) # 2 required env var missing set -euo pipefail API_URL="${MAXIMUS_API_URL:-https://api.lacompagniemaximus.com}" TOKEN="${MAXIMUS_API_TEST_TOKEN:-}" DATE="${SMOKE_DATE:-$(date -d 'yesterday' +%Y-%m-%d)}" if [ -z "$TOKEN" ]; then echo "error: MAXIMUS_API_TEST_TOKEN must be set to a premium test license token." >&2 echo " See tests/smoke/README.md for how to obtain one." >&2 exit 2 fi TMP=$(mktemp) trap 'rm -f "$TMP"' EXIT pass() { echo " pass: $1"; } fail() { echo " FAIL: $1" >&2; exit 1; } echo "smoke: $API_URL/v1/prices (date=$DATE)" # ----------------------------------------------------------------------------- # Case 1 — stock happy path # ----------------------------------------------------------------------------- echo "[1/4] stock happy path (AAPL)" if ! curl -fsS \ -H "Authorization: Bearer $TOKEN" \ -o "$TMP" \ "$API_URL/v1/prices?symbol=AAPL&date=$DATE"; then fail "stock fetch did not return 200 for AAPL" fi if ! jq -e '.price > 0' "$TMP" >/dev/null; then fail "stock response did not contain a positive .price field" fi pass "AAPL .price = $(jq -r '.price' "$TMP")" # ----------------------------------------------------------------------------- # Case 2 — crypto happy path # ----------------------------------------------------------------------------- echo "[2/4] crypto happy path (BTC)" if ! curl -fsS \ -H "Authorization: Bearer $TOKEN" \ -o "$TMP" \ "$API_URL/v1/prices?symbol=BTC&date=$DATE"; then fail "crypto fetch did not return 200 for BTC" fi if ! jq -e '.price > 0' "$TMP" >/dev/null; then fail "crypto response did not contain a positive .price field" fi pass "BTC .price = $(jq -r '.price' "$TMP")" # ----------------------------------------------------------------------------- # Case 3 — invalid symbol -> 404 / symbol_not_found # ----------------------------------------------------------------------------- echo "[3/4] invalid symbol (NOTREAL_XYZ)" http=$(curl -s -o "$TMP" -w '%{http_code}' \ -H "Authorization: Bearer $TOKEN" \ "$API_URL/v1/prices?symbol=NOTREAL_XYZ&date=$DATE") if [ "$http" != "404" ]; then fail "invalid symbol expected HTTP 404, got $http" fi if ! jq -e '.error.code == "symbol_not_found"' "$TMP" >/dev/null; then fail "invalid symbol expected error.code = 'symbol_not_found', got: $(cat "$TMP")" fi pass "404 + symbol_not_found" # ----------------------------------------------------------------------------- # Case 4 — no auth -> 401 / missing_token # ----------------------------------------------------------------------------- echo "[4/4] missing auth" http=$(curl -s -o "$TMP" -w '%{http_code}' \ "$API_URL/v1/prices?symbol=AAPL&date=$DATE") if [ "$http" != "401" ]; then fail "missing-auth expected HTTP 401, got $http" fi if ! jq -e '.error.code == "missing_token"' "$TMP" >/dev/null; then fail "missing-auth expected error.code = 'missing_token', got: $(cat "$TMP")" fi pass "401 + missing_token" echo "" echo "smoke: all 4 cases pass"