@nwire/test-kit 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/dist/__tests__/harness-extensions.test.d.ts +13 -0
- package/dist/__tests__/harness-extensions.test.d.ts.map +1 -0
- package/dist/__tests__/harness-extensions.test.js +135 -0
- package/dist/__tests__/harness-extensions.test.js.map +1 -0
- package/dist/__tests__/harness.test.js +1 -1
- package/dist/bdd.d.ts +1 -1
- package/dist/harness-extensions.d.ts +110 -0
- package/dist/harness-extensions.d.ts.map +1 -0
- package/dist/harness-extensions.js +148 -0
- package/dist/harness-extensions.js.map +1 -0
- package/dist/harness.d.ts +1 -1
- package/dist/harness.js +1 -1
- package/dist/harness.js.map +1 -1
- package/dist/test-kit.d.ts +8 -7
- package/dist/test-kit.d.ts.map +1 -1
- package/dist/test-kit.js +8 -7
- package/dist/test-kit.js.map +1 -1
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -44,6 +44,46 @@ describe("enrolStudent", () => {
|
|
|
44
44
|
- `createTestApp` / `bootTestApp` — supertest agent helpers for HTTP-level tests.
|
|
45
45
|
- `isReachable(url)` — startup probe for Docker-backed services.
|
|
46
46
|
|
|
47
|
+
## Integration helpers
|
|
48
|
+
|
|
49
|
+
Layered on `harness()` for ergonomic integration tests. Each one is a thin proxy — the base `Harness` interface stays untouched.
|
|
50
|
+
|
|
51
|
+
### asUser
|
|
52
|
+
|
|
53
|
+
Pin `envelope.user` on every dispatch/query in a scoped proxy. The acting user (and tenant) flows through to handlers, RBAC middleware, and audit fields automatically.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
await asUser(h, { id: "u-1", roles: ["admin"], tenant: "t-1" }).dispatch(createPost, { ... });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### simulateRequest
|
|
60
|
+
|
|
61
|
+
Run a request through a wired Koa app as if it came over HTTP — wraps supertest so test code doesn't need to know which agent helper to import. Returns `{ status, body, headers }`.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const res = await simulateRequest(api.toKoa(), { method: "POST", path: "/posts", body: { ... } });
|
|
65
|
+
expect(res.status).toBe(201);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### checkPolicy
|
|
69
|
+
|
|
70
|
+
Build an ability for a user via a `@nwire/rbac`-shaped factory and run a `can(action, subject?)` check. Returns `{ can, reason? }` — `reason` carries the CASL rule message when access is denied.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const check = await checkPolicy(buildAbility, user, "delete", subject("Post", post));
|
|
74
|
+
expect(check.can).toBe(false);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### onLog
|
|
78
|
+
|
|
79
|
+
Tap every `logger.{info,warn,error,debug}` call made through the runtime. Returns an unsubscribe function. Use to assert "warned about X" without swapping in a fake logger.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const off = onLog(h, (e) => expect(e.message).not.toMatch(/PII/));
|
|
83
|
+
// ... drive a flow ...
|
|
84
|
+
off();
|
|
85
|
+
```
|
|
86
|
+
|
|
47
87
|
## When to use
|
|
48
88
|
|
|
49
89
|
In every Nwire test file. Fits every level — `harness` covers unit/integration, `dockerCompose` covers real-deps, `feature` covers BDD acceptance.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage for the four harness extension helpers — one spec each:
|
|
3
|
+
*
|
|
4
|
+
* asUser — pinned envelope.user reaches the handler
|
|
5
|
+
* simulateRequest — runs a request through a wired Koa app
|
|
6
|
+
* checkPolicy — wraps a CASL-shaped ability factory
|
|
7
|
+
* onLog — taps every logger call
|
|
8
|
+
*
|
|
9
|
+
* Each spec is intentionally small — the helpers are thin proxies, the
|
|
10
|
+
* unit-tests prove the contract, not the underlying primitives.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=harness-extensions.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-extensions.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/harness-extensions.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage for the four harness extension helpers — one spec each:
|
|
3
|
+
*
|
|
4
|
+
* asUser — pinned envelope.user reaches the handler
|
|
5
|
+
* simulateRequest — runs a request through a wired Koa app
|
|
6
|
+
* checkPolicy — wraps a CASL-shaped ability factory
|
|
7
|
+
* onLog — taps every logger call
|
|
8
|
+
*
|
|
9
|
+
* Each spec is intentionally small — the helpers are thin proxies, the
|
|
10
|
+
* unit-tests prove the contract, not the underlying primitives.
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect } from "vitest";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
import * as forge from "@nwire/forge";
|
|
15
|
+
import { defineEvent } from "@nwire/messages";
|
|
16
|
+
import { httpInterface, post } from "@nwire/http";
|
|
17
|
+
import { harness } from "../harness.js";
|
|
18
|
+
import { asUser, simulateRequest, checkPolicy, onLog } from "../harness-extensions.js";
|
|
19
|
+
// ─── shared fixture: a one-action demo app ─────────────────────────
|
|
20
|
+
// Tiny app that captures envelope.user on dispatch so the asUser spec
|
|
21
|
+
// can assert on it. Same shape as the existing harness.test.ts demo.
|
|
22
|
+
const GreetInput = z.object({ who: z.string() });
|
|
23
|
+
const GreetedEvent = defineEvent({
|
|
24
|
+
name: "ext-demo.greeted",
|
|
25
|
+
schema: z.object({ who: z.string() }),
|
|
26
|
+
});
|
|
27
|
+
const Greeted = forge.eventFactory(GreetedEvent);
|
|
28
|
+
let lastUser = undefined;
|
|
29
|
+
const greet = forge.defineAction({
|
|
30
|
+
name: "ext-demo.greet",
|
|
31
|
+
schema: GreetInput,
|
|
32
|
+
emits: [GreetedEvent],
|
|
33
|
+
handler: async (input, ctx) => {
|
|
34
|
+
lastUser = ctx.envelope.user;
|
|
35
|
+
return Greeted({ who: input.who });
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
const demoModule = forge.defineModule("ext-demo", {
|
|
39
|
+
actions: [greet],
|
|
40
|
+
events: [GreetedEvent],
|
|
41
|
+
});
|
|
42
|
+
const demoApp = forge.defineApp("ext-demo", { modules: [demoModule] });
|
|
43
|
+
describe("harness extensions", () => {
|
|
44
|
+
describe("asUser", () => {
|
|
45
|
+
it("pins envelope.user on subsequent dispatches", async () => {
|
|
46
|
+
const h = await harness({ app: demoApp });
|
|
47
|
+
try {
|
|
48
|
+
lastUser = undefined;
|
|
49
|
+
const alex = { id: "u-alex", roles: ["admin"], tenant: "t-1" };
|
|
50
|
+
await asUser(h, alex).dispatch(greet, { who: "Alice" });
|
|
51
|
+
await h.idle();
|
|
52
|
+
expect(lastUser).toEqual(alex);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
await h.stop();
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("simulateRequest", () => {
|
|
60
|
+
it("runs a POST through a wired httpInterface", async () => {
|
|
61
|
+
// A standalone http() app — no Nwire app needed. simulateRequest
|
|
62
|
+
// doesn't depend on the harness; the api param carries the
|
|
63
|
+
// wired Koa instance. We pass `null` for the harness in the
|
|
64
|
+
// helper signature (helper ignores it for the standalone path).
|
|
65
|
+
const api = httpInterface().wire(post("/echo", { body: z.object({ msg: z.string() }) }), async ({ input }) => ({ echoed: input.msg }));
|
|
66
|
+
const koaApp = api.toKoa();
|
|
67
|
+
const res = await simulateRequest(koaApp, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
path: "/echo",
|
|
70
|
+
body: { msg: "hi" },
|
|
71
|
+
headers: { "content-type": "application/json" },
|
|
72
|
+
});
|
|
73
|
+
expect(res.status).toBe(200);
|
|
74
|
+
expect(res.body).toEqual({ echoed: "hi" });
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe("checkPolicy", () => {
|
|
78
|
+
it("returns can/cannot for a CASL-shaped ability factory", async () => {
|
|
79
|
+
// Inline ability factory mimicking @nwire/rbac's defineAbility
|
|
80
|
+
// shape — { can(action, subj), cannot, relevantRuleFor }. Keeps
|
|
81
|
+
// the test self-contained without pulling in CASL.
|
|
82
|
+
const buildAbility = (user) => {
|
|
83
|
+
const isAdmin = user?.roles?.includes("admin") ?? false;
|
|
84
|
+
return {
|
|
85
|
+
can: (action) => isAdmin || action === "read",
|
|
86
|
+
cannot: (action) => !(isAdmin || action === "read"),
|
|
87
|
+
relevantRuleFor: () => ({ reason: "role required" }),
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
const admin = await checkPolicy(buildAbility, { id: "a", roles: ["admin"] }, "delete");
|
|
91
|
+
expect(admin).toEqual({ can: true });
|
|
92
|
+
const guest = await checkPolicy(buildAbility, { id: "g" }, "delete");
|
|
93
|
+
expect(guest.can).toBe(false);
|
|
94
|
+
expect(guest.reason).toBe("role required");
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
describe("onLog", () => {
|
|
98
|
+
it("invokes the tap for every logger call and unsubscribes cleanly", async () => {
|
|
99
|
+
// Inject our own captured logger so we can prove the wrapper
|
|
100
|
+
// forwards calls AND fires the tap.
|
|
101
|
+
const sink = [];
|
|
102
|
+
const capture = {
|
|
103
|
+
debug: (m) => sink.push({ level: "debug", message: m }),
|
|
104
|
+
info: (m) => sink.push({ level: "info", message: m }),
|
|
105
|
+
warn: (m) => sink.push({ level: "warn", message: m }),
|
|
106
|
+
error: (m) => sink.push({ level: "error", message: m }),
|
|
107
|
+
child: () => capture,
|
|
108
|
+
};
|
|
109
|
+
const h = await harness({ app: demoApp, providers: { logger: capture } });
|
|
110
|
+
try {
|
|
111
|
+
const tapped = [];
|
|
112
|
+
const off = onLog(h, (entry) => tapped.push({ level: entry.level, message: entry.message }));
|
|
113
|
+
// Drive logger calls directly through the runtime's logger so
|
|
114
|
+
// we don't have to reason about which dispatch sites log what.
|
|
115
|
+
const runtime = h.app.runtime;
|
|
116
|
+
runtime.logger.warn("watch out", { foo: 1 });
|
|
117
|
+
runtime.logger.info("hello");
|
|
118
|
+
expect(tapped).toEqual([
|
|
119
|
+
{ level: "warn", message: "watch out" },
|
|
120
|
+
{ level: "info", message: "hello" },
|
|
121
|
+
]);
|
|
122
|
+
// Inner logger still received the calls.
|
|
123
|
+
expect(sink.find((e) => e.message === "watch out")).toBeDefined();
|
|
124
|
+
// After unsubscribe, the tap stops firing.
|
|
125
|
+
off();
|
|
126
|
+
runtime.logger.error("post-unsub");
|
|
127
|
+
expect(tapped.find((e) => e.message === "post-unsub")).toBeUndefined();
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
await h.stop();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
//# sourceMappingURL=harness-extensions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-extensions.test.js","sourceRoot":"","sources":["../../src/__tests__/harness-extensions.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEpF,sEAAsE;AACtE,sEAAsE;AACtE,qEAAqE;AACrE,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjD,MAAM,YAAY,GAAG,WAAW,CAAC;IAC/B,IAAI,EAAE,kBAAkB;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;CACtC,CAAC,CAAC;AACH,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;AAEjD,IAAI,QAAQ,GAAY,SAAS,CAAC;AAClC,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC;IAC/B,IAAI,EAAE,gBAAgB;IACtB,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,CAAC,YAAY,CAAC;IACrB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC5B,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC7B,OAAO,OAAO,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE;IAChD,OAAO,EAAE,CAAC,KAAK,CAAC;IAChB,MAAM,EAAE,CAAC,YAAY,CAAC;CACvB,CAAC,CAAC;AACH,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AAEvE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC;gBACH,QAAQ,GAAG,SAAS,CAAC;gBACrB,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAW,CAAC;gBACxE,MAAM,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;gBACxD,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;oBAAS,CAAC;gBACT,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,iEAAiE;YACjE,2DAA2D;YAC3D,4DAA4D;YAC5D,gEAAgE;YAChE,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC,IAAI,CAC9B,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EACtD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAG,KAAyB,CAAC,GAAG,EAAE,CAAC,CAClE,CAAC;YACF,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE;gBACxC,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;gBACnB,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;aAChD,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,+DAA+D;YAC/D,gEAAgE;YAChE,mDAAmD;YACnD,MAAM,YAAY,GAAG,CAAC,IAA0C,EAAE,EAAE;gBAClE,MAAM,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;gBACxD,OAAO;oBACL,GAAG,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,OAAO,IAAI,MAAM,KAAK,MAAM;oBACrD,MAAM,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,MAAM,KAAK,MAAM,CAAC;oBAC3D,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;iBACrD,CAAC;YACJ,CAAC,CAAC;YACF,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YACvF,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;YAErC,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;YACrE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC9B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;YAC9E,6DAA6D;YAC7D,oCAAoC;YACpC,MAAM,IAAI,GAA8C,EAAE,CAAC;YAC3D,MAAM,OAAO,GAAW;gBACtB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBACvD,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBACrD,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBACrD,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBACvD,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO;aACrB,CAAC;YACF,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAC1E,IAAI,CAAC;gBACH,MAAM,MAAM,GAA8C,EAAE,CAAC;gBAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAC7B,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAC5D,CAAC;gBAEF,8DAA8D;gBAC9D,+DAA+D;gBAC/D,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAwC,CAAC;gBAC/D,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC7C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAE7B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;oBACrB,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE;oBACvC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;iBACpC,CAAC,CAAC;gBACH,yCAAyC;gBACzC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;gBAElE,2CAA2C;gBAC3C,GAAG,EAAE,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;gBACnC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;YACzE,CAAC;oBAAS,CAAC;gBACT,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -6,7 +6,7 @@ import { describe, it, expect } from "vitest";
|
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import * as forge from "@nwire/forge";
|
|
8
8
|
import { defineEvent } from "@nwire/messages";
|
|
9
|
-
import { harness } from "../harness";
|
|
9
|
+
import { harness } from "../harness.js";
|
|
10
10
|
const GreetInput = z.object({ who: z.string() });
|
|
11
11
|
const GreetedEvent = defineEvent({
|
|
12
12
|
name: "demo.greeted",
|
package/dist/bdd.d.ts
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* The wrapper is intentionally tiny — we pass through to the real Gherkin
|
|
25
25
|
* runner. `@amiceli/vitest-cucumber` is a peerDependency.
|
|
26
26
|
*/
|
|
27
|
-
import type { Harness } from "./harness";
|
|
27
|
+
import type { Harness } from "./harness.js";
|
|
28
28
|
export interface BddContext {
|
|
29
29
|
/** Filled in by the user's background step. */
|
|
30
30
|
harness?: Harness;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness extensions — four ergonomic helpers layered on `harness()` for
|
|
3
|
+
* integration tests:
|
|
4
|
+
*
|
|
5
|
+
* - `asUser(user)` — pins envelope.user for every dispatch/query in a
|
|
6
|
+
* scoped proxy. Use to test "logged in as X" flows without re-stitching
|
|
7
|
+
* envelopes by hand.
|
|
8
|
+
* - `simulateRequest(req)` — runs a request through a wired Koa app as
|
|
9
|
+
* if it came over HTTP. Wraps supertest so callers don't need to know
|
|
10
|
+
* which agent helper to import.
|
|
11
|
+
* - `checkPolicy(user, action, subject?)` — wraps `@nwire/rbac`'s
|
|
12
|
+
* `defineAbility` result for assert-style policy tests.
|
|
13
|
+
* - `onLog(handler)` — taps every `logger.{info,warn,error,debug}` call
|
|
14
|
+
* made by the runtime. Lets a test assert "warned about X" without
|
|
15
|
+
* swapping in a fake logger.
|
|
16
|
+
*
|
|
17
|
+
* These helpers are additive — the base `Harness` interface is unchanged.
|
|
18
|
+
* They live in a separate file so the in-memory `harness` core stays small
|
|
19
|
+
* and the optional deps (`@nwire/auth`, `@nwire/rbac`, `koa`) stay opt-in.
|
|
20
|
+
*/
|
|
21
|
+
import type { ActionDefinition } from "@nwire/forge";
|
|
22
|
+
import type { ZodTypeAny } from "@nwire/messages";
|
|
23
|
+
import type { z } from "zod";
|
|
24
|
+
import type { Harness } from "./harness.js";
|
|
25
|
+
export interface UserLike {
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly email?: string;
|
|
28
|
+
readonly name?: string;
|
|
29
|
+
readonly roles?: readonly string[];
|
|
30
|
+
readonly scopes?: readonly string[];
|
|
31
|
+
readonly tenant?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Subset of `Harness` returned by `asUser()`. Same `dispatch` / `query`
|
|
35
|
+
* shape, but with the pinned user threaded through every call. Other
|
|
36
|
+
* surface (telemetry, idle, stop) stays on the original harness — the
|
|
37
|
+
* scoped proxy is intentionally narrow.
|
|
38
|
+
*/
|
|
39
|
+
export interface ScopedHarness {
|
|
40
|
+
dispatch<TSchema extends ZodTypeAny>(action: ActionDefinition<TSchema>, input: z.input<TSchema>, envelope?: {
|
|
41
|
+
tenant?: string;
|
|
42
|
+
correlationId?: string;
|
|
43
|
+
}): Promise<unknown>;
|
|
44
|
+
query<TResult = unknown>(queryDef: {
|
|
45
|
+
readonly name: string;
|
|
46
|
+
}, input: unknown, tenant?: string): Promise<TResult>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Return a thin proxy that pins `envelope.user` (and `envelope.userId`,
|
|
50
|
+
* `envelope.tenant` derived from the user) on every dispatch/query.
|
|
51
|
+
* Pass `undefined` to clear — the returned proxy is then anonymous.
|
|
52
|
+
*
|
|
53
|
+
* await harness.asUser({ id: "u1", roles: ["admin"] }).dispatch(...)
|
|
54
|
+
*/
|
|
55
|
+
export declare function asUser(harness: Harness, user: UserLike | undefined): ScopedHarness;
|
|
56
|
+
export interface SimulatedRequest {
|
|
57
|
+
readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
58
|
+
readonly path: string;
|
|
59
|
+
readonly body?: unknown;
|
|
60
|
+
readonly headers?: Record<string, string>;
|
|
61
|
+
}
|
|
62
|
+
export interface SimulatedResponse {
|
|
63
|
+
readonly status: number;
|
|
64
|
+
readonly body: unknown;
|
|
65
|
+
readonly headers: Record<string, string>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Run a request through a Koa app as if it came over HTTP. The harness
|
|
69
|
+
* doesn't boot a Koa app on its own (the in-process runtime has no HTTP
|
|
70
|
+
* surface), so callers pass the wired Koa instance explicitly. Returns a
|
|
71
|
+
* minimal `{ status, body, headers }` triple so test code doesn't have to
|
|
72
|
+
* know the supertest API.
|
|
73
|
+
*/
|
|
74
|
+
export declare function simulateRequest(app: any, req: SimulatedRequest): Promise<SimulatedResponse>;
|
|
75
|
+
export interface PolicyCheck {
|
|
76
|
+
readonly can: boolean;
|
|
77
|
+
readonly reason?: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Build a CASL Ability for `user` via the supplied `buildAbility` factory
|
|
81
|
+
* and run a `can(action, subject?)` check. Returns `{ can, reason? }` —
|
|
82
|
+
* `reason` carries the CASL rule message when access is denied.
|
|
83
|
+
*
|
|
84
|
+
* Requires `@nwire/rbac` to be available. We `await import()` it instead
|
|
85
|
+
* of declaring a hard dep so test-kit doesn't force a CASL install on
|
|
86
|
+
* users who don't run RBAC tests.
|
|
87
|
+
*/
|
|
88
|
+
export declare function checkPolicy(buildAbility: (user: UserLike | null) => {
|
|
89
|
+
can(action: string, subject?: unknown): boolean;
|
|
90
|
+
cannot(action: string, subject?: unknown): boolean;
|
|
91
|
+
relevantRuleFor?(action: string, subject?: unknown): {
|
|
92
|
+
reason?: string;
|
|
93
|
+
} | null;
|
|
94
|
+
}, user: UserLike | null, action: string, subject?: unknown): Promise<PolicyCheck>;
|
|
95
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
96
|
+
export interface LogEntry {
|
|
97
|
+
readonly level: LogLevel;
|
|
98
|
+
readonly message: string;
|
|
99
|
+
readonly fields?: Record<string, unknown>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Tap every log call made through the harness's logger. Returns an
|
|
103
|
+
* unsubscribe function. The tap wraps `harness.app.runtime.logger` —
|
|
104
|
+
* `child()` calls inherit the tap so envelope-scoped loggers fire it too.
|
|
105
|
+
*
|
|
106
|
+
* This mutates the runtime's logger reference in place (test-only). Call
|
|
107
|
+
* the returned function to restore the original logger.
|
|
108
|
+
*/
|
|
109
|
+
export declare function onLog(harness: Harness, handler: (entry: LogEntry) => void): () => void;
|
|
110
|
+
//# sourceMappingURL=harness-extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-extensions.d.ts","sourceRoot":"","sources":["../src/harness-extensions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness extensions — four ergonomic helpers layered on `harness()` for
|
|
3
|
+
* integration tests:
|
|
4
|
+
*
|
|
5
|
+
* - `asUser(user)` — pins envelope.user for every dispatch/query in a
|
|
6
|
+
* scoped proxy. Use to test "logged in as X" flows without re-stitching
|
|
7
|
+
* envelopes by hand.
|
|
8
|
+
* - `simulateRequest(req)` — runs a request through a wired Koa app as
|
|
9
|
+
* if it came over HTTP. Wraps supertest so callers don't need to know
|
|
10
|
+
* which agent helper to import.
|
|
11
|
+
* - `checkPolicy(user, action, subject?)` — wraps `@nwire/rbac`'s
|
|
12
|
+
* `defineAbility` result for assert-style policy tests.
|
|
13
|
+
* - `onLog(handler)` — taps every `logger.{info,warn,error,debug}` call
|
|
14
|
+
* made by the runtime. Lets a test assert "warned about X" without
|
|
15
|
+
* swapping in a fake logger.
|
|
16
|
+
*
|
|
17
|
+
* These helpers are additive — the base `Harness` interface is unchanged.
|
|
18
|
+
* They live in a separate file so the in-memory `harness` core stays small
|
|
19
|
+
* and the optional deps (`@nwire/auth`, `@nwire/rbac`, `koa`) stay opt-in.
|
|
20
|
+
*/
|
|
21
|
+
import supertest from "supertest";
|
|
22
|
+
/**
|
|
23
|
+
* Return a thin proxy that pins `envelope.user` (and `envelope.userId`,
|
|
24
|
+
* `envelope.tenant` derived from the user) on every dispatch/query.
|
|
25
|
+
* Pass `undefined` to clear — the returned proxy is then anonymous.
|
|
26
|
+
*
|
|
27
|
+
* await harness.asUser({ id: "u1", roles: ["admin"] }).dispatch(...)
|
|
28
|
+
*/
|
|
29
|
+
export function asUser(harness, user) {
|
|
30
|
+
// Direct runtime access — the public Harness.dispatch path only accepts
|
|
31
|
+
// tenant/userId/correlationId on its envelope arg. We need to seed
|
|
32
|
+
// `user` too, which is on MessageEnvelope but not on the public dispatch
|
|
33
|
+
// overload. Going through runtime.dispatch with a hand-seeded envelope
|
|
34
|
+
// keeps the type contract honest without widening the public Harness API.
|
|
35
|
+
const runtime = harness.app.runtime;
|
|
36
|
+
return {
|
|
37
|
+
async dispatch(action, input, envelope) {
|
|
38
|
+
if (!user)
|
|
39
|
+
return runtime.dispatch(action, input);
|
|
40
|
+
const { seedEnvelope } = await import("@nwire/envelope");
|
|
41
|
+
const seeded = seedEnvelope({
|
|
42
|
+
tenant: envelope?.tenant ?? user.tenant,
|
|
43
|
+
userId: user.id,
|
|
44
|
+
user,
|
|
45
|
+
correlationId: envelope?.correlationId,
|
|
46
|
+
});
|
|
47
|
+
return runtime.dispatch(action, input, seeded);
|
|
48
|
+
},
|
|
49
|
+
async query(queryDef, input, tenant) {
|
|
50
|
+
// Queries don't carry an envelope today — pass the user's tenant if
|
|
51
|
+
// the caller didn't override. Once queries gain envelope support,
|
|
52
|
+
// user pinning flows through here automatically.
|
|
53
|
+
return runtime.query(queryDef.name, input, tenant ?? user?.tenant ?? "");
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Run a request through a Koa app as if it came over HTTP. The harness
|
|
59
|
+
* doesn't boot a Koa app on its own (the in-process runtime has no HTTP
|
|
60
|
+
* surface), so callers pass the wired Koa instance explicitly. Returns a
|
|
61
|
+
* minimal `{ status, body, headers }` triple so test code doesn't have to
|
|
62
|
+
* know the supertest API.
|
|
63
|
+
*/
|
|
64
|
+
export async function simulateRequest(
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
app, req) {
|
|
67
|
+
if (!app) {
|
|
68
|
+
throw new Error("simulateRequest: pass a wired Koa app instance as the first argument — " +
|
|
69
|
+
"the harness's in-process runtime has no HTTP surface.");
|
|
70
|
+
}
|
|
71
|
+
// Accept either a raw Koa instance (has .callback) or a pre-built agent.
|
|
72
|
+
const agent = typeof app.callback === "function"
|
|
73
|
+
? supertest(app.callback())
|
|
74
|
+
: app;
|
|
75
|
+
const method = req.method.toLowerCase();
|
|
76
|
+
let request = agent[method](req.path);
|
|
77
|
+
for (const [key, value] of Object.entries(req.headers ?? {})) {
|
|
78
|
+
request = request.set(key, value);
|
|
79
|
+
}
|
|
80
|
+
if (req.body !== undefined)
|
|
81
|
+
request = request.send(req.body);
|
|
82
|
+
const res = await request;
|
|
83
|
+
return {
|
|
84
|
+
status: res.status,
|
|
85
|
+
body: res.body,
|
|
86
|
+
headers: res.headers,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Build a CASL Ability for `user` via the supplied `buildAbility` factory
|
|
91
|
+
* and run a `can(action, subject?)` check. Returns `{ can, reason? }` —
|
|
92
|
+
* `reason` carries the CASL rule message when access is denied.
|
|
93
|
+
*
|
|
94
|
+
* Requires `@nwire/rbac` to be available. We `await import()` it instead
|
|
95
|
+
* of declaring a hard dep so test-kit doesn't force a CASL install on
|
|
96
|
+
* users who don't run RBAC tests.
|
|
97
|
+
*/
|
|
98
|
+
export async function checkPolicy(buildAbility, user, action, subject) {
|
|
99
|
+
try {
|
|
100
|
+
const ability = buildAbility(user);
|
|
101
|
+
const can = subject !== undefined ? ability.can(action, subject) : ability.can(action);
|
|
102
|
+
if (can)
|
|
103
|
+
return { can: true };
|
|
104
|
+
const rule = typeof ability.relevantRuleFor === "function"
|
|
105
|
+
? ability.relevantRuleFor(action, subject)
|
|
106
|
+
: null;
|
|
107
|
+
return { can: false, reason: rule?.reason ?? `denied: ${action}` };
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
throw new Error(`checkPolicy: buildAbility threw — ensure @nwire/rbac is installed and the factory is valid (${err.message})`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Tap every log call made through the harness's logger. Returns an
|
|
115
|
+
* unsubscribe function. The tap wraps `harness.app.runtime.logger` —
|
|
116
|
+
* `child()` calls inherit the tap so envelope-scoped loggers fire it too.
|
|
117
|
+
*
|
|
118
|
+
* This mutates the runtime's logger reference in place (test-only). Call
|
|
119
|
+
* the returned function to restore the original logger.
|
|
120
|
+
*/
|
|
121
|
+
export function onLog(harness, handler) {
|
|
122
|
+
// We monkey-patch the logger on the runtime so every existing reference
|
|
123
|
+
// (envelope-scoped child loggers already handed out) sees the tap too.
|
|
124
|
+
// The wrapper preserves the original behavior and forwards calls.
|
|
125
|
+
const runtime = harness.app.runtime;
|
|
126
|
+
const original = runtime.logger;
|
|
127
|
+
const wrapped = wrapLogger(original, handler);
|
|
128
|
+
runtime.logger = wrapped;
|
|
129
|
+
return () => {
|
|
130
|
+
runtime.logger = original;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function wrapLogger(inner, handler) {
|
|
134
|
+
const wrap = (level) => function (message, fields) {
|
|
135
|
+
handler({ level, message, fields });
|
|
136
|
+
inner[level](message, fields);
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
debug: wrap("debug"),
|
|
140
|
+
info: wrap("info"),
|
|
141
|
+
warn: wrap("warn"),
|
|
142
|
+
error: wrap("error"),
|
|
143
|
+
child(bindings) {
|
|
144
|
+
return wrapLogger(inner.child(bindings), handler);
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=harness-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness-extensions.js","sourceRoot":"","sources":["../src/harness-extensions.ts"],"names":[],"mappings":"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"}
|
package/dist/harness.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import type { AppDefinition, ActionDefinition, CreateAppOptions } from "@nwire/forge";
|
|
15
15
|
import type { z } from "zod";
|
|
16
16
|
import type { ZodTypeAny } from "@nwire/messages";
|
|
17
|
-
import { TelemetryProbe } from "./telemetry-probe";
|
|
17
|
+
import { TelemetryProbe } from "./telemetry-probe.js";
|
|
18
18
|
export interface HarnessOptions {
|
|
19
19
|
/** AppDefinition to boot. */
|
|
20
20
|
readonly app: AppDefinition;
|
package/dist/harness.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Uses in-memory adapters by default. Pass `providers` to swap in real
|
|
12
12
|
* stores / buses / queues for integration testing.
|
|
13
13
|
*/
|
|
14
|
-
import { TelemetryProbe } from "./telemetry-probe";
|
|
14
|
+
import { TelemetryProbe } from "./telemetry-probe.js";
|
|
15
15
|
export async function harness(options) {
|
|
16
16
|
const app = options.app.create(options.providers ?? {});
|
|
17
17
|
const probe = new TelemetryProbe();
|
package/dist/harness.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA6CnD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACnD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,cAAc,EAAE,CAAC;IACnC,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACnF,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IAElB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE;QAC3B,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,GAAG;QACH,SAAS,EAAE,KAAK;QAChB,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ;YACpC,OAAO,EAAE,CAAC;YACV,IAAI,CAAC;gBACH,uEAAuE;gBACvE,iEAAiE;gBACjE,wEAAwE;gBACxE,6DAA6D;gBAC7D,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;oBACzD,MAAM,MAAM,GAAG,YAAY,CAAC;wBAC1B,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,aAAa,EAAE,QAAQ,CAAC,aAAa;qBACtC,CAAC,CAAC;oBACH,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA6CnD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACnD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAI,cAAc,EAAE,CAAC;IACnC,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACnF,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IAElB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE;QAC3B,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,GAAG;QACH,SAAS,EAAE,KAAK;QAChB,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ;YACpC,OAAO,EAAE,CAAC;YACV,IAAI,CAAC;gBACH,uEAAuE;gBACvE,iEAAiE;gBACjE,wEAAwE;gBACxE,6DAA6D;gBAC7D,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;oBACzD,MAAM,MAAM,GAAG,YAAY,CAAC;wBAC1B,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;wBACvB,aAAa,EAAE,QAAQ,CAAC,aAAa;qBACtC,CAAC,CAAC;oBACH,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAc,EAAE,MAAM,CAAC,CAAC;gBACpE,CAAC;gBACD,OAAO,MAAM,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAc,CAAC,CAAC;YAC5D,CAAC;oBAAS,CAAC;gBACT,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,EAAE;YACtC,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,EAAE,EAAE,SAAS,GAAG,IAAI;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC7B,IAAI,OAAO,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,OAAO;oBAAE,OAAO;gBACjE,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,gDAAgD,SAAS,eAAe,OAAO,GAAG,CACnF,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI;YACR,WAAW,EAAE,CAAC;YACd,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACrD,CAAC"}
|
package/dist/test-kit.d.ts
CHANGED
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Plus existing helpers: zod fixture factory, supertest agent.
|
|
17
17
|
*/
|
|
18
|
-
export { harness, type Harness, type HarnessOptions } from "./harness";
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
18
|
+
export { harness, type Harness, type HarnessOptions } from "./harness.js";
|
|
19
|
+
export { asUser, simulateRequest, checkPolicy, onLog, type UserLike, type ScopedHarness, type SimulatedRequest, type SimulatedResponse, type PolicyCheck, type LogLevel, type LogEntry, } from "./harness-extensions.js";
|
|
20
|
+
export { TelemetryProbe, type TelemetryFilter } from "./telemetry-probe.js";
|
|
21
|
+
export { dockerCompose, PRESETS as DOCKER_COMPOSE_PRESETS, type ComposeStack, type ComposePreset, } from "./docker-compose.js";
|
|
22
|
+
export { isReachable } from "./is-reachable.js";
|
|
23
|
+
export { feature, type BddContext } from "./bdd.js";
|
|
24
|
+
export { factory, sequence, type Factory, type SequenceCounter } from "./zod-fixture-factory.js";
|
|
25
|
+
export { createTestApp, bootTestApp, type BootedTestApp } from "./supertest-app-helper.js";
|
|
25
26
|
//# sourceMappingURL=test-kit.d.ts.map
|
package/dist/test-kit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-kit.d.ts","sourceRoot":"","sources":["../src/test-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,aAAa,EACb,OAAO,IAAI,sBAAsB,EACjC,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"test-kit.d.ts","sourceRoot":"","sources":["../src/test-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,MAAM,EACN,eAAe,EACf,WAAW,EACX,KAAK,EACL,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,QAAQ,GACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,aAAa,EACb,OAAO,IAAI,sBAAsB,EACjC,KAAK,YAAY,EACjB,KAAK,aAAa,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/test-kit.js
CHANGED
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Plus existing helpers: zod fixture factory, supertest agent.
|
|
17
17
|
*/
|
|
18
|
-
export { harness } from "./harness";
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
export {
|
|
18
|
+
export { harness } from "./harness.js";
|
|
19
|
+
export { asUser, simulateRequest, checkPolicy, onLog, } from "./harness-extensions.js";
|
|
20
|
+
export { TelemetryProbe } from "./telemetry-probe.js";
|
|
21
|
+
export { dockerCompose, PRESETS as DOCKER_COMPOSE_PRESETS, } from "./docker-compose.js";
|
|
22
|
+
export { isReachable } from "./is-reachable.js";
|
|
23
|
+
export { feature } from "./bdd.js";
|
|
23
24
|
// Pre-existing helpers
|
|
24
|
-
export { factory, sequence } from "./zod-fixture-factory";
|
|
25
|
-
export { createTestApp, bootTestApp } from "./supertest-app-helper";
|
|
25
|
+
export { factory, sequence } from "./zod-fixture-factory.js";
|
|
26
|
+
export { createTestApp, bootTestApp } from "./supertest-app-helper.js";
|
|
26
27
|
//# sourceMappingURL=test-kit.js.map
|
package/dist/test-kit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-kit.js","sourceRoot":"","sources":["../src/test-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAqC,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,cAAc,EAAwB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,aAAa,EACb,OAAO,IAAI,sBAAsB,GAGlC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAmB,MAAM,OAAO,CAAC;AAEjD,uBAAuB;AACvB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAsC,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,WAAW,EAAsB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"test-kit.js","sourceRoot":"","sources":["../src/test-kit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAqC,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,MAAM,EACN,eAAe,EACf,WAAW,EACX,KAAK,GAQN,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAwB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,aAAa,EACb,OAAO,IAAI,sBAAsB,GAGlC,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAmB,MAAM,OAAO,CAAC;AAEjD,uBAAuB;AACvB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAsC,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,aAAa,EAAE,WAAW,EAAsB,MAAM,wBAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nwire/test-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Shared test helpers and zod-driven fixture factories",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fixtures",
|
|
@@ -28,15 +28,17 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"supertest": "^7.2.2",
|
|
30
30
|
"zod": "^4.0.0",
|
|
31
|
-
"@nwire/
|
|
32
|
-
"@nwire/
|
|
33
|
-
"@nwire/
|
|
31
|
+
"@nwire/forge": "0.9.0",
|
|
32
|
+
"@nwire/messages": "0.8.17",
|
|
33
|
+
"@nwire/envelope": "0.8.17",
|
|
34
|
+
"@nwire/logger": "0.8.17"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
37
|
"@types/koa": "^2.15.0",
|
|
37
38
|
"@types/node": "^22.19.9",
|
|
38
39
|
"@types/supertest": "^6.0.3",
|
|
39
|
-
"typescript": "^5.9.3"
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"@nwire/http": "0.9.0"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
42
44
|
"@amiceli/vitest-cucumber": "^4.0.0",
|
|
@@ -51,7 +53,7 @@
|
|
|
51
53
|
}
|
|
52
54
|
},
|
|
53
55
|
"scripts": {
|
|
54
|
-
"build": "tsc",
|
|
56
|
+
"build": "tsc && node ../../scripts/fix-dist-extensions.mjs dist",
|
|
55
57
|
"dev": "tsc --watch",
|
|
56
58
|
"typecheck": "tsc --noEmit"
|
|
57
59
|
}
|