+277
-23
@@ -2,37 +2,291 @@
|
||||
set -euo pipefail
|
||||
|
||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
workdir="$(mktemp -d)"
|
||||
trap 'rm -rf "$workdir"' EXIT
|
||||
tests_run=0
|
||||
|
||||
cat >"$workdir/.env" <<'EOF'
|
||||
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
|
||||
}
|
||||
|
||||
mkdir -p "$workdir/bin"
|
||||
cat >"$workdir/bin/curl" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf '%s\n' '{"files":["https://shx.example/mock-file"]}'
|
||||
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
|
||||
chmod +x "$workdir/bin/curl"
|
||||
install_mock_curl "$workdir"
|
||||
touch "$workdir/demo.txt"
|
||||
|
||||
cat >"$workdir/bin/jq" <<'EOF'
|
||||
#!/usr/bin/env python3
|
||||
import json, sys
|
||||
payload = json.load(sys.stdin)
|
||||
for item in payload.get("files", []):
|
||||
print(item)
|
||||
EOF
|
||||
chmod +x "$workdir/bin/jq"
|
||||
if run_upload "$workdir" "$workdir/demo.txt" >"$workdir/out.txt" 2>"$workdir/err.txt"; then
|
||||
echo "expected missing token failure" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch "$workdir/demo.txt"
|
||||
assert_file_contains 'error: SHX_TOKEN is not set' "$workdir/err.txt"
|
||||
rm -rf "$workdir"
|
||||
pass
|
||||
}
|
||||
|
||||
PATH="$workdir/bin:$PATH" \
|
||||
SHX_ENV_FILE="$workdir/.env" \
|
||||
"$repo_root/bin/shx-upload" "$workdir/demo.txt" >"$workdir/out.txt"
|
||||
test_missing_jq_in_normal_mode() {
|
||||
local workdir
|
||||
workdir="$(make_workdir)"
|
||||
|
||||
grep -Fx 'https://shx.example/mock-file' "$workdir/out.txt"
|
||||
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"
|
||||
|
||||
echo 'smoke ok'
|
||||
(
|
||||
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)"
|
||||
|
||||
Reference in New Issue
Block a user