@in2grate/testing 0.1.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.
Files changed (49) hide show
  1. package/dist/cassette-clients.d.ts +26 -0
  2. package/dist/cassette-clients.d.ts.map +1 -0
  3. package/dist/cassette-clients.js +174 -0
  4. package/dist/cassette-clients.js.map +1 -0
  5. package/dist/cassette-store.d.ts +16 -0
  6. package/dist/cassette-store.d.ts.map +1 -0
  7. package/dist/cassette-store.js +34 -0
  8. package/dist/cassette-store.js.map +1 -0
  9. package/dist/cassette.test.d.ts +2 -0
  10. package/dist/cassette.test.d.ts.map +1 -0
  11. package/dist/cassette.test.js +414 -0
  12. package/dist/cassette.test.js.map +1 -0
  13. package/dist/error-helpers.test.d.ts +2 -0
  14. package/dist/error-helpers.test.d.ts.map +1 -0
  15. package/dist/error-helpers.test.js +66 -0
  16. package/dist/error-helpers.test.js.map +1 -0
  17. package/dist/http-mocks.test.d.ts +2 -0
  18. package/dist/http-mocks.test.d.ts.map +1 -0
  19. package/dist/http-mocks.test.js +89 -0
  20. package/dist/http-mocks.test.js.map +1 -0
  21. package/dist/index.d.ts +133 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +333 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/oauth.test.d.ts +2 -0
  26. package/dist/oauth.test.d.ts.map +1 -0
  27. package/dist/oauth.test.js +53 -0
  28. package/dist/oauth.test.js.map +1 -0
  29. package/dist/poll.test.d.ts +2 -0
  30. package/dist/poll.test.d.ts.map +1 -0
  31. package/dist/poll.test.js +78 -0
  32. package/dist/poll.test.js.map +1 -0
  33. package/dist/redact.d.ts +20 -0
  34. package/dist/redact.d.ts.map +1 -0
  35. package/dist/redact.js +83 -0
  36. package/dist/redact.js.map +1 -0
  37. package/dist/replay.test.d.ts +2 -0
  38. package/dist/replay.test.d.ts.map +1 -0
  39. package/dist/replay.test.js +169 -0
  40. package/dist/replay.test.js.map +1 -0
  41. package/dist/secrets.test.d.ts +2 -0
  42. package/dist/secrets.test.d.ts.map +1 -0
  43. package/dist/secrets.test.js +30 -0
  44. package/dist/secrets.test.js.map +1 -0
  45. package/dist/state.test.d.ts +2 -0
  46. package/dist/state.test.d.ts.map +1 -0
  47. package/dist/state.test.js +66 -0
  48. package/dist/state.test.js.map +1 -0
  49. package/package.json +32 -0
