Feat v0.6.1-v0.6.2: backup/restore, docs surface, dynamic OpenAPI
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 20s
CI/CD / test-frontend (pull_request) Successful in 6s
CI/CD / test-sqlite (pull_request) Has been cancelled
CI/CD / build-and-deploy (pull_request) Has been cancelled
CI/CD / test-go-pg (pull_request) Has been cancelled
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 20s
CI/CD / test-frontend (pull_request) Successful in 6s
CI/CD / test-sqlite (pull_request) Has been cancelled
CI/CD / build-and-deploy (pull_request) Has been cancelled
CI/CD / test-go-pg (pull_request) Has been cancelled
v0.6.1 — Backup tooling (.swb ZIP export/import), admin backup section, docs surface with markdown rendering, 5 reference docs, 6 handler tests. v0.6.2 — Dark mode contrast fixes, topbar nav, 📖 docs icon, dynamic OpenAPI spec with extension route merging, docs outline sidebar, scroll/routing fixes; 7 new tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
139
ci/e2e-backup-test.sh
Executable file
139
ci/e2e-backup-test.sh
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
# e2e-backup-test.sh — Backup/restore E2E test (v0.6.1)
|
||||
#
|
||||
# Requires: docker compose running with a single instance.
|
||||
# Usage:
|
||||
# docker compose up --build -d
|
||||
# ./ci/e2e-backup-test.sh
|
||||
# docker compose down -v
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
BASE="http://localhost:8080"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
pass() { PASS=$((PASS + 1)); echo " PASS: $1"; }
|
||||
fail() { FAIL=$((FAIL + 1)); echo " FAIL: $1"; }
|
||||
|
||||
# ── Wait for service ─────────────────────────
|
||||
echo "=== Waiting for service ==="
|
||||
for i in $(seq 1 30); do
|
||||
if curl -sf "$BASE/health" > /dev/null 2>&1; then
|
||||
echo " service ready"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
if [ "$i" -eq 30 ]; then
|
||||
echo "FATAL: service did not become healthy"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Login as admin ───────────────────────────
|
||||
echo "=== Authenticating ==="
|
||||
TOKEN=$(curl -sf "$BASE/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"login":"admin","password":"admin"}' | jq -r '.access_token')
|
||||
|
||||
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
|
||||
echo "FATAL: login failed"
|
||||
exit 1
|
||||
fi
|
||||
echo " admin token acquired"
|
||||
|
||||
auth() { echo "Authorization: Bearer $TOKEN"; }
|
||||
|
||||
# ── Seed test data ───────────────────────────
|
||||
echo "=== Seeding test data ==="
|
||||
|
||||
# Create a test user
|
||||
curl -sf "$BASE/api/v1/auth/register" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"backup-test-user","email":"bktest@test.com","password":"testpass123"}' > /dev/null
|
||||
|
||||
USER_COUNT=$(curl -sf "$BASE/api/v1/admin/users" -H "$(auth)" | jq '.data | length')
|
||||
echo " users: $USER_COUNT"
|
||||
|
||||
# ── Test 1: List backups (empty) ─────────────
|
||||
echo "=== Test 1: List backups (empty) ==="
|
||||
LIST=$(curl -sf "$BASE/api/v1/admin/backups" -H "$(auth)")
|
||||
COUNT=$(echo "$LIST" | jq '.data | length')
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
pass "empty backup list"
|
||||
else
|
||||
fail "expected 0 backups, got $COUNT"
|
||||
fi
|
||||
|
||||
# ── Test 2: Create server-side backup ────────
|
||||
echo "=== Test 2: Create server-side backup ==="
|
||||
RESULT=$(curl -sf "$BASE/api/v1/admin/backup?store=true" \
|
||||
-X POST \
|
||||
-H "$(auth)")
|
||||
FILENAME=$(echo "$RESULT" | jq -r '.data.filename')
|
||||
if [ -n "$FILENAME" ] && [ "$FILENAME" != "null" ]; then
|
||||
pass "created backup: $FILENAME"
|
||||
else
|
||||
fail "backup creation failed: $RESULT"
|
||||
fi
|
||||
|
||||
# ── Test 3: List backups (has one) ───────────
|
||||
echo "=== Test 3: List backups (has one) ==="
|
||||
LIST=$(curl -sf "$BASE/api/v1/admin/backups" -H "$(auth)")
|
||||
COUNT=$(echo "$LIST" | jq '.data | length')
|
||||
if [ "$COUNT" -eq 1 ]; then
|
||||
pass "one backup listed"
|
||||
else
|
||||
fail "expected 1 backup, got $COUNT"
|
||||
fi
|
||||
|
||||
# ── Test 4: Download backup ──────────────────
|
||||
echo "=== Test 4: Download backup ==="
|
||||
TMPFILE=$(mktemp /tmp/backup-test-XXXXXX.swb)
|
||||
HTTP_CODE=$(curl -sf -o "$TMPFILE" -w "%{http_code}" \
|
||||
"$BASE/api/v1/admin/backups/$FILENAME" -H "$(auth)")
|
||||
if [ "$HTTP_CODE" = "200" ] && [ -s "$TMPFILE" ]; then
|
||||
pass "download OK ($(wc -c < "$TMPFILE") bytes)"
|
||||
else
|
||||
fail "download failed (HTTP $HTTP_CODE)"
|
||||
fi
|
||||
|
||||
# ── Test 5: Streaming backup (direct download) ──
|
||||
echo "=== Test 5: Streaming backup ==="
|
||||
STREAM_FILE=$(mktemp /tmp/backup-stream-XXXXXX.swb)
|
||||
HTTP_CODE=$(curl -sf -o "$STREAM_FILE" -w "%{http_code}" \
|
||||
-X POST "$BASE/api/v1/admin/backup" -H "$(auth)")
|
||||
if [ "$HTTP_CODE" = "200" ] && [ -s "$STREAM_FILE" ]; then
|
||||
pass "streaming download OK ($(wc -c < "$STREAM_FILE") bytes)"
|
||||
else
|
||||
fail "streaming download failed (HTTP $HTTP_CODE)"
|
||||
fi
|
||||
|
||||
# ── Test 6: Delete backup ────────────────────
|
||||
echo "=== Test 6: Delete backup ==="
|
||||
DEL=$(curl -sf -X DELETE "$BASE/api/v1/admin/backups/$FILENAME" -H "$(auth)")
|
||||
DELETED=$(echo "$DEL" | jq -r '.data.deleted')
|
||||
if [ "$DELETED" = "$FILENAME" ]; then
|
||||
pass "deleted backup"
|
||||
else
|
||||
fail "delete failed: $DEL"
|
||||
fi
|
||||
|
||||
# Verify deletion
|
||||
LIST=$(curl -sf "$BASE/api/v1/admin/backups" -H "$(auth)")
|
||||
COUNT=$(echo "$LIST" | jq '.data | length')
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
pass "backup list empty after delete"
|
||||
else
|
||||
fail "expected 0 backups after delete, got $COUNT"
|
||||
fi
|
||||
|
||||
# ── Cleanup ──────────────────────────────────
|
||||
rm -f "$TMPFILE" "$STREAM_FILE"
|
||||
|
||||
# ── Summary ──────────────────────────────────
|
||||
echo ""
|
||||
echo "=== Results: $PASS passed, $FAIL failed ==="
|
||||
if [ "$FAIL" -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user