From ce7c5b2474aa933bee5926f7db631cc3ff57655d Mon Sep 17 00:00:00 2001 From: nns Date: Tue, 9 Jun 2026 03:49:44 +0500 Subject: [PATCH] test(s28): acceptance script verify-sprint28.sh (5 checks) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validates the full Sprint 28 deliverable in one script: 1. api-reference.md has ≥240 endpoints 2. HSTS header set on stage 3. Integration suite 10/10 passes 4. quality-watchdog last status = 🟢 5. Hangfire ≥13 recurring jobs registered Exit 0 if all pass; runs in ~2 минуты. Co-Authored-By: Claude Opus 4.7 --- scripts/verify-sprint28.sh | 96 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100755 scripts/verify-sprint28.sh diff --git a/scripts/verify-sprint28.sh b/scripts/verify-sprint28.sh new file mode 100755 index 0000000..ea463f1 --- /dev/null +++ b/scripts/verify-sprint28.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Sprint 28 verification — выполняется как acceptance test всей sprint'a. +# +# Что проверяет: +# 1. api-reference.md содержит 240 endpoints +# 2. HSTS header выставлен на stage +# 3. Все 10 integration тестов проходят +# 4. quality-watchdog текущий статус — 🟢 +# +# Exit code: 0 если всё OK, 1+ если что-то не так. + +set -uo pipefail + +STAGE_URL="${STAGE_URL:-https://test.admin.food-market.kz}" +REPO="$(cd "$(dirname "$0")/.." && pwd)" +FAIL=0 + +cyan() { echo -e "\033[36m$1\033[0m"; } +green() { echo -e "\033[32m✓ $1\033[0m"; } +red() { echo -e "\033[31m✗ $1\033[0m"; } + +cyan "=== Sprint 28 acceptance test ===" +echo + +# ── 1. api-reference.md count +cyan "1. api-reference.md count" +COUNT=$(grep -E "^\| (GET|POST|PUT|DELETE|PATCH) \|" "$REPO/docs/api-reference.md" | wc -l) +HEADER_COUNT=$(grep -E "Всего endpoint" "$REPO/docs/api-reference.md" | grep -oE "[0-9]+" | head -1) +if [ "$COUNT" -ge 240 ] && [ "$HEADER_COUNT" -ge 240 ]; then + green "api-reference.md: $COUNT endpoints (header claims $HEADER_COUNT)" +else + red "api-reference.md: $COUNT endpoints (expected ≥240)" + FAIL=$((FAIL + 1)) +fi + +# ── 2. HSTS header +cyan "2. HSTS header on stage" +HSTS=$(curl -fsSI --max-time 10 "$STAGE_URL/" 2>/dev/null | grep -i "strict-transport-security" | head -1) +if echo "$HSTS" | grep -q "max-age="; then + green "HSTS present: $HSTS" +else + red "HSTS missing on $STAGE_URL" + FAIL=$((FAIL + 1)) +fi + +# ── 3. Integration tests +cyan "3. Integration tests (10 expected)" +cd "$REPO/tests/integration" 2>/dev/null +if [ ! -d node_modules ]; then + echo " installing deps..." + pnpm install --frozen-lockfile > /dev/null 2>&1 || true +fi +INTEGRATION_OUT=$(timeout 300 pnpm exec playwright test --reporter=line 2>&1 | tail -3) +if echo "$INTEGRATION_OUT" | grep -qE "[0-9]+ passed"; then + PASS_NUM=$(echo "$INTEGRATION_OUT" | grep -oE "[0-9]+ passed" | head -1 | grep -oE "[0-9]+") + if [ "$PASS_NUM" -ge 10 ]; then + green "integration: $PASS_NUM passed" + else + red "integration: only $PASS_NUM passed (expected ≥10)" + FAIL=$((FAIL + 1)) + fi +else + red "integration: failed to determine count" + FAIL=$((FAIL + 1)) +fi + +# ── 4. Quality watchdog status +cyan "4. quality-watchdog last run status" +STATUS=$(grep -oE "🟢|🟡|🔴" "$REPO/docs/quality-status.md" 2>/dev/null | head -1) +if [ "$STATUS" = "🟢" ]; then + green "quality-watchdog: green" +else + red "quality-watchdog: $STATUS (expected 🟢)" + FAIL=$((FAIL + 1)) +fi + +# ── 5. Hangfire jobs registered (proxy via DB query — optional) +cyan "5. Hangfire recurring jobs registered (13 expected)" +JOBS=$(ssh -o ConnectTimeout=5 nns@192.168.1.190 \ + "docker exec food-market-stage-postgres-1 psql -U food_market -d food_market -tA -c \ + \"SELECT count(DISTINCT key) FROM hangfire.hash WHERE key LIKE 'recurring-job:%'\"" 2>/dev/null) +if [ "$JOBS" -ge 13 ]; then + green "Hangfire: $JOBS recurring jobs (≥13)" +else + red "Hangfire: only $JOBS jobs (expected ≥13)" + FAIL=$((FAIL + 1)) +fi + +echo +if [ "$FAIL" -eq 0 ]; then + green "=== Sprint 28 acceptance: ALL CHECKS PASSED ===" + exit 0 +else + red "=== Sprint 28 acceptance: $FAIL CHECKS FAILED ===" + exit 1 +fi