@@ -0,0 +1,26 @@
1
+ import type { HttpClient, CassetteFile } from '@in2grate/sdk';
2
+ import type { CassetteStore } from './cassette-store.js';
3
+ /**
4
+ * A minimal fetch-based HttpClient with no metering or SQLite dependency.
5
+ * Used in cassette record mode so tests can make real outbound HTTP calls.
6
+ */
7
+ export declare function createFetchHttpClient(): HttpClient;
8
+ /**
9
+ * Content-based replay HttpClient — no real network calls permitted.
10
+ * Matches requests by method + URL + body hash (content-based, not FIFO).
11
+ * Each matched interaction is consumed once; identical repeated calls get separate entries.
12
+ */
13
+ export declare function createCassetteReplayClient(cassette: CassetteFile, cassetteName: string, cassetteBaseDir: string, httpCalls: Array<{
14
+ url: string;
15
+ method: string;
16
+ }>): HttpClient;
17
+ /**
18
+ * Recording HttpClient that captures and persists interactions after every call.
19
+ * Redacts sensitive headers and body paths (from IN2_CASSETTE_REDACT_PATHS) before writing.
20
+ * Overwrites any existing cassette on disk; each record run starts a fresh cassette.
21
+ */
22
+ export declare function createCassetteRecordClient(inner: HttpClient, store: CassetteStore, cassetteName: string, httpCalls: Array<{
23
+ url: string;
24
+ method: string;
25
+ }>): HttpClient;
26
+ //# sourceMappingURL=cassette-clients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassette-clients.d.ts","sourceRoot":"","sources":["../src/cassette-clients.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAGV,YAAY,EAEb,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AASzD;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,UAAU,CA0DlD;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAChD,UAAU,CAwCZ;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,aAAa,EACpB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAChD,UAAU,CA4DZ"}
@@ -0,0 +1,174 @@
1
+ import { redactHeaders, redactBody, hashBody } from './redact.js';
2
+ // GET / HEAD / DELETE carry no request body — skip body-hash matching for these
3
+ const BODYLESS_METHODS = new Set(['GET', 'HEAD', 'DELETE']);
4
+ function shouldHashBody(method) {
5
+ return !BODYLESS_METHODS.has(method.toUpperCase());
6
+ }
7
+ /**
8
+ * A minimal fetch-based HttpClient with no metering or SQLite dependency.
9
+ * Used in cassette record mode so tests can make real outbound HTTP calls.
10
+ */
11
+ export function createFetchHttpClient() {
12
+ async function request(url, opts) {
13
+ const method = opts?.method ?? 'GET';
14
+ const headers = {
15
+ ...(opts?.body != null ? { 'Content-Type': 'application/json' } : {}),
16
+ ...opts?.headers,
17
+ };
18
+ const fetchInit = { method, headers };
19
+ if (opts?.body != null)
20
+ fetchInit.body = JSON.stringify(opts.body);
21
+ const controller = opts?.timeoutMs != null ? new AbortController() : undefined;
22
+ let timer;
23
+ if (controller != null && opts?.timeoutMs != null) {
24
+ timer = setTimeout(() => controller.abort(), opts.timeoutMs);
25
+ fetchInit.signal = controller.signal;
26
+ }
27
+ let res;
28
+ try {
29
+ res = await fetch(url, fetchInit);
30
+ }
31
+ finally {
32
+ if (timer !== undefined)
33
+ clearTimeout(timer);
34
+ }
35
+ const responseType = opts?.responseType ?? 'json';
36
+ let data;
37
+ if (responseType === 'text') {
38
+ data = (await res.text());
39
+ }
40
+ else if (responseType === 'arrayBuffer' || responseType === 'raw') {
41
+ data = new Uint8Array(await res.arrayBuffer());
42
+ }
43
+ else {
44
+ const text = await res.text();
45
+ if (text.trim().length === 0) {
46
+ data = null;
47
+ }
48
+ else {
49
+ try {
50
+ data = JSON.parse(text);
51
+ }
52
+ catch {
53
+ throw new Error(`Failed to parse JSON response from ${method} ${url}: ${text}`);
54
+ }
55
+ }
56
+ }
57
+ const respHeaders = {};
58
+ res.headers.forEach((v, k) => {
59
+ respHeaders[k] = v;
60
+ });
61
+ return { status: res.status, headers: respHeaders, data };
62
+ }
63
+ return {
64
+ request,
65
+ get: (url, opts) => request(url, { ...opts, method: 'GET' }),
66
+ post: (url, body, opts) => request(url, { ...opts, method: 'POST', body }),
67
+ put: (url, body, opts) => request(url, { ...opts, method: 'PUT', body }),
68
+ patch: (url, body, opts) => request(url, { ...opts, method: 'PATCH', body }),
69
+ delete: (url, opts) => request(url, { ...opts, method: 'DELETE' }),
70
+ };
71
+ }
72
+ /**
73
+ * Content-based replay HttpClient — no real network calls permitted.
74
+ * Matches requests by method + URL + body hash (content-based, not FIFO).
75
+ * Each matched interaction is consumed once; identical repeated calls get separate entries.
76
+ */
77
+ export function createCassetteReplayClient(cassette, cassetteName, cassetteBaseDir, httpCalls) {
78
+ const used = new Array(cassette.interactions.length).fill(false);
79
+ async function request(url, opts) {
80
+ const method = opts?.method ?? 'GET';
81
+ const bodyHash = shouldHashBody(method) ? hashBody(opts?.body) : '';
82
+ httpCalls.push({ url, method });
83
+ const idx = cassette.interactions.findIndex((interaction, i) => {
84
+ if (used[i])
85
+ return false;
86
+ if (interaction.request.method !== method || interaction.request.url !== url)
87
+ return false;
88
+ return !shouldHashBody(method) || interaction.request.bodyHash === bodyHash;
89
+ });
90
+ if (idx === -1) {
91
+ throw new Error(`Cassette miss: no recorded response for ${method} ${url}\n` +
92
+ ` Cassette: "${cassetteName}" in ${cassetteBaseDir}\n` +
93
+ ` Body hash: ${bodyHash || '(none)'}\n` +
94
+ ` Hint: run \`in2 test --record\` to re-record.`);
95
+ }
96
+ used[idx] = true;
97
+ const interaction = cassette.interactions[idx];
98
+ return {
99
+ status: interaction.response.status,
100
+ headers: interaction.response.headers,
101
+ data: interaction.response.body,
102
+ };
103
+ }
104
+ return {
105
+ request,
106
+ get: (url, opts) => request(url, { ...opts, method: 'GET' }),
107
+ post: (url, body, opts) => request(url, { ...opts, method: 'POST', body }),
108
+ put: (url, body, opts) => request(url, { ...opts, method: 'PUT', body }),
109
+ patch: (url, body, opts) => request(url, { ...opts, method: 'PATCH', body }),
110
+ delete: (url, opts) => request(url, { ...opts, method: 'DELETE' }),
111
+ };
112
+ }
113
+ /**
114
+ * Recording HttpClient that captures and persists interactions after every call.
115
+ * Redacts sensitive headers and body paths (from IN2_CASSETTE_REDACT_PATHS) before writing.
116
+ * Overwrites any existing cassette on disk; each record run starts a fresh cassette.
117
+ */
118
+ export function createCassetteRecordClient(inner, store, cassetteName, httpCalls) {
119
+ // Always start fresh — each record run overwrites the previous cassette
120
+ const interactions = [];
121
+ async function request(url, opts) {
122
+ const method = opts?.method ?? 'GET';
123
+ const bodyHash = shouldHashBody(method) ? hashBody(opts?.body) : '';
124
+ const reqHeaders = {
125
+ ...(opts?.body != null ? { 'Content-Type': 'application/json' } : {}),
126
+ ...opts?.headers,
127
+ };
128
+ httpCalls.push({ url, method });
129
+ const response = await inner.request(url, opts);
130
+ let bodyType;
131
+ let body;
132
+ if (response.data instanceof Uint8Array) {
133
+ bodyType = 'bytes';
134
+ body = Buffer.from(response.data).toString('base64');
135
+ }
136
+ else if (typeof response.data === 'string') {
137
+ bodyType = 'text';
138
+ body = response.data;
139
+ }
140
+ else {
141
+ bodyType = 'json';
142
+ body = redactBody(response.data);
143
+ }
144
+ interactions.push({
145
+ request: {
146
+ method,
147
+ url,
148
+ headers: redactHeaders(reqHeaders),
149
+ bodyHash,
150
+ },
151
+ response: {
152
+ status: response.status,
153
+ headers: redactHeaders(response.headers),
154
+ bodyType,
155
+ body,
156
+ },
157
+ });
158
+ // Flush after every interaction so partial records survive test failures
159
+ store.save(cassetteName, {
160
+ meta: { createdAt: new Date().toISOString(), version: 1 },
161
+ interactions: [...interactions],
162
+ });
163
+ return response;
164
+ }
165
+ return {
166
+ request,
167
+ get: (url, opts) => request(url, { ...opts, method: 'GET' }),
168
+ post: (url, body, opts) => request(url, { ...opts, method: 'POST', body }),
169
+ put: (url, body, opts) => request(url, { ...opts, method: 'PUT', body }),
170
+ patch: (url, body, opts) => request(url, { ...opts, method: 'PATCH', body }),
171
+ delete: (url, opts) => request(url, { ...opts, method: 'DELETE' }),
172
+ };
173
+ }
174
+ //# sourceMappingURL=cassette-clients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassette-clients.js","sourceRoot":"","sources":["../src/cassette-clients.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { CassetteFile } from '@in2grate/sdk';
2
+ export declare class CassetteStore {
3
+ readonly baseDir: string;
4
+ constructor(baseDir: string);
5
+ private filePath;
6
+ load(name: string): CassetteFile | null;
7
+ save(name: string, file: CassetteFile): void;
8
+ }
9
+ /** Resolve cassette base dir from IN2_CASSETTE_DIR env, or default to <projectRoot>/tests/cassettes */
10
+ export declare function resolveCassetteDir(): string;
11
+ /** Resolve cassette name: explicit option → IN2_CASSETTE_TEST_NAME env → flow name → "default" */
12
+ export declare function resolveCassetteName(opts: {
13
+ cassetteName?: string;
14
+ flowName?: string;
15
+ }): string;
16
+ //# sourceMappingURL=cassette-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassette-store.d.ts","sourceRoot":"","sources":["../src/cassette-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,qBAAa,aAAa;IACZ,QAAQ,CAAC,OAAO,EAAE,MAAM;gBAAf,OAAO,EAAE,MAAM;IAEpC,OAAO,CAAC,QAAQ;IAIhB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAMvC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;CAI7C;AAED,uGAAuG;AACvG,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C;AAED,kGAAkG;AAClG,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE9F"}
@@ -0,0 +1,34 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export class CassetteStore {
4
+ baseDir;
5
+ constructor(baseDir) {
6
+ this.baseDir = baseDir;
7
+ }
8
+ filePath(name) {
9
+ return path.join(this.baseDir, `${name}.json`);
10
+ }
11
+ load(name) {
12
+ const fp = this.filePath(name);
13
+ if (!fs.existsSync(fp))
14
+ return null;
15
+ return JSON.parse(fs.readFileSync(fp, 'utf-8'));
16
+ }
17
+ save(name, file) {
18
+ fs.mkdirSync(this.baseDir, { recursive: true });
19
+ fs.writeFileSync(this.filePath(name), JSON.stringify(file, null, 2) + '\n', 'utf-8');
20
+ }
21
+ }
22
+ /** Resolve cassette base dir from IN2_CASSETTE_DIR env, or default to <projectRoot>/tests/cassettes */
23
+ export function resolveCassetteDir() {
24
+ const envDir = process.env['IN2_CASSETTE_DIR'];
25
+ if (envDir)
26
+ return path.resolve(envDir);
27
+ const projectDir = process.env['IN2_PROJECT_DIR'] ?? process.cwd();
28
+ return path.join(projectDir, 'tests', 'cassettes');
29
+ }
30
+ /** Resolve cassette name: explicit option → IN2_CASSETTE_TEST_NAME env → flow name → "default" */
31
+ export function resolveCassetteName(opts) {
32
+ return opts.cassetteName ?? process.env['IN2_CASSETTE_TEST_NAME'] ?? opts.flowName ?? 'default';
33
+ }
34
+ //# sourceMappingURL=cassette-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassette-store.js","sourceRoot":"","sources":["../src/cassette-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,OAAO,aAAa;IACH;IAArB,YAAqB,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAEhC,QAAQ,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,IAAY;QACf,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAiB,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,IAAY,EAAE,IAAkB;QACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACvF,CAAC;CACF;AAED,uGAAuG;AACvG,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAC/C,IAAI,MAAM;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACnE,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AACrD,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,mBAAmB,CAAC,IAAkD;IACpF,OAAO,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;AAClG,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cassette.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cassette.test.d.ts","sourceRoot":"","sources":["../src/cassette.test.ts"],"names":[],"mappings":""}