121 lines
4.2 KiB
Bash
Executable File
121 lines
4.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
COMPOSE_FILE="${ROOT_DIR}/docker-compose.yml"
|
|
BACKEND_URL="${BACKEND_URL:-http://localhost:8000}"
|
|
WAIT_SECONDS="${WAIT_SECONDS:-60}"
|
|
PYTHON_BIN="${PYTHON_BIN:-python3}"
|
|
EDITOR_EMAIL="${EDITOR_EMAIL:-editor@example.com}"
|
|
|
|
cleanup() {
|
|
docker compose -f "${COMPOSE_FILE}" down --remove-orphans >/dev/null 2>&1 || true
|
|
}
|
|
|
|
request() {
|
|
local method="$1"
|
|
local path="$2"
|
|
local body="${3:-}"
|
|
|
|
if [[ -n "${body}" ]]; then
|
|
curl -fsS -X "${method}" -H "Content-Type: application/json" \
|
|
-H "X-Demo-User-Email: ${EDITOR_EMAIL}" --data "${body}" "${BACKEND_URL}${path}"
|
|
return
|
|
fi
|
|
|
|
curl -fsS -X "${method}" -H "X-Demo-User-Email: ${EDITOR_EMAIL}" "${BACKEND_URL}${path}"
|
|
}
|
|
|
|
wait_backend() {
|
|
local deadline=$((SECONDS + WAIT_SECONDS))
|
|
while (( SECONDS < deadline )); do
|
|
if curl -fsS "${BACKEND_URL}/health" >/dev/null 2>&1; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
echo "Timed out waiting for backend at ${BACKEND_URL}" >&2
|
|
return 1
|
|
}
|
|
|
|
json_eval() {
|
|
local expression="$1"
|
|
"${PYTHON_BIN}" -c "import json,sys; print(${expression})"
|
|
}
|
|
|
|
create_researched_article() {
|
|
local suffix="$1"
|
|
local site_id article_body article_id questions_json commands question_id answer plan_id
|
|
|
|
site_id="$(request GET /api/sites | json_eval "json.load(sys.stdin)[0]['site']['id']")"
|
|
article_body="$(
|
|
SITE_ID="${site_id}" SUFFIX="${suffix}" "${PYTHON_BIN}" - <<'PY'
|
|
import json
|
|
import os
|
|
import uuid
|
|
|
|
suffix = os.environ["SUFFIX"]
|
|
print(json.dumps({
|
|
"target_site_id": os.environ["SITE_ID"],
|
|
"brief_description": f"Evidence smoke {suffix} {uuid.uuid4()}",
|
|
"working_title": "Evidence Smoke Flow",
|
|
"content_type": "longform_guide",
|
|
"primary_keyword": suffix,
|
|
}))
|
|
PY
|
|
)"
|
|
article_id="$(request POST /api/articles "${article_body}" | json_eval "json.load(sys.stdin)['article']['id']")"
|
|
questions_json="$(request POST "/api/articles/${article_id}/boundary-questions/generate")"
|
|
commands="$(
|
|
QUESTIONS_JSON="${questions_json}" "${PYTHON_BIN}" - <<'PY'
|
|
import json
|
|
import os
|
|
|
|
for question in json.loads(os.environ["QUESTIONS_JSON"])["questions"]:
|
|
if question["is_required"]:
|
|
print(f"{question['id']}\tAccepted answer for {question['category']}.")
|
|
PY
|
|
)"
|
|
while IFS=$'\t' read -r question_id answer; do
|
|
[[ -z "${question_id}" ]] && continue
|
|
patch_body="$(ANSWER="${answer}" "${PYTHON_BIN}" - <<'PY'
|
|
import json
|
|
import os
|
|
|
|
print(json.dumps({"answer": os.environ["ANSWER"]}))
|
|
PY
|
|
)"
|
|
request PATCH "/api/articles/${article_id}/boundary-questions/${question_id}" "${patch_body}" >/dev/null
|
|
done <<< "${commands}"
|
|
request POST "/api/articles/${article_id}/boundary-questions/submit" >/dev/null
|
|
plan_id="$(request POST "/api/articles/${article_id}/plan/generate" | json_eval "json.load(sys.stdin)['plan']['id']")"
|
|
request POST "/api/articles/${article_id}/plans/${plan_id}/approve" >/dev/null
|
|
request POST "/api/articles/${article_id}/research/start" >/dev/null
|
|
printf '%s' "${article_id}"
|
|
}
|
|
|
|
cd "${ROOT_DIR}"
|
|
trap cleanup EXIT
|
|
|
|
docker compose -f "${COMPOSE_FILE}" up --build -d
|
|
wait_backend
|
|
|
|
sufficient_id="$(create_researched_article "sufficient evidence coverage")"
|
|
sufficient_json="$(request GET "/api/articles/${sufficient_id}/evidence")"
|
|
sufficient_reasons="$(printf '%s' "${sufficient_json}" | json_eval "len(json.load(sys.stdin)['insufficient_evidence_reasons'])")"
|
|
if [[ "${sufficient_reasons}" != "0" ]]; then
|
|
echo "Expected sufficient flow without evidence reasons" >&2
|
|
exit 1
|
|
fi
|
|
|
|
insufficient_id="$(create_researched_article "insufficient evidence coverage")"
|
|
insufficient_json="$(request GET "/api/articles/${insufficient_id}/evidence")"
|
|
insufficient_status="$(printf '%s' "${insufficient_json}" | json_eval "json.load(sys.stdin)['article']['status']")"
|
|
unsupported_count="$(printf '%s' "${insufficient_json}" | json_eval "len([claim for claim in json.load(sys.stdin)['claims'] if claim['support_status'] == 'UNSUPPORTED'])")"
|
|
if [[ "${insufficient_status}" != "PLAN_REVISION_REQUIRED" || "${unsupported_count}" == "0" ]]; then
|
|
echo "Expected insufficient flow to return to PLAN_REVISION_REQUIRED with unsupported claims" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "evidence flow smoke ok"
|