146 lines
4.9 KiB
Bash
Executable File
146 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
LOCAL_ENV_FILE="${TDC114_SMOKE_ENV_FILE:-$ROOT_DIR/scripts/.env.smoke.local}"
|
|
|
|
if [ -f "$LOCAL_ENV_FILE" ]; then
|
|
# shellcheck disable=SC1090
|
|
source "$LOCAL_ENV_FILE"
|
|
fi
|
|
|
|
if [ -z "${TDC114_API_BASE:-}" ]; then
|
|
echo "TDC114_API_BASE is required for API smoke tests." >&2
|
|
echo "Example: TDC114_API_BASE=http://127.0.0.1:5000 $0" >&2
|
|
if [ -f "$LOCAL_ENV_FILE" ]; then
|
|
echo "Loaded local smoke env from $LOCAL_ENV_FILE" >&2
|
|
fi
|
|
exit 64
|
|
fi
|
|
|
|
if [ "${TDC114_API_BASE:-}" = "https://staging.example.com" ]; then
|
|
echo "TDC114_API_BASE still points to the example placeholder. Update $LOCAL_ENV_FILE first." >&2
|
|
exit 64
|
|
fi
|
|
|
|
BASE_URL="${TDC114_API_BASE%/}"
|
|
AUTH_FLOW="${TDC114_SMOKE_AUTH_FLOW:-phone-login}"
|
|
TMP_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
|
|
request() {
|
|
local method="$1"
|
|
local path="$2"
|
|
local body="${3:-}"
|
|
local token="${4:-}"
|
|
local output_file="$TMP_DIR/response"
|
|
local headers=(-H "Accept: application/json")
|
|
if [ -n "$token" ]; then
|
|
headers+=(-H "Authorization: Bearer $token")
|
|
fi
|
|
if [ -n "$body" ]; then
|
|
headers+=(-H "Content-Type: application/json")
|
|
curl -sS --max-time 10 -o "$output_file" -w "%{http_code}" \
|
|
-X "$method" "${headers[@]}" --data "$body" "$BASE_URL$path"
|
|
else
|
|
curl -sS --max-time 10 -o "$output_file" -w "%{http_code}" \
|
|
-X "$method" "${headers[@]}" "$BASE_URL$path"
|
|
fi
|
|
}
|
|
|
|
assert_status() {
|
|
local name="$1"
|
|
local actual="$2"
|
|
shift 2
|
|
for expected in "$@"; do
|
|
if [ "$actual" = "$expected" ]; then
|
|
echo "PASS $name: HTTP $actual"
|
|
return 0
|
|
fi
|
|
done
|
|
echo "FAIL $name: HTTP $actual" >&2
|
|
echo "Response body:" >&2
|
|
sed -n '1,40p' "$TMP_DIR/response" >&2
|
|
exit 1
|
|
}
|
|
|
|
extract_json_string() {
|
|
local key="$1"
|
|
sed -n "s/.*\"$key\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" "$TMP_DIR/response" | head -n 1
|
|
}
|
|
|
|
echo "tdc114plus API smoke: $BASE_URL"
|
|
|
|
status="$(request GET "/api/v1/tdc114plus/directory/employees")"
|
|
assert_status "unauthorized directory guard" "$status" 401 403
|
|
|
|
status="$(request POST "/api/v1/tdc114plus/auth/phone-login" '{"phoneNumber":"123","device":{"platform":"smoke","appVersion":"0.1.0","deviceName":"api-smoke"}}')"
|
|
assert_status "invalid phone-login validation" "$status" 400
|
|
|
|
status="$(request POST "/api/v1/tdc114plus/auth/link/init" '{"phoneNumber":"123","device":{"platform":"smoke","appVersion":"0.1.0","deviceName":"api-smoke"}}')"
|
|
assert_status "invalid link-init validation" "$status" 400
|
|
|
|
status="$(request POST "/api/v1/tdc114plus/auth/link/poll" '{"pendingRef":"api-smoke-missing-ref"}')"
|
|
assert_status "link-poll expired pendingRef" "$status" 200
|
|
|
|
if [ "${TDC114_SKIP_AUTH_SMOKE:-false}" = "true" ]; then
|
|
echo "SKIP authenticated smoke: TDC114_SKIP_AUTH_SMOKE=true"
|
|
exit 0
|
|
fi
|
|
|
|
if [ -z "${TDC114_SMOKE_PHONE:-}" ]; then
|
|
echo "SKIP authenticated smoke: TDC114_SMOKE_PHONE is not set"
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$AUTH_FLOW" = "link" ]; then
|
|
login_body="$(printf '{"phoneNumber":"%s","device":{"platform":"smoke","appVersion":"0.1.0","deviceName":"api-smoke"}}' "$TDC114_SMOKE_PHONE")"
|
|
status="$(request POST "/api/v1/tdc114plus/auth/link/init" "$login_body")"
|
|
assert_status "link-init success" "$status" 200
|
|
|
|
pending_ref="$(extract_json_string "pendingRef")"
|
|
if [ -z "$pending_ref" ]; then
|
|
echo "FAIL link-init success: pendingRef is missing" >&2
|
|
exit 1
|
|
fi
|
|
|
|
status="$(request POST "/api/v1/tdc114plus/auth/link/poll" "$(printf '{"pendingRef":"%s"}' "$pending_ref")")"
|
|
assert_status "link-poll pending" "$status" 200
|
|
|
|
poll_code="$(extract_json_string "code")"
|
|
if [ -n "$poll_code" ] && [ "$poll_code" != "authorization_pending" ] && [ "$poll_code" != "slow_down" ]; then
|
|
echo "FAIL link-poll pending: unexpected code=$poll_code" >&2
|
|
sed -n '1,40p' "$TMP_DIR/response" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "PASS staging link smoke: init succeeded and poll is pending"
|
|
echo "NOTE manual approval is still required to complete end-to-end login."
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$AUTH_FLOW" != "phone-login" ]; then
|
|
echo "Unknown TDC114_SMOKE_AUTH_FLOW=$AUTH_FLOW" >&2
|
|
echo "Expected one of: phone-login, link" >&2
|
|
exit 64
|
|
fi
|
|
|
|
login_body="$(printf '{"phoneNumber":"%s","device":{"platform":"smoke","appVersion":"0.1.0","deviceName":"api-smoke"}}' "$TDC114_SMOKE_PHONE")"
|
|
status="$(request POST "/api/v1/tdc114plus/auth/phone-login" "$login_body")"
|
|
assert_status "phone-login success" "$status" 200
|
|
|
|
token="$(extract_json_string "token")"
|
|
if [ -z "$token" ]; then
|
|
echo "FAIL phone-login success: token is missing" >&2
|
|
exit 1
|
|
fi
|
|
|
|
status="$(request GET "/api/v1/tdc114plus/directory/employees?limit=10" "" "$token")"
|
|
assert_status "employee list" "$status" 200
|
|
|
|
status="$(request GET "/api/v1/tdc114plus/organization/tenants" "" "$token")"
|
|
assert_status "tenant list" "$status" 200
|
|
|
|
status="$(request GET "/api/v1/tdc114plus/organization/orgchart" "" "$token")"
|
|
assert_status "orgchart" "$status" 200
|