Skip to content

Tests

Test infrastructure for ksef-client-ts: unit tests (vitest, mocked) and E2E tests (against live KSeF TEST environment).

Overview

All tests use vitest and live in the tests/ directory:

  • Unit tests (tests/unit/) — mocked, no network access. Cover services, HTTP layer, crypto, CLI, builders, validation, workflows, and error hierarchy.
  • E2E tests (tests/e2e/) — run against the live KSeF TEST environment (api-test.ksef.mf.gov.pl). No secrets needed — all auth uses self-signed certificates.

Running

bash
yarn test                # Unit tests (tests/unit)
yarn test:watch          # Unit tests in watch mode
yarn test:e2e            # E2E tests (tests/e2e)
yarn vitest run tests/unit/services/auth.test.ts   # Single file

Unit Tests

157 test files, 2905 tests. Located in tests/unit/. All service/HTTP calls are mocked — no network access, fast execution.

Coverage by Area

AreaFilesWhat is tested
cli34All 17 command groups, client factory, config/session store, error handler, output formatting
services14All 14 API services — request construction, response parsing, error propagation
http10RestClient, RetryPolicy (backoff, jitter), RateLimitPolicy (token bucket), PresignedUrlPolicy, AuthManager (401 refresh), transport, RestRequest builder, KSeF feature constants, circuit breaker
workflows10Auth workflow, online/batch session, invoice export, incremental export, HWM coordinator, polling utility
errors9Full error hierarchy — KSeFError, ApiError, RateLimitError, UnauthorizedError (ProblemDetails), ForbiddenError (reasonCode), batch timeout
crypto8CryptographyService (AES, RSA, ECDH, CSR), SignatureService (XAdES), CertificateService (self-signed), CertificateFetcher, PKCS#12 loader, auth XML builder
validation10Regex patterns + checksum validators (NIP, PESEL, KSeF number CRC-8), constraints, char validity, XSD validation helpers
xml9FA2/FA3/PEF builders, invoice serializer, XSD validation, property ordering
pdf29Template DSL validation and interpretation, every block renderer, the built-in layouts against fixtures, document flags, formatters, i18n bundles, QR derivation and sizing, font loading, strict mode
utils7Concurrency helpers, filesystem utilities, hashing, date/time helpers
builders5AuthTokenRequest, AuthKsefTokenRequest, InvoiceQueryFilter, Permissions (person/entity/authorization), batch file
offline4Offline invoice deadlines, file storage, holiday calendar, workflow orchestration
qr3QrCodeService (PNG/SVG), VerificationLinkService (Code I/II URLs), environment QR URLs
config2Environment resolution, options defaults
models2Document structure types, token permission models
client1KSeFClient initialization, service wiring, login/logout orchestration

Conventions

  • Mock RestClient.execute or RestClient.executeRaw to verify request construction
  • Test both success paths and error paths (wrong status codes, missing fields)
  • Builders test validation: required fields, constraints, edge cases
  • Crypto tests use real crypto operations (key generation, signing, encrypt/decrypt)

E2E Tests

36 test files running against the live KSeF TEST environment. No API tokens or env vars needed.

Zero Secrets

All tests use self-signed certificate authentication:

  1. Generate a random valid NIP
  2. Generate a self-signed RSA company seal certificate with VATPL-{NIP} in Subject DN
  3. Sign an XAdES auth request and submit to KSeF
  4. KSeF TEST accepts self-signed certs (verifyCertificateChain=false)

This means tests can run on any machine, any CI, without configuring credentials.

Test Suites

#FileWhat it testsAuthTimeout
0101-lighthouse.test.tsSystem status, messagesNone30s
0202-auth-token.test.tsToken auth flow (challenge, encrypt, submit, access token, refresh)Cert (bootstrap) + Token60s
0303-auth-xades.test.tsCert generation (RSA/ECDSA), XAdES signing, full cert authCert60s
0404-session-online.test.tsOnline session lifecycle: open, send, poll, close, UPO, get invoice. Negative: wrong NIP (445)Cert + Crypto180s
0505-session-batch.test.tsBatch session: 5 invoices in ZIP, upload, poll, verify all processedCert + Crypto300s
0606-invoices.test.tsQuery metadata, get by KSeF number, async export with decryptCert + Crypto300s
0707-permissions.test.tsPersonal grants query, grant/query/revoke person permissions cycleCert120s
0808-tokens.test.tsToken generate/query/get/revoke lifecycleCert120s
0909-certificates.test.tsCertificate limits, full enrollment lifecycle (CSR, enroll, retrieve, revoke)Cert120s
1010-limits.test.tsContext/subject/rate limitsCert60s
1111-active-sessions.test.tsList active sessions, revoke current sessionCert120s
1212-test-data.test.tsTestData API: create/remove subjects and persons, grant/revoke permissionsCert120s
1313-peppol.test.tsQuery Peppol providersCert60s
1414-permissions-entity.test.tsEntity permission grantsCert120s
1515-permissions-authorization.test.tsAuthorization permission grantsCert120s
1616-permissions-eu-entity.test.tsEU entity permission grantsCert120s
1717-permissions-subunit.test.tsSubunit permission grantsCert120s
1818-permissions-indirect.test.tsIndirect permission grantsCert120s
1919-test-data-limits.test.tsTestData API limitsCert120s
2020-workflow-auth.test.tsHigh-level auth workflowCert120s
2121-workflow-online-session.test.tsHigh-level online session workflowCert + Crypto300s
2222-workflow-invoice-export.test.tsHigh-level invoice export workflowCert + Crypto300s
2323-workflow-incremental-export.test.tsIncremental export workflowCert + Crypto300s
2424-workflow-external-signing.test.tsExternal XAdES signing workflowCert120s
2525-error-handling.test.tsAPI error handling pathsCert120s
2626-duplicate-invoice.test.tsDuplicate invoice rejectionCert + Crypto180s
2727-enforcement.test.tsPermission enforcementCert120s
2828-upo-parsing.test.tsUPO XML parsingCert + Crypto180s
2929-technical-correction.test.tsTechnical correction invoicesCert + Crypto180s
3030-rr-invoicing.test.tsFA_RR invoicingCert + Crypto180s
3131-invoice-build-cli-smoke.test.tsksef invoice build CLI smokeCert60s
3131-self-invoicing.test.tsSelf-invoicing flowCert + Crypto180s
3232-invoice-build-send.test.tsBuild and send invoice via CLICert + Crypto180s
3232-offline-invoice.test.tsOffline invoice lifecycleCert + Crypto300s
3333-xml-serialization.test.tsInvoice XML serialization round-tripNone60s
3434-collective-identifiers.test.tsCollective identifier lifecycleCert + Crypto180s
3535-invoice-pdf-cli.test.tsksef invoice pdf through the built CLI: the whole preview set, plus the inputs it refusesNone120s
3636-invoice-pdf-library.test.tsThe same rendering through ksef-client-ts/pdf: template objects, supplied QR URLs, every render optionNone120s

The PDF Specs (35, 36)

Both are exceptions to everything above: they authenticate against nothing and reach the network at no point — a render reads a local document and writes bytes. They need yarn build first, because 35 drives the built CLI (dist/cli.js) and 36 imports the built package.

They also leave something behind on purpose. Each writes a numbered set of PDFs into .pdf-preview/ (override with KSEF_PDF_OUT), distinguished by a cli-/lib- prefix, so the pages can be opened and judged by eye after a run. The assertions themselves are deliberately shallow — a file appears and is a structurally complete PDF — because asserting on glyph positions breaks on every deliberate design change while saying nothing about whether the page reads well. What they do catch is the class of failure unit tests cannot see: a template that stops validating at import, a bundling regression that drops the fonts, a flag that stops being wired, an optional peer that fails to load.

Auth Helpers

Located in tests/e2e/helpers/auth.ts:

  • authenticateWithCert(nip?) — Primary method. Generates random NIP + self-signed cert, calls loginWithCertificate. Returns { client, nip }.
  • authenticateWithCertAndCrypto(nip?) — Same + calls crypto.init() and returns encryptionData (cipherKey, cipherIv, encryptionInfo). Required for invoice send/export operations.
  • createTestClient() — Creates KSeFClient({ environment: 'TEST' }) without auth.

Other Helpers

  • helpers/identifiers.tsgenerateRandomNip() (valid checksum, XSD-compliant), generateRandomPesel(), generateUniqueInvoiceNumber()
  • helpers/invoices.tsprepareInvoiceXml() loads FA_2/FA_3 XML templates from fixtures/, replaces #nip#, #invoicing_date#, #invoice_number#. prepareAndEncryptInvoice() also encrypts with AES-256-CBC.
  • helpers/polling.tspollUntil(action, condition, options) — generic async poller for session status, auth status, export completion, etc.
  • helpers/env.tsFIXTURE_DIR path, hasTokenAuth() (only used internally).

Fixtures

  • fixtures/invoice-fa2.xml — FA(2) v1-0E invoice template
  • fixtures/invoice-fa3.xml — FA(3) v1-0E invoice template

Placeholders: #nip#, #invoicing_date#, #invoice_number#.

How Token Auth Test Works (02)

Since no env vars are available, the test bootstraps its own token:

  1. beforeAll: authenticate via cert, call tokens.generateToken(), save the token string
  2. Tests use the generated token for loginWithToken, manual step-by-step flow, and refresh

Key Implementation Details

  • Auth status polling: Both loginWithToken() and loginWithCertificate() in src/client.ts poll getAuthStatus() until status code is 200 before calling getAccessToken(). This prevents race conditions when KSeF is still processing the auth request.
  • executeVoid(): RestClient has a dedicated executeVoid() method for API endpoints that return empty bodies (closeSession, revokeToken, TestData operations). This avoids JSON.parse errors on empty responses.
  • NIP validation: generateRandomNip() follows the XSD TNIP pattern [1-9]((\d[1-9])|([1-9]\d))\d{7} — digits 2-3 cannot both be zero.
  • crypto.init() is NOT called by loginWithCertificate() — tests that need encryption must call it explicitly via authenticateWithCertAndCrypto().

CI

GitHub Actions workflow at .github/workflows/ci.yml (consolidated):

  • Triggers: push to main (src/tests changes), pull requests, manual dispatch
  • Unit tests: Node 18/20/22 matrix, coverage badge via gist
  • E2E tests: against KSeF TEST environment, 30min timeout, no secrets required

Released under the MIT License.