This adds unit tests to the checkout code and changes CI so images are only published for releases. There is no change in behaviour. It is step 2 and step 3 of libretech/mp#71.
Checkout code you can test
The PayPal order request, the pricing, the VAT rates and the log line move into pure modules under src/checkout/ and src/logging/. These need neither Strapi nor the PayPal SDK at runtime.
npm test runs Node's built-in test runner directly on the TypeScript files, with no dependencies.
There are 21 tests:
13 pin today's output.
8 describe the correct behaviour for the known defects of libretech/mp#67 and are marked todo. The follow-up refactoring turns them into regular tests.
CI
Tests run on Node 22.14.0, the Node of the image, for every pull request, every push to main and every release tag.
The image is built for a pull request (build only) and for a v* tag (built, and published when PUBLISH_ENABLED is set).
main no longer publishes :main and :sha-* images, since nothing pulls them.
Checked before opening:
21 tests, 13 pass, 8 todo, 0 fail, on Node 24 and on Node 22.14 inside the v0.1.1 image (offline).
TypeScript check in the image: 0 errors.
An offline replay of the checkout gives identical results and log lines before and after the change, apart from timestamps.
This adds unit tests to the checkout code and changes CI so images are only published for releases. There is no change in behaviour. It is step 2 and step 3 of https://git.librete.ch/libretech/mp/issues/71.
**Checkout code you can test**
- The PayPal order request, the pricing, the VAT rates and the log line move into pure modules under `src/checkout/` and `src/logging/`. These need neither Strapi nor the PayPal SDK at runtime.
- `npm test` runs Node's built-in test runner directly on the TypeScript files, with no dependencies.
- There are 21 tests:
- 13 pin today's output.
- 8 describe the correct behaviour for the known defects of https://git.librete.ch/libretech/mp/issues/67 and are marked *todo*. The follow-up refactoring turns them into regular tests.
**CI**
- Tests run on Node 22.14.0, the Node of the image, for every pull request, every push to main and every release tag.
- The image is built for a pull request (build only) and for a `v*` tag (built, and published when `PUBLISH_ENABLED` is set).
- main no longer publishes `:main` and `:sha-*` images, since nothing pulls them.
**Checked before opening:**
- 21 tests, 13 pass, 8 todo, 0 fail, on Node 24 and on Node 22.14 inside the `v0.1.1` image (offline).
- TypeScript check in the image: 0 errors.
- An offline replay of the checkout gives identical results and log lines before and after the change, apart from timestamps.
src/checkout/ holds code without the PayPal SDK or Strapi at runtime, so it can be
unit tested without node_modules:
- vat.ts: vatIncludedDecimal and vatDecimal. config/constants.ts re-exports them
under the same names and keeps vatDecimalExcluded.
- pricing.ts: calculateTotalProductPrice, unchanged. The product service
re-exports it, so every importer keeps working.
- paypal-order.ts: the order request createSessionOrThrow builds, in two halves.
buildPayPalOrderItems (the total guard and the unsent items) still runs
before the try block, and buildPayPalOrderRequest inside it. Errors and log
lines stay as they were, for every input. The SDK enums are replaced by their
string values (CAPTURE, SET_PROVIDED_ADDRESS).
No behaviour change.
Refs libretech/mp#71
The printf template of config/logger.ts becomes formatLogLine, with the same
logic, so it can be unit tested without winston.
No behaviour change.
Refs libretech/mp#71
npm test runs node:test on the TypeScript sources with Node's type stripping
(Node 22.14 in the image, Node 24 locally), with no dependencies.
Node, unlike tsc, does not resolve extensionless relative imports. TypeScript
5.2 cannot emit .ts import extensions. tests/unit/support therefore registers
a small resolve hook that appends ".ts" for imports from .ts files.
- pricing, paypal-order, log-format: characterization tests of the current
output.
- The known defects of
libretech/mp#67 are tests of the correct
behaviour, marked todo: null, two-line and price-null addresses and
deliveries, a deleted product, the payment surcharge missing from the
breakdown, and in the log line circular JSON, the Basic credentials of an
axios error, and an Error rendered as {}.
- That the breakdown adds up to the amount holds today, including for the
subtotals closest to a half cent, so that test is a regular one.
Refs libretech/mp#71
Every push to main published :main and :sha-* images, which nothing pulls.
The libreshop images had grown to 5.8 GB in the registry, on a Gitea host that
is nearly out of space.
- test: npm test for every pull request, every push to main and every release
tag. It runs in the image's base (Dockerfile FROM, node:22.14.0-alpine), so
on the runtime's Node, without network and without dependencies. The source
is piped into the container, because the job container's paths do not exist
on the Docker host.
- build: after the tests, for a pull request (build only) and for a v* tag
(build and, with PUBLISH_ENABLED, publish :vX.Y.Z and :latest).
Refs libretech/mp#71
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
This adds unit tests to the checkout code and changes CI so images are only published for releases. There is no change in behaviour. It is step 2 and step 3 of libretech/mp#71.
Checkout code you can test
src/checkout/andsrc/logging/. These need neither Strapi nor the PayPal SDK at runtime.npm testruns Node's built-in test runner directly on the TypeScript files, with no dependencies.CI
v*tag (built, and published whenPUBLISH_ENABLEDis set).:mainand:sha-*images, since nothing pulls them.Checked before opening:
v0.1.1image (offline).707ca854fbto8bdc2c6b7a