@aventara/testing
v1.0.0-rc.12
Published
Conformance and extension testing utilities for Aventara.
Readme
@aventara/testing
Conformance fixtures and testing utilities for Aventara extensions. They test an adapter or a transport host from outside.
createFakeAdapter: an in-memory adapter, with transaction tracing, for testing code that runs anAvFrameworkwithout a database.runAvProtocolConformance(driver): drives the protocol corpus (AvProtocolFixtures) through one host and reports, per row, every mismatch with the expected status, code, cause, headers and body. A host supplies anAvProtocolDriver: given anAvFramework, a session that sends one protocol request and returns the answer, and closes.AvProtocolCorpus: the corpus's server side, for serving it through your own client or host (below).@aventara/testing/fixtures/protocol-v1.json: the same corpus as plain JSON, for a client or host written in any language (below).
It depends on @aventara/core only.
Install
npm install --save-dev @aventara/testing@rcNode ^22.23.4 || >=24.22.1. ES modules.
Serving the corpus through your own stack
runAvProtocolConformance builds the corpus AvFramework itself. To serve it from a host or test bench of your own,
for example to point a client you are writing at it, take it from AvProtocolCorpus:
import { AvProtocolCorpus, AvProtocolFixtures } from "@aventara/testing";
const framework = await AvProtocolCorpus.framework();
// Mount `framework` under AvProtocolCorpus.entrypoint ("/api") with your host,
// then send each row's `request` and compare the answer with the row's `server`.framework(contractHash?): a fresh corpusAvFramework, backed by an in-memory adapter whose answers every row states. Pass a row'sAventara-Contract-Hashto get the contract that row targets (a cached read'sGETsends no such header: pass its query'sv). A few rows target a contract without transactions, the/_access/canrows one withaccess, and the cached-read rows one withcachestages; every other hash (a stale one included) gets the main contract.entrypoint: where the corpus is mounted; every row'spathis relative to it.clientContractHash: the main ClientContract's hash. A client generated against it sends this hash, andGET /_contractnames it.
A row whose client.outcome is "transport-error" describes an answer no host produces (a proxy's HTML page, a
dropped connection); skip it when serving, as the conformance run does. A row's adapterCalls counts the operations
the corpus adapter was handed, which only the conformance run can observe.
The corpus as JSON
@aventara/testing/fixtures/protocol-v1.json holds the whole corpus for protocol version 1. It is generated from
AvProtocolFixtures when the package is built, with every row in the same order and with the same fields, so a client
or host written in another language can be held to the same answers:
{
"protocolVersion": 1,
"entrypoint": "/api",
"clientContractHash": "sha256:…",
"contracts": [{ "hash": "sha256:…", "document": "{\"enums\":{},…}" }, …],
"rows": [{ "label": "…", "request": { … }, "server": { … }, "client": { … } }, …]
}contracts: each ClientContract a row targets: its hash and its exactGET /_contractbytes (document, a string). The first is the main contract,clientContractHash; a row targets another by sending its hash (a cached read'sGETas its query'sv).rows: asAvProtocolFixturedescribes them. A cached read'srequestcarries itsquery(without the?). A streamedPOST /_allanswer (Accept: application/x-ndjson) is no envelope: its row'scodeisnulland itsbodyBytesare the lines in order. One body is too large to write out (one byte over the 1 MiB request limit): itsrequest.body.contentis a recipe,{ "prefix": "…", "repeat": "x", "times": 1048567, "suffix": "…" }, standing forprefix+repeatrepeatedtimestimes +suffix. Every othercontentis the body's text.
From JavaScript: require("@aventara/testing/fixtures/protocol-v1.json"), or import it with { type: "json" }.
Documentation
@aventara/core's README is where to start (the framework, its adapters and hosts). @aventara/nest is held to this
corpus on Express and Fastify in its own tests. Each package's README ships in its tarball and shows on its npm page.
License
PolyForm Shield 1.0.0 with an additional permission. It is free to use, including in commercial applications, but you
may not use it to build a product that competes with Aventara itself. See LICENSE and
LICENSE-ADDITIONAL-PERMISSION.md.
