test(backend): split smoke regression into core and pricing publish flows

separate smoke coverage into core backend checks and pricing publish flow checks

make regression runs more focused and easier to maintain
improve troubleshooting when a smoke stage fails
This commit is contained in:
greebo
2026-03-20 13:25:32 +03:00
parent 239b32a246
commit 210981c953
5 changed files with 746 additions and 249 deletions

View File

@@ -0,0 +1,117 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "${TMP_DIR}"' EXIT
# shellcheck source=backend/scripts/smoke_common.sh
source "${SCRIPT_DIR}/smoke_common.sh"
wait_for_health
create_fresh_scheme_from_upload "smoke-pricing-publish"
request "scheme_current" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/current" "200"
request "ensure_draft" "POST" "${API_URL}/api/v1/schemes/${SCHEME_ID}/draft/ensure" "200"
DRAFT_VERSION_ID="$(json_get "${TMP_DIR}/ensure_draft.body" "scheme_version_id")"
echo "DRAFT_VERSION_ID=${DRAFT_VERSION_ID}"
request "draft_structure" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/draft/structure?expected_scheme_version_id=${DRAFT_VERSION_ID}" "200"
read -r PRICED_SEAT_ID UNPRICED_SEAT_ID <<EOF
$(python3 - "${TMP_DIR}/draft_structure.body" <<'PY'
import json
import sys
from pathlib import Path
payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
seat_ids = [seat["seat_id"] for seat in payload.get("seats", []) if seat.get("seat_id")]
if len(seat_ids) < 2:
raise SystemExit("Fixture must contain at least two seats with seat_id for pricing smoke")
print(seat_ids[0], seat_ids[1])
PY
)
EOF
echo "PRICED_SEAT_ID=${PRICED_SEAT_ID}"
echo "UNPRICED_SEAT_ID=${UNPRICED_SEAT_ID}"
STAMP="$(date +%s)-$$"
PRICING_CATEGORY_NAME="smoke-pricing-${STAMP}"
PRICING_CATEGORY_CODE="SMOKE_${STAMP}"
request "create_pricing_category" "POST" \
"${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing/categories?expected_scheme_version_id=${DRAFT_VERSION_ID}" \
"200" \
"{\"name\":\"${PRICING_CATEGORY_NAME}\",\"code\":\"${PRICING_CATEGORY_CODE}\"}"
PRICING_CATEGORY_ID="$(json_get "${TMP_DIR}/create_pricing_category.body" "pricing_category_id")"
echo "PRICING_CATEGORY_ID=${PRICING_CATEGORY_ID}"
request "create_price_rule" "POST" \
"${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing/rules?expected_scheme_version_id=${DRAFT_VERSION_ID}" \
"200" \
"{\"pricing_category_id\":\"${PRICING_CATEGORY_ID}\",\"target_type\":\"seat\",\"target_ref\":\"${PRICED_SEAT_ID}\",\"amount\":\"1234.56\",\"currency\":\"RUB\"}"
PRICE_RULE_ID="$(json_get "${TMP_DIR}/create_price_rule.body" "price_rule_id")"
echo "PRICE_RULE_ID=${PRICE_RULE_ID}"
request "pricing_bundle" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing" "200"
assert_json_len_eq "${TMP_DIR}/pricing_bundle.body" "categories" "1"
assert_json_len_eq "${TMP_DIR}/pricing_bundle.body" "rules" "1"
request "pricing_coverage" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing/coverage" "200"
assert_json_int_gt "${TMP_DIR}/pricing_coverage.body" "priced_seats" "0"
assert_json_int_gt "${TMP_DIR}/pricing_coverage.body" "unpriced_seats" "0"
request "pricing_explain_priced" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing/explain/${PRICED_SEAT_ID}" "200"
assert_json_eq "${TMP_DIR}/pricing_explain_priced.body" "has_price" "true"
assert_json_eq "${TMP_DIR}/pricing_explain_priced.body" "reason_code" "ok"
assert_json_eq "${TMP_DIR}/pricing_explain_priced.body" "matched_rule.matched_rule_level" "seat"
assert_json_eq "${TMP_DIR}/pricing_explain_priced.body" "matched_rule.matched_target_ref" "${PRICED_SEAT_ID}"
request "pricing_explain_unpriced" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing/explain/${UNPRICED_SEAT_ID}" "200"
assert_json_eq "${TMP_DIR}/pricing_explain_unpriced.body" "has_price" "false"
assert_json_eq "${TMP_DIR}/pricing_explain_unpriced.body" "reason_code" "no_price_rule"
request "pricing_rule_diagnostics" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/pricing/rules/diagnostics" "200"
assert_json_int_eq "${TMP_DIR}/pricing_rule_diagnostics.body" "summary.total_rules" "1"
assert_json_int_gt "${TMP_DIR}/pricing_rule_diagnostics.body" "summary.matched_seats_total" "0"
request "seat_price" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/current/seats/${PRICED_SEAT_ID}/price" "200"
assert_json_eq "${TMP_DIR}/seat_price.body" "matched_rule_level" "seat"
assert_json_eq "${TMP_DIR}/seat_price.body" "matched_target_ref" "${PRICED_SEAT_ID}"
assert_json_eq "${TMP_DIR}/seat_price.body" "amount" "1234.56"
request "test_mode_priced" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/test/seats/${PRICED_SEAT_ID}" "200"
assert_json_eq "${TMP_DIR}/test_mode_priced.body" "has_price" "true"
assert_json_eq "${TMP_DIR}/test_mode_priced.body" "selectable" "true"
request "test_mode_unpriced" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/test/seats/${UNPRICED_SEAT_ID}" "200"
assert_json_eq "${TMP_DIR}/test_mode_unpriced.body" "has_price" "false"
assert_json_eq "${TMP_DIR}/test_mode_unpriced.body" "reason_code" "no_price_rule"
request "draft_pricing_snapshot" "POST" "${API_URL}/api/v1/schemes/${SCHEME_ID}/draft/pricing/snapshot?expected_scheme_version_id=${DRAFT_VERSION_ID}" "200"
request "publish_readiness" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/draft/publish-readiness?expected_scheme_version_id=${DRAFT_VERSION_ID}" "200"
assert_json_eq "${TMP_DIR}/publish_readiness.body" "snapshot.available" "true"
assert_json_eq "${TMP_DIR}/publish_readiness.body" "readiness.is_ready_to_publish" "true"
request "publish_preview_refresh" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/draft/publish-preview?refresh=true&expected_scheme_version_id=${DRAFT_VERSION_ID}" "200"
request "publish_preview_cached" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/draft/publish-preview?expected_scheme_version_id=${DRAFT_VERSION_ID}" "200"
request "publish_scheme" "POST" "${API_URL}/api/v1/schemes/${SCHEME_ID}/publish?expected_scheme_version_id=${DRAFT_VERSION_ID}" "200"
assert_json_eq "${TMP_DIR}/publish_scheme.body" "scheme_version_id" "${DRAFT_VERSION_ID}"
assert_json_eq "${TMP_DIR}/publish_scheme.body" "status" "published"
request "scheme_detail" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}" "200"
assert_json_eq "${TMP_DIR}/scheme_detail.body" "status" "published"
request "scheme_current" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/current" "200"
assert_json_eq "${TMP_DIR}/scheme_current.body" "status" "published"
request "audit_trail" "GET" "${API_URL}/api/v1/schemes/${SCHEME_ID}/audit" "200"
assert_file_contains "${TMP_DIR}/audit_trail.body" "\"event_type\":\"scheme.published\""
echo
echo "===== done ====="
echo "[OK] smoke pricing/publish completed successfully"
echo "FRESH_SCHEME_ID=${SCHEME_ID}"