test(npm): add publish parse/precheck integration suite (S11 Step 14, part 3/3)
📦 Stacked MRs
This change is split into 3 stacked merge requests to keep each part within the team's review size limits (~600 LoC ideal). Each part targets the previous one (part 1 targets main). Please review and merge them in order, bottom-up — merging part 1 auto-retargets the rest.
Stack (review/merge bottom-up)
- feat(npm): add publish-flow error codes and mes... (!642 - merged) • David Fernandez • 19.2
- feat(npm): add publish parse + envelope validat... (!643 - merged) • David Fernandez • 19.2
- test(npm): add publish parse/precheck integrati... (!644 - merged) • David Fernandez • 19.2
👈
📌 This part
Part 3 of 3 of npm hosted — Step 14: publish handler parse, envelope validate, pre-check.
Adds the end-to-end integration suite for the publish parse + pre-check handler. Every failure path is driven through the real slug/repo middleware chain against a testcontainers PostgreSQL, asserting the HTTP status, the S01 error-envelope code, and — on every failure path — that no upload session is created (the pre-check rejects before any tarball is staged). Depends on the handler in part 2.
✅ Spec coverage
| AC | Criterion | Test |
|---|---|---|
| AC 2 | re-publish existing version → 409 version_exists, no session |
TestPublishPrecheck_VersionExists |
| AC 9 | envelope body > max_publish_envelope_size → 413, no session |
TestPublishPrecheck_EnvelopeTooLarge |
| AC 30 | versions_count at cap → 422 version_count_exceeded, no session |
TestPublishPrecheck_VersionCountExceeded |
| AC 38 | envelope shape invalid → 400 publish_envelope_invalid (integration half) |
TestPublishPrecheck_EnvelopeShapeInvalid (4 subtests) |
| AC 39 | name fails npm regex → 422 package_name_invalid (integration half) |
TestPublishPrecheck_PackageNameInvalid (4 subtests) |
| AC 42 | per-version byte span > max_envelope_package_json_size → 422 envelope_package_json_too_large |
TestPublishPrecheck_EnvelopePackageJSONTooLarge |
| AC 47 | versions map with two entries → 400 publish_envelope_invalid (integration half) |
TestPublishPrecheck_TwoVersionEntries |
| AC 54 | quota exceeded → 429 quota_exceeded, no session |
TestPublishPrecheck_QuotaExceeded |
The unit halves of AC 38/39/42/47 and AC 37 (non-JSON body → 400 bad_request) are owned by the merged streampub library (Step 13).
🔗 References
- Plan:
docs/plans/2026-05-11-npm-hosted.md— Step 14 - Spec:
docs/specs/S11-npm-hosted.md
Related to #132 (closed)