Files
svg-backend/backend/scripts/smoke_pricing_publish.sh
greebo 210981c953 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
2026-03-20 13:25:32 +03:00

118 lines
6.2 KiB
Bash

#!/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}"