#!/usr/bin/env bash # test_lint_archive.sh — тестирует POST /console/api/ai/lint-archive # Валидные архивы всех 4 языков → ok: true # Архив с синтаксической ошибкой → ok: false # Архив > 100 KB → HTTP 413 # Zip bomb (маленький zip, большой распакованный) → HTTP 413 # Архив без поддерживаемых файлов → HTTP 400 # Без поля archive → HTTP 400 set -uo pipefail ROOT_DIR=$(cd "$(dirname "$0")" && pwd) source "${ROOT_DIR}/lib.sh" SUB="livetest@test.local" ARCHIVES_DIR="${ROOT_DIR}/../test-archives" TMP=$(mktemp -d) cleanup() { rm -rf "$TMP"; } trap cleanup EXIT echo "" echo "========================================" echo " test_lint_archive.sh" echo "========================================" lint_post() { local zip_path="$1" curl -s -w "\n%{http_code}" -X POST "${BASE}/ai/lint-archive" \ -H "X-Auth-Token: ${SUB}" \ -F "archive=@${zip_path}" } # ── Вспомогательная функция: создать zip с одним файлом ───────────────────── make_zip() { local name="$1" filename="$2" content="$3" local dir="${TMP}/${name}" mkdir -p "$dir" printf '%s' "$content" > "${dir}/${filename}" (cd "$dir" && zip -q "../${name}.zip" "$filename") echo "${TMP}/${name}.zip" } # ── Python валидный ─────────────────────────────────────────────────────────── echo "" echo ">>> Python: валидный архив → ok:true" R=$(lint_post "${ARCHIVES_DIR}/py-hello.zip") HTTP=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$HTTP" "200" "Python lint → 200" OK=$(json_field "$BODY" ok) [ "$OK" = "True" ] || [ "$OK" = "true" ] && pass "Python lint ok=true" || fail "Python lint ok=$OK" # ── Node.js валидный ───────────────────────────────────────────────────────── echo "" echo ">>> Node.js: валидный архив → ok:true" R=$(lint_post "${ARCHIVES_DIR}/node-hello.zip") HTTP=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$HTTP" "200" "Node.js lint → 200" OK=$(json_field "$BODY" ok) [ "$OK" = "True" ] || [ "$OK" = "true" ] && pass "Node.js lint ok=true" || fail "Node.js lint ok=$OK" # ── Ruby валидный ──────────────────────────────────────────────────────────── echo "" echo ">>> Ruby: валидный архив → ok:true" R=$(lint_post "${ARCHIVES_DIR}/ruby-hello.zip") HTTP=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$HTTP" "200" "Ruby lint → 200" OK=$(json_field "$BODY" ok) [ "$OK" = "True" ] || [ "$OK" = "true" ] && pass "Ruby lint ok=true" || fail "Ruby lint ok=$OK" # ── PHP валидный ───────────────────────────────────────────────────────────── echo "" echo ">>> PHP: валидный архив → ok:true" R=$(lint_post "${ARCHIVES_DIR}/php-hello.zip") HTTP=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$HTTP" "200" "PHP lint → 200" OK=$(json_field "$BODY" ok) [ "$OK" = "True" ] || [ "$OK" = "true" ] && pass "PHP lint ok=true" || fail "PHP lint ok=$OK" # ── Синтаксическая ошибка Python ───────────────────────────────────────────── echo "" echo ">>> Python: синтаксическая ошибка → ok:false" BAD_PY=$(make_zip "bad-py" "bad.py" "def broken(:\n pass") R=$(lint_post "$BAD_PY") HTTP=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$HTTP" "200" "Python bad lint → 200" OK=$(json_field "$BODY" ok) [ "$OK" = "False" ] || [ "$OK" = "false" ] && pass "Python bad lint ok=false" || fail "Python bad lint ok=$OK" # ── Синтаксическая ошибка Node.js ──────────────────────────────────────────── echo "" echo ">>> Node.js: синтаксическая ошибка → ok:false" BAD_JS=$(make_zip "bad-js" "bad.js" "module.exports = function( { return 'broken'; };") R=$(lint_post "$BAD_JS") HTTP=$(echo "$R" | tail -1) BODY=$(echo "$R" | sed '$d') check_http "$HTTP" "200" "Node.js bad lint → 200" OK=$(json_field "$BODY" ok) [ "$OK" = "False" ] || [ "$OK" = "false" ] && pass "Node.js bad lint ok=false" || fail "Node.js bad lint ok=$OK" # ── Архив > 100 KB → 413 ───────────────────────────────────────────────────── echo "" echo ">>> Архив > 100 KB → 413" BIG_ZIP="${TMP}/big.zip" # Случайные бинарные данные не сжимаются → zip гарантированно > 100 KB dd if=/dev/urandom bs=1024 count=130 2>/dev/null > "${TMP}/big.bin" (cd "$TMP" && zip -q big.zip big.bin) R=$(lint_post "$BIG_ZIP") HTTP=$(echo "$R" | tail -1) check_http "$HTTP" "413" "Большой архив → 413" # ── Нет поддерживаемых файлов → 400 ───────────────────────────────────────── echo "" echo ">>> Архив без поддерживаемых файлов → 400" NO_CODE=$(make_zip "no-code" "README.md" "# Hello") R=$(lint_post "$NO_CODE") HTTP=$(echo "$R" | tail -1) check_http "$HTTP" "400" "Нет поддерживаемых файлов → 400" # ── Без поля archive → 400 ─────────────────────────────────────────────────── echo "" echo ">>> Без поля archive → 400" R=$(curl -s -w "\n%{http_code}" -X POST "${BASE}/ai/lint-archive" \ -H "X-Auth-Token: ${SUB}") HTTP=$(echo "$R" | tail -1) check_http "$HTTP" "400" "Без поля archive → 400" # ── Невалидный zip (не zip-файл) → 400 ─────────────────────────────────────── echo "" echo ">>> Невалидный zip (текстовый файл) → 400" echo "not a zip" > "${TMP}/fake.zip" R=$(lint_post "${TMP}/fake.zip") HTTP=$(echo "$R" | tail -1) check_http "$HTTP" "400" "Невалидный zip → 400" print_summary