@yoryoboy/bi-mcp 1.16.0 → 1.17.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/dist/.tsbuildinfo +1 -1
- package/dist/index.js +34 -1
- package/dist/index.js.map +2 -2
- package/dist/mcp-use.json +2 -2
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js +137 -0
- package/dist/src/services/mercadolibre/__tests__/mercadolibre-payments.test.js.map +7 -0
- package/dist/src/services/mercadolibre/mercadolibre-api.js +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-api.js.map +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-billing.js +93 -1
- package/dist/src/services/mercadolibre/mercadolibre-billing.js.map +2 -2
- package/dist/src/services/mercadolibre/mercadolibre-payments.js +60 -0
- package/dist/src/services/mercadolibre/mercadolibre-payments.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js +284 -0
- package/dist/src/tools/mercadolibre/get-billing-provisions-by-order.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-full-storage-charges.js +183 -0
- package/dist/src/tools/mercadolibre/get-full-storage-charges.js.map +7 -0
- package/dist/src/tools/mercadolibre/get-payment-details.js +322 -0
- package/dist/src/tools/mercadolibre/get-payment-details.js.map +7 -0
- package/dist/src/tools/mercadolibre/index.js +20 -0
- package/dist/src/tools/mercadolibre/index.js.map +2 -2
- package/dist/tests/meli/mercadolibre-billing-provisions.test.js +176 -0
- package/dist/tests/meli/mercadolibre-billing-provisions.test.js.map +2 -2
- package/dist/tests/meli/mercadolibre-payment-details.test.js +356 -0
- package/dist/tests/meli/mercadolibre-payment-details.test.js.map +7 -0
- package/dist/tests/meli/mercadolibre-payments.test.js +62 -0
- package/dist/tests/meli/mercadolibre-payments.test.js.map +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const {
|
|
3
|
+
errorMock,
|
|
4
|
+
objectMock,
|
|
5
|
+
resolveProfileMock,
|
|
6
|
+
formatErrorMock,
|
|
7
|
+
paymentDetailsMock,
|
|
8
|
+
paymentDetailsBatchMock
|
|
9
|
+
} = vi.hoisted(
|
|
10
|
+
() => ({
|
|
11
|
+
errorMock: vi.fn((message) => ({ kind: "error", message })),
|
|
12
|
+
objectMock: vi.fn((payload) => ({ kind: "object", payload })),
|
|
13
|
+
resolveProfileMock: vi.fn(),
|
|
14
|
+
formatErrorMock: vi.fn(
|
|
15
|
+
(err, fallback) => `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`
|
|
16
|
+
),
|
|
17
|
+
paymentDetailsMock: vi.fn(),
|
|
18
|
+
paymentDetailsBatchMock: vi.fn()
|
|
19
|
+
})
|
|
20
|
+
);
|
|
21
|
+
vi.mock("mcp-use/server", () => ({
|
|
22
|
+
object: objectMock,
|
|
23
|
+
error: errorMock
|
|
24
|
+
}));
|
|
25
|
+
vi.mock("../../src/tools/mercadolibre/profile-resolution.js", () => ({
|
|
26
|
+
resolveMercadoLibreProfileOrSelection: resolveProfileMock
|
|
27
|
+
}));
|
|
28
|
+
vi.mock("../../src/services/mercadolibre/mercadolibre-api.js", () => ({
|
|
29
|
+
formatMercadoLibreError: formatErrorMock
|
|
30
|
+
}));
|
|
31
|
+
vi.mock("../../src/services/mercadolibre/mercadolibre-payments.js", () => ({
|
|
32
|
+
getMercadoLibrePaymentDetails: paymentDetailsMock,
|
|
33
|
+
getMercadoLibrePaymentDetailsBatch: paymentDetailsBatchMock
|
|
34
|
+
}));
|
|
35
|
+
import {
|
|
36
|
+
meliGetPaymentDetailsHandler,
|
|
37
|
+
meliGetPaymentDetailsSchema
|
|
38
|
+
} from "../../src/tools/mercadolibre/get-payment-details.js";
|
|
39
|
+
describe("meli_get_payment_details handler", () => {
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
vi.clearAllMocks();
|
|
42
|
+
vi.mocked(resolveProfileMock).mockResolvedValue({
|
|
43
|
+
ok: true,
|
|
44
|
+
value: { profileId: "meli-profile-1" }
|
|
45
|
+
});
|
|
46
|
+
vi.mocked(paymentDetailsMock).mockResolvedValue({
|
|
47
|
+
id: 28382111111,
|
|
48
|
+
status: "approved",
|
|
49
|
+
status_detail: "accredited",
|
|
50
|
+
currency_id: "ARS",
|
|
51
|
+
transaction_amount: 100,
|
|
52
|
+
date_created: "2023-10-27T10:00:00.000-04:00",
|
|
53
|
+
date_last_updated: "2023-10-27T10:05:00.000-04:00",
|
|
54
|
+
payment_method_id: "credit_card",
|
|
55
|
+
payment_type_id: "credit_card",
|
|
56
|
+
installments: 1,
|
|
57
|
+
description: "Payment for order #12345",
|
|
58
|
+
order: {
|
|
59
|
+
id: 1234567890
|
|
60
|
+
},
|
|
61
|
+
payer: {
|
|
62
|
+
id: 987654321,
|
|
63
|
+
email: "buyer@example.com",
|
|
64
|
+
first_name: "Test",
|
|
65
|
+
last_name: "User",
|
|
66
|
+
type: "customer"
|
|
67
|
+
},
|
|
68
|
+
transaction_details: {
|
|
69
|
+
total_paid_amount: 100,
|
|
70
|
+
net_received_amount: 95,
|
|
71
|
+
overpaid_amount: 0,
|
|
72
|
+
external_reference: "order_12345"
|
|
73
|
+
},
|
|
74
|
+
fee_details: [{ type: "MERCHANT_FEES", amount: 5 }]
|
|
75
|
+
});
|
|
76
|
+
vi.mocked(paymentDetailsBatchMock).mockResolvedValue({
|
|
77
|
+
successful: [],
|
|
78
|
+
failed: []
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
it("returns a compact single-payment payload with summary and breakdowns", async () => {
|
|
82
|
+
const result = await meliGetPaymentDetailsHandler({
|
|
83
|
+
profileId: "custom-profile",
|
|
84
|
+
paymentId: "28382111111"
|
|
85
|
+
});
|
|
86
|
+
expect(resolveProfileMock).toHaveBeenCalledWith("custom-profile");
|
|
87
|
+
expect(paymentDetailsMock).toHaveBeenCalledWith("meli-profile-1", "28382111111");
|
|
88
|
+
expect(result).toEqual({
|
|
89
|
+
kind: "object",
|
|
90
|
+
payload: {
|
|
91
|
+
metadata: {
|
|
92
|
+
profile_id: "meli-profile-1",
|
|
93
|
+
mode: "single",
|
|
94
|
+
requested_count: 1,
|
|
95
|
+
successful_count: 1,
|
|
96
|
+
failed_count: 0,
|
|
97
|
+
coverage_complete: true,
|
|
98
|
+
requested_payment_ids: ["28382111111"],
|
|
99
|
+
successful_payment_ids: ["28382111111"],
|
|
100
|
+
endpoint: "/v1/payments/{payment_id}"
|
|
101
|
+
},
|
|
102
|
+
summary: {
|
|
103
|
+
requested_count: 1,
|
|
104
|
+
successful_count: 1,
|
|
105
|
+
failed_count: 0,
|
|
106
|
+
payments_with_order_count: 1,
|
|
107
|
+
payments_without_order_count: 0,
|
|
108
|
+
payments_without_payer_count: 0,
|
|
109
|
+
currency_totals: {
|
|
110
|
+
ARS: {
|
|
111
|
+
count: 1,
|
|
112
|
+
transaction_amount: 100,
|
|
113
|
+
total_paid_amount: 100,
|
|
114
|
+
net_received_amount: 95,
|
|
115
|
+
overpaid_amount: 0,
|
|
116
|
+
fee_total: 5
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
status_counts: { approved: 1 },
|
|
120
|
+
payment_method_counts: { credit_card: 1 },
|
|
121
|
+
payment_type_counts: { credit_card: 1 }
|
|
122
|
+
},
|
|
123
|
+
breakdowns: {
|
|
124
|
+
by_currency: [
|
|
125
|
+
{
|
|
126
|
+
currency_id: "ARS",
|
|
127
|
+
count: 1,
|
|
128
|
+
transaction_amount: 100,
|
|
129
|
+
total_paid_amount: 100,
|
|
130
|
+
net_received_amount: 95,
|
|
131
|
+
overpaid_amount: 0,
|
|
132
|
+
fee_total: 5
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
by_status: [{ key: "approved", count: 1, rate: 1 }],
|
|
136
|
+
by_payment_method: [{ key: "credit_card", count: 1, rate: 1 }],
|
|
137
|
+
by_payment_type: [{ key: "credit_card", count: 1, rate: 1 }]
|
|
138
|
+
},
|
|
139
|
+
payments_schema: [
|
|
140
|
+
"payment_id",
|
|
141
|
+
"status",
|
|
142
|
+
"status_detail",
|
|
143
|
+
"currency_id",
|
|
144
|
+
"transaction_amount",
|
|
145
|
+
"total_paid_amount",
|
|
146
|
+
"net_received_amount",
|
|
147
|
+
"overpaid_amount",
|
|
148
|
+
"payment_method_id",
|
|
149
|
+
"payment_type_id",
|
|
150
|
+
"installments",
|
|
151
|
+
"date_created",
|
|
152
|
+
"date_last_updated",
|
|
153
|
+
"description",
|
|
154
|
+
"order_id",
|
|
155
|
+
"payer_id",
|
|
156
|
+
"payer_email",
|
|
157
|
+
"payer_type",
|
|
158
|
+
"payer_first_name",
|
|
159
|
+
"payer_last_name",
|
|
160
|
+
"fee_count",
|
|
161
|
+
"fee_total",
|
|
162
|
+
"external_reference"
|
|
163
|
+
],
|
|
164
|
+
payments: [
|
|
165
|
+
[
|
|
166
|
+
"28382111111",
|
|
167
|
+
"approved",
|
|
168
|
+
"accredited",
|
|
169
|
+
"ARS",
|
|
170
|
+
100,
|
|
171
|
+
100,
|
|
172
|
+
95,
|
|
173
|
+
0,
|
|
174
|
+
"credit_card",
|
|
175
|
+
"credit_card",
|
|
176
|
+
1,
|
|
177
|
+
"2023-10-27 10:00",
|
|
178
|
+
"2023-10-27 10:05",
|
|
179
|
+
"Payment for order #12345",
|
|
180
|
+
"1234567890",
|
|
181
|
+
"987654321",
|
|
182
|
+
"buyer@example.com",
|
|
183
|
+
"customer",
|
|
184
|
+
"Test",
|
|
185
|
+
"User",
|
|
186
|
+
1,
|
|
187
|
+
5,
|
|
188
|
+
"order_12345"
|
|
189
|
+
]
|
|
190
|
+
],
|
|
191
|
+
payment_fee_details_schema: ["payment_id", "fee_type", "fee_amount"],
|
|
192
|
+
payment_fee_details: [["28382111111", "MERCHANT_FEES", 5]]
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
it("accepts the exact 250-payment boundary and rejects invalid selector combinations", () => {
|
|
197
|
+
const exactBoundaryPaymentIds = Array.from({ length: 250 }, (_, index) => `p-${index + 1}`);
|
|
198
|
+
expect(
|
|
199
|
+
meliGetPaymentDetailsSchema.safeParse({
|
|
200
|
+
profileId: "custom-profile",
|
|
201
|
+
paymentIds: exactBoundaryPaymentIds
|
|
202
|
+
}).success
|
|
203
|
+
).toBe(true);
|
|
204
|
+
expect(
|
|
205
|
+
() => meliGetPaymentDetailsSchema.parse({
|
|
206
|
+
profileId: "custom-profile"
|
|
207
|
+
})
|
|
208
|
+
).toThrow(/paymentId|paymentIds/);
|
|
209
|
+
expect(
|
|
210
|
+
() => meliGetPaymentDetailsSchema.parse({
|
|
211
|
+
profileId: "custom-profile",
|
|
212
|
+
paymentId: "28382111111",
|
|
213
|
+
paymentIds: ["28382111112"]
|
|
214
|
+
})
|
|
215
|
+
).toThrow(/paymentId|paymentIds/);
|
|
216
|
+
expect(
|
|
217
|
+
() => meliGetPaymentDetailsSchema.parse({
|
|
218
|
+
profileId: "custom-profile",
|
|
219
|
+
paymentIds: Array.from({ length: 251 }, (_, index) => `p-${index + 1}`)
|
|
220
|
+
})
|
|
221
|
+
).toThrow(/250/);
|
|
222
|
+
});
|
|
223
|
+
it("returns the selection payload unchanged when the profile cannot be resolved", async () => {
|
|
224
|
+
vi.mocked(resolveProfileMock).mockResolvedValue({
|
|
225
|
+
ok: false,
|
|
226
|
+
response: { selection_required: true }
|
|
227
|
+
});
|
|
228
|
+
const result = await meliGetPaymentDetailsHandler({
|
|
229
|
+
profileId: "unknown-profile",
|
|
230
|
+
paymentId: "28382111111"
|
|
231
|
+
});
|
|
232
|
+
expect(result).toEqual({ selection_required: true });
|
|
233
|
+
expect(paymentDetailsMock).not.toHaveBeenCalled();
|
|
234
|
+
});
|
|
235
|
+
it("returns a compact batch payload with partial failures", async () => {
|
|
236
|
+
vi.mocked(paymentDetailsBatchMock).mockResolvedValue({
|
|
237
|
+
successful: [
|
|
238
|
+
{
|
|
239
|
+
paymentId: "28382111111",
|
|
240
|
+
payment: {
|
|
241
|
+
id: 28382111111,
|
|
242
|
+
status: "approved",
|
|
243
|
+
status_detail: "accredited",
|
|
244
|
+
currency_id: "ARS",
|
|
245
|
+
transaction_amount: 100,
|
|
246
|
+
date_created: "2023-10-27T10:00:00.000-04:00",
|
|
247
|
+
date_last_updated: "2023-10-27T10:05:00.000-04:00",
|
|
248
|
+
payment_method_id: "credit_card",
|
|
249
|
+
payment_type_id: "credit_card",
|
|
250
|
+
installments: 1,
|
|
251
|
+
order: { id: 1234567890 },
|
|
252
|
+
payer: { id: 987654321, email: "buyer@example.com", type: "customer" },
|
|
253
|
+
transaction_details: {
|
|
254
|
+
total_paid_amount: 100,
|
|
255
|
+
net_received_amount: 95,
|
|
256
|
+
overpaid_amount: 0
|
|
257
|
+
},
|
|
258
|
+
fee_details: [{ type: "MERCHANT_FEES", amount: 5 }]
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
paymentId: "28382111112",
|
|
263
|
+
payment: {
|
|
264
|
+
id: 28382111112,
|
|
265
|
+
status: "pending",
|
|
266
|
+
currency_id: "USD",
|
|
267
|
+
transaction_amount: 50,
|
|
268
|
+
date_created: "2023-10-27T11:00:00.000-04:00",
|
|
269
|
+
date_last_updated: "2023-10-27T11:05:00.000-04:00",
|
|
270
|
+
payment_method_id: "debit_card",
|
|
271
|
+
payment_type_id: "debit_card",
|
|
272
|
+
installments: 1,
|
|
273
|
+
transaction_details: {
|
|
274
|
+
total_paid_amount: 50,
|
|
275
|
+
net_received_amount: 48,
|
|
276
|
+
overpaid_amount: 0
|
|
277
|
+
},
|
|
278
|
+
fee_details: []
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
],
|
|
282
|
+
failed: [
|
|
283
|
+
{
|
|
284
|
+
paymentId: "28382111113",
|
|
285
|
+
message: "formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404",
|
|
286
|
+
statusCode: 404,
|
|
287
|
+
attempts: 1,
|
|
288
|
+
retryable: false
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
});
|
|
292
|
+
const result = await meliGetPaymentDetailsHandler({
|
|
293
|
+
profileId: "custom-profile",
|
|
294
|
+
paymentIds: ["28382111111", "28382111112", "28382111113"]
|
|
295
|
+
});
|
|
296
|
+
expect(paymentDetailsBatchMock).toHaveBeenCalledWith("meli-profile-1", [
|
|
297
|
+
"28382111111",
|
|
298
|
+
"28382111112",
|
|
299
|
+
"28382111113"
|
|
300
|
+
]);
|
|
301
|
+
expect(result).toEqual({
|
|
302
|
+
kind: "object",
|
|
303
|
+
payload: expect.objectContaining({
|
|
304
|
+
metadata: expect.objectContaining({
|
|
305
|
+
mode: "batch",
|
|
306
|
+
requested_count: 3,
|
|
307
|
+
successful_count: 2,
|
|
308
|
+
failed_count: 1,
|
|
309
|
+
coverage_complete: false,
|
|
310
|
+
requested_payment_ids: ["28382111111", "28382111112", "28382111113"],
|
|
311
|
+
successful_payment_ids: ["28382111111", "28382111112"],
|
|
312
|
+
failed_payment_ids: ["28382111113"]
|
|
313
|
+
}),
|
|
314
|
+
failures: [
|
|
315
|
+
{
|
|
316
|
+
paymentId: "28382111113",
|
|
317
|
+
message: "formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404",
|
|
318
|
+
statusCode: 404,
|
|
319
|
+
attempts: 1,
|
|
320
|
+
retryable: false
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
})
|
|
324
|
+
});
|
|
325
|
+
const [firstRow, secondRow] = result.payload.payments;
|
|
326
|
+
expect(firstRow).toHaveLength(23);
|
|
327
|
+
expect(secondRow).toHaveLength(23);
|
|
328
|
+
expect(secondRow[2]).toBeNull();
|
|
329
|
+
expect(secondRow[13]).toBeNull();
|
|
330
|
+
expect(secondRow[14]).toBeNull();
|
|
331
|
+
expect(secondRow[15]).toBeNull();
|
|
332
|
+
expect(secondRow[16]).toBeNull();
|
|
333
|
+
expect(secondRow[17]).toBeNull();
|
|
334
|
+
expect(secondRow[18]).toBeNull();
|
|
335
|
+
expect(secondRow[19]).toBeNull();
|
|
336
|
+
expect(secondRow[22]).toBeNull();
|
|
337
|
+
});
|
|
338
|
+
it("returns a formatted error when the payment lookup fails", async () => {
|
|
339
|
+
vi.mocked(paymentDetailsMock).mockRejectedValueOnce(
|
|
340
|
+
new Error("Request failed with status code 404")
|
|
341
|
+
);
|
|
342
|
+
const result = await meliGetPaymentDetailsHandler({
|
|
343
|
+
profileId: "custom-profile",
|
|
344
|
+
paymentId: "28382111111"
|
|
345
|
+
});
|
|
346
|
+
expect(formatErrorMock).toHaveBeenCalledWith(
|
|
347
|
+
expect.any(Error),
|
|
348
|
+
"Failed to fetch MercadoLibre payment details"
|
|
349
|
+
);
|
|
350
|
+
expect(result).toEqual({
|
|
351
|
+
kind: "error",
|
|
352
|
+
message: "formatted:Failed to fetch MercadoLibre payment details:Request failed with status code 404"
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
//# sourceMappingURL=mercadolibre-payment-details.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../tests/meli/mercadolibre-payment-details.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst {\n errorMock,\n objectMock,\n resolveProfileMock,\n formatErrorMock,\n paymentDetailsMock,\n paymentDetailsBatchMock,\n} = vi.hoisted(\n () => ({\n errorMock: vi.fn((message: string) => ({ kind: \"error\", message })),\n objectMock: vi.fn((payload: unknown) => ({ kind: \"object\", payload })),\n resolveProfileMock: vi.fn(),\n formatErrorMock: vi.fn(\n (err: unknown, fallback: string) =>\n `formatted:${fallback}:${err instanceof Error ? err.message : String(err)}`\n ),\n paymentDetailsMock: vi.fn(),\n paymentDetailsBatchMock: vi.fn(),\n })\n);\n\nvi.mock(\"mcp-use/server\", () => ({\n object: objectMock,\n error: errorMock,\n}));\n\nvi.mock(\"../../src/tools/mercadolibre/profile-resolution.js\", () => ({\n resolveMercadoLibreProfileOrSelection: resolveProfileMock,\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-api.js\", () => ({\n formatMercadoLibreError: formatErrorMock,\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-payments.js\", () => ({\n getMercadoLibrePaymentDetails: paymentDetailsMock,\n getMercadoLibrePaymentDetailsBatch: paymentDetailsBatchMock,\n}));\n\nimport {\n meliGetPaymentDetailsHandler,\n meliGetPaymentDetailsSchema,\n} from \"../../src/tools/mercadolibre/get-payment-details.js\";\n\ndescribe(\"meli_get_payment_details handler\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(resolveProfileMock).mockResolvedValue({\n ok: true,\n value: { profileId: \"meli-profile-1\" },\n });\n\n vi.mocked(paymentDetailsMock).mockResolvedValue({\n id: 28382111111,\n status: \"approved\",\n status_detail: \"accredited\",\n currency_id: \"ARS\",\n transaction_amount: 100,\n date_created: \"2023-10-27T10:00:00.000-04:00\",\n date_last_updated: \"2023-10-27T10:05:00.000-04:00\",\n payment_method_id: \"credit_card\",\n payment_type_id: \"credit_card\",\n installments: 1,\n description: \"Payment for order #12345\",\n order: {\n id: 1234567890,\n },\n payer: {\n id: 987654321,\n email: \"buyer@example.com\",\n first_name: \"Test\",\n last_name: \"User\",\n type: \"customer\",\n },\n transaction_details: {\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n external_reference: \"order_12345\",\n },\n fee_details: [{ type: \"MERCHANT_FEES\", amount: 5 }],\n } as never);\n\n vi.mocked(paymentDetailsBatchMock).mockResolvedValue({\n successful: [],\n failed: [],\n });\n });\n\n it(\"returns a compact single-payment payload with summary and breakdowns\", async () => {\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"custom-profile\",\n paymentId: \"28382111111\",\n });\n\n expect(resolveProfileMock).toHaveBeenCalledWith(\"custom-profile\");\n expect(paymentDetailsMock).toHaveBeenCalledWith(\"meli-profile-1\", \"28382111111\");\n expect(result).toEqual({\n kind: \"object\",\n payload: {\n metadata: {\n profile_id: \"meli-profile-1\",\n mode: \"single\",\n requested_count: 1,\n successful_count: 1,\n failed_count: 0,\n coverage_complete: true,\n requested_payment_ids: [\"28382111111\"],\n successful_payment_ids: [\"28382111111\"],\n endpoint: \"/v1/payments/{payment_id}\",\n },\n summary: {\n requested_count: 1,\n successful_count: 1,\n failed_count: 0,\n payments_with_order_count: 1,\n payments_without_order_count: 0,\n payments_without_payer_count: 0,\n currency_totals: {\n ARS: {\n count: 1,\n transaction_amount: 100,\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n fee_total: 5,\n },\n },\n status_counts: { approved: 1 },\n payment_method_counts: { credit_card: 1 },\n payment_type_counts: { credit_card: 1 },\n },\n breakdowns: {\n by_currency: [\n {\n currency_id: \"ARS\",\n count: 1,\n transaction_amount: 100,\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n fee_total: 5,\n },\n ],\n by_status: [{ key: \"approved\", count: 1, rate: 1 }],\n by_payment_method: [{ key: \"credit_card\", count: 1, rate: 1 }],\n by_payment_type: [{ key: \"credit_card\", count: 1, rate: 1 }],\n },\n payments_schema: [\n \"payment_id\",\n \"status\",\n \"status_detail\",\n \"currency_id\",\n \"transaction_amount\",\n \"total_paid_amount\",\n \"net_received_amount\",\n \"overpaid_amount\",\n \"payment_method_id\",\n \"payment_type_id\",\n \"installments\",\n \"date_created\",\n \"date_last_updated\",\n \"description\",\n \"order_id\",\n \"payer_id\",\n \"payer_email\",\n \"payer_type\",\n \"payer_first_name\",\n \"payer_last_name\",\n \"fee_count\",\n \"fee_total\",\n \"external_reference\",\n ],\n payments: [\n [\n \"28382111111\",\n \"approved\",\n \"accredited\",\n \"ARS\",\n 100,\n 100,\n 95,\n 0,\n \"credit_card\",\n \"credit_card\",\n 1,\n \"2023-10-27 10:00\",\n \"2023-10-27 10:05\",\n \"Payment for order #12345\",\n \"1234567890\",\n \"987654321\",\n \"buyer@example.com\",\n \"customer\",\n \"Test\",\n \"User\",\n 1,\n 5,\n \"order_12345\",\n ],\n ],\n payment_fee_details_schema: [\"payment_id\", \"fee_type\", \"fee_amount\"],\n payment_fee_details: [[\"28382111111\", \"MERCHANT_FEES\", 5]],\n },\n });\n });\n\n it(\"accepts the exact 250-payment boundary and rejects invalid selector combinations\", () => {\n const exactBoundaryPaymentIds = Array.from({ length: 250 }, (_, index) => `p-${index + 1}`);\n\n expect(\n meliGetPaymentDetailsSchema.safeParse({\n profileId: \"custom-profile\",\n paymentIds: exactBoundaryPaymentIds,\n }).success\n ).toBe(true);\n\n expect(() =>\n meliGetPaymentDetailsSchema.parse({\n profileId: \"custom-profile\",\n })\n ).toThrow(/paymentId|paymentIds/);\n\n expect(() =>\n meliGetPaymentDetailsSchema.parse({\n profileId: \"custom-profile\",\n paymentId: \"28382111111\",\n paymentIds: [\"28382111112\"],\n })\n ).toThrow(/paymentId|paymentIds/);\n\n expect(() =>\n meliGetPaymentDetailsSchema.parse({\n profileId: \"custom-profile\",\n paymentIds: Array.from({ length: 251 }, (_, index) => `p-${index + 1}`),\n })\n ).toThrow(/250/);\n });\n\n it(\"returns the selection payload unchanged when the profile cannot be resolved\", async () => {\n vi.mocked(resolveProfileMock).mockResolvedValue({\n ok: false,\n response: { selection_required: true },\n } as never);\n\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"unknown-profile\",\n paymentId: \"28382111111\",\n });\n\n expect(result).toEqual({ selection_required: true });\n expect(paymentDetailsMock).not.toHaveBeenCalled();\n });\n\n it(\"returns a compact batch payload with partial failures\", async () => {\n vi.mocked(paymentDetailsBatchMock).mockResolvedValue({\n successful: [\n {\n paymentId: \"28382111111\",\n payment: {\n id: 28382111111,\n status: \"approved\",\n status_detail: \"accredited\",\n currency_id: \"ARS\",\n transaction_amount: 100,\n date_created: \"2023-10-27T10:00:00.000-04:00\",\n date_last_updated: \"2023-10-27T10:05:00.000-04:00\",\n payment_method_id: \"credit_card\",\n payment_type_id: \"credit_card\",\n installments: 1,\n order: { id: 1234567890 },\n payer: { id: 987654321, email: \"buyer@example.com\", type: \"customer\" },\n transaction_details: {\n total_paid_amount: 100,\n net_received_amount: 95,\n overpaid_amount: 0,\n },\n fee_details: [{ type: \"MERCHANT_FEES\", amount: 5 }],\n },\n },\n {\n paymentId: \"28382111112\",\n payment: {\n id: 28382111112,\n status: \"pending\",\n currency_id: \"USD\",\n transaction_amount: 50,\n date_created: \"2023-10-27T11:00:00.000-04:00\",\n date_last_updated: \"2023-10-27T11:05:00.000-04:00\",\n payment_method_id: \"debit_card\",\n payment_type_id: \"debit_card\",\n installments: 1,\n transaction_details: {\n total_paid_amount: 50,\n net_received_amount: 48,\n overpaid_amount: 0,\n },\n fee_details: [],\n },\n },\n ],\n failed: [\n {\n paymentId: \"28382111113\",\n message: \"formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404\",\n statusCode: 404,\n attempts: 1,\n retryable: false,\n },\n ],\n });\n\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"custom-profile\",\n paymentIds: [\"28382111111\", \"28382111112\", \"28382111113\"],\n });\n\n expect(paymentDetailsBatchMock).toHaveBeenCalledWith(\"meli-profile-1\", [\n \"28382111111\",\n \"28382111112\",\n \"28382111113\",\n ]);\n expect(result).toEqual({\n kind: \"object\",\n payload: expect.objectContaining({\n metadata: expect.objectContaining({\n mode: \"batch\",\n requested_count: 3,\n successful_count: 2,\n failed_count: 1,\n coverage_complete: false,\n requested_payment_ids: [\"28382111111\", \"28382111112\", \"28382111113\"],\n successful_payment_ids: [\"28382111111\", \"28382111112\"],\n failed_payment_ids: [\"28382111113\"],\n }),\n failures: [\n {\n paymentId: \"28382111113\",\n message: \"formatted:Failed to fetch MercadoLibre payment 28382111113:Request failed with status code 404\",\n statusCode: 404,\n attempts: 1,\n retryable: false,\n },\n ],\n }),\n });\n\n const [firstRow, secondRow] = (result as unknown as {\n payload: { payments: Array<(string | number | null)[]> };\n }).payload.payments;\n\n expect(firstRow).toHaveLength(23);\n expect(secondRow).toHaveLength(23);\n expect(secondRow[2]).toBeNull();\n expect(secondRow[13]).toBeNull();\n expect(secondRow[14]).toBeNull();\n expect(secondRow[15]).toBeNull();\n expect(secondRow[16]).toBeNull();\n expect(secondRow[17]).toBeNull();\n expect(secondRow[18]).toBeNull();\n expect(secondRow[19]).toBeNull();\n expect(secondRow[22]).toBeNull();\n });\n\n it(\"returns a formatted error when the payment lookup fails\", async () => {\n vi.mocked(paymentDetailsMock).mockRejectedValueOnce(\n new Error(\"Request failed with status code 404\")\n );\n\n const result = await meliGetPaymentDetailsHandler({\n profileId: \"custom-profile\",\n paymentId: \"28382111111\",\n });\n\n expect(formatErrorMock).toHaveBeenCalledWith(\n expect.any(Error),\n \"Failed to fetch MercadoLibre payment details\"\n );\n expect(result).toEqual({\n kind: \"error\",\n message:\n \"formatted:Failed to fetch MercadoLibre payment details:Request failed with status code 404\",\n });\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const { accessProfileMock, createClientMock, getPaymentMock } = vi.hoisted(() => ({
|
|
3
|
+
accessProfileMock: vi.fn(),
|
|
4
|
+
createClientMock: vi.fn(),
|
|
5
|
+
getPaymentMock: vi.fn()
|
|
6
|
+
}));
|
|
7
|
+
vi.mock("../../src/config/mercadolibre.js", () => ({
|
|
8
|
+
getMercadoLibreAccessForProfile: accessProfileMock
|
|
9
|
+
}));
|
|
10
|
+
vi.mock("../../src/services/mercadolibre/mercadolibre-api.js", () => ({
|
|
11
|
+
createMercadoLibreClient: createClientMock
|
|
12
|
+
}));
|
|
13
|
+
import {
|
|
14
|
+
getMercadoLibrePaymentDetails,
|
|
15
|
+
getMercadoLibrePaymentDetailsBatch
|
|
16
|
+
} from "../../src/services/mercadolibre/mercadolibre-payments.js";
|
|
17
|
+
describe("getMercadoLibrePaymentDetails", () => {
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
vi.clearAllMocks();
|
|
20
|
+
vi.mocked(accessProfileMock).mockResolvedValue({
|
|
21
|
+
accessToken: "meli-token"
|
|
22
|
+
});
|
|
23
|
+
vi.mocked(createClientMock).mockReturnValue({
|
|
24
|
+
get: getPaymentMock
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
it("encodes the payment id in the request path", async () => {
|
|
28
|
+
vi.mocked(getPaymentMock).mockResolvedValueOnce({ data: { id: "ok" } });
|
|
29
|
+
const result = await getMercadoLibrePaymentDetails("meli-profile-1", "pay/ment id?=1");
|
|
30
|
+
expect(accessProfileMock).toHaveBeenCalledWith("meli-profile-1");
|
|
31
|
+
expect(createClientMock).toHaveBeenCalledWith("meli-token", "https://api.mercadopago.com");
|
|
32
|
+
expect(getPaymentMock).toHaveBeenCalledWith("/v1/payments/pay%2Fment%20id%3F%3D1");
|
|
33
|
+
expect(result).toEqual({ id: "ok" });
|
|
34
|
+
});
|
|
35
|
+
it("propagates upstream failures", async () => {
|
|
36
|
+
const upstreamError = new Error("Request failed with status code 401");
|
|
37
|
+
vi.mocked(getPaymentMock).mockRejectedValueOnce(upstreamError);
|
|
38
|
+
await expect(
|
|
39
|
+
getMercadoLibrePaymentDetails("meli-profile-1", "28382111111")
|
|
40
|
+
).rejects.toBe(upstreamError);
|
|
41
|
+
});
|
|
42
|
+
it("chunks payment batches in groups of 50", async () => {
|
|
43
|
+
vi.mocked(getPaymentMock).mockImplementation(async (path) => ({
|
|
44
|
+
data: { id: path.split("/").pop() }
|
|
45
|
+
}));
|
|
46
|
+
const paymentIds = Array.from({ length: 101 }, (_, index) => `pay-${index + 1}`);
|
|
47
|
+
const originalAllSettled = Promise.allSettled.bind(Promise);
|
|
48
|
+
const allSettledSpy = vi.spyOn(Promise, "allSettled").mockImplementation(((iterable) => originalAllSettled(iterable)));
|
|
49
|
+
const result = await getMercadoLibrePaymentDetailsBatch("meli-profile-1", paymentIds);
|
|
50
|
+
expect(accessProfileMock).toHaveBeenCalledWith("meli-profile-1");
|
|
51
|
+
expect(allSettledSpy).toHaveBeenCalledTimes(3);
|
|
52
|
+
expect(allSettledSpy.mock.calls[0]?.[0]).toHaveLength(50);
|
|
53
|
+
expect(allSettledSpy.mock.calls[1]?.[0]).toHaveLength(50);
|
|
54
|
+
expect(allSettledSpy.mock.calls[2]?.[0]).toHaveLength(1);
|
|
55
|
+
expect(result.successful).toHaveLength(101);
|
|
56
|
+
expect(result.failed).toHaveLength(0);
|
|
57
|
+
expect(result.successful[0]).toEqual({ paymentId: "pay-1", payment: { id: "pay-1" } });
|
|
58
|
+
expect(result.successful[100]).toEqual({ paymentId: "pay-101", payment: { id: "pay-101" } });
|
|
59
|
+
allSettledSpy.mockRestore();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=mercadolibre-payments.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../tests/meli/mercadolibre-payments.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { beforeEach, describe, expect, it, vi } from \"vitest\";\n\nconst { accessProfileMock, createClientMock, getPaymentMock } = vi.hoisted(() => ({\n accessProfileMock: vi.fn(),\n createClientMock: vi.fn(),\n getPaymentMock: vi.fn(),\n}));\n\nvi.mock(\"../../src/config/mercadolibre.js\", () => ({\n getMercadoLibreAccessForProfile: accessProfileMock,\n}));\n\nvi.mock(\"../../src/services/mercadolibre/mercadolibre-api.js\", () => ({\n createMercadoLibreClient: createClientMock,\n}));\n\nimport {\n getMercadoLibrePaymentDetails,\n getMercadoLibrePaymentDetailsBatch,\n} from \"../../src/services/mercadolibre/mercadolibre-payments.js\";\n\ndescribe(\"getMercadoLibrePaymentDetails\", () => {\n beforeEach(() => {\n vi.clearAllMocks();\n\n vi.mocked(accessProfileMock).mockResolvedValue({\n accessToken: \"meli-token\",\n });\n\n vi.mocked(createClientMock).mockReturnValue({\n get: getPaymentMock,\n } as never);\n });\n\n it(\"encodes the payment id in the request path\", async () => {\n vi.mocked(getPaymentMock).mockResolvedValueOnce({ data: { id: \"ok\" } });\n\n const result = await getMercadoLibrePaymentDetails(\"meli-profile-1\", \"pay/ment id?=1\");\n\n expect(accessProfileMock).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(createClientMock).toHaveBeenCalledWith(\"meli-token\", \"https://api.mercadopago.com\");\n expect(getPaymentMock).toHaveBeenCalledWith(\"/v1/payments/pay%2Fment%20id%3F%3D1\");\n expect(result).toEqual({ id: \"ok\" });\n });\n\n it(\"propagates upstream failures\", async () => {\n const upstreamError = new Error(\"Request failed with status code 401\");\n vi.mocked(getPaymentMock).mockRejectedValueOnce(upstreamError);\n\n await expect(\n getMercadoLibrePaymentDetails(\"meli-profile-1\", \"28382111111\")\n ).rejects.toBe(upstreamError);\n });\n\n it(\"chunks payment batches in groups of 50\", async () => {\n vi.mocked(getPaymentMock).mockImplementation(async (path: string) => ({\n data: { id: path.split(\"/\").pop() },\n }));\n\n const paymentIds = Array.from({ length: 101 }, (_, index) => `pay-${index + 1}`);\n const originalAllSettled = Promise.allSettled.bind(Promise);\n const allSettledSpy = vi\n .spyOn(Promise, \"allSettled\")\n .mockImplementation(((iterable: Iterable<PromiseLike<unknown> | unknown>) =>\n originalAllSettled(iterable)) as typeof Promise.allSettled);\n\n const result = await getMercadoLibrePaymentDetailsBatch(\"meli-profile-1\", paymentIds);\n\n expect(accessProfileMock).toHaveBeenCalledWith(\"meli-profile-1\");\n expect(allSettledSpy).toHaveBeenCalledTimes(3);\n expect(allSettledSpy.mock.calls[0]?.[0]).toHaveLength(50);\n expect(allSettledSpy.mock.calls[1]?.[0]).toHaveLength(50);\n expect(allSettledSpy.mock.calls[2]?.[0]).toHaveLength(1);\n expect(result.successful).toHaveLength(101);\n expect(result.failed).toHaveLength(0);\n expect(result.successful[0]).toEqual({ paymentId: \"pay-1\", payment: { id: \"pay-1\" } });\n expect(result.successful[100]).toEqual({ paymentId: \"pay-101\", payment: { id: \"pay-101\" } });\n\n allSettledSpy.mockRestore();\n });\n});\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY,UAAU,QAAQ,IAAI,UAAU;AAErD,MAAM,EAAE,mBAAmB,kBAAkB,eAAe,IAAI,GAAG,QAAQ,OAAO;AAAA,EAChF,mBAAmB,GAAG,GAAG;AAAA,EACzB,kBAAkB,GAAG,GAAG;AAAA,EACxB,gBAAgB,GAAG,GAAG;AACxB,EAAE;AAEF,GAAG,KAAK,oCAAoC,OAAO;AAAA,EACjD,iCAAiC;AACnC,EAAE;AAEF,GAAG,KAAK,uDAAuD,OAAO;AAAA,EACpE,0BAA0B;AAC5B,EAAE;AAEF;AAAA,EACE;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iCAAiC,MAAM;AAC9C,aAAW,MAAM;AACf,OAAG,cAAc;AAEjB,OAAG,OAAO,iBAAiB,EAAE,kBAAkB;AAAA,MAC7C,aAAa;AAAA,IACf,CAAC;AAED,OAAG,OAAO,gBAAgB,EAAE,gBAAgB;AAAA,MAC1C,KAAK;AAAA,IACP,CAAU;AAAA,EACZ,CAAC;AAED,KAAG,8CAA8C,YAAY;AAC3D,OAAG,OAAO,cAAc,EAAE,sBAAsB,EAAE,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;AAEtE,UAAM,SAAS,MAAM,8BAA8B,kBAAkB,gBAAgB;AAErF,WAAO,iBAAiB,EAAE,qBAAqB,gBAAgB;AAC/D,WAAO,gBAAgB,EAAE,qBAAqB,cAAc,6BAA6B;AACzF,WAAO,cAAc,EAAE,qBAAqB,qCAAqC;AACjF,WAAO,MAAM,EAAE,QAAQ,EAAE,IAAI,KAAK,CAAC;AAAA,EACrC,CAAC;AAED,KAAG,gCAAgC,YAAY;AAC7C,UAAM,gBAAgB,IAAI,MAAM,qCAAqC;AACrE,OAAG,OAAO,cAAc,EAAE,sBAAsB,aAAa;AAE7D,UAAM;AAAA,MACJ,8BAA8B,kBAAkB,aAAa;AAAA,IAC/D,EAAE,QAAQ,KAAK,aAAa;AAAA,EAC9B,CAAC;AAED,KAAG,0CAA0C,YAAY;AACvD,OAAG,OAAO,cAAc,EAAE,mBAAmB,OAAO,UAAkB;AAAA,MACpE,MAAM,EAAE,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,EAAE;AAAA,IACpC,EAAE;AAEF,UAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,CAAC,GAAG,UAAU,OAAO,QAAQ,CAAC,EAAE;AAC/E,UAAM,qBAAqB,QAAQ,WAAW,KAAK,OAAO;AAC1D,UAAM,gBAAgB,GACnB,MAAM,SAAS,YAAY,EAC3B,oBAAoB,CAAC,aACpB,mBAAmB,QAAQ,EAA+B;AAE9D,UAAM,SAAS,MAAM,mCAAmC,kBAAkB,UAAU;AAEpF,WAAO,iBAAiB,EAAE,qBAAqB,gBAAgB;AAC/D,WAAO,aAAa,EAAE,sBAAsB,CAAC;AAC7C,WAAO,cAAc,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE;AACxD,WAAO,cAAc,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE;AACxD,WAAO,cAAc,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC;AACvD,WAAO,OAAO,UAAU,EAAE,aAAa,GAAG;AAC1C,WAAO,OAAO,MAAM,EAAE,aAAa,CAAC;AACpC,WAAO,OAAO,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,WAAW,SAAS,SAAS,EAAE,IAAI,QAAQ,EAAE,CAAC;AACrF,WAAO,OAAO,WAAW,GAAG,CAAC,EAAE,QAAQ,EAAE,WAAW,WAAW,SAAS,EAAE,IAAI,UAAU,EAAE,CAAC;AAE3F,kBAAc,YAAY;AAAA,EAC5B,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|