Skip to main content

Test-support API

Audience: developers & AI agents writing specs · Scope: the secret-gated HTTP endpoint + the support client that specs use to arrange fixtures and read state · Last reviewed: 2026-07-11

Part of Testing. Reuse these commands in new specs instead of writing DB or CLI glue.

TL;DR — Playwright runs in Node; the app is PHP/Joomla. They meet through one authenticated HTTP endpoint (ConfigboxControllerBctestsupportBcTestSupport) that runs the app's own code to inspect and prepare state, run the deal-update flow in capture mode, and mint follow-up tokens. Specs call it through the synchronous support client (tests/support/cli.ts). Using the app's own code keeps tests honest and avoids duplicating schema knowledge.

The endpoint & auth

GET {BASE_URL}/index.php?option=com_configbox&controller=bctestsupport&task=run&command=<cmd>&arg1=<…>&arg2=<…>
Header: X-BC-Test-Support-Secret: <the environment's test_support_secret setting>
  • Fail-closed & secret-gated. It works only when the per-environment setting test_support_secret (Backend → Settings → Functional Test Harness) is set and the caller presents the same value (constant-time compare). A blank setting disables the endpoint (403) — leave it blank except while running the suite. Put the matching value in tests/.env as TEST_SUPPORT_SECRET.
  • Capture is inline. The process* commands run in capture mode and return the intercepted Pipedrive payloads in the response (captures), which the client mirrors to tests/.captures/. Nothing is sent.
  • The same logic is also a server-local CLI (docroot/cli/cb_pipedrive_test_support.php) for manual use on the box; the suite no longer needs it.

The client (tests/support/cli.ts)

support.* is synchronous (curl + execFileSync), so call sites read top-to-bottom with no await. Companion helpers: support/captures.ts (capturesForSerial(serial)), support/seedQuote.ts (seedDecorativeQuote(page)), support/followupForm.ts (form gestures).

Commands

Every command below is reachable as support.<method>(…). R = read-only, W = mutates test data, = real external write (opt-in / live only).

Harness & config

Commandsupport.…Purpose
modemode()resolved capture/send mode, environment, DEV org idR
field-keysfieldKeys()the settings-sourced custom-field keys the payload uses (env-specific hashes)R
page-urlspageUrls()server-resolved SEF URLs for the My Quotes + login pages (assert a redirect target without hard-coding)R

Quote state & fixtures

Commandsupport.…Purpose
quote-state <serial>quoteState() / latestQuote()every revision's pipedrive_* columns (+ id/name/revision/stage/dates/oot)R
set-quote-owner <serial> <cbUserId>setQuoteOwner()reassign every revision to another owner (the non-owner test)W
delete-quote <serial>deleteQuote()hard-delete every revision + child rows (cleanup; no Pipedrive)W
reset-feedback <serial>resetFeedback()clear the Quote Follow-Up feedback so the page renders the fresh form stateW

Quote Follow-Up

Commandsupport.…Purpose
seed-stages / clear-stagesseedStages() / clearStages()populate/remove a deterministic synthetic stage set (no live import needed)W
mint-followup-token <serial> [expired]mintFollowupToken()sign a grant token for the serial's agent (open the no-login page authorized; not a login)R
set-followup-api-secret <secret>setFollowupApiSecret()set/clear the Link API shared secret (auth matrix); returns the previous value to restoreW

Stage-sync

Commandsupport.…Purpose
stage-sync-rows <serial>stageSyncRows() / latestStageSyncRow()the always-on recorder's rows for a serialR
clear-stage-sync <serial>clearStageSync()delete a serial's sync rows (cleanup — they have no FK to the quote)W

Nudge

Commandsupport.…Purpose
set-stage-cadence <stageId> <csv>setStageCadence()set a stage's nudge cadence ("small,mid,large", "0,0,0" = due now); returns previousW
set-nudge-gates <excl> <incl>setNudgeGates()flip the internal/test deal-type gates; returns previousW
collect-due-rows <serial>collectNudgeDueRow()run the real due computation for one serial without writing a sheet — is it due, with what bucket/anchorR

Deal-update flow (capture)

Commandsupport.…Purpose
schedule <serial>schedule()flag the latest revision for a deal update (drive the runner without the UI)W
set-deal-id <serial> <dealId>setDealId()link a quote to an existing deal id (the update-path fixture)W
process / process-serial <serial>process() / processSerial()run the deal update (whole queue / one serial) in capture mode; returns the captured payloadsW
clear-capturesclearCaptures()empty the local capture file (server-side no-op)R

Live / real destinations (★ opt-in, DEV org 6034 only)

Commandsupport.…Purpose
read-deal <serial>readDeal()read the live Pipedrive deal (stage_id/pipeline_id/status/…)R
create-fixture-deal <serial>createFixtureDeal()create a throwaway DEV-org deal + link it (so the push takes the guard-safe update path)
delete-deal <serial>deleteDeal()delete the linked real deal (live-smoke teardown)
process-serial <serial> (send)processSerialLive()run the deal update in send mode (real write; org-6034 guard applies)
export-sheet / read-sheet-rows <serial>exportSheet() / readSheetRows()run the real stage-sync sheet export / read it back★ / R
build-nudge-sheet / read-nudge-sheet-rows <serial>buildNudgeSheet() / readNudgeSheetRows()run the real nudge reconcile / read it back★ / R

Adding a command

  1. system_overrides/BcTestSupport.php — add a case in run() calling a new private static method (read state, or mutate test data; keep it test-only and idempotent-friendly). A setter that changes a setting should return the previous value so the spec can restore it.
  2. tests/support/cli.ts — add a support.<method>() wrapper (typed return) that calls call('<cmd>', …).
  3. Document it — add a row to the right table above, so the next spec reuses it.

Safety

These are powerful, test-only mutations (delete quotes, reassign owners, mint grant tokens, write settings). They are reachable only through the secret-gated controller (or the server-local CLI) — never wire BcTestSupport to an unauthenticated path. Real external writes are confined to DEV org 6034 by the always-on guard. See ../pipedrive/testing.md for the capture/guard detail.