Back to Stirling Pdf

PAYG cucumber scenarios

testing/cucumber/features/payg/README.md

2.12.02.5 KB
Original Source

PAYG cucumber scenarios

End-to-end coverage for the PAYG shadow charging engine (PR #6519 / PR-S3 in notes/PAYG_DESIGN.md §7.5).

Running locally

bash
./testing/test-payg.sh

That script:

  1. Boots testing/compose/docker-compose-saas.yml (Stirling-PDF with STIRLING_FLAVOR=saas + a Postgres holding the stirling_pdf schema)
  2. Waits for backend health
  3. Pipes testing/compose/payg/saas-seed.sql into the test postgres, creating a payg-cucumber-team flipped to wallet_policy.engine = 'PAYG_SHADOW' and a test user with API key payg-cucumber-key
  4. Runs python -m behave features/payg
  5. Tears the stack down

What's covered (automated, run by docker-compose-tests-saas.yml on CI)

ScenarioValidates
First tool call writes a CHARGED rowFilter + interceptor fire end-to-end; shadow row written
Lineage join — second call on outputJobService.joinOrOpen lineage matching; no new shadow row
First-step 5xx refunds + closes the processmarkFirstStepFailed flips row to REFUNDED, job to CLOSED
4xx leaves the row CHARGED"customer paid for the attempt" semantics
ZIP-returning tool records per-PDF OUTPUTPaygOutputExtractor unpacks + records signatures
Multi-file input writes a single shadow rowMulti-input group sizing
X-Stirling-Automation sets PIPELINE sourceHeader → JobSource detection

The 5xx scenario drives the refund path through PaygCucumberThrowController — a @Profile("payg-cucumber") stub in app/saas/.../payg/test/ that always throws. The profile is activated by docker-compose-saas.yml's SPRING_PROFILES_ACTIVE=saas,payg-cucumber and is never set in production.

Manual-only scenarios

One part of the shadow engine can't reasonably be driven from this suite and is verified by hand each time its code path changes. The procedure lives in notes/PAYG_DESIGN.md §7.5.2 "PAYG cucumber: manual-only scenarios".

  • Kill-switch (PAYG_FILTER_ENABLED=false). Needs a docker-container restart mid-suite; orchestrating that in behave is more harness fragility than it's worth for a flag that's only flipped during incident response.

Fixtures

The scenarios reuse testing/cucumber/exampleFiles/:

  • ghost1.pdf — single-page reference PDF
  • tables.pdf — multi-page input for split / ZIP scenarios

If those filenames change in the main cucumber harness, update features/steps/payg_step_definitions.py SINGLE_PAGE_PDF / THREE_PAGE_PDF constants to match.