#!/usr/bin/env bash set -euo pipefail if [ -z "${BASE_URL:-}" ]; then if curl --silent --fail http://127.0.0.1:8085/api/health >/dev/null 2>&1; then BASE_URL="http://127.0.0.1:8085" elif curl --silent --fail http://host.containers.internal:8085/api/health >/dev/null 2>&1; then BASE_URL="http://host.containers.internal:8085" else echo "ERROR: could not determine BASE_URL. Tried 127.0.0.1 and host.containers.internal." >&2 exit 1 fi fi TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT echo "== Feature test 1: roots endpoint returns configured roots with stable fields ==" curl --fail --silent --show-error \ "${BASE_URL}/api/files/roots" \ -o "${TMP_DIR}/roots.json" cat "${TMP_DIR}/roots.json" python3 - "${TMP_DIR}/roots.json" > "${TMP_DIR}/root_id.txt" <<'PY' import json import sys from pathlib import Path data = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) items = data.get("items") assert isinstance(items, list), "roots.items must be a list" assert len(items) > 0, "roots.items must not be empty" first = items[0] for key in ["id", "path", "exists", "readable"]: assert key in first, f"root missing key: {key}" assert isinstance(first["id"], str) and first["id"], "root.id must be non-empty string" assert isinstance(first["path"], str) and first["path"], "root.path must be non-empty string" assert isinstance(first["exists"], bool), "root.exists must be boolean" assert isinstance(first["readable"], bool), "root.readable must be boolean" print(first["id"]) PY ROOT_ID="$(cat "${TMP_DIR}/root_id.txt")" echo echo "== Feature test 2: discover within root returns response shape and allowed extensions only ==" curl --fail --silent --show-error \ "${BASE_URL}/api/files/discover?root_id=${ROOT_ID}&subpath=&recursive=false&limit=200" \ -o "${TMP_DIR}/discover.json" cat "${TMP_DIR}/discover.json" python3 - "${TMP_DIR}/discover.json" "$ROOT_ID" <<'PY' import json import sys from pathlib import Path data = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) root_id = sys.argv[2] assert data.get("root_id") == root_id, "discover.root_id mismatch" assert "root_path" in data and isinstance(data["root_path"], str), "discover.root_path missing/invalid" assert "items" in data and isinstance(data["items"], list), "discover.items missing/invalid" allowed = {".mkv", ".mp4", ".avi", ".m4v", ".srt"} for item in data["items"]: for key in ["name", "path", "relative_path", "extension", "size_bytes", "modified_at_unix"]: assert key in item, f"discover item missing key: {key}" assert item["extension"] in allowed, f"unexpected extension: {item['extension']}" print("discover shape validation passed") PY echo echo "== Feature test 3: traversal/absolute subpath is rejected ==" curl --silent --show-error \ -o "${TMP_DIR}/discover_bad_abs.json" \ -w "%{http_code}" \ "${BASE_URL}/api/files/discover?root_id=${ROOT_ID}&subpath=/etc&recursive=false&limit=10" \ > "${TMP_DIR}/discover_bad_abs.status" curl --silent --show-error \ -o "${TMP_DIR}/discover_bad_parent.json" \ -w "%{http_code}" \ "${BASE_URL}/api/files/discover?root_id=${ROOT_ID}&subpath=../secret&recursive=false&limit=10" \ > "${TMP_DIR}/discover_bad_parent.status" cat "${TMP_DIR}/discover_bad_abs.json" cat "${TMP_DIR}/discover_bad_parent.json" python3 - "${TMP_DIR}/discover_bad_abs.status" "${TMP_DIR}/discover_bad_abs.json" "${TMP_DIR}/discover_bad_parent.status" "${TMP_DIR}/discover_bad_parent.json" <<'PY' import json import sys from pathlib import Path status_abs = Path(sys.argv[1]).read_text(encoding="utf-8").strip() json_abs = json.loads(Path(sys.argv[2]).read_text(encoding="utf-8")) status_parent = Path(sys.argv[3]).read_text(encoding="utf-8").strip() json_parent = json.loads(Path(sys.argv[4]).read_text(encoding="utf-8")) assert status_abs == "400", f"absolute subpath should be 400, got {status_abs}" assert status_parent == "400", f"parent traversal should be 400, got {status_parent}" assert "detail" in json_abs, "absolute subpath response missing detail" assert "detail" in json_parent, "parent traversal response missing detail" print("subpath security validation passed") PY echo echo "All file discovery feature tests passed."