#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" tests_run=0 pass() { tests_run=$((tests_run + 1)) } assert_eq() { local expected="$1" local actual="$2" if [[ "$expected" != "$actual" ]]; then echo "assertion failed: expected [$expected], got [$actual]" >&2 exit 1 fi } assert_file_contains() { local needle="$1" local path="$2" if ! grep -Fq "$needle" "$path"; then echo "assertion failed: [$needle] not found in $path" >&2 exit 1 fi } assert_file_not_contains() { local needle="$1" local path="$2" if grep -Fq "$needle" "$path"; then echo "assertion failed: [$needle] unexpectedly found in $path" >&2 exit 1 fi } make_workdir() { mktemp -d } install_mock_curl() { local workdir="$1" cat >"$workdir/bin/curl" <<'EOF' #!/usr/bin/env bash set -euo pipefail printf '%s\n' "$@" >"$MOCK_CURL_ARGS_FILE" outfile="" http_code="${MOCK_CURL_HTTP_CODE:-200}" body="${MOCK_CURL_BODY:-}" if [[ -z "$body" ]]; then body='{"files":["https://shx.example/mock-file"]}' fi while [[ $# -gt 0 ]]; do case "$1" in -o) outfile="$2" shift 2 ;; -w) shift 2 ;; *) shift ;; esac done if [[ "${MOCK_CURL_EXIT_CODE:-0}" != "0" ]]; then echo "${MOCK_CURL_STDERR:-mock curl transport error}" >&2 exit "$MOCK_CURL_EXIT_CODE" fi printf '%s' "$body" >"$outfile" printf '%s' "$http_code" EOF chmod +x "$workdir/bin/curl" } install_mock_jq() { local workdir="$1" cat >"$workdir/bin/jq" <<'EOF' #!/usr/bin/env python3 import json import sys args = sys.argv[1:] raw = sys.stdin.read() payload = json.loads(raw) flags = [arg for arg in args if arg.startswith("-")] query = next((arg for arg in args if not arg.startswith("-")), "") if query == '.files | arrays and length > 0': files = payload.get("files") ok = isinstance(files, list) and len(files) > 0 sys.exit(0 if ok else 1) if query == '.files[]': files = payload.get("files") if not isinstance(files, list): sys.exit(1) for item in files: print(item) sys.exit(0) if query == 'if type=="object" then .error // .message // .reason // empty else empty end': if isinstance(payload, dict): for key in ("error", "message", "reason"): value = payload.get(key) if value: print(value) sys.exit(0) sys.exit(0) raise SystemExit(f"unsupported jq query: {query} with flags {flags}") EOF chmod +x "$workdir/bin/jq" } write_env() { local workdir="$1" cat >"$workdir/.env" <<'EOF' SHX_URL=https://shx.example SHX_TOKEN=test-token EOF } run_upload() { local workdir="$1" shift ( cd "$repo_root" env -u SHX_TOKEN -u ZIPLINE_TOKEN \ PATH="$workdir/bin:${PATH:-}" \ SHX_ENV_FILE="$workdir/.env" \ MOCK_CURL_ARGS_FILE="$workdir/curl-args.txt" \ "$repo_root/bin/shx-upload" "$@" ) } test_success_and_request_shape() { local workdir workdir="$(make_workdir)" mkdir -p "$workdir/bin" write_env "$workdir" install_mock_curl "$workdir" install_mock_jq "$workdir" touch "$workdir/demo.txt" run_upload "$workdir" "$workdir/demo.txt" >"$workdir/out.txt" 2>"$workdir/err.txt" assert_file_contains 'https://shx.example/mock-file' "$workdir/out.txt" assert_file_contains 'authorization: test-token' "$workdir/curl-args.txt" assert_file_contains "file=@$workdir/demo.txt" "$workdir/curl-args.txt" assert_file_contains '/api/upload' "$workdir/curl-args.txt" assert_file_not_contains 'error:' "$workdir/err.txt" rm -rf "$workdir" pass } test_missing_file() { local workdir workdir="$(make_workdir)" mkdir -p "$workdir/bin" write_env "$workdir" install_mock_curl "$workdir" if run_upload "$workdir" "$workdir/does-not-exist.txt" >"$workdir/out.txt" 2>"$workdir/err.txt"; then echo "expected missing file failure" >&2 exit 1 fi assert_file_contains 'error: file not found:' "$workdir/err.txt" rm -rf "$workdir" pass } test_missing_token() { local workdir workdir="$(make_workdir)" mkdir -p "$workdir/bin" cat >"$workdir/.env" <<'EOF' SHX_URL=https://shx.example EOF install_mock_curl "$workdir" touch "$workdir/demo.txt" if run_upload "$workdir" "$workdir/demo.txt" >"$workdir/out.txt" 2>"$workdir/err.txt"; then echo "expected missing token failure" >&2 exit 1 fi assert_file_contains 'error: SHX_TOKEN is not set' "$workdir/err.txt" rm -rf "$workdir" pass } test_missing_jq_in_normal_mode() { local workdir workdir="$(make_workdir)" mkdir -p "$workdir/bin" write_env "$workdir" install_mock_curl "$workdir" ln -s /bin/bash "$workdir/bin/bash" ln -s /bin/cat "$workdir/bin/cat" ln -s /bin/rm "$workdir/bin/rm" ln -s /usr/bin/mktemp "$workdir/bin/mktemp" touch "$workdir/demo.txt" ( cd "$repo_root" env -u SHX_TOKEN -u ZIPLINE_TOKEN \ PATH="$workdir/bin" \ SHX_ENV_FILE="$workdir/.env" \ MOCK_CURL_ARGS_FILE="$workdir/curl-args.txt" \ /bin/bash "$repo_root/bin/shx-upload" "$workdir/demo.txt" ) >"$workdir/out.txt" 2>"$workdir/err.txt" && { echo "expected missing jq failure" >&2 exit 1 } assert_file_contains 'error: jq is required unless --json is used' "$workdir/err.txt" rm -rf "$workdir" pass } test_server_failure_surfaces_body() { local workdir workdir="$(make_workdir)" mkdir -p "$workdir/bin" write_env "$workdir" install_mock_curl "$workdir" install_mock_jq "$workdir" touch "$workdir/demo.txt" ( export MOCK_CURL_HTTP_CODE=401 export MOCK_CURL_BODY='{"error":"invalid token"}' run_upload "$workdir" "$workdir/demo.txt" ) >"$workdir/out.txt" 2>"$workdir/err.txt" && { echo "expected server failure" >&2 exit 1 } assert_file_contains 'error: upload failed for' "$workdir/err.txt" assert_file_contains 'server: invalid token' "$workdir/err.txt" rm -rf "$workdir" pass } test_invalid_success_shape_fails() { local workdir workdir="$(make_workdir)" mkdir -p "$workdir/bin" write_env "$workdir" install_mock_curl "$workdir" install_mock_jq "$workdir" touch "$workdir/demo.txt" ( export MOCK_CURL_BODY='{"success":true}' run_upload "$workdir" "$workdir/demo.txt" ) >"$workdir/out.txt" 2>"$workdir/err.txt" && { echo "expected invalid response failure" >&2 exit 1 } assert_file_contains 'error: upload response missing a non-empty .files array' "$workdir/err.txt" assert_file_contains 'server response: {"success":true}' "$workdir/err.txt" rm -rf "$workdir" pass } test_success_and_request_shape test_missing_file test_missing_token test_missing_jq_in_normal_mode test_server_failure_surfaces_body test_invalid_success_shape_fails echo "smoke ok ($tests_run tests)"