from __future__ import annotations import re from pathlib import Path ROOT = Path(__file__).resolve().parents[3] SCRIPT = ROOT / "scripts" / "backup" / "backup-awoooi.sh" def test_daily_backup_has_no_hardcoded_database_password() -> None: text = SCRIPT.read_text(encoding="utf-8") assignment = re.search(r"^AWOOOI_DB_PASS=(.+)$", text, re.MULTILINE) assert assignment is not None assert assignment.group(1) == '"${AWOOOI_DB_PASS:-}"' assert "PGPASSWORD='${AWOOOI_DB_PASS}'" not in text assert 'PGPASSFILE="$pgpass"' in text assert "pg_dump --no-password" in text def test_daily_backup_resolves_runtime_database_url_and_fails_closed() -> None: text = SCRIPT.read_text(encoding="utf-8") assert "resolve_database_url()" in text assert "load_database_config()" in text assert "AWOOOI_BACKUP_DATABASE_URL BACKUP_DATABASE_URL DATABASE_URL" in text assert "無法解析 AWOOOI DATABASE_URL;拒絕使用舊硬編密碼" in text assert "base64 -d" in text assert 'printf \'%s\\n\' "${decoded}"' in text def test_daily_backup_uses_same_rls_safe_pg_dump_contract_as_frequent_lane() -> None: text = SCRIPT.read_text(encoding="utf-8") assert "dump_database_with_rls_guard()" in text assert 'PGOPTIONS="-c statement_timeout=0 -c max_parallel_workers_per_gather=0"' in text assert "ALTER TABLE %I.%I ${mode} ROW LEVEL SECURITY" in text assert "trap restore_force_rls EXIT" in text assert 'dump_database_with_rls_guard \\\n "awoooi_prod"' in text