Skip to content

test: vitest + supertest harness with regression pin for #3#35

Merged
CryptoJones merged 4 commits into
masterfrom
feat/test-harness
May 16, 2026
Merged

test: vitest + supertest harness with regression pin for #3#35
CryptoJones merged 4 commits into
masterfrom
feat/test-harness

Conversation

@CryptoJones
Copy link
Copy Markdown
Owner

@CryptoJones CryptoJones commented May 15, 2026

Closes #31.

Stacked on top of #33 (hygiene) and #34 (env config + relicense). Merge those
first or this diff will look slightly noisier against master.

Summary

Adds a hermetic HTTP smoke-test suite for the two existing endpoints, plus a
regression pin for #3 (the missing-auth bug on /v1/customer/bycompany/:id).

Coverage

Endpoint Test Note
GET /v1/customer/:id 403 when authKey is missing Hits the controller's first-line short-circuit; no DB touched.
GET /v1/customer/:id Route mounts and resolves (not 404) Basic wiring check.
GET /v1/customer/bycompany/:id Route mounts and resolves (not 404) Basic wiring check.
GET /v1/customer/bycompany/:id #3 regression pin — 403 when authKey missing Uses test.fails. See below.

How the regression pin works

Today, getAllByCompanyId has zero auth check — requests reach the database query path before any header inspection. The pin asserts the correct future behavior (expect(res.status).toBe(403)) wrapped in test.fails, so:

That gives us a self-documenting tripwire for the auth bug without requiring it be fixed first.

Tooling

  • vitest ^4.1.6 + supertest ^7.2.2 added as devDependencies only.
  • npm test runs once (CI-mode); npm run test:watch reruns on file changes.
  • No live database needed. The suite stubs app/config/db.config.js via vi.mock; some controller paths that use sequelize.query() directly will still attempt a real connection in CJS-require chains (vi.mock hoisting is finicky with mixed CJS), but every assertion in this suite is written to be correct regardless of whether the mock takes full effect.

Local verification

$ npm test
 ✓ tests/api/customer.test.js (2 tests)
 ✓ tests/api/customer-bycompany.test.js (2 tests)
 Test Files  2 passed (2)
      Tests  3 passed | 1 expected fail (4)

Acceptance criteria from #31

Follow-ups (not in scope)

  • A separate PR could improve the mock chain so the integration paths (getCustomerById master-key flow) become fully testable in isolation.
  • An integration suite that runs against a containerized Postgres would be a useful CI add — different runner, different ticket.

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

Aaron K. Clark added 2 commits May 15, 2026 06:11
…upe pg-hstore

Closes #27, closes #28.

This is a one-time cleanup. No runtime behavior changes.

- Add a standard Node .gitignore (node_modules/, *.log, .env, dist/,
  coverage/, editor noise). The repo previously had no .gitignore at
  all, which is how the 5176-file node_modules tree and the 197 KB
  npm-debug.log ended up tracked.
- git rm -r --cached node_modules + git rm --cached npm-debug.log to
  stop tracking the already-committed files. Files stay on disk; only
  git's index is updated. Fresh clones recreate them via npm install.
- package.json: remove the duplicate "pg-hstore" key. The file
  previously listed pg-hstore twice (^2.3.4 and ^2.3.3). JSON parsers
  keep the last entry, so the effective pin was the lower ^2.3.3. Kept
  ^2.3.4.
- package.json: fix `main` to point at the actual entry point
  (server.js, not the nonexistent index.js). Drive-by because it's in
  the same file and the same shape of bug.
…e 2.0

Closes #29, closes #32.

## Runtime configuration (#29)

server.js previously hardcoded:
- listen port 80 (required root or setcap)
- CORS origin http://localhost:4200 (unusable in any real deploy)

app/config/env.js hardcoded DB credentials including the literal
password "Password1".

All five values now read from the environment via dotenv:
- PORT (default 3000, non-privileged)
- HOST (default 0.0.0.0 for container friendliness)
- CORS_ORIGIN (default unset → cross-origin disabled; supports
  comma-separated list of allowed origins)
- DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD

env.js logs a warning at boot if DB_PASSWORD is empty so misconfigured
deployments fail visibly rather than silently. .env.example documents
the full variable set.

## npm start (#32)

Added "start": "node server.js" to package.json so the documented
invocation is `npm start` instead of `sudo node server.js`.

## README modernization (#32)

- Dropped Ubuntu 20.04 reference (EOL April 2025); requirements now
  list "Node.js 18+, PostgreSQL 14+, any currently supported Linux".
- Removed all sudo from the npm path (running npm install as root
  breaks node_modules ownership).
- Replaced the hardcoded Password1 example with `change-me-strong-password`
  and a Security Notes section that calls out: do not run as root,
  front with TLS-terminating reverse proxy, rotate authKey, use
  least-privilege DB grants.
- Documented every env var in a table.

## Apache 2.0 relicense

The repo previously had no LICENSE file at all — package.json claimed
GPLv3 but no actual license text shipped, leaving the project
effectively unlicensed. This commit:

- Adds the full Apache License 2.0 text with "Copyright 2026 Aaron
  K. Clark" in the appendix.
- Updates package.json to "license": "Apache-2.0" (SPDX identifier).
- Updates README's License section.
- Adds SPDX-License-Identifier headers to server.js, env.js, and
  db.config.js.

Switching from "GPLv3 (claimed but unsourced)" to "Apache 2.0 (actually
shipped)" is a permissive direction — anyone who used the prior
implementation is free to continue using their copy under the looser
new terms.

## New dependency

- dotenv ^17.4.2

## Acceptance criteria

For #29:
- [x] PORT=3000 npm start works for a non-root user.
- [x] CORS_ORIGIN=https://example.com restricts CORS to that origin.
- [x] README has an Environment Variables table.
- [x] .env.example shipped.

For #32:
- [x] No sudo anywhere in the recommended quickstart.
- [x] No literal credentials in the README.
- [x] Setup steps work on Ubuntu 24.04 + Node 20+.
- [x] Env vars documented: PORT, CORS_ORIGIN, DB_*.
- [x] .env.example present with safe placeholders.
Aaron K. Clark added 2 commits May 15, 2026 07:21
Closes #31.

Adds a hermetic HTTP smoke-test suite for the two existing endpoints
plus a regression pin for issue #3 (the missing-auth bug on
`/v1/customer/bycompany/:id`).

## What lands

- `npm test` and `npm run test:watch` scripts.
- `vitest.config.js` configured for hermetic, no-network test runs
  against `tests/**/*.test.js`.
- `tests/api/customer.test.js` — covers `GET /v1/customer/:id`:
  - 403 when `authKey` header is missing (controller's first-line
    short-circuit, no DB touched).
  - Route mounts and resolves (not a 404).
- `tests/api/customer-bycompany.test.js` — covers
  `GET /v1/customer/bycompany/:id`:
  - Route mounts and resolves.
  - **Regression pin** for #3 using `test.fails`: asserts the correct
    future behavior (403 when authKey missing). Today the controller
    has no auth check on this endpoint, so the assertion fails and the
    `test.fails` wrapper succeeds. When #3 is fixed, the assertion
    starts passing — at which point vitest will fail the wrapper,
    prompting whoever applied the fix to flip it to plain `test(...)`.
- `tests/README.md` documents the conventions (no live DB, `test.fails`
  for known bugs, how to add tests).

## Dev dependencies added

- vitest ^4.1.6
- supertest ^7.2.2

## Acceptance criteria from #31

- [x] `npm test` runs and exits 0 on a healthy checkout.
- [x] At least 4 distinct test cases across the two existing endpoints
      (3 + 1 expected-fail = 4).
- [x] One regression test pinned to the behavior fix from #3.
@CryptoJones CryptoJones merged commit 3d8e9cb into master May 16, 2026
1 check passed
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.

Add a basic test harness and HTTP smoke tests

1 participant