Skip to content

test(#19): project isolation coverage across unit and integration suites - #36

Open
jpricardo wants to merge 2 commits into
feat/multi-tenancyfrom
test/project-isolation
Open

test(#19): project isolation coverage across unit and integration suites#36
jpricardo wants to merge 2 commits into
feat/multi-tenancyfrom
test/project-isolation

Conversation

@jpricardo

Copy link
Copy Markdown
Owner

Closes #19.

Three of the issue's boxes were already ticked by earlier phases — the isolation test, the data-layer cascade test, and the retention-cleanup test all existed. The real gaps were the broker's membership middleware and an end-to-end cascade.

Broker unit tests

X-User-Login / membership enforcement had no coverage at all. The project handlers dial the Logger themselves via LOGGER_RPC_ADDR, so there was no seam for a mock: fakelogger_test.go puts a real net/rpc server on the other end of that dial instead, which keeps the wire contract intact — including net/rpc flattening errors into strings, which the broker matches on for E11000 and "last owner".

project_access_test.go then drives the real router:

  • internal-secret and X-User-Login rejection across all 17 internal routes
  • non-member 403 vs. unknown-project 404
  • owner-only guards, including asserting the denied call never reaches the logger
  • cross-project log ids returning 404, and GET /projects/{id}/logs forwarding the path's project
  • create-project owner assignment, duplicate-slug 409, and the rollback when the owner cannot be attached

Broker suite: 9 → 58 passing assertions.

Integration

  • project_cascade_test.go builds a project the way the dashboard does — create, mint key, set retention, send events — then deletes it and checks all five collections are clear, that the minted key reads nothing back, and that a second delete is a 404.
  • TestWritePathRoundTrip gained a batch case proving a forged project_id in the body is overwritten by the key's project.
  • Added a cross-read isolation case and GetProjectMembers coverage.

Two things found along the way

The suite didn't fit CI's budget. Baseline was 252s against a 300s timeout, because every test built its own containers and stack. The fixtures are now shared (sharedStack, sharedModelsMongo, teardown via TestMain): 252s → 71s, with four more tests than before.

A latent startup race. The Listener declares and binds the queue at its own pace, and a topic exchange silently drops what it cannot route — so a Broker answering /ping was never proof that an accepted event would be stored. This bit during a slow post-recompile startup: events vanished. waitForPipeline now publishes canaries until one comes back out of MongoDB before any test runs.

Also: logwolf-server/logger has unit tests that CI never ran. Added to the workflow; CLAUDE.md and the logger OVERVIEW updated to match.

Verification

All four suites green. Mutation-tested rather than trusted green: removing the four owner-only guards fails exactly the 5 expected broker tests, and breaking the api_keys/settings cascade fails both cascade tests with precise messages.

No production source changed — the diff is tests, CI, and docs.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
logwolf-docs Ready Ready Preview Aug 22, 2026 6:17pm

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.

2 participants