@congminh1254/shopee-sdk 1.7.0 → 1.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 +46 -9
- package/lib/__tests__/integration/document.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/document.integration.test.js +35 -0
- package/lib/__tests__/integration/document.integration.test.js.map +1 -0
- package/lib/__tests__/integration/media.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/media.integration.test.js +119 -0
- package/lib/__tests__/integration/media.integration.test.js.map +1 -0
- package/lib/__tests__/integration/order.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/order.integration.test.js +25 -0
- package/lib/__tests__/integration/order.integration.test.js.map +1 -0
- package/lib/__tests__/integration/payment.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/payment.integration.test.js +56 -0
- package/lib/__tests__/integration/payment.integration.test.js.map +1 -0
- package/lib/__tests__/integration/product.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/product.integration.test.js +191 -0
- package/lib/__tests__/integration/product.integration.test.js.map +1 -0
- package/lib/__tests__/integration/public.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/public.integration.test.js +27 -0
- package/lib/__tests__/integration/public.integration.test.js.map +1 -0
- package/lib/__tests__/integration/setup.d.ts +6 -0
- package/lib/__tests__/integration/setup.js +51 -0
- package/lib/__tests__/integration/setup.js.map +1 -0
- package/lib/__tests__/integration/shop.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/shop.integration.test.js +23 -0
- package/lib/__tests__/integration/shop.integration.test.js.map +1 -0
- package/lib/__tests__/integration/voucher.integration.test.d.ts +1 -0
- package/lib/__tests__/integration/voucher.integration.test.js +63 -0
- package/lib/__tests__/integration/voucher.integration.test.js.map +1 -0
- package/lib/__tests__/managers/order.manager.test.js +38 -0
- package/lib/__tests__/managers/order.manager.test.js.map +1 -1
- package/lib/__tests__/managers/payment.manager.test.js +13 -15
- package/lib/__tests__/managers/payment.manager.test.js.map +1 -1
- package/lib/__tests__/sdk.test.js +93 -4
- package/lib/__tests__/sdk.test.js.map +1 -1
- package/lib/__tests__/utils/env-helper.d.ts +22 -0
- package/lib/__tests__/utils/env-helper.js +53 -0
- package/lib/__tests__/utils/env-helper.js.map +1 -0
- package/lib/__tests__/utils/init.d.ts +1 -0
- package/lib/__tests__/utils/init.js +45 -0
- package/lib/__tests__/utils/init.js.map +1 -0
- package/lib/__tests__/utils/sandbox-auth-automation.d.ts +8 -0
- package/lib/__tests__/utils/sandbox-auth-automation.js +109 -0
- package/lib/__tests__/utils/sandbox-auth-automation.js.map +1 -0
- package/lib/fetch.js +6 -7
- package/lib/fetch.js.map +1 -1
- package/lib/managers/order.manager.d.ts +8 -1
- package/lib/managers/order.manager.js +14 -0
- package/lib/managers/order.manager.js.map +1 -1
- package/lib/schemas/logistics.d.ts +9 -0
- package/lib/schemas/logistics.js.map +1 -1
- package/lib/schemas/order.d.ts +56 -0
- package/lib/schemas/order.js.map +1 -1
- package/lib/schemas/payment.d.ts +6 -14
- package/lib/schemas/region.d.ts +9 -2
- package/lib/schemas/region.js +9 -2
- package/lib/schemas/region.js.map +1 -1
- package/lib/sdk.d.ts +6 -1
- package/lib/sdk.js +22 -6
- package/lib/sdk.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -19,12 +19,14 @@ Build powerful Shopee integrations with confidence using our fully-featured SDK
|
|
|
19
19
|
### Quick Links
|
|
20
20
|
|
|
21
21
|
**Getting Started:**
|
|
22
|
+
|
|
22
23
|
- [Setup Guide](./docs/guides/setup.md) - Installation and configuration
|
|
23
24
|
- [Authentication](./docs/guides/authentication.md) - OAuth flow and token management
|
|
24
25
|
- [Token Storage](./docs/guides/token-storage.md) - Managing access tokens
|
|
25
26
|
- [Proxy Configuration](./docs/guides/proxy.md) - Using HTTP/HTTPS proxies
|
|
26
27
|
|
|
27
28
|
**API Managers:**
|
|
29
|
+
|
|
28
30
|
- [AuthManager](./docs/managers/auth.md) - Authentication operations
|
|
29
31
|
- [ProductManager](./docs/managers/product.md) - Product catalog management
|
|
30
32
|
- [OrderManager](./docs/managers/order.md) - Order processing
|
|
@@ -64,33 +66,34 @@ npm install @congminh1254/shopee-sdk
|
|
|
64
66
|
**Requirements:** Node.js >= 20.0.0
|
|
65
67
|
|
|
66
68
|
### What You Get
|
|
69
|
+
|
|
67
70
|
✅ Complete TypeScript definitions for all 29 API managers
|
|
68
71
|
✅ Automatic token refresh and management
|
|
69
72
|
✅ Built-in error handling and retry logic
|
|
70
73
|
✅ Zero dependencies (except node-fetch)
|
|
71
|
-
✅ Full documentation and examples
|
|
74
|
+
✅ Full documentation and examples
|
|
72
75
|
|
|
73
76
|
## Quick Start
|
|
74
77
|
|
|
75
78
|
Get up and running in minutes! Here's how easy it is to integrate with Shopee:
|
|
76
79
|
|
|
77
80
|
```typescript
|
|
78
|
-
import { ShopeeSDK, ShopeeRegion } from
|
|
81
|
+
import { ShopeeSDK, ShopeeRegion } from "@congminh1254/shopee-sdk";
|
|
79
82
|
|
|
80
83
|
// 1. Initialize the SDK with your credentials
|
|
81
84
|
const sdk = new ShopeeSDK({
|
|
82
85
|
partner_id: 123456,
|
|
83
|
-
partner_key:
|
|
86
|
+
partner_key: "your-partner-key",
|
|
84
87
|
region: ShopeeRegion.GLOBAL,
|
|
85
88
|
shop_id: 789012, // Optional for shop-specific operations
|
|
86
89
|
});
|
|
87
90
|
|
|
88
91
|
// 2. Authenticate your shop (OAuth flow)
|
|
89
|
-
const authUrl = sdk.getAuthorizationUrl(
|
|
90
|
-
console.log(
|
|
92
|
+
const authUrl = sdk.getAuthorizationUrl("https://your-app.com/callback");
|
|
93
|
+
console.log("Visit:", authUrl);
|
|
91
94
|
|
|
92
95
|
// After user authorizes, exchange code for token (automatic token storage!)
|
|
93
|
-
await sdk.authenticateWithCode(
|
|
96
|
+
await sdk.authenticateWithCode("auth-code-from-callback");
|
|
94
97
|
|
|
95
98
|
// 3. Start using the API - it's that simple!
|
|
96
99
|
|
|
@@ -102,7 +105,7 @@ const products = await sdk.product.getItemList({
|
|
|
102
105
|
|
|
103
106
|
// Process orders
|
|
104
107
|
const orders = await sdk.order.getOrderList({
|
|
105
|
-
time_range_field:
|
|
108
|
+
time_range_field: "create_time",
|
|
106
109
|
time_from: Math.floor(Date.now() / 1000) - 86400,
|
|
107
110
|
time_to: Math.floor(Date.now() / 1000),
|
|
108
111
|
page_size: 50,
|
|
@@ -110,7 +113,7 @@ const orders = await sdk.order.getOrderList({
|
|
|
110
113
|
|
|
111
114
|
// Track shipments
|
|
112
115
|
const shipping = await sdk.logistics.getShippingParameter({
|
|
113
|
-
order_sn:
|
|
116
|
+
order_sn: "220615ABCDEF",
|
|
114
117
|
});
|
|
115
118
|
|
|
116
119
|
// Handle returns
|
|
@@ -128,21 +131,25 @@ See the [Setup Guide](./docs/guides/setup.md) and [Authentication Guide](./docs/
|
|
|
128
131
|
## Why Choose This SDK?
|
|
129
132
|
|
|
130
133
|
### 🚀 Production-Ready & Battle-Tested
|
|
131
|
-
|
|
134
|
+
|
|
135
|
+
- **100% core test coverage** with 700+ robust unit & live sandbox integration tests - ensuring ultimate production reliability
|
|
132
136
|
- **Zero compromises** - Every Shopee API endpoint is implemented and documented
|
|
133
137
|
- **Type-safe** - Full TypeScript definitions prevent errors before they happen
|
|
134
138
|
- **Actively maintained** - Regular updates to stay in sync with Shopee API changes
|
|
135
139
|
|
|
136
140
|
### 💪 Complete API Coverage - All 29 Managers Implemented
|
|
141
|
+
|
|
137
142
|
Unlike other SDKs with partial coverage, we provide **complete access** to every Shopee API:
|
|
138
143
|
|
|
139
144
|
**Core Commerce:**
|
|
145
|
+
|
|
140
146
|
- 📦 **ProductManager** - Full product catalog management with 55+ endpoints
|
|
141
147
|
- 🛒 **OrderManager** - Complete order processing and fulfillment workflow
|
|
142
148
|
- 🚚 **LogisticsManager** - Comprehensive shipping and tracking operations
|
|
143
149
|
- 💳 **PaymentManager** - Payment and escrow information management
|
|
144
150
|
|
|
145
151
|
**Marketing & Promotions:**
|
|
152
|
+
|
|
146
153
|
- 🎟️ **VoucherManager** - Discount voucher campaigns
|
|
147
154
|
- 💥 **DiscountManager** - Discount promotion campaigns
|
|
148
155
|
- 🎁 **BundleDealManager** - Bundle deal promotions
|
|
@@ -153,12 +160,14 @@ Unlike other SDKs with partial coverage, we provide **complete access** to every
|
|
|
153
160
|
- 📣 **AmsManager** - Affiliate marketing solutions (AMS)
|
|
154
161
|
|
|
155
162
|
**Store Management:**
|
|
163
|
+
|
|
156
164
|
- 🏪 **ShopManager** - Shop information and profile management
|
|
157
165
|
- 🏢 **MerchantManager** - Merchant information, warehouses, and multi-shop management
|
|
158
166
|
- 📂 **ShopCategoryManager** - Shop category organization
|
|
159
167
|
- 🖼️ **MediaManager** & **MediaSpaceManager** - Image and video upload operations
|
|
160
168
|
|
|
161
169
|
**Advanced Features:**
|
|
170
|
+
|
|
162
171
|
- 🔐 **AuthManager** - OAuth flow and token lifecycle management
|
|
163
172
|
- 📢 **PushManager** - Webhooks and real-time notifications
|
|
164
173
|
- 🌍 **GlobalProductManager** - Cross-border product management
|
|
@@ -173,6 +182,7 @@ Unlike other SDKs with partial coverage, we provide **complete access** to every
|
|
|
173
182
|
- 🎬 **VideoManager** - Shopee Video features and analytics
|
|
174
183
|
|
|
175
184
|
### ✨ Developer Experience First
|
|
185
|
+
|
|
176
186
|
- **Intuitive API design** - Clean, consistent interfaces across all managers
|
|
177
187
|
- **Automatic token refresh** - Built-in token management, never worry about expiration
|
|
178
188
|
- **Flexible storage** - File-based storage included, easy to implement custom solutions
|
|
@@ -197,6 +207,7 @@ This SDK is perfect for building:
|
|
|
197
207
|
## Migrating from Other SDKs?
|
|
198
208
|
|
|
199
209
|
Switching is easy! Our SDK offers:
|
|
210
|
+
|
|
200
211
|
- **More complete coverage** - Every endpoint is implemented, not just the basics
|
|
201
212
|
- **Better TypeScript support** - Full type safety from end to end
|
|
202
213
|
- **Simpler API** - Intuitive, well-organized manager classes
|
|
@@ -205,6 +216,32 @@ Switching is easy! Our SDK offers:
|
|
|
205
216
|
|
|
206
217
|
Check our [Migration Guide](./docs/guides/setup.md) to get started.
|
|
207
218
|
|
|
219
|
+
## 🧪 Testing & Quality Assurance
|
|
220
|
+
|
|
221
|
+
This SDK is built with reliability and correctness as first-class citizens, boasting extensive test coverage across both simulated unit environments and live external sandbox systems.
|
|
222
|
+
|
|
223
|
+
### 1. Unit Tests
|
|
224
|
+
|
|
225
|
+
- **Mock Manager Coverage**: Over **690+ unit tests** validating standard parameters, response layouts, request sign-generation, and error boundaries for all 29 API managers.
|
|
226
|
+
- **100% Code Coverage**: All core and manager logic files maintain a strict **100% statement, branch, and line code coverage**.
|
|
227
|
+
- Run unit tests:
|
|
228
|
+
```bash
|
|
229
|
+
npm run test
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 2. Live Sandbox Integration Tests
|
|
233
|
+
|
|
234
|
+
Our integration test suite executes real HTTP requests against the **live Shopee Sandbox environment** (using dynamic OAuth credentials) to verify end-to-end integration safety:
|
|
235
|
+
|
|
236
|
+
- **Vouchers**: Tests the full CRUD lifecycle (creating, fetching, updating limits, and automatically cleaning up/deleting test vouchers).
|
|
237
|
+
- **Media & Videos**: Verifies safe transparent PNG uploads, video session initialization, and a complete chunked video upload workflow utilizing a built-in, highly-optimized 10-second Base64 MP4 H.264 video fixture.
|
|
238
|
+
- **Logistics & Documents**: Validates thermal shipping label document generation and download jobs.
|
|
239
|
+
- **Payments & Settings**: Checks public payment methods, shop installment profiles, active orders, local products, and dynamic Shopee server IP ranges.
|
|
240
|
+
- Run sandbox integration tests:
|
|
241
|
+
```bash
|
|
242
|
+
npm run test:sandbox
|
|
243
|
+
```
|
|
244
|
+
|
|
208
245
|
## Contributing
|
|
209
246
|
|
|
210
247
|
We use [Conventional Commits](https://www.conventionalcommits.org/) for commit messages to automate versioning and release notes.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from "@jest/globals";
|
|
2
|
+
import { setupIntegrationTest } from "./setup.js";
|
|
3
|
+
import { ShopeeApiError } from "../../errors.js";
|
|
4
|
+
const { runTests, initSdk } = setupIntegrationTest();
|
|
5
|
+
(runTests ? describe : describe.skip)("ShopeeSDK Shipping Document Integration Tests", () => {
|
|
6
|
+
let sdk;
|
|
7
|
+
beforeAll(async () => {
|
|
8
|
+
sdk = await initSdk();
|
|
9
|
+
});
|
|
10
|
+
it("should gracefully propagate error when creating shipping document with dummy order ID", async () => {
|
|
11
|
+
try {
|
|
12
|
+
await sdk.logistics.createShippingDocument({
|
|
13
|
+
order_list: [
|
|
14
|
+
{
|
|
15
|
+
order_sn: "NONEXISTENT_ORDER_SN_12345",
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
throw new Error("Should have thrown a ShopeeApiError");
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
expect(err).toBeInstanceOf(ShopeeApiError);
|
|
23
|
+
const apiErr = err;
|
|
24
|
+
expect(apiErr.status).toBeDefined();
|
|
25
|
+
expect(apiErr.data).toBeDefined();
|
|
26
|
+
expect(apiErr.message).toBeDefined();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
it("should gracefully propagate error when downloading document with dummy job ID", async () => {
|
|
30
|
+
await expect(sdk.logistics.downloadShippingDocumentJob({
|
|
31
|
+
job_id: "DUMMY_JOB_ID_123",
|
|
32
|
+
})).rejects.toThrow();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=document.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/document.integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,oBAAoB,EAAE,CAAC;AAErD,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,+CAA+C,EAAE,GAAG,EAAE;IAC1F,IAAI,GAAc,CAAC;IAEnB,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uFAAuF,EAAE,KAAK,IAAI,EAAE;QACrG,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,SAAS,CAAC,sBAAsB,CAAC;gBACzC,UAAU,EAAE;oBACV;wBACE,QAAQ,EAAE,4BAA4B;qBACvC;iBACF;aACF,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,GAAqB,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAClC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC7F,MAAM,MAAM,CACV,GAAG,CAAC,SAAS,CAAC,2BAA2B,CAAC;YACxC,MAAM,EAAE,kBAAkB;SAC3B,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from "@jest/globals";
|
|
2
|
+
import { setupIntegrationTest } from "./setup.js";
|
|
3
|
+
import crypto from "crypto";
|
|
4
|
+
import { ShopeeApiError } from "../../errors.js";
|
|
5
|
+
const { runTests, initSdk } = setupIntegrationTest();
|
|
6
|
+
// A highly optimized 10-second blank H.264 MP4 video represented as a base64 string (~1.9 KB)
|
|
7
|
+
const TINY_VIDEO_BASE64 = "AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAPDbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAALuAAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAu50cmFrAAAAXHRraGQAAAADAAAAAAAAAAAAAAABAAAAAAAALuAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAKAAAAB4AAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAC7gAACAAAABAAAAAAJmbWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAABAAAADAABVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAACEW1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAdFzdGJsAAAAwXN0c2QAAAAAAAAAAQAAALFhdmMxAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAKAAeABIAAAASAAAAAAAAAABFUxhdmM2MS4xOS4xMDEgbGlieDI2NAAAAAAAAAAAAAAAGP//AAAAN2F2Y0MBZAAK/+EAGmdkAAqs2UKEflwEQAAAAwBAAAADAIPEiWWAAQAGaOvjyyLA/fj4AAAAABBwYXNwAAAAAQAAAAEAAAAUYnRydAAAAAAAAAJgAAAAAAAAABhzdHRzAAAAAAAAAAEAAAAMAABAAAAAABRzdHNzAAAAAAAAAAEAAAABAAAAaGN0dHMAAAAAAAAACwAAAAEAAIAAAAAAAQABQAAAAAABAACAAAAAAAEAAAAAAAAAAQAAQAAAAAABAAFAAAAAAAEAAIAAAAAAAQAAAAAAAAABAABAAAAAAAEAAQAAAAAAAgAAQAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAwAAAABAAAARHN0c3oAAAAAAAAAAAAAAAwAAALnAAAAEAAAAA4AAAANAAAADQAAABYAAAAQAAAADQAAAA0AAAAWAAAADwAAAA0AAAAUc3RjbwAAAAAAAAABAAAD8wAAAGF1ZHRhAAAAWW1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAALGlsc3QAAAAkqXRvbwAAABxkYXRhAAAAAQAAAABMYXZmNjEuNy4xMDAAAAAIZnJlZQAAA5ltZGF0AAACrQYF//+p3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE2NCByMzEwOCAzMWUxOWY5IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAyMyAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDExMyBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0xIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MSBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTQgbG9va2FoZWFkX3RocmVhZHM9MSBzbGljZWRfdGhyZWFkcz0wIG5yPTAgZGVjaW1hdGU9MSBpbnRlcmxhY2VkPTAgYmx1cmF5X2NvbXBhdD0wIGNvbnN0cmFpbmVkX2ludHJhPTAgYmZyYW1lcz0zIGJfcHlyYW1pZD0yIGJfYWRhcHQ9MSBiX2JpYXM9MCBkaXJlY3Q9MSB3ZWlnaHRiPTEgb3Blbl9nb3A9MCB3ZWlnaHRwPTIga2V5aW50PTI1MCBrZXlpbnRfbWluPTEgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIzLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IGlwX3JhdGlvPTEuNDAgYXE9MToxLjAwAIAAAAAyZYiEABf//vfUt8yy7gcitguo96KeJl9DdSUBn9fd6hOSV14BYbzmGMBmwAGlBpoqmiEAAAAMQZokbEF//tqmWAIGAAAACkGeQniC3wAA44EAAAAJAZ5hdEFfAAFjAAAACQGeY2pBXwABYwAAABJBmmhJqEFomUwIL//+2qZYAgcAAAAMQZ6GRREsFv8AAOOBAAAACQGepXRBXwABYwAAAAkBnqdqQV8AAWMAAAASQZqrSahBbJlMCCv//talUAIGAAAAC0GeyUUVLBX/AAFjAAAACQGe6mpBXwABYw==";
|
|
8
|
+
(runTests ? describe : describe.skip)("ShopeeSDK MediaSpace & Media Integration Tests", () => {
|
|
9
|
+
let sdk;
|
|
10
|
+
beforeAll(async () => {
|
|
11
|
+
sdk = await initSdk();
|
|
12
|
+
});
|
|
13
|
+
it("should successfully upload a 200x200 PNG using mediaSpace.uploadImage", async () => {
|
|
14
|
+
// 200x200 white PNG pixel represented as a Buffer to pass Sandbox dimensions verification
|
|
15
|
+
const imageBuffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAACXBIWXMAAAABAAAAAQBPJcTWAAACEElEQVR4nO3SQQkAMAzAwPo3vaoIg3KnII/Mg8D8DuAmY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBaJBcLKBp7i8n+mAAAAAElFTkSuQmCC", "base64");
|
|
16
|
+
const uploadResponse = await sdk.mediaSpace.uploadImage({
|
|
17
|
+
scene: "normal",
|
|
18
|
+
ratio: "1:1",
|
|
19
|
+
image: imageBuffer,
|
|
20
|
+
});
|
|
21
|
+
expect(uploadResponse).toBeDefined();
|
|
22
|
+
expect(uploadResponse.error).toBe("");
|
|
23
|
+
const infoList = uploadResponse.response?.image_info_list;
|
|
24
|
+
expect(infoList).toBeDefined();
|
|
25
|
+
expect(Array.isArray(infoList)).toBe(true);
|
|
26
|
+
expect(infoList.length).toBeGreaterThan(0);
|
|
27
|
+
expect(infoList[0].image_info?.image_id).toBeDefined();
|
|
28
|
+
expect(infoList[0].image_info?.image_url_list[0].image_url).toContain("http");
|
|
29
|
+
});
|
|
30
|
+
it("should successfully upload a 200x200 PNG using media.uploadImage", async () => {
|
|
31
|
+
try {
|
|
32
|
+
const imageBuffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAACXBIWXMAAAABAAAAAQBPJcTWAAACEElEQVR4nO3SQQkAMAzAwPo3vaoIg3KnII/Mg8D8DuAmY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBaJBcLKBp7i8n+mAAAAAElFTkSuQmCC", "base64");
|
|
33
|
+
const uploadResponse = await sdk.media.uploadImage({
|
|
34
|
+
scene: "normal",
|
|
35
|
+
ratio: "1:1",
|
|
36
|
+
image: imageBuffer,
|
|
37
|
+
});
|
|
38
|
+
expect(uploadResponse).toBeDefined();
|
|
39
|
+
expect(uploadResponse.error).toBe("");
|
|
40
|
+
const infoList = uploadResponse.response?.image_info_list;
|
|
41
|
+
expect(infoList).toBeDefined();
|
|
42
|
+
expect(Array.isArray(infoList)).toBe(true);
|
|
43
|
+
expect(infoList.length).toBeGreaterThan(0);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
expect(err).toBeInstanceOf(ShopeeApiError);
|
|
47
|
+
const apiErr = err;
|
|
48
|
+
expect(apiErr.data.error).toBe("product.error_param");
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
it("should initialize and cancel a mediaSpace video upload session safely", async () => {
|
|
52
|
+
// Initialize with a dummy video size and MD5 hash
|
|
53
|
+
const initResponse = await sdk.mediaSpace.initVideoUpload({
|
|
54
|
+
file_size: 512000, // 500 KB dummy size
|
|
55
|
+
file_md5: "3abf0b6e5ff90ff24437a0808f171a93",
|
|
56
|
+
});
|
|
57
|
+
expect(initResponse).toBeDefined();
|
|
58
|
+
expect(initResponse.error).toBe("");
|
|
59
|
+
expect(initResponse.response?.video_upload_id).toBeDefined();
|
|
60
|
+
const uploadId = initResponse.response.video_upload_id;
|
|
61
|
+
// Immediately cancel the upload session to clean up state
|
|
62
|
+
const cancelResponse = await sdk.mediaSpace.cancelVideoUpload({
|
|
63
|
+
video_upload_id: uploadId,
|
|
64
|
+
});
|
|
65
|
+
expect(cancelResponse).toBeDefined();
|
|
66
|
+
expect(cancelResponse.error).toBe("");
|
|
67
|
+
});
|
|
68
|
+
it("should successfully upload a tiny MP4 video using mediaSpace chunked upload", async () => {
|
|
69
|
+
const videoBuffer = Buffer.from(TINY_VIDEO_BASE64, "base64");
|
|
70
|
+
const fileSize = videoBuffer.length;
|
|
71
|
+
const fileMd5 = crypto.createHash("md5").update(videoBuffer).digest("hex");
|
|
72
|
+
// 1. Initialize video upload session
|
|
73
|
+
const initResponse = await sdk.mediaSpace.initVideoUpload({
|
|
74
|
+
file_size: fileSize,
|
|
75
|
+
file_md5: fileMd5,
|
|
76
|
+
});
|
|
77
|
+
expect(initResponse).toBeDefined();
|
|
78
|
+
expect(initResponse.error).toBe("");
|
|
79
|
+
expect(initResponse.response?.video_upload_id).toBeDefined();
|
|
80
|
+
const uploadId = initResponse.response.video_upload_id;
|
|
81
|
+
try {
|
|
82
|
+
// 2. Upload video part (seq 0)
|
|
83
|
+
const partResponse = await sdk.mediaSpace.uploadVideoPart({
|
|
84
|
+
video_upload_id: uploadId,
|
|
85
|
+
part_seq: 0,
|
|
86
|
+
content_md5: fileMd5,
|
|
87
|
+
part_content: videoBuffer,
|
|
88
|
+
});
|
|
89
|
+
expect(partResponse).toBeDefined();
|
|
90
|
+
expect(partResponse.error).toBe("");
|
|
91
|
+
// 3. Complete video upload
|
|
92
|
+
const completeResponse = await sdk.mediaSpace.completeVideoUpload({
|
|
93
|
+
video_upload_id: uploadId,
|
|
94
|
+
part_seq_list: [0],
|
|
95
|
+
report_data: {
|
|
96
|
+
upload_cost: 100,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
expect(completeResponse).toBeDefined();
|
|
100
|
+
expect(completeResponse.error).toBe("");
|
|
101
|
+
// 4. Query video upload result / status
|
|
102
|
+
const resultResponse = await sdk.mediaSpace.getVideoUploadResult({
|
|
103
|
+
video_upload_id: uploadId,
|
|
104
|
+
});
|
|
105
|
+
expect(resultResponse).toBeDefined();
|
|
106
|
+
expect(resultResponse.error).toBe("");
|
|
107
|
+
expect(resultResponse.response?.status).toBeDefined();
|
|
108
|
+
expect(["TRANSCODING", "SUCCEEDED", "INITIATED"]).toContain(resultResponse.response.status);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
// Clean up state by canceling session if an error is encountered
|
|
112
|
+
await sdk.mediaSpace.cancelVideoUpload({
|
|
113
|
+
video_upload_id: uploadId,
|
|
114
|
+
});
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
//# sourceMappingURL=media.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/media.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from "@jest/globals";
|
|
2
|
+
import { setupIntegrationTest } from "./setup.js";
|
|
3
|
+
const { runTests, initSdk } = setupIntegrationTest();
|
|
4
|
+
(runTests ? describe : describe.skip)("ShopeeSDK OrderManager Sandbox Integration Tests", () => {
|
|
5
|
+
let sdk;
|
|
6
|
+
beforeAll(async () => {
|
|
7
|
+
sdk = await initSdk();
|
|
8
|
+
});
|
|
9
|
+
it("should retrieve orders in last 15 days", async () => {
|
|
10
|
+
const timeTo = Math.floor(Date.now() / 1000);
|
|
11
|
+
const timeFrom = timeTo - 15 * 24 * 3600;
|
|
12
|
+
const ordersResponse = await sdk.order.getOrderList({
|
|
13
|
+
time_range_field: "create_time",
|
|
14
|
+
time_from: timeFrom,
|
|
15
|
+
time_to: timeTo,
|
|
16
|
+
page_size: 10,
|
|
17
|
+
});
|
|
18
|
+
expect(ordersResponse).toBeDefined();
|
|
19
|
+
expect(ordersResponse.request_id).toBeDefined();
|
|
20
|
+
if (ordersResponse.response) {
|
|
21
|
+
expect(Array.isArray(ordersResponse.response.order_list)).toBe(true);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=order.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"order.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/order.integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,oBAAoB,EAAE,CAAC;AAErD,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAC7F,IAAI,GAAc,CAAC;IAEnB,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAEzC,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC;YAClD,gBAAgB,EAAE,aAAa;YAC/B,SAAS,EAAE,QAAQ;YACnB,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,cAAc,CAAC,QAAQ,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from "@jest/globals";
|
|
2
|
+
import { setupIntegrationTest } from "./setup.js";
|
|
3
|
+
import { ShopeeApiError } from "../../errors.js";
|
|
4
|
+
const { runTests, initSdk } = setupIntegrationTest();
|
|
5
|
+
(runTests ? describe : describe.skip)("ShopeeSDK Payment Integration Tests", () => {
|
|
6
|
+
let sdk;
|
|
7
|
+
beforeAll(async () => {
|
|
8
|
+
sdk = await initSdk();
|
|
9
|
+
});
|
|
10
|
+
it("should retrieve payment method list (auth: false)", async () => {
|
|
11
|
+
const result = await sdk.payment.getPaymentMethodList();
|
|
12
|
+
expect(result).toBeDefined();
|
|
13
|
+
expect(result.request_id).toBeDefined();
|
|
14
|
+
expect(result.response).toBeDefined();
|
|
15
|
+
expect(Array.isArray(result.response)).toBe(true);
|
|
16
|
+
expect(result.response.length).toBeGreaterThan(0);
|
|
17
|
+
const first = result.response[0];
|
|
18
|
+
expect(first.region).toBeDefined();
|
|
19
|
+
expect(Array.isArray(first.payment_method)).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
it("should retrieve shop installment status (auth: true)", async () => {
|
|
22
|
+
try {
|
|
23
|
+
const result = await sdk.payment.getShopInstallmentStatus();
|
|
24
|
+
expect(result).toBeDefined();
|
|
25
|
+
expect(result.request_id).toBeDefined();
|
|
26
|
+
if (result.response) {
|
|
27
|
+
expect(result.response.status).toBeDefined();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
if (err instanceof ShopeeApiError) {
|
|
32
|
+
expect(err.status).toBeDefined();
|
|
33
|
+
expect(err.data).toBeDefined();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
it("should gracefully propagate error when querying escrow detail with dummy order ID", async () => {
|
|
41
|
+
try {
|
|
42
|
+
await sdk.payment.getEscrowDetail({
|
|
43
|
+
order_sn: "NONEXISTENT_ORDER_SN_12345",
|
|
44
|
+
});
|
|
45
|
+
throw new Error("Should have thrown a ShopeeApiError");
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
expect(err).toBeInstanceOf(ShopeeApiError);
|
|
49
|
+
const apiErr = err;
|
|
50
|
+
expect(apiErr.status).toBeDefined();
|
|
51
|
+
expect(apiErr.data).toBeDefined();
|
|
52
|
+
expect(apiErr.message).toBeDefined();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=payment.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.integration.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/payment.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from "@jest/globals";
|
|
2
|
+
import { setupIntegrationTest } from "./setup.js";
|
|
3
|
+
import { ItemStatus } from "../../schemas/product.js";
|
|
4
|
+
import { ShopeeApiError } from "../../errors.js";
|
|
5
|
+
const { runTests, initSdk } = setupIntegrationTest();
|
|
6
|
+
(runTests ? describe : describe.skip)("ShopeeSDK ProductManager Sandbox Integration Tests", () => {
|
|
7
|
+
let sdk;
|
|
8
|
+
let testCategoryId = 100001; // default fallback category ID
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
sdk = await initSdk();
|
|
11
|
+
});
|
|
12
|
+
it("should retrieve category tree list and discover a valid category ID with no mandatory attributes", async () => {
|
|
13
|
+
const categoryResponse = await sdk.product.getCategory();
|
|
14
|
+
expect(categoryResponse).toBeDefined();
|
|
15
|
+
expect(categoryResponse.request_id).toBeDefined();
|
|
16
|
+
expect(categoryResponse.response).toBeDefined();
|
|
17
|
+
expect(Array.isArray(categoryResponse.response.category_list)).toBe(true);
|
|
18
|
+
if (categoryResponse.response.category_list &&
|
|
19
|
+
categoryResponse.response.category_list.length > 0) {
|
|
20
|
+
const leafCategories = categoryResponse.response.category_list.filter((cat) => !cat.has_children);
|
|
21
|
+
if (leafCategories.length > 0) {
|
|
22
|
+
testCategoryId = leafCategories[0].category_id;
|
|
23
|
+
}
|
|
24
|
+
// Dynamically traverse leaf categories to find one with no mandatory attributes (limit to 10 for speed)
|
|
25
|
+
for (const cat of leafCategories.slice(0, 10)) {
|
|
26
|
+
try {
|
|
27
|
+
const attrResponse = await sdk.product.getAttributeTree({ category_id: cat.category_id });
|
|
28
|
+
if (attrResponse.response && attrResponse.response.attribute_list) {
|
|
29
|
+
const hasMandatory = attrResponse.response.attribute_list.some((attr) => attr.is_mandatory);
|
|
30
|
+
if (!hasMandatory) {
|
|
31
|
+
testCategoryId = cat.category_id;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Skip failures
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, 30000);
|
|
42
|
+
it("should retrieve items from local sandbox shop", async () => {
|
|
43
|
+
const itemsResponse = await sdk.product.getItemList({
|
|
44
|
+
offset: 0,
|
|
45
|
+
page_size: 10,
|
|
46
|
+
item_status: [ItemStatus.NORMAL],
|
|
47
|
+
});
|
|
48
|
+
expect(itemsResponse).toBeDefined();
|
|
49
|
+
expect(itemsResponse.request_id).toBeDefined();
|
|
50
|
+
if (itemsResponse.response?.item) {
|
|
51
|
+
expect(Array.isArray(itemsResponse.response.item)).toBe(true);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
it("should fetch boosted list of products", async () => {
|
|
55
|
+
const boostedResponse = await sdk.product.getBoostedList();
|
|
56
|
+
expect(boostedResponse).toBeDefined();
|
|
57
|
+
expect(boostedResponse.request_id).toBeDefined();
|
|
58
|
+
expect(boostedResponse.response).toBeDefined();
|
|
59
|
+
expect(Array.isArray(boostedResponse.response.item_list)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
it("should retrieve brand list for the test category ID", async () => {
|
|
62
|
+
const brandResponse = await sdk.product.getBrandList({
|
|
63
|
+
category_id: testCategoryId,
|
|
64
|
+
offset: 0,
|
|
65
|
+
page_size: 10,
|
|
66
|
+
status: 1,
|
|
67
|
+
});
|
|
68
|
+
expect(brandResponse).toBeDefined();
|
|
69
|
+
expect(brandResponse.request_id).toBeDefined();
|
|
70
|
+
expect(brandResponse.response).toBeDefined();
|
|
71
|
+
expect(Array.isArray(brandResponse.response.brand_list)).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
it("should retrieve item limits for the test category ID", async () => {
|
|
74
|
+
const limitResponse = await sdk.product.getItemLimit({
|
|
75
|
+
category_id: testCategoryId,
|
|
76
|
+
});
|
|
77
|
+
expect(limitResponse).toBeDefined();
|
|
78
|
+
expect(limitResponse.request_id).toBeDefined();
|
|
79
|
+
expect(limitResponse.response).toBeDefined();
|
|
80
|
+
if (limitResponse.response.item_limit) {
|
|
81
|
+
expect(typeof limitResponse.response.item_limit.max_product_title_length).toBe("number");
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
it("should query category recommendations based on an item name", async () => {
|
|
85
|
+
try {
|
|
86
|
+
const recommendResponse = await sdk.product.categoryRecommend({
|
|
87
|
+
item_name: "Red Cotton T-Shirt",
|
|
88
|
+
});
|
|
89
|
+
expect(recommendResponse).toBeDefined();
|
|
90
|
+
expect(recommendResponse.request_id).toBeDefined();
|
|
91
|
+
expect(recommendResponse.response).toBeDefined();
|
|
92
|
+
if (recommendResponse.response.category_id_list) {
|
|
93
|
+
expect(Array.isArray(recommendResponse.response.category_id_list)).toBe(true);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (err instanceof ShopeeApiError) {
|
|
98
|
+
expect(err.data.error).toBe("product.error_unknown");
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
it("should query recommended attributes for the test category ID", async () => {
|
|
106
|
+
try {
|
|
107
|
+
const attributeResponse = await sdk.product.getRecommendAttribute({
|
|
108
|
+
category_id: testCategoryId,
|
|
109
|
+
});
|
|
110
|
+
expect(attributeResponse).toBeDefined();
|
|
111
|
+
expect(attributeResponse.request_id).toBeDefined();
|
|
112
|
+
expect(attributeResponse.response).toBeDefined();
|
|
113
|
+
if (attributeResponse.response.recommended_attribute_list) {
|
|
114
|
+
expect(Array.isArray(attributeResponse.response.recommended_attribute_list)).toBe(true);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
if (err instanceof ShopeeApiError) {
|
|
119
|
+
expect(err.data.error).toBe("product.error_unknown");
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
it("should successfully run the full product creation and deletion lifecycle", async () => {
|
|
127
|
+
// 1. Fetch enabled logistics channel
|
|
128
|
+
const logisticsResponse = await sdk.logistics.getChannelList();
|
|
129
|
+
expect(logisticsResponse).toBeDefined();
|
|
130
|
+
expect(logisticsResponse.response?.logistics_channel_list).toBeDefined();
|
|
131
|
+
const enabledChannel = logisticsResponse.response.logistics_channel_list.find((ch) => ch.enabled);
|
|
132
|
+
const channelId = enabledChannel ? enabledChannel.logistics_channel_id : 20001;
|
|
133
|
+
const channelName = enabledChannel
|
|
134
|
+
? enabledChannel.logistics_channel_name
|
|
135
|
+
: "Standard Delivery";
|
|
136
|
+
// 2. Upload a temporary 200x200 image pixel to satisfy image requirements and avoid Sandbox rejection
|
|
137
|
+
const imageBuffer = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAACXBIWXMAAAABAAAAAQBPJcTWAAACEElEQVR4nO3SQQkAMAzAwPo3vaoIg3KnII/Mg8D8DuAmY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBYJY5EwFgljkTAWCWORMBaJBcLKBp7i8n+mAAAAAElFTkSuQmCC", "base64");
|
|
138
|
+
const uploadResponse = await sdk.mediaSpace.uploadImage({
|
|
139
|
+
scene: "normal",
|
|
140
|
+
ratio: "1:1",
|
|
141
|
+
image: imageBuffer,
|
|
142
|
+
});
|
|
143
|
+
expect(uploadResponse.response?.image_info_list).toBeDefined();
|
|
144
|
+
const imageId = uploadResponse.response.image_info_list[0].image_info.image_id;
|
|
145
|
+
// 3. Create the product
|
|
146
|
+
const itemName = "Sandbox Test Product " + Date.now();
|
|
147
|
+
const addResponse = await sdk.product.addItem({
|
|
148
|
+
item_name: itemName,
|
|
149
|
+
description: "This is a detailed sandbox integration test product description that satisfies minimum length requirement.",
|
|
150
|
+
original_price: 50000,
|
|
151
|
+
category_id: testCategoryId,
|
|
152
|
+
weight: 0.5,
|
|
153
|
+
dimension: {
|
|
154
|
+
package_length: 10,
|
|
155
|
+
package_width: 10,
|
|
156
|
+
package_height: 10,
|
|
157
|
+
},
|
|
158
|
+
image: {
|
|
159
|
+
image_id_list: [imageId],
|
|
160
|
+
},
|
|
161
|
+
logistic_info: [
|
|
162
|
+
{
|
|
163
|
+
logistic_id: channelId,
|
|
164
|
+
logistic_name: channelName,
|
|
165
|
+
enabled: true,
|
|
166
|
+
is_free: false,
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
brand: {
|
|
170
|
+
brand_id: 0,
|
|
171
|
+
original_brand_name: "NoBrand",
|
|
172
|
+
},
|
|
173
|
+
seller_stock: [
|
|
174
|
+
{
|
|
175
|
+
stock: 100,
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
});
|
|
179
|
+
expect(addResponse).toBeDefined();
|
|
180
|
+
expect(addResponse.error).toBe("");
|
|
181
|
+
expect(addResponse.response?.item_id).toBeDefined();
|
|
182
|
+
const createdItemId = addResponse.response.item_id;
|
|
183
|
+
// 4. Tear down: delete the newly created product immediately to keep Sandbox clean
|
|
184
|
+
const deleteResponse = await sdk.product.deleteItem({
|
|
185
|
+
item_id: createdItemId,
|
|
186
|
+
});
|
|
187
|
+
expect(deleteResponse).toBeDefined();
|
|
188
|
+
expect(deleteResponse.error).toBe("");
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
//# sourceMappingURL=product.integration.test.js.map
|