@codespar/sdk 0.9.0 → 0.10.1
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 +182 -19
- package/dist/__tests__/base-url-resolution.test.d.ts +10 -0
- package/dist/__tests__/base-url-resolution.test.d.ts.map +1 -0
- package/dist/__tests__/base-url-resolution.test.js +57 -0
- package/dist/__tests__/base-url-resolution.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +16 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +163 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/forward-mocks.test.d.ts +15 -0
- package/dist/__tests__/forward-mocks.test.d.ts.map +1 -0
- package/dist/__tests__/forward-mocks.test.js +134 -0
- package/dist/__tests__/forward-mocks.test.js.map +1 -0
- package/dist/__tests__/mocks-wire-parity.test.d.ts +15 -0
- package/dist/__tests__/mocks-wire-parity.test.d.ts.map +1 -0
- package/dist/__tests__/mocks-wire-parity.test.js +71 -0
- package/dist/__tests__/mocks-wire-parity.test.js.map +1 -0
- package/dist/__tests__/shop.test.d.ts +17 -0
- package/dist/__tests__/shop.test.d.ts.map +1 -0
- package/dist/__tests__/shop.test.js +213 -0
- package/dist/__tests__/shop.test.js.map +1 -0
- package/dist/__tests__/testing.test.d.ts +2 -0
- package/dist/__tests__/testing.test.d.ts.map +1 -0
- package/dist/__tests__/testing.test.js +133 -0
- package/dist/__tests__/testing.test.js.map +1 -0
- package/dist/__tests__/tool-result-codes.test.d.ts +18 -0
- package/dist/__tests__/tool-result-codes.test.d.ts.map +1 -0
- package/dist/__tests__/tool-result-codes.test.js +164 -0
- package/dist/__tests__/tool-result-codes.test.js.map +1 -0
- package/dist/errors.d.ts +43 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +77 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +128 -49
- package/dist/session.js.map +1 -1
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +97 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tool-result-codes.d.ts +82 -0
- package/dist/tool-result-codes.d.ts.map +1 -0
- package/dist/tool-result-codes.js +99 -0
- package/dist/tool-result-codes.js.map +1 -0
- package/dist/types.d.ts +20 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the createSession body builder's `mocks` forwarding.
|
|
3
|
+
*
|
|
4
|
+
* Asserts:
|
|
5
|
+
* - Wire-neutrality: a cs.create without `mocks` produces a body
|
|
6
|
+
* byte-identical to today's shape (R18).
|
|
7
|
+
* - Forwarded shape: a cs.create with `mocks` includes the field
|
|
8
|
+
* verbatim — no SDK-side rewriting of canonical names.
|
|
9
|
+
* - Empty `mocks: {}` is forwarded (the backend accepts; strict-
|
|
10
|
+
* mode R3a activates only on non-empty maps).
|
|
11
|
+
* - Double-underscore key form reaches the backend unrewritten
|
|
12
|
+
* so the canonical-form rejection surfaces at the right layer.
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
15
|
+
import { CodeSpar } from "../index.js";
|
|
16
|
+
function mockSessionResponse() {
|
|
17
|
+
return {
|
|
18
|
+
ok: true,
|
|
19
|
+
status: 201,
|
|
20
|
+
text: async () => "",
|
|
21
|
+
json: async () => ({
|
|
22
|
+
id: "ses_demo",
|
|
23
|
+
org_id: "org_demo",
|
|
24
|
+
user_id: "user_demo",
|
|
25
|
+
servers: ["asaas"],
|
|
26
|
+
status: "active",
|
|
27
|
+
created_at: new Date().toISOString(),
|
|
28
|
+
closed_at: null,
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
describe("createSession body builder forwards mocks", () => {
|
|
33
|
+
const originalFetch = globalThis.fetch;
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
globalThis.fetch = originalFetch;
|
|
36
|
+
});
|
|
37
|
+
it("omits mocks key from the wire body when undefined (R18 wire-neutral)", async () => {
|
|
38
|
+
const fetchMock = vi
|
|
39
|
+
.fn()
|
|
40
|
+
.mockResolvedValueOnce(mockSessionResponse());
|
|
41
|
+
globalThis.fetch = fetchMock;
|
|
42
|
+
const cs = new CodeSpar({
|
|
43
|
+
apiKey: "csk_live_test",
|
|
44
|
+
baseUrl: "https://api.example.com",
|
|
45
|
+
});
|
|
46
|
+
await cs.create("user_demo", { servers: ["asaas"] });
|
|
47
|
+
const init = fetchMock.mock
|
|
48
|
+
.calls[0][1];
|
|
49
|
+
const body = JSON.parse(init.body);
|
|
50
|
+
expect("mocks" in body).toBe(false);
|
|
51
|
+
expect(body).toEqual({ servers: ["asaas"], user_id: "user_demo" });
|
|
52
|
+
});
|
|
53
|
+
it("forwards mocks verbatim when present", async () => {
|
|
54
|
+
const fetchMock = vi
|
|
55
|
+
.fn()
|
|
56
|
+
.mockResolvedValueOnce(mockSessionResponse());
|
|
57
|
+
globalThis.fetch = fetchMock;
|
|
58
|
+
const cs = new CodeSpar({
|
|
59
|
+
apiKey: "csk_live_test",
|
|
60
|
+
baseUrl: "https://api.example.com",
|
|
61
|
+
});
|
|
62
|
+
await cs.create("user_demo", {
|
|
63
|
+
servers: ["asaas"],
|
|
64
|
+
mocks: {
|
|
65
|
+
"asaas/create_payment": { id: "pay_test_42", status: "PENDING" },
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
const init = fetchMock.mock
|
|
69
|
+
.calls[0][1];
|
|
70
|
+
const body = JSON.parse(init.body);
|
|
71
|
+
expect(body.mocks).toEqual({
|
|
72
|
+
"asaas/create_payment": { id: "pay_test_42", status: "PENDING" },
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
it("accepts and forwards an empty mocks={} body", async () => {
|
|
76
|
+
const fetchMock = vi
|
|
77
|
+
.fn()
|
|
78
|
+
.mockResolvedValueOnce(mockSessionResponse());
|
|
79
|
+
globalThis.fetch = fetchMock;
|
|
80
|
+
const cs = new CodeSpar({
|
|
81
|
+
apiKey: "csk_live_test",
|
|
82
|
+
baseUrl: "https://api.example.com",
|
|
83
|
+
});
|
|
84
|
+
await cs.create("user_demo", { servers: ["asaas"], mocks: {} });
|
|
85
|
+
const init = fetchMock.mock
|
|
86
|
+
.calls[0][1];
|
|
87
|
+
const body = JSON.parse(init.body);
|
|
88
|
+
expect(body.mocks).toEqual({});
|
|
89
|
+
});
|
|
90
|
+
it("does NOT rewrite double-underscore keys — they reach the backend verbatim", async () => {
|
|
91
|
+
const fetchMock = vi
|
|
92
|
+
.fn()
|
|
93
|
+
.mockResolvedValueOnce(mockSessionResponse());
|
|
94
|
+
globalThis.fetch = fetchMock;
|
|
95
|
+
const cs = new CodeSpar({
|
|
96
|
+
apiKey: "csk_live_test",
|
|
97
|
+
baseUrl: "https://api.example.com",
|
|
98
|
+
});
|
|
99
|
+
await cs.create("user_demo", {
|
|
100
|
+
servers: ["asaas"],
|
|
101
|
+
mocks: { asaas__create_payment: { id: "pay_test_42" } },
|
|
102
|
+
});
|
|
103
|
+
const init = fetchMock.mock
|
|
104
|
+
.calls[0][1];
|
|
105
|
+
const body = JSON.parse(init.body);
|
|
106
|
+
const mocks = body.mocks;
|
|
107
|
+
expect(Object.keys(mocks)).toEqual(["asaas__create_payment"]);
|
|
108
|
+
});
|
|
109
|
+
it("matches the canonical fixture byte-for-byte when the same input lands", async () => {
|
|
110
|
+
// Same canonical body used by the Python parity test.
|
|
111
|
+
const fetchMock = vi
|
|
112
|
+
.fn()
|
|
113
|
+
.mockResolvedValueOnce(mockSessionResponse());
|
|
114
|
+
globalThis.fetch = fetchMock;
|
|
115
|
+
const cs = new CodeSpar({
|
|
116
|
+
apiKey: "csk_live_test",
|
|
117
|
+
baseUrl: "https://api.example.com",
|
|
118
|
+
});
|
|
119
|
+
await cs.create("user_demo", {
|
|
120
|
+
servers: ["asaas"],
|
|
121
|
+
mocks: {
|
|
122
|
+
"asaas/create_payment": { id: "pay_test_42", status: "PENDING" },
|
|
123
|
+
"asaas/get_payment": [
|
|
124
|
+
{ id: "pay_test_42", status: "PENDING" },
|
|
125
|
+
{ id: "pay_test_42", status: "CONFIRMED" },
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
const init = fetchMock.mock
|
|
130
|
+
.calls[0][1];
|
|
131
|
+
expect(init.body).toBe('{"servers":["asaas"],"user_id":"user_demo","mocks":{"asaas/create_payment":{"id":"pay_test_42","status":"PENDING"},"asaas/get_payment":[{"id":"pay_test_42","status":"PENDING"},{"id":"pay_test_42","status":"CONFIRMED"}]}}');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=forward-mocks.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward-mocks.test.js","sourceRoot":"","sources":["../../src/__tests__/forward-mocks.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-shape parity test for the test-mode mocks field.
|
|
3
|
+
*
|
|
4
|
+
* Asserts that the TypeScript SessionConfig type carries the optional
|
|
5
|
+
* `mocks` field with the right shape, and that the serialized form
|
|
6
|
+
* matches the canonical fixture used by the Python SDK's parallel
|
|
7
|
+
* test. Both languages serialize the same example to byte-identical
|
|
8
|
+
* JSON; any drift here is a wire-contract break.
|
|
9
|
+
*
|
|
10
|
+
* The canonical fixture lives at packages/python/tests/_fixtures/
|
|
11
|
+
* mocks_canonical.json — kept in sync by hand. Future contributors
|
|
12
|
+
* MUST update both files together when extending the example.
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=mocks-wire-parity.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocks-wire-parity.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mocks-wire-parity.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-shape parity test for the test-mode mocks field.
|
|
3
|
+
*
|
|
4
|
+
* Asserts that the TypeScript SessionConfig type carries the optional
|
|
5
|
+
* `mocks` field with the right shape, and that the serialized form
|
|
6
|
+
* matches the canonical fixture used by the Python SDK's parallel
|
|
7
|
+
* test. Both languages serialize the same example to byte-identical
|
|
8
|
+
* JSON; any drift here is a wire-contract break.
|
|
9
|
+
*
|
|
10
|
+
* The canonical fixture lives at packages/python/tests/_fixtures/
|
|
11
|
+
* mocks_canonical.json — kept in sync by hand. Future contributors
|
|
12
|
+
* MUST update both files together when extending the example.
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect } from "vitest";
|
|
15
|
+
const CANONICAL_BODY = {
|
|
16
|
+
servers: ["asaas"],
|
|
17
|
+
user_id: "user_demo",
|
|
18
|
+
mocks: {
|
|
19
|
+
"asaas/create_payment": { id: "pay_test_42", status: "PENDING" },
|
|
20
|
+
"asaas/get_payment": [
|
|
21
|
+
{ id: "pay_test_42", status: "PENDING" },
|
|
22
|
+
{ id: "pay_test_42", status: "CONFIRMED" },
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
describe("MockObject + MockValue type aliases", () => {
|
|
27
|
+
it("accepts a plain dict as MockObject", () => {
|
|
28
|
+
const obj = { id: "pay_test_42", status: "PENDING" };
|
|
29
|
+
expect(obj.id).toBe("pay_test_42");
|
|
30
|
+
});
|
|
31
|
+
it("accepts a single MockObject as MockValue (static mock)", () => {
|
|
32
|
+
const v = { id: "pay_test_42", status: "PENDING" };
|
|
33
|
+
expect(v).toBeDefined();
|
|
34
|
+
});
|
|
35
|
+
it("accepts a MockObject array as MockValue (stateful mock)", () => {
|
|
36
|
+
const v = [
|
|
37
|
+
{ id: "pay_test_42", status: "PENDING" },
|
|
38
|
+
{ id: "pay_test_42", status: "CONFIRMED" },
|
|
39
|
+
];
|
|
40
|
+
expect(Array.isArray(v)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe("CreateSessionOptions carries optional mocks field", () => {
|
|
44
|
+
it("accepts a SessionConfig with no mocks (wire-neutral)", () => {
|
|
45
|
+
const cfg = { servers: ["asaas"] };
|
|
46
|
+
expect(cfg.mocks).toBeUndefined();
|
|
47
|
+
});
|
|
48
|
+
it("accepts a SessionConfig with canonical mocks shape", () => {
|
|
49
|
+
const cfg = {
|
|
50
|
+
servers: ["asaas"],
|
|
51
|
+
mocks: {
|
|
52
|
+
"asaas/create_payment": { id: "pay_test_42", status: "PENDING" },
|
|
53
|
+
"asaas/get_payment": [
|
|
54
|
+
{ id: "pay_test_42", status: "PENDING" },
|
|
55
|
+
{ id: "pay_test_42", status: "CONFIRMED" },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
expect(cfg.mocks?.["asaas/create_payment"]).toBeDefined();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe("Canonical body serializes to byte-identical JSON", () => {
|
|
63
|
+
it("matches the Python SDK fixture byte-for-byte", () => {
|
|
64
|
+
// The canonical body field order is preserved by the JSON.stringify
|
|
65
|
+
// contract used in createSession's body builder. If field ordering
|
|
66
|
+
// changes here, the Python side must change too.
|
|
67
|
+
const serialized = JSON.stringify(CANONICAL_BODY);
|
|
68
|
+
expect(serialized).toBe('{"servers":["asaas"],"user_id":"user_demo","mocks":{"asaas/create_payment":{"id":"pay_test_42","status":"PENDING"},"asaas/get_payment":[{"id":"pay_test_42","status":"PENDING"},{"id":"pay_test_42","status":"CONFIRMED"}]}}');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=mocks-wire-parity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocks-wire-parity.test.js","sourceRoot":"","sources":["../../src/__tests__/mocks-wire-parity.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI9C,MAAM,cAAc,GAAG;IACrB,OAAO,EAAE,CAAC,OAAO,CAAC;IAClB,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE;QACL,sBAAsB,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE;QAChE,mBAAmB,EAAE;YACnB,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE;YACxC,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE;SAC3C;KACF;CACO,CAAC;AAEX,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,GAAG,GAAe,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QACjE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,CAAC,GAAc,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC9D,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,GAAc;YACnB,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE;YACxC,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE;SAC3C,CAAC;QACF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mDAAmD,EAAE,GAAG,EAAE;IACjE,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,GAAG,GAAkB,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,GAAG,GAAkB;YACzB,OAAO,EAAE,CAAC,OAAO,CAAC;YAClB,KAAK,EAAE;gBACL,sBAAsB,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE;gBAChE,mBAAmB,EAAE;oBACnB,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE;oBACxC,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE;iBAC3C;aACF;SACF,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,oEAAoE;QACpE,mEAAmE;QACnE,iDAAiD;QACjD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CACrB,8NAA8N,CAC/N,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codespar_shop typed facade tests.
|
|
3
|
+
*
|
|
4
|
+
* Covers the discriminated `ShopArgs`/`ShopResult` union: it gives a
|
|
5
|
+
* caller the action-correct result type without an untyped cast. A
|
|
6
|
+
* `ready_for_payment` status result exposes typed `pix_copia_e_cola` +
|
|
7
|
+
* `total_minor`; a `canceled` result exposes typed `error`. The facade also mirrors `charge()`: it dispatches
|
|
8
|
+
* `execute("codespar_shop", args)` and throws `shop failed: <error>` on
|
|
9
|
+
* `!success`.
|
|
10
|
+
*
|
|
11
|
+
* These drive the real `createSession` facade with a mocked `fetch`, so
|
|
12
|
+
* the shipped client surface is exercised end-to-end (not a test
|
|
13
|
+
* double); the wire dispatch (`tool` + `input`) is asserted on the
|
|
14
|
+
* mocked `/execute` call.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=shop.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shop.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/shop.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codespar_shop typed facade tests.
|
|
3
|
+
*
|
|
4
|
+
* Covers the discriminated `ShopArgs`/`ShopResult` union: it gives a
|
|
5
|
+
* caller the action-correct result type without an untyped cast. A
|
|
6
|
+
* `ready_for_payment` status result exposes typed `pix_copia_e_cola` +
|
|
7
|
+
* `total_minor`; a `canceled` result exposes typed `error`. The facade also mirrors `charge()`: it dispatches
|
|
8
|
+
* `execute("codespar_shop", args)` and throws `shop failed: <error>` on
|
|
9
|
+
* `!success`.
|
|
10
|
+
*
|
|
11
|
+
* These drive the real `createSession` facade with a mocked `fetch`, so
|
|
12
|
+
* the shipped client surface is exercised end-to-end (not a test
|
|
13
|
+
* double); the wire dispatch (`tool` + `input`) is asserted on the
|
|
14
|
+
* mocked `/execute` call.
|
|
15
|
+
*/
|
|
16
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
17
|
+
import { createSession } from "../session.js";
|
|
18
|
+
function envelope(over) {
|
|
19
|
+
return {
|
|
20
|
+
success: true,
|
|
21
|
+
data: null,
|
|
22
|
+
error: null,
|
|
23
|
+
duration: 1,
|
|
24
|
+
server: "_codespar",
|
|
25
|
+
tool: "codespar_shop",
|
|
26
|
+
...over,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build a REAL session (`createSession`) whose `/execute` route returns
|
|
31
|
+
* a caller-supplied envelope, so `shop()` exercises the shipped facade
|
|
32
|
+
* end-to-end — not a test double. `fetch` is mocked: the create POST
|
|
33
|
+
* returns a session, the execute POST returns the envelope.
|
|
34
|
+
*/
|
|
35
|
+
async function sessionReturning(over) {
|
|
36
|
+
const calls = [];
|
|
37
|
+
const env = envelope(over);
|
|
38
|
+
const fetchMock = vi.fn(async (url, init) => {
|
|
39
|
+
if (typeof url === "string" && url.endsWith("/execute")) {
|
|
40
|
+
const body = JSON.parse(init?.body ?? "{}");
|
|
41
|
+
calls.push({ toolName: body.tool, params: body.input });
|
|
42
|
+
return {
|
|
43
|
+
ok: true,
|
|
44
|
+
status: 200,
|
|
45
|
+
text: async () => "",
|
|
46
|
+
json: async () => env,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// create session
|
|
50
|
+
return {
|
|
51
|
+
ok: true,
|
|
52
|
+
status: 201,
|
|
53
|
+
text: async () => "",
|
|
54
|
+
json: async () => ({
|
|
55
|
+
id: "ses_shop",
|
|
56
|
+
org_id: "org_test",
|
|
57
|
+
user_id: "consumer_123",
|
|
58
|
+
servers: ["cobasi"],
|
|
59
|
+
status: "active",
|
|
60
|
+
created_at: new Date().toISOString(),
|
|
61
|
+
closed_at: null,
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
globalThis.fetch = fetchMock;
|
|
66
|
+
const session = await createSession("consumer_123", { servers: ["cobasi"] }, { baseUrl: "https://api.example.com", apiKey: "csk_live_test" });
|
|
67
|
+
return { session, calls };
|
|
68
|
+
}
|
|
69
|
+
const originalFetch = globalThis.fetch;
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
globalThis.fetch = originalFetch;
|
|
72
|
+
});
|
|
73
|
+
describe("session.shop facade", () => {
|
|
74
|
+
it("dispatches execute('codespar_shop', args) and returns typed data", async () => {
|
|
75
|
+
const data = {
|
|
76
|
+
rail: "vtex",
|
|
77
|
+
products: [
|
|
78
|
+
{
|
|
79
|
+
product_id: "p1",
|
|
80
|
+
sku_id: "sku1",
|
|
81
|
+
title: "Ração",
|
|
82
|
+
price_minor: 1990,
|
|
83
|
+
currency: "BRL",
|
|
84
|
+
available: true,
|
|
85
|
+
variants: [{ sku_id: "sku1", available: true }],
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
const { session, calls } = await sessionReturning({ success: true, data });
|
|
90
|
+
const args = {
|
|
91
|
+
action: "search",
|
|
92
|
+
query: "ração para gato",
|
|
93
|
+
merchant: "cobasi",
|
|
94
|
+
limit: 10,
|
|
95
|
+
};
|
|
96
|
+
const result = await session.shop(args);
|
|
97
|
+
expect(calls).toHaveLength(1);
|
|
98
|
+
expect(calls[0].toolName).toBe("codespar_shop");
|
|
99
|
+
expect(calls[0].params).toEqual(args);
|
|
100
|
+
// discriminate on the search shape.
|
|
101
|
+
if ("products" in result) {
|
|
102
|
+
const search = result;
|
|
103
|
+
expect(search.rail).toBe("vtex");
|
|
104
|
+
expect(search.products[0].variants[0].sku_id).toBe("sku1");
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
throw new Error("expected a search result");
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
it("throws 'shop failed: <error>' when the envelope is unsuccessful", async () => {
|
|
111
|
+
const { session } = await sessionReturning({
|
|
112
|
+
success: false,
|
|
113
|
+
error: "invalid_args",
|
|
114
|
+
});
|
|
115
|
+
await expect(session.shop({ action: "search", query: "x" })).rejects.toThrow("shop failed: invalid_args");
|
|
116
|
+
});
|
|
117
|
+
it("throws 'shop failed: unknown' when no error string is present", async () => {
|
|
118
|
+
const { session } = await sessionReturning({ success: false });
|
|
119
|
+
await expect(session.shop({ action: "checkout_status", checkout_session_id: "c1" })).rejects.toThrow("shop failed: unknown");
|
|
120
|
+
});
|
|
121
|
+
it("checkout returns an in_progress session result (async start)", async () => {
|
|
122
|
+
const data = {
|
|
123
|
+
checkout_session_id: "cks_1",
|
|
124
|
+
status: "in_progress",
|
|
125
|
+
message: "started",
|
|
126
|
+
};
|
|
127
|
+
const { session } = await sessionReturning({ success: true, data });
|
|
128
|
+
const result = await session.shop({
|
|
129
|
+
action: "checkout",
|
|
130
|
+
merchant: "cobasi",
|
|
131
|
+
items: [{ variant_id: "sku1", quantity: 1 }],
|
|
132
|
+
consumer_id: "consumer_123",
|
|
133
|
+
});
|
|
134
|
+
if ("products" in result) {
|
|
135
|
+
throw new Error("expected a checkout result, got search");
|
|
136
|
+
}
|
|
137
|
+
// Narrowed off the search variant; status is reachable + typed.
|
|
138
|
+
expect(result.status).toBe("in_progress");
|
|
139
|
+
expect(result.checkout_session_id).toBe("cks_1");
|
|
140
|
+
});
|
|
141
|
+
it("a ready_for_payment status exposes typed pix_copia_e_cola + total_minor", async () => {
|
|
142
|
+
const data = {
|
|
143
|
+
checkout_session_id: "cks_1",
|
|
144
|
+
status: "ready_for_payment",
|
|
145
|
+
rail: "vtex",
|
|
146
|
+
total_minor: 1990,
|
|
147
|
+
pix_copia_e_cola: "00020126...br.gov.bcb.pix",
|
|
148
|
+
};
|
|
149
|
+
const { session } = await sessionReturning({ success: true, data });
|
|
150
|
+
const result = await session.shop({
|
|
151
|
+
action: "checkout_status",
|
|
152
|
+
checkout_session_id: "cks_1",
|
|
153
|
+
});
|
|
154
|
+
if ("products" in result) {
|
|
155
|
+
throw new Error("expected a status result, got search");
|
|
156
|
+
}
|
|
157
|
+
// Narrowed off search; the payable Pix is typed, not unknown.
|
|
158
|
+
if (result.status === "ready_for_payment") {
|
|
159
|
+
const pix = result.pix_copia_e_cola;
|
|
160
|
+
const total = result.total_minor;
|
|
161
|
+
expect(pix).toContain("br.gov.bcb.pix");
|
|
162
|
+
expect(total).toBe(1990);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
throw new Error("expected ready_for_payment");
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
it("a canceled status exposes the typed error field", async () => {
|
|
169
|
+
const data = {
|
|
170
|
+
checkout_session_id: "cks_2",
|
|
171
|
+
status: "canceled",
|
|
172
|
+
error: "browser_worker_checkout_failed",
|
|
173
|
+
};
|
|
174
|
+
const { session } = await sessionReturning({ success: true, data });
|
|
175
|
+
const result = await session.shop({
|
|
176
|
+
action: "checkout_status",
|
|
177
|
+
checkout_session_id: "cks_2",
|
|
178
|
+
});
|
|
179
|
+
if ("products" in result) {
|
|
180
|
+
throw new Error("expected a status result, got search");
|
|
181
|
+
}
|
|
182
|
+
if (result.status === "canceled") {
|
|
183
|
+
const err = result.error;
|
|
184
|
+
expect(err).toBe("browser_worker_checkout_failed");
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
throw new Error("expected canceled");
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
/**
|
|
192
|
+
* Compile-time discriminated-union assertions. These do not run
|
|
193
|
+
* assertions at runtime — they fail the build if the union stops
|
|
194
|
+
* narrowing correctly, which is the real guarantee the contract makes.
|
|
195
|
+
*/
|
|
196
|
+
describe("ShopResult type-level narrowing (compile-time)", () => {
|
|
197
|
+
it("narrows each variant by its discriminant without an unknown cast", () => {
|
|
198
|
+
const widen = (r) => {
|
|
199
|
+
if ("products" in r) {
|
|
200
|
+
// ShopSearchResult
|
|
201
|
+
return r.rail;
|
|
202
|
+
}
|
|
203
|
+
if (r.status === "in_progress" && !("rail" in r)) {
|
|
204
|
+
// ShopCheckoutResult — status is the literal "in_progress"
|
|
205
|
+
return r.checkout_session_id;
|
|
206
|
+
}
|
|
207
|
+
// ShopStatusResult
|
|
208
|
+
return r.pix_copia_e_cola ?? r.error ?? r.status;
|
|
209
|
+
};
|
|
210
|
+
expect(typeof widen).toBe("function");
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
//# sourceMappingURL=shop.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shop.test.js","sourceRoot":"","sources":["../../src/__tests__/shop.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAU7D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAO9C,SAAS,QAAQ,CAAC,IAAyB;IACzC,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,WAAW;QACnB,IAAI,EAAE,eAAe;QACrB,GAAG,IAAI;KACR,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,gBAAgB,CAAC,IAAyB;IAIvD,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,GAAW,EAAE,IAAwB,EAAE,EAAE;QACtE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAGzC,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACxD,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;gBACpB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,GAAG;aACtB,CAAC;QACJ,CAAC;QACD,iBAAiB;QACjB,OAAO;YACL,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;YACpB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;gBACjB,EAAE,EAAE,UAAU;gBACd,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,cAAc;gBACvB,OAAO,EAAE,CAAC,QAAQ,CAAC;gBACnB,MAAM,EAAE,QAAQ;gBAChB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACpC,SAAS,EAAE,IAAI;aAChB,CAAC;SACH,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,UAAU,CAAC,KAAK,GAAG,SAAoC,CAAC;IAExD,MAAM,OAAO,GAAG,MAAM,aAAa,CACjC,cAAc,EACd,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,EACvB,EAAE,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,eAAe,EAAE,CAChE,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;AACvC,SAAS,CAAC,GAAG,EAAE;IACb,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,IAAI,GAAqB;YAC7B,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE;gBACR;oBACE,UAAU,EAAE,IAAI;oBAChB,MAAM,EAAE,MAAM;oBACd,KAAK,EAAE,OAAO;oBACd,WAAW,EAAE,IAAI;oBACjB,QAAQ,EAAE,KAAK;oBACf,SAAS,EAAE,IAAI;oBACf,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;iBAChD;aACF;SACF,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3E,MAAM,IAAI,GAAa;YACrB,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,iBAAiB;YACxB,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,EAAE;SACV,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAExC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEvC,oCAAoC;QACpC,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,MAAM,GAAqB,MAAM,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,gBAAgB,CAAC;YACzC,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,cAAc;SACtB,CAAC,CAAC;QACH,MAAM,MAAM,CACV,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAC/C,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,MAAM,MAAM,CACV,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CACvE,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,IAAI,GAAuB;YAC/B,mBAAmB,EAAE,OAAO;YAC5B,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE,SAAS;SACnB,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;YAC5C,WAAW,EAAE,cAAc;SAC5B,CAAC,CAAC;QAEH,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,gEAAgE;QAChE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,IAAI,GAAqB;YAC7B,mBAAmB,EAAE,OAAO;YAC5B,MAAM,EAAE,mBAAmB;YAC3B,IAAI,EAAE,MAAM;YACZ,WAAW,EAAE,IAAI;YACjB,gBAAgB,EAAE,2BAA2B;SAC9C,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,MAAM,EAAE,iBAAiB;YACzB,mBAAmB,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,8DAA8D;QAC9D,IAAI,MAAM,CAAC,MAAM,KAAK,mBAAmB,EAAE,CAAC;YAC1C,MAAM,GAAG,GAAuB,MAAM,CAAC,gBAAgB,CAAC;YACxD,MAAM,KAAK,GAAuB,MAAM,CAAC,WAAW,CAAC;YACrD,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YACxC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,IAAI,GAAqB;YAC7B,mBAAmB,EAAE,OAAO;YAC5B,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,gCAAgC;SACxC,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YAChC,MAAM,EAAE,iBAAiB;YACzB,mBAAmB,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,MAAM,GAAG,GAAuB,MAAM,CAAC,KAAK,CAAC;YAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH;;;;GAIG;AACH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,KAAK,GAAG,CAAC,CAAa,EAAU,EAAE;YACtC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;gBACpB,mBAAmB;gBACnB,OAAO,CAAC,CAAC,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC;gBACjD,2DAA2D;gBAC3D,OAAO,CAAC,CAAC,mBAAmB,CAAC;YAC/B,CAAC;YACD,mBAAmB;YACnB,OAAO,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QACnD,CAAC,CAAC;QACF,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/testing.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { fakeSession } from "../testing/index.js";
|
|
3
|
+
describe("@codespar/sdk/testing — exported surface", () => {
|
|
4
|
+
it("exports fakeSession and the ToolResult type from a single import", () => {
|
|
5
|
+
expect(typeof fakeSession).toBe("function");
|
|
6
|
+
// ToolResult is a type-only re-export; the assertion below proves it
|
|
7
|
+
// is usable in a value position via a typed identity function.
|
|
8
|
+
const passthrough = (r) => r;
|
|
9
|
+
const sample = {
|
|
10
|
+
success: true,
|
|
11
|
+
data: {},
|
|
12
|
+
error: null,
|
|
13
|
+
duration: 0,
|
|
14
|
+
server: "",
|
|
15
|
+
tool: "x",
|
|
16
|
+
};
|
|
17
|
+
expect(passthrough(sample)).toBe(sample);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe("fakeSession — strict mode (default)", () => {
|
|
21
|
+
it("throws verbatim 'fakeSession: no response registered for tool <name>' on miss", async () => {
|
|
22
|
+
const session = fakeSession();
|
|
23
|
+
await expect(session.execute("asaas/create_payment", { value: 100 })).rejects.toThrow("fakeSession: no response registered for tool asaas/create_payment");
|
|
24
|
+
});
|
|
25
|
+
it("error message is byte-identical to the contract string", async () => {
|
|
26
|
+
const session = fakeSession();
|
|
27
|
+
let captured = null;
|
|
28
|
+
try {
|
|
29
|
+
await session.execute("foo/bar", {});
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
captured = err;
|
|
33
|
+
}
|
|
34
|
+
expect(captured).toBeInstanceOf(Error);
|
|
35
|
+
expect(captured.message).toBe("fakeSession: no response registered for tool foo/bar");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
describe("fakeSession — registered responses", () => {
|
|
39
|
+
it("returns the static ToolResult registered for a tool name", async () => {
|
|
40
|
+
const session = fakeSession({
|
|
41
|
+
"asaas/create_customer": {
|
|
42
|
+
success: true,
|
|
43
|
+
data: { id: "cus_test_1", name: "Maria" },
|
|
44
|
+
error: null,
|
|
45
|
+
duration: 0,
|
|
46
|
+
server: "asaas",
|
|
47
|
+
tool: "asaas/create_customer",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const result = await session.execute("asaas/create_customer", { name: "Maria" });
|
|
51
|
+
expect(result.success).toBe(true);
|
|
52
|
+
expect(result.data).toEqual({ id: "cus_test_1", name: "Maria" });
|
|
53
|
+
expect(result.tool).toBe("asaas/create_customer");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe("fakeSession — per-tool function variant", () => {
|
|
57
|
+
it("invokes a sync response function with the call's params and returns its result", async () => {
|
|
58
|
+
const session = fakeSession({
|
|
59
|
+
"asaas/create_customer": (input) => ({
|
|
60
|
+
success: true,
|
|
61
|
+
data: { echoed: input },
|
|
62
|
+
error: null,
|
|
63
|
+
duration: 0,
|
|
64
|
+
server: "asaas",
|
|
65
|
+
tool: "asaas/create_customer",
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
const result = await session.execute("asaas/create_customer", { name: "Joana" });
|
|
69
|
+
expect(result.data).toEqual({ echoed: { name: "Joana" } });
|
|
70
|
+
});
|
|
71
|
+
it("awaits a Promise-returning response function", async () => {
|
|
72
|
+
const session = fakeSession({
|
|
73
|
+
"asaas/create_customer": async (input) => ({
|
|
74
|
+
success: true,
|
|
75
|
+
data: { async_echoed: input },
|
|
76
|
+
error: null,
|
|
77
|
+
duration: 0,
|
|
78
|
+
server: "asaas",
|
|
79
|
+
tool: "asaas/create_customer",
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
const result = await session.execute("asaas/create_customer", { name: "Joana" });
|
|
83
|
+
expect(result.data).toEqual({ async_echoed: { name: "Joana" } });
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
describe("fakeSession — lenient mode", () => {
|
|
87
|
+
it("returns {success:true, data:{}} for unregistered tools when lenient: true", async () => {
|
|
88
|
+
const session = fakeSession({}, { lenient: true });
|
|
89
|
+
const result = await session.execute("asaas/create_payment", { value: 100 });
|
|
90
|
+
expect(result.success).toBe(true);
|
|
91
|
+
expect(result.data).toEqual({});
|
|
92
|
+
expect(result.error).toBeNull();
|
|
93
|
+
expect(result.tool).toBe("asaas/create_payment");
|
|
94
|
+
});
|
|
95
|
+
it("does not override a registered failure response in lenient mode", async () => {
|
|
96
|
+
const session = fakeSession({
|
|
97
|
+
"asaas/create_payment": {
|
|
98
|
+
success: false,
|
|
99
|
+
data: null,
|
|
100
|
+
error: "boom",
|
|
101
|
+
duration: 0,
|
|
102
|
+
server: "asaas",
|
|
103
|
+
tool: "asaas/create_payment",
|
|
104
|
+
},
|
|
105
|
+
}, { lenient: true });
|
|
106
|
+
const result = await session.execute("asaas/create_payment", { value: 100 });
|
|
107
|
+
expect(result.success).toBe(false);
|
|
108
|
+
expect(result.error).toBe("boom");
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
describe("fakeSession — Session interface conformance", () => {
|
|
112
|
+
it("returns a value assignable to Session without casts", () => {
|
|
113
|
+
// Compile-time check: the literal annotation forces structural conformance.
|
|
114
|
+
// If this file compiles, the conformance check has passed.
|
|
115
|
+
const session = fakeSession();
|
|
116
|
+
expect(typeof session.execute).toBe("function");
|
|
117
|
+
expect(typeof session.send).toBe("function");
|
|
118
|
+
expect(typeof session.sendStream).toBe("function");
|
|
119
|
+
expect(typeof session.proxyExecute).toBe("function");
|
|
120
|
+
expect(typeof session.authorize).toBe("function");
|
|
121
|
+
expect(typeof session.connections).toBe("function");
|
|
122
|
+
expect(typeof session.close).toBe("function");
|
|
123
|
+
expect(typeof session.discover).toBe("function");
|
|
124
|
+
expect(typeof session.connectionWizard).toBe("function");
|
|
125
|
+
expect(typeof session.charge).toBe("function");
|
|
126
|
+
expect(typeof session.ship).toBe("function");
|
|
127
|
+
expect(typeof session.paymentStatus).toBe("function");
|
|
128
|
+
expect(typeof session.paymentStatusStream).toBe("function");
|
|
129
|
+
expect(typeof session.verificationStatus).toBe("function");
|
|
130
|
+
expect(typeof session.verificationStatusStream).toBe("function");
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
//# sourceMappingURL=testing.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.test.js","sourceRoot":"","sources":["../../src/__tests__/testing.test.ts"],"names":[],"mappings":"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"}
|