Skip to content

Tests: Wave 3 — /api service + auth-engine spine (135 tests, one bug fixed)#62

Merged
WebTigers merged 5 commits into
mainfrom
test/wave3-collect
Jul 24, 2026
Merged

Tests: Wave 3 — /api service + auth-engine spine (135 tests, one bug fixed)#62
WebTigers merged 5 commits into
mainfrom
test/wave3-collect

Conversation

@WebTigers

Copy link
Copy Markdown
Owner

What

Wave 3 of the test backfill: the /api service layer + the kernel auth engine — the highest-value, highest-risk surface in the platform. Built by four parallel agents (each in its own worktree + isolated DB), then collected onto one DB and verified together.

Combined integration suite: 250 tests / 845 assertions green (was 116). Unit suite unchanged (247, green).

Base scaffolding (unblocks all service tests)

  • IntegrationTestCase::login()/loginAs()/logout() — set a real non-persistent Zend_Auth identity and register the actual shipped Tiger_Acl_Acl policy, so a service's _isAdmin()/ACL gate decides against the rules that really ship, not a fixture.
  • tests/bootstrap.php module-class autoloader (Mod_Type_Namemodules/<mod>/<types>/Name.php), registered last — a real /api service + its form/model instantiate with no require_once and no ZF1 module-resource-loader boot.
  • ServiceScaffoldTest (5) proves it against the real admin-gated Access_Service_User.

Coverage (135 new tests)

  • Signup (19) — guest tenant-graph create, validation + rollback, duplicate/disable/CSRF guards, verifyEmail redeem.
  • Code-exec / install cluster (35) — the compile-gate RCE boundary (server PHP compiles only from org_id='' rows, asserted on the compiled bytes), superadmin deny-by-default (guest and plain admin denied), nag-never-disable fail-open licensing (Tiger_License_Checker, System_Service_Updates).
  • Admin CRUD (55) — Access_Service_User/Org, Cms_Service_Page/Menu/Settings: deny-by-default ACL, the DataTables {draw,recordsTotal,recordsFiltered,data} envelope + server-computed permission flags, validate→transaction, soft-delete/restore, page version-on-save + slug 301, menu subtree reorder, settings→config tier.
  • Auth engine (26) — Tiger_Service_Authentication: password login + org-resolved role + audit row, no-enumeration parity, brute-force lockout, pepper migration, one-time challenges (code-login / reset), TOTP 2FA orchestration, session/lock/return-to. Exercises the real session paths via Zend_Session::$_unitTestEnabled (array-backed), not stubs.

Bug fixed (a test surfaced it)

Signup_Service_Signup::create() committed the tenant graph in _transaction(), then issued the email_verify challenge + sent mail after commit — with the challenge issue() outside the mail try/catch. A throw there unwound into create()'s catch → result=0 on a fully-committed account the user could neither use nor re-create (email-uniqueness). Fix: issue the challenge inside the transaction (atomic with the user — a challenge-write failure now rolls the whole signup back); _sendVerification reduced to best-effort post-commit mail.

Also

Only test files + the single signup fix + .gitignore change; no other framework/module source touched.

🤖 Generated with Claude Code

WebTigers and others added 5 commits July 24, 2026 13:19
…caffolding

The tiger-core integration base migrated a DB but had no way to test an /api SERVICE (which gates on
an authenticated identity + ACL). Adds:
- login(userId, orgId, role) — writes a non-persistent Zend_Auth identity {user_id,org_id,role} so a
  service's _isAdmin()/ACL gate + $this->_user_id/_org_id see an actor, stamps the model actor+org, and
  registers the REAL shipped policy (new Tiger_Acl_Acl — core + every module acl.ini) so isAllowed()
  reflects real rules, not a fixture. loginAs(role) shorthand; logout() reverts to guest; tearDown clears.
- ServiceScaffoldTest (5) — proves it end-to-end against a real admin-gated service (Access_Service_User):
  identity+actor set, the shipped acl.ini decides (admin allowed / user+guest denied), guest is refused
  dispatching datatable, admin clears the gate. Unblocks the Wave-3 Signup/Modules/Code/Auth service tests.

Note for service tests: a MODULE service class isn't on the harness autoload path — require_once its file
(it only extends the autoloadable Tiger_Service_Service). Kernel services (Tiger_Service_*) autoload.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The test harness deliberately never boots ZF1's module resource loader, so a
module's classes (Access_Service_User, Signup_Form_Signup, …) weren't on the
autoload path — a service test had to require_once the file by hand. Register a
LAST-resort module autoloader that maps `Mod_Type_Name` → modules/<mod>/<types>/
Name.php (and `Mod_XController` → controllers/), so a real /api service + its
form/model instantiate naturally. Drops the require_once from ServiceScaffoldTest;
it now doubles as proof the loader resolves a real admin-gated service.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n COVERAGE-PLAN §9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collect four parallel Wave-3 branches (own worktree + DB each) onto one DB and
verify together: the combined integration suite is 250 tests / 845 assertions green.

Coverage:
- Signup/SignupServiceTest (19) — guest tenant-graph create, validation+rollback,
  duplicate/disable/CSRF guards, verifyEmail redeem.
- Code/{Runtime,CodeService} + System/{Modules,Updates} + License/Checker (35) —
  the code-exec/install cluster: the compile-gate RCE boundary (server PHP compiles
  only from org_id='' rows, asserted on compiled bytes), superadmin deny-by-default,
  nag-never-disable fail-open licensing.
- Access/{User,Org} + Cms/{Page,Menu,Settings} (55) — admin CRUD: deny-by-default
  ACL, DataTables envelope + permission flags, validate->transaction, soft-delete,
  page version-on-save + slug 301, menu subtree reorder, settings->config tier.
- Service/AuthenticationTest (26) — kernel login engine: password login + org-resolved
  role + audit, no-enumeration parity, brute-force lockout, pepper migration, one-time
  challenges (code-login/reset), TOTP 2FA orchestration, session/lock/return-to. Runs
  the REAL session paths via Zend_Session::$_unitTestEnabled.

Bug fixed (a test surfaced it): Signup_Service_Signup::create() committed the tenant
graph, then issued the email_verify challenge + mailed OUTSIDE the mail try/catch — a
challenge-write throw reported result=0 on a fully-committed, un-recreatable account.
Now the challenge is issued INSIDE the transaction (atomic with the user); mail is
best-effort post-commit.

Also: gitignore the PHPUnit result cache + the code runtime's storage/public artifacts.
Findings #7-#10 (nested-transaction isolation follow-up, non-atomic settings save, et al.)
logged in COVERAGE-PLAN §9.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The integration suite passed but PHPUnit exited non-zero: in CI (no MTA) PHP mail()
fails, and the signup/OTP swallow-and-error_log paths then printed during 4 tests,
which strict-output flags as "risky". Give Tiger_Mail a process-wide default-transport
override (mirrors Zend_Mail::setDefaultTransport but is honored by the wrapper, which
always resolves its own transport) — precedence: explicit per-call > process default >
config-resolved. Null in production, so zero behavior change there. The test bootstrap
points it at a Zend_Mail_Transport_File writing to a throwaway dir, so every send()
captures-instead-of-delivers and never fails. No more risky tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@WebTigers
WebTigers merged commit 49347b0 into main Jul 24, 2026
10 checks passed
@WebTigers
WebTigers deleted the test/wave3-collect branch July 24, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant