This guide describes the test harnesses and release checks that exist in this repository. It deliberately avoids hypothetical helpers and commands.
Run these commands from the package root:
npm run typecheck
npm run lint
npm run verify:docs
npm test
npm run test:e2e
npm run test:infrastructure
npm run build
npm run verify:package
The checks cover different boundaries:
| Command | Boundary |
|---|---|
npm run typecheck |
Strict first-party TypeScript contract |
npm run lint |
Source, dashboard, connector, test, script, and dev-server rules |
npm run verify:docs |
Balanced code fences, Markdown/HTML local targets, heading fragments, public imports, npm scripts, and Data Hub GraphQL examples |
npm test |
Unit and focused integration specifications through Vitest |
npm run test:e2e |
Vendure-backed loader and pipeline behavior |
npm run test:infrastructure |
Sequential Docker acceptance for Redis replicas, OTLP, and external protocols |
npm run build |
Server declarations, distributable dashboard source, and dashboard bundle |
npm run verify:package |
Clean tarball install, CJS/ESM loading, and public-subpath TypeScript compile |
Run a focused specification while developing:
npx vitest run src/services/config/secret.service.spec.ts
npx vitest run src/runtime/executors/loaders/product-handler.spec.ts
npx vitest run --config vitest.e2e.config.ts e2e/loaders/product-loader.e2e-spec.ts
Do not describe a feature as verified because an unrelated suite passed. Name the exact test and assertion that exercises the behavior.
Unit specifications live beside the source as *.spec.ts or *.spec.tsx.
Prefer testing public behavior and failure semantics over implementation calls.
Representative existing tests:
src/services/pipeline/pipeline-policy.spec.ts checks runnable lifecycle rules.src/services/events/message-processing.spec.ts checks broker acknowledgement,
retry, and dead-letter behavior.src/runtime/executors/sink-handler-security.spec.ts checks fail-closed sink
authentication and outbound security.src/services/destinations/export-destination.service.spec.ts checks durable,
channel-scoped destination definitions.dashboard/utils/wizard-to-pipeline.spec.ts checks lossless wizard conversion.src/sdk/dsl/documentation-examples.spec.ts compiles documented DSL patterns.Every production bug fix should have a regression test that fails for the old behavior. Include malformed input, missing configuration, permission-sensitive paths, partial failures, and empty data where they apply.
Mocks and spies are allowed in tests only. Use them at the network or Vendure service boundary, and make their result shape match the real API. Do not mock the unit under test.
For remote assets, tests use deterministic valid image bytes rather than live internet URLs. For HTTP and connector paths, assert request construction, security validation, bounded response handling, and partial-failure mapping. Real-service verification remains a separate deployment gate.
Install dependencies with npm ci, ensure Docker Compose is available, then
run an individual boundary or the sequential aggregate:
npm run test:infrastructure:redis
npm run test:infrastructure:otlp
npm run test:infrastructure:external
npm run test:infrastructure
The runners use digest-pinned images, unique Compose project names, local
installed test binaries, bounded waits, and cleanup traps. External service
ports bind only to 127.0.0.1 and use per-run ports where the protocol permits.
The aggregate Redis suite starts independent Node.js processes and checks atomic
shared counters, webhook quotas, locks, Streams consumers, consumer-process
crash recovery, fail-closed outage behavior, and reconnect to one Redis server.
Streams workers trust only the isolated Compose broker hostname through the
normal SSRF policy; production defaults remain unchanged.
It then starts a primary, two replicas, and a three-Sentinel quorum. The runner
waits until lock and quota state has reached both replicas, keeps the application
client alive, sends SIGKILL to the primary from outside that client, and proves
automatic election, replica reconfiguration, and state continuity through both
existing and fresh clients. It does not prove Redis Cluster behavior,
persistence recovery, network-partition or split-brain behavior, or an
infrastructure provider’s managed failover.
The OTLP suite uses a real TLS-enabled OpenTelemetry Collector and verifies
metrics, traces, trust of its generated certificate authority, rejection by an
untrusted client, collector-scoped CA loading, structured outage reporting, and
queued retry after restart.
The certificate, collector, and output directories are removed afterward. The
external suite uses RabbitMQ, MinIO, FTP, SFTP, PostgreSQL, MySQL, a
transport-level Pimcore HTTP server, and the repository mock contracts. The
RabbitMQ cases prove publisher confirms, long-lived consumption, manual
settlement, broker-enforced prefetch, cancellation, and redelivery through a
real AMQP broker. PostgreSQL and MySQL
require an ephemeral client certificate and verify the generated server CA and
localhost certificate identity. The suite proves active TLS sessions and
rejects an untrusted CA, a hostname mismatch, and a missing client certificate.
It does not replace target RabbitMQ TLS/HA/failover, AWS IAM/TLS, FTPS, database
HA/failover or historical upgrade rehearsal, private-key SFTP rotation, or an
active real Pimcore Data Hub validation. See the
production sign-off matrix
before making deployment claims.
npm run test:e2e uses vitest.e2e.config.ts and the shared environment in
e2e/test-config.ts. The harness starts Vendure with the plugin, uses an
isolated database, and exercises real Vendure services and persistence.
The loader suites under e2e/loaders/ verify persisted entities, not only
handler counters. Assertions should cover:
ErrorResultUnion outcomes.Use the shared helpers in e2e/loaders/mode-test-helpers.ts only when their
contract matches the loader. A helper must not weaken an assertion to make
different loader semantics look identical.
For an added or changed resolver/controller, cover:
Resolver unit tests are useful for mapping and fail-closed behavior, but they do not replace an authenticated Vendure API test.
Dashboard utilities and state conversions use Vitest specifications next to the implementation. Keep business conversion logic outside React components so it can be tested without rendering the whole Vendure dashboard.
Important boundaries include:
The supported production check is the Vendure/Vite dashboard build. A raw standalone TypeScript run can also inspect first-party diagnostics, but installed Vendure source contains Vite virtual modules that are resolved by the supported build pipeline.
GraphQL clients and shared enum output are generated by:
npm run codegen
CI runs generation and then requires a clean diff. When the SDL or a dashboard operation changes, regenerate and review:
schema.graphql;src/gql/generated.ts;dashboard/gql/;Never hand-edit generated files.
npm run verify:package builds on the current dist output and then:
Run npm run build first when invoking this check directly.
Local tests are not proof of third-party infrastructure. Before production, exercise the final package against every configured service:
Include process termination between durable state transitions. Verify recovery after restart, duplicate delivery, secret rotation, and exhausted retries.
The release workflow must pass all local commands above and also:
npm audit --omit=dev --audit-level=high
npm sbom --omit=dev --sbom-format=spdx --sbom-type=library
Review the generated SBOM and license obligations before distribution. An audit or SBOM generated from an older lockfile is not release evidence.