Testing
What is tested, and what deliberately is not
There are no UI tests. No component tests, no browser tests, and no test that reads a .tsx file and asserts on its contents. The interface is verified by hand against docs/testing/manual-qa-guide.md.
That is a deliberate trade, not an oversight. A UI test suite on a product whose interface changes shape often costs more than it catches: it goes red for renames rather than defects, and it slows the gate until people stop running the part that catches real bugs.
Every automated test answers a question about money, security, or a rule of the board. If a failure would only tell you that a component was renamed, the test does not belong here.
The two kinds
Unit tests
Pure functions, no database, no clock, no network. The rank engine, money arithmetic, URL normalisation, the SSRF guard, the config validator, the doctor, the operator credentials, the throne window, SVG escaping.
They run everywhere, in about a second.
Integration tests
src/lib/webhook.integration.test.ts.
Every claim in that file is a claim about what Postgres does: that a conditional UPDATE ... WHERE status='pending' matches at most once, that ON CONFLICT DO NOTHING ... RETURNING returns nothing on a duplicate, that a transaction rolls back every statement when one throws, and that a gist exclusion constraint rejects an overlapping range.
A hand-written fake would model those semantics as the author believes them to be, which is exactly the belief under test. So these run against a real database or they do not run.
These tests need a real Postgres database.
Without TEST_DATABASE_URL they SKIP, loudly. A skip is never a pass.
Running them
npm run test # everything; integration tests skip without a database
With a database:
docker run -d --name outbid-test-pg \
-e POSTGRES_PASSWORD=outbid -e POSTGRES_USER=outbid -e POSTGRES_DB=outbid_test \
-p 55439:5432 postgres:17-alpine
# in .env.local
# TEST_DATABASE_URL=postgres://outbid:outbid@localhost:55439/outbid_test
npm run db:migrate:test
npm run test
Use a throwaway database. The integration tests TRUNCATE tables.
The gate
npm run gate
Typecheck, tests, lint, format check, doctor, and the production build. This is what must pass before a deploy.
Proving a detector can fire
Several tests here exist to catch a defect: the SSRF guard, the doctor checks, reconciliation, the licence-header check.
A detector that reports nothing everywhere is indistinguishable from a broken one. So each of those has a test that injects the exact defect it looks for and asserts it reports it — not merely that it stays quiet on good input.
The clearest example: the DNS-rebinding test makes the resolver answer public once and private the second time, and asserts the pinned dispatcher never asks twice.