@congminh1254/shopee-sdk 1.6.2 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +9 -3
  2. package/lib/__tests__/errors.test.d.ts +1 -0
  3. package/lib/__tests__/errors.test.js +49 -0
  4. package/lib/__tests__/errors.test.js.map +1 -0
  5. package/lib/__tests__/fetch.test.d.ts +1 -0
  6. package/lib/__tests__/fetch.test.js +494 -0
  7. package/lib/__tests__/fetch.test.js.map +1 -0
  8. package/lib/__tests__/integration.test.d.ts +1 -0
  9. package/lib/__tests__/integration.test.js +201 -0
  10. package/lib/__tests__/integration.test.js.map +1 -0
  11. package/lib/__tests__/managers/account-health.manager.test.d.ts +1 -0
  12. package/lib/__tests__/managers/account-health.manager.test.js +446 -0
  13. package/lib/__tests__/managers/account-health.manager.test.js.map +1 -0
  14. package/lib/__tests__/managers/add-on-deal.manager.test.d.ts +1 -0
  15. package/lib/__tests__/managers/add-on-deal.manager.test.js +636 -0
  16. package/lib/__tests__/managers/add-on-deal.manager.test.js.map +1 -0
  17. package/lib/__tests__/managers/ads.manager.test.d.ts +1 -0
  18. package/lib/__tests__/managers/ads.manager.test.js +1016 -0
  19. package/lib/__tests__/managers/ads.manager.test.js.map +1 -0
  20. package/lib/__tests__/managers/ams.manager.test.d.ts +1 -0
  21. package/lib/__tests__/managers/ams.manager.test.js +1170 -0
  22. package/lib/__tests__/managers/ams.manager.test.js.map +1 -0
  23. package/lib/__tests__/managers/auth.manager.test.d.ts +1 -0
  24. package/lib/__tests__/managers/auth.manager.test.js +193 -0
  25. package/lib/__tests__/managers/auth.manager.test.js.map +1 -0
  26. package/lib/__tests__/managers/bundle-deal.manager.test.d.ts +1 -0
  27. package/lib/__tests__/managers/bundle-deal.manager.test.js +465 -0
  28. package/lib/__tests__/managers/bundle-deal.manager.test.js.map +1 -0
  29. package/lib/__tests__/managers/discount.manager.test.d.ts +1 -0
  30. package/lib/__tests__/managers/discount.manager.test.js +615 -0
  31. package/lib/__tests__/managers/discount.manager.test.js.map +1 -0
  32. package/lib/__tests__/managers/fbs.manager.test.d.ts +1 -0
  33. package/lib/__tests__/managers/fbs.manager.test.js +349 -0
  34. package/lib/__tests__/managers/fbs.manager.test.js.map +1 -0
  35. package/lib/__tests__/managers/first-mile.manager.test.d.ts +1 -0
  36. package/lib/__tests__/managers/first-mile.manager.test.js +629 -0
  37. package/lib/__tests__/managers/first-mile.manager.test.js.map +1 -0
  38. package/lib/__tests__/managers/follow-prize.manager.test.d.ts +1 -0
  39. package/lib/__tests__/managers/follow-prize.manager.test.js +408 -0
  40. package/lib/__tests__/managers/follow-prize.manager.test.js.map +1 -0
  41. package/lib/__tests__/managers/global-product.manager.test.d.ts +1 -0
  42. package/lib/__tests__/managers/global-product.manager.test.js +1253 -0
  43. package/lib/__tests__/managers/global-product.manager.test.js.map +1 -0
  44. package/lib/__tests__/managers/livestream.manager.test.d.ts +1 -0
  45. package/lib/__tests__/managers/livestream.manager.test.js +877 -0
  46. package/lib/__tests__/managers/livestream.manager.test.js.map +1 -0
  47. package/lib/__tests__/managers/logistics.manager.test.d.ts +1 -0
  48. package/lib/__tests__/managers/logistics.manager.test.js +1125 -0
  49. package/lib/__tests__/managers/logistics.manager.test.js.map +1 -0
  50. package/lib/__tests__/managers/media-space.manager.test.d.ts +1 -0
  51. package/lib/__tests__/managers/media-space.manager.test.js +556 -0
  52. package/lib/__tests__/managers/media-space.manager.test.js.map +1 -0
  53. package/lib/__tests__/managers/media.manager.test.d.ts +1 -0
  54. package/lib/__tests__/managers/media.manager.test.js +681 -0
  55. package/lib/__tests__/managers/media.manager.test.js.map +1 -0
  56. package/lib/__tests__/managers/merchant.manager.test.d.ts +1 -0
  57. package/lib/__tests__/managers/merchant.manager.test.js +328 -0
  58. package/lib/__tests__/managers/merchant.manager.test.js.map +1 -0
  59. package/lib/__tests__/managers/order.manager.test.d.ts +1 -0
  60. package/lib/__tests__/managers/order.manager.test.js +937 -0
  61. package/lib/__tests__/managers/order.manager.test.js.map +1 -0
  62. package/lib/__tests__/managers/payment.manager.test.d.ts +1 -0
  63. package/lib/__tests__/managers/payment.manager.test.js +1167 -0
  64. package/lib/__tests__/managers/payment.manager.test.js.map +1 -0
  65. package/lib/__tests__/managers/product.manager.test.d.ts +1 -0
  66. package/lib/__tests__/managers/product.manager.test.js +2247 -0
  67. package/lib/__tests__/managers/product.manager.test.js.map +1 -0
  68. package/lib/__tests__/managers/public.manager.test.d.ts +1 -0
  69. package/lib/__tests__/managers/public.manager.test.js +209 -0
  70. package/lib/__tests__/managers/public.manager.test.js.map +1 -0
  71. package/lib/__tests__/managers/push.manager.test.d.ts +1 -0
  72. package/lib/__tests__/managers/push.manager.test.js +244 -0
  73. package/lib/__tests__/managers/push.manager.test.js.map +1 -0
  74. package/lib/__tests__/managers/returns.manager.test.d.ts +1 -0
  75. package/lib/__tests__/managers/returns.manager.test.js +783 -0
  76. package/lib/__tests__/managers/returns.manager.test.js.map +1 -0
  77. package/lib/__tests__/managers/sbs.manager.test.d.ts +1 -0
  78. package/lib/__tests__/managers/sbs.manager.test.js +492 -0
  79. package/lib/__tests__/managers/sbs.manager.test.js.map +1 -0
  80. package/lib/__tests__/managers/shop-category.manager.test.d.ts +1 -0
  81. package/lib/__tests__/managers/shop-category.manager.test.js +425 -0
  82. package/lib/__tests__/managers/shop-category.manager.test.js.map +1 -0
  83. package/lib/__tests__/managers/shop-flash-sale.manager.test.d.ts +1 -0
  84. package/lib/__tests__/managers/shop-flash-sale.manager.test.js +492 -0
  85. package/lib/__tests__/managers/shop-flash-sale.manager.test.js.map +1 -0
  86. package/lib/__tests__/managers/shop.manager.test.d.ts +1 -0
  87. package/lib/__tests__/managers/shop.manager.test.js +637 -0
  88. package/lib/__tests__/managers/shop.manager.test.js.map +1 -0
  89. package/lib/__tests__/managers/top-picks.manager.test.d.ts +1 -0
  90. package/lib/__tests__/managers/top-picks.manager.test.js +324 -0
  91. package/lib/__tests__/managers/top-picks.manager.test.js.map +1 -0
  92. package/lib/__tests__/managers/video.manager.test.d.ts +1 -0
  93. package/lib/__tests__/managers/video.manager.test.js +1039 -0
  94. package/lib/__tests__/managers/video.manager.test.js.map +1 -0
  95. package/lib/__tests__/managers/voucher.manager.test.d.ts +1 -0
  96. package/lib/__tests__/managers/voucher.manager.test.js +442 -0
  97. package/lib/__tests__/managers/voucher.manager.test.js.map +1 -0
  98. package/lib/__tests__/sdk.test.d.ts +1 -0
  99. package/lib/__tests__/sdk.test.js +316 -0
  100. package/lib/__tests__/sdk.test.js.map +1 -0
  101. package/lib/__tests__/storage/custom-token-storage.test.d.ts +1 -0
  102. package/lib/__tests__/storage/custom-token-storage.test.js +337 -0
  103. package/lib/__tests__/storage/custom-token-storage.test.js.map +1 -0
  104. package/lib/__tests__/utils/signature.test.d.ts +1 -0
  105. package/lib/__tests__/utils/signature.test.js +38 -0
  106. package/lib/__tests__/utils/signature.test.js.map +1 -0
  107. package/lib/__tests__/utils/spec-audit.test.d.ts +1 -0
  108. package/lib/__tests__/utils/spec-audit.test.js +176 -0
  109. package/lib/__tests__/utils/spec-audit.test.js.map +1 -0
  110. package/lib/errors.js +2 -0
  111. package/lib/errors.js.map +1 -1
  112. package/lib/fetch.js +1 -1
  113. package/lib/fetch.js.map +1 -1
  114. package/lib/managers/ads.manager.d.ts +1 -41
  115. package/lib/managers/ads.manager.js +0 -54
  116. package/lib/managers/ads.manager.js.map +1 -1
  117. package/lib/managers/auth.manager.d.ts +2 -1
  118. package/lib/managers/auth.manager.js +2 -5
  119. package/lib/managers/auth.manager.js.map +1 -1
  120. package/lib/managers/base.manager.js +1 -0
  121. package/lib/managers/base.manager.js.map +1 -1
  122. package/lib/managers/media.manager.d.ts +36 -1
  123. package/lib/managers/media.manager.js +68 -0
  124. package/lib/managers/media.manager.js.map +1 -1
  125. package/lib/managers/order.manager.js +1 -0
  126. package/lib/managers/order.manager.js.map +1 -1
  127. package/lib/managers/payment.manager.d.ts +13 -1
  128. package/lib/managers/payment.manager.js +26 -0
  129. package/lib/managers/payment.manager.js.map +1 -1
  130. package/lib/managers/product.manager.js +1 -1
  131. package/lib/managers/product.manager.js.map +1 -1
  132. package/lib/schemas/ads.d.ts +2 -56
  133. package/lib/schemas/ams.d.ts +92 -0
  134. package/lib/schemas/base.d.ts +2 -0
  135. package/lib/schemas/discount.d.ts +4 -0
  136. package/lib/schemas/fetch.d.ts +1 -1
  137. package/lib/schemas/livestream.d.ts +14 -0
  138. package/lib/schemas/media.d.ts +107 -0
  139. package/lib/schemas/merchant.d.ts +2 -0
  140. package/lib/schemas/order.d.ts +22 -0
  141. package/lib/schemas/payment.d.ts +96 -0
  142. package/lib/schemas/product.d.ts +253 -15
  143. package/lib/schemas/public.d.ts +3 -0
  144. package/lib/schemas/region.d.ts +9 -2
  145. package/lib/schemas/region.js +9 -2
  146. package/lib/schemas/region.js.map +1 -1
  147. package/lib/schemas/returns.d.ts +38 -1
  148. package/lib/schemas/shop.d.ts +16 -0
  149. package/lib/schemas/video.d.ts +83 -37
  150. package/lib/schemas/voucher.d.ts +2 -0
  151. package/lib/sdk.d.ts +6 -1
  152. package/lib/sdk.js +53 -6
  153. package/lib/sdk.js.map +1 -1
  154. package/lib/storage/custom-token-storage.js +2 -0
  155. package/lib/storage/custom-token-storage.js.map +1 -1
  156. package/lib/version.d.ts +1 -1
  157. package/lib/version.js +1 -1
  158. package/package.json +3 -3
@@ -0,0 +1,2247 @@
1
+ import { jest } from "@jest/globals";
2
+ import { ProductManager } from "../../managers/product.manager.js";
3
+ import { ShopeeRegion } from "../../schemas/region.js";
4
+ import { ShopeeFetch } from "../../fetch.js";
5
+ import { ItemStatus, } from "../../schemas/product.js";
6
+ // Mock ShopeeFetch.fetch static method
7
+ const mockFetch = jest.fn();
8
+ ShopeeFetch.fetch = mockFetch;
9
+ describe("ProductManager", () => {
10
+ let productManager;
11
+ let mockConfig;
12
+ const mockShopeeFetch = mockFetch;
13
+ beforeEach(() => {
14
+ jest.clearAllMocks();
15
+ mockConfig = {
16
+ partner_id: 12345,
17
+ partner_key: "test_partner_key",
18
+ shop_id: 67890,
19
+ region: ShopeeRegion.GLOBAL,
20
+ base_url: "https://partner.test-stable.shopeemobile.com/api/v2",
21
+ };
22
+ productManager = new ProductManager(mockConfig);
23
+ });
24
+ describe("getComment", () => {
25
+ it("should get product comments with required parameters", async () => {
26
+ const mockResponse = {
27
+ request_id: "test-request-id",
28
+ error: "",
29
+ message: "",
30
+ response: {
31
+ item_comment_list: [
32
+ {
33
+ order_sn: "ORDER123",
34
+ comment_id: 123,
35
+ comment: "Great product!",
36
+ buyer_username: "user123",
37
+ item_id: 789,
38
+ model_id: 0,
39
+ model_id_list: [1001],
40
+ rating_star: 5,
41
+ editable: "EDITABLE",
42
+ hidden: false,
43
+ create_time: 1234567890,
44
+ media: {
45
+ image_url_list: [],
46
+ video_url_list: [],
47
+ },
48
+ },
49
+ ],
50
+ more: false,
51
+ next_cursor: "",
52
+ },
53
+ };
54
+ mockShopeeFetch.mockResolvedValue(mockResponse);
55
+ const result = await productManager.getComment({
56
+ item_id: 789,
57
+ comment_id: 123,
58
+ cursor: "",
59
+ page_size: 10,
60
+ });
61
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_comment", {
62
+ method: "GET",
63
+ auth: true,
64
+ params: {
65
+ item_id: 789,
66
+ comment_id: 123,
67
+ cursor: "",
68
+ page_size: 10,
69
+ },
70
+ });
71
+ expect(result).toEqual(mockResponse);
72
+ });
73
+ it("should get comments with minimal required parameters", async () => {
74
+ const mockResponse = {
75
+ request_id: "test-request-id",
76
+ error: "",
77
+ message: "",
78
+ response: {
79
+ item_comment_list: [],
80
+ more: false,
81
+ next_cursor: "",
82
+ },
83
+ };
84
+ mockShopeeFetch.mockResolvedValue(mockResponse);
85
+ const result = await productManager.getComment({
86
+ cursor: "",
87
+ page_size: 10,
88
+ });
89
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_comment", {
90
+ method: "GET",
91
+ auth: true,
92
+ params: {
93
+ cursor: "",
94
+ page_size: 10,
95
+ },
96
+ });
97
+ expect(result).toEqual(mockResponse);
98
+ });
99
+ });
100
+ describe("replyComment", () => {
101
+ it("should reply to a product comment", async () => {
102
+ const mockResponse = {
103
+ request_id: "test-request-id",
104
+ error: "",
105
+ message: "",
106
+ response: {
107
+ result_list: [
108
+ {
109
+ comment_id: 123,
110
+ },
111
+ ],
112
+ },
113
+ };
114
+ mockShopeeFetch.mockResolvedValue(mockResponse);
115
+ const result = await productManager.replyComment({
116
+ comment_list: [
117
+ {
118
+ comment_id: 123,
119
+ comment: "Thank you for your feedback!",
120
+ },
121
+ ],
122
+ });
123
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/reply_comment", {
124
+ method: "POST",
125
+ auth: true,
126
+ body: {
127
+ comment_list: [
128
+ {
129
+ comment_id: 123,
130
+ comment: "Thank you for your feedback!",
131
+ },
132
+ ],
133
+ },
134
+ });
135
+ expect(result).toEqual(mockResponse);
136
+ });
137
+ });
138
+ describe("getItemList", () => {
139
+ it("should get item list with pagination", async () => {
140
+ const mockResponse = {
141
+ request_id: "test-request-id",
142
+ error: "",
143
+ message: "",
144
+ response: {
145
+ item: [
146
+ {
147
+ item_id: 123456,
148
+ item_status: ItemStatus.NORMAL,
149
+ update_time: 1234567890,
150
+ },
151
+ {
152
+ item_id: 789012,
153
+ item_status: ItemStatus.BANNED,
154
+ update_time: 1234567891,
155
+ },
156
+ ],
157
+ total_count: 2,
158
+ has_next_page: false,
159
+ next_offset: 0,
160
+ },
161
+ };
162
+ mockShopeeFetch.mockResolvedValue(mockResponse);
163
+ const result = await productManager.getItemList({
164
+ offset: 0,
165
+ page_size: 50,
166
+ update_time_from: 1234567800,
167
+ update_time_to: 1234567900,
168
+ item_status: [ItemStatus.NORMAL],
169
+ });
170
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_list", {
171
+ method: "GET",
172
+ auth: true,
173
+ params: {
174
+ offset: 0,
175
+ page_size: 50,
176
+ update_time_from: 1234567800,
177
+ update_time_to: 1234567900,
178
+ item_status: [ItemStatus.NORMAL],
179
+ },
180
+ });
181
+ expect(result).toEqual(mockResponse);
182
+ });
183
+ it("should get item list with minimal parameters", async () => {
184
+ const mockResponse = {
185
+ request_id: "test-request-id",
186
+ error: "",
187
+ message: "",
188
+ response: {
189
+ item: [],
190
+ total_count: 0,
191
+ has_next_page: false,
192
+ next_offset: 0,
193
+ },
194
+ };
195
+ mockShopeeFetch.mockResolvedValue(mockResponse);
196
+ const result = await productManager.getItemList({
197
+ offset: 0,
198
+ page_size: 10,
199
+ item_status: [ItemStatus.NORMAL],
200
+ });
201
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_list", {
202
+ method: "GET",
203
+ auth: true,
204
+ params: {
205
+ offset: 0,
206
+ page_size: 10,
207
+ item_status: [ItemStatus.NORMAL],
208
+ },
209
+ });
210
+ expect(result).toEqual(mockResponse);
211
+ });
212
+ });
213
+ describe("getItemBaseInfo", () => {
214
+ it("should get item base info for multiple items", async () => {
215
+ const mockResponse = {
216
+ request_id: "test-request-id",
217
+ error: "",
218
+ message: "",
219
+ response: {
220
+ item_list: [
221
+ {
222
+ item_id: 123456,
223
+ category_id: 100001,
224
+ item_name: "Test Product 1",
225
+ item_sku: "SKU-001",
226
+ create_time: 1234567890,
227
+ update_time: 1234567891,
228
+ item_status: ItemStatus.NORMAL,
229
+ has_model: false,
230
+ condition: "NEW",
231
+ size_chart: "",
232
+ item_dangerous: 0,
233
+ },
234
+ {
235
+ item_id: 789012,
236
+ category_id: 100002,
237
+ item_name: "Test Product 2",
238
+ item_sku: "SKU-002",
239
+ create_time: 1234567892,
240
+ update_time: 1234567893,
241
+ item_status: ItemStatus.NORMAL,
242
+ has_model: true,
243
+ condition: "USED",
244
+ size_chart: "size_chart_url",
245
+ item_dangerous: 0,
246
+ },
247
+ ],
248
+ },
249
+ };
250
+ mockShopeeFetch.mockResolvedValue(mockResponse);
251
+ const result = await productManager.getItemBaseInfo({
252
+ item_id_list: [123456, 789012],
253
+ need_tax_info: false,
254
+ need_complaint_policy: true,
255
+ });
256
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_base_info", {
257
+ method: "GET",
258
+ auth: true,
259
+ params: {
260
+ item_id_list: "123456,789012",
261
+ need_tax_info: false,
262
+ need_complaint_policy: true,
263
+ },
264
+ });
265
+ expect(result).toEqual(mockResponse);
266
+ });
267
+ it("should get item base info for single item", async () => {
268
+ const mockResponse = {
269
+ request_id: "test-request-id",
270
+ error: "",
271
+ message: "",
272
+ response: {
273
+ item_list: [
274
+ {
275
+ item_id: 123456,
276
+ category_id: 100001,
277
+ item_name: "Single Product",
278
+ item_sku: "SKU-SINGLE",
279
+ create_time: 1234567890,
280
+ update_time: 1234567891,
281
+ item_status: ItemStatus.NORMAL,
282
+ has_model: false,
283
+ condition: "NEW",
284
+ size_chart: "",
285
+ item_dangerous: 0,
286
+ },
287
+ ],
288
+ },
289
+ };
290
+ mockShopeeFetch.mockResolvedValue(mockResponse);
291
+ const result = await productManager.getItemBaseInfo({
292
+ item_id_list: [123456],
293
+ });
294
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_base_info", {
295
+ method: "GET",
296
+ auth: true,
297
+ params: {
298
+ item_id_list: "123456",
299
+ },
300
+ });
301
+ expect(result).toEqual(mockResponse);
302
+ });
303
+ });
304
+ describe("getModelList", () => {
305
+ it("should get model list for an item", async () => {
306
+ const mockResponse = {
307
+ request_id: "test-request-id",
308
+ error: "",
309
+ message: "",
310
+ response: {
311
+ tier_variation: [
312
+ {
313
+ name: "Color",
314
+ option_list: [
315
+ { option: "Red", image: { image_id: "img1" } },
316
+ { option: "Blue", image: { image_id: "img2" } },
317
+ ],
318
+ },
319
+ {
320
+ name: "Size",
321
+ option_list: [{ option: "S" }, { option: "M" }, { option: "L" }],
322
+ },
323
+ ],
324
+ model: [
325
+ {
326
+ model_id: 1001,
327
+ tier_index: [0, 0],
328
+ price_info: [
329
+ {
330
+ current_price: 29.99,
331
+ original_price: 29.99,
332
+ inflated_price_of_original_price: 29.99,
333
+ inflated_price_of_current_price: 29.99,
334
+ },
335
+ ],
336
+ stock_info_v2: {
337
+ summary_info: {
338
+ total_available_stock: 100,
339
+ total_reserved_stock: 5,
340
+ },
341
+ },
342
+ model_sku: "SKU-RED-S",
343
+ gtin_code: "123456789012",
344
+ },
345
+ {
346
+ model_id: 1002,
347
+ tier_index: [0, 1],
348
+ price_info: [
349
+ {
350
+ current_price: 29.99,
351
+ original_price: 29.99,
352
+ inflated_price_of_original_price: 29.99,
353
+ inflated_price_of_current_price: 29.99,
354
+ },
355
+ ],
356
+ stock_info_v2: {
357
+ summary_info: {
358
+ total_available_stock: 150,
359
+ total_reserved_stock: 10,
360
+ },
361
+ },
362
+ model_sku: "SKU-RED-M",
363
+ gtin_code: "123456789013",
364
+ },
365
+ ],
366
+ },
367
+ };
368
+ mockShopeeFetch.mockResolvedValue(mockResponse);
369
+ const result = await productManager.getModelList({
370
+ item_id: 123456,
371
+ });
372
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_model_list", {
373
+ method: "GET",
374
+ auth: true,
375
+ params: {
376
+ item_id: 123456,
377
+ },
378
+ });
379
+ expect(result).toEqual(mockResponse);
380
+ });
381
+ });
382
+ describe("updatePrice", () => {
383
+ it("should update product price successfully", async () => {
384
+ const mockResponse = {
385
+ request_id: "test-request-id",
386
+ error: "",
387
+ message: "",
388
+ response: {
389
+ success_list: [
390
+ {
391
+ model_id: 0,
392
+ original_price: 99.99,
393
+ },
394
+ ],
395
+ failure_list: [],
396
+ },
397
+ };
398
+ mockShopeeFetch.mockResolvedValue(mockResponse);
399
+ const result = await productManager.updatePrice({
400
+ item_id: 123456,
401
+ price_list: [
402
+ {
403
+ model_id: 0,
404
+ original_price: 99.99,
405
+ },
406
+ ],
407
+ });
408
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_price", {
409
+ method: "POST",
410
+ auth: true,
411
+ body: {
412
+ item_id: 123456,
413
+ price_list: [
414
+ {
415
+ model_id: 0,
416
+ original_price: 99.99,
417
+ },
418
+ ],
419
+ },
420
+ });
421
+ expect(result).toEqual(mockResponse);
422
+ });
423
+ it("should update multiple model prices", async () => {
424
+ const mockResponse = {
425
+ request_id: "test-request-id",
426
+ error: "",
427
+ message: "",
428
+ response: {
429
+ success_list: [
430
+ {
431
+ model_id: 1001,
432
+ original_price: 49.99,
433
+ },
434
+ {
435
+ model_id: 1002,
436
+ original_price: 59.99,
437
+ },
438
+ ],
439
+ failure_list: [],
440
+ },
441
+ };
442
+ mockShopeeFetch.mockResolvedValue(mockResponse);
443
+ const result = await productManager.updatePrice({
444
+ item_id: 123456,
445
+ price_list: [
446
+ {
447
+ model_id: 1001,
448
+ original_price: 49.99,
449
+ },
450
+ {
451
+ model_id: 1002,
452
+ original_price: 59.99,
453
+ },
454
+ ],
455
+ });
456
+ expect(result.response.success_list).toHaveLength(2);
457
+ expect(result).toEqual(mockResponse);
458
+ });
459
+ it("should handle price update failures", async () => {
460
+ const mockResponse = {
461
+ request_id: "test-request-id",
462
+ error: "",
463
+ message: "",
464
+ response: {
465
+ success_list: [],
466
+ failure_list: [
467
+ {
468
+ model_id: 1001,
469
+ failed_reason: "Price too low",
470
+ },
471
+ ],
472
+ },
473
+ };
474
+ mockShopeeFetch.mockResolvedValue(mockResponse);
475
+ const result = await productManager.updatePrice({
476
+ item_id: 123456,
477
+ price_list: [
478
+ {
479
+ model_id: 1001,
480
+ original_price: 0.01,
481
+ },
482
+ ],
483
+ });
484
+ expect(result.response.failure_list).toHaveLength(1);
485
+ expect(result.response.failure_list?.[0].failed_reason).toBe("Price too low");
486
+ });
487
+ });
488
+ describe("updateStock", () => {
489
+ it("should update product stock successfully", async () => {
490
+ const mockResponse = {
491
+ request_id: "test-request-id",
492
+ error: "",
493
+ message: "",
494
+ response: {
495
+ success_list: [
496
+ {
497
+ model_id: 0,
498
+ seller_stock: [
499
+ {
500
+ stock: 100,
501
+ },
502
+ ],
503
+ },
504
+ ],
505
+ failure_list: [],
506
+ },
507
+ };
508
+ mockShopeeFetch.mockResolvedValue(mockResponse);
509
+ const result = await productManager.updateStock({
510
+ item_id: 123456,
511
+ stock_list: [
512
+ {
513
+ model_id: 0,
514
+ seller_stock: [
515
+ {
516
+ stock: 100,
517
+ },
518
+ ],
519
+ },
520
+ ],
521
+ });
522
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_stock", {
523
+ method: "POST",
524
+ auth: true,
525
+ body: {
526
+ item_id: 123456,
527
+ stock_list: [
528
+ {
529
+ model_id: 0,
530
+ seller_stock: [
531
+ {
532
+ stock: 100,
533
+ },
534
+ ],
535
+ },
536
+ ],
537
+ },
538
+ });
539
+ expect(result).toEqual(mockResponse);
540
+ });
541
+ it("should update stock with location_id", async () => {
542
+ const mockResponse = {
543
+ request_id: "test-request-id",
544
+ error: "",
545
+ message: "",
546
+ response: {
547
+ success_list: [
548
+ {
549
+ model_id: 1001,
550
+ seller_stock: [
551
+ {
552
+ location_id: "LOC-001",
553
+ stock: 50,
554
+ },
555
+ ],
556
+ },
557
+ ],
558
+ failure_list: [],
559
+ },
560
+ };
561
+ mockShopeeFetch.mockResolvedValue(mockResponse);
562
+ const result = await productManager.updateStock({
563
+ item_id: 123456,
564
+ stock_list: [
565
+ {
566
+ model_id: 1001,
567
+ seller_stock: [
568
+ {
569
+ location_id: "LOC-001",
570
+ stock: 50,
571
+ },
572
+ ],
573
+ },
574
+ ],
575
+ });
576
+ expect(result.response.success_list?.[0].seller_stock[0].location_id).toBe("LOC-001");
577
+ });
578
+ it("should handle stock update failures", async () => {
579
+ const mockResponse = {
580
+ request_id: "test-request-id",
581
+ error: "",
582
+ message: "",
583
+ response: {
584
+ success_list: [],
585
+ failure_list: [
586
+ {
587
+ model_id: 1001,
588
+ failed_reason: "Insufficient stock",
589
+ },
590
+ ],
591
+ },
592
+ };
593
+ mockShopeeFetch.mockResolvedValue(mockResponse);
594
+ const result = await productManager.updateStock({
595
+ item_id: 123456,
596
+ stock_list: [
597
+ {
598
+ model_id: 1001,
599
+ seller_stock: [
600
+ {
601
+ stock: -10,
602
+ },
603
+ ],
604
+ },
605
+ ],
606
+ });
607
+ expect(result.response.failure_list).toHaveLength(1);
608
+ });
609
+ });
610
+ describe("deleteItem", () => {
611
+ it("should delete a product item successfully", async () => {
612
+ const mockResponse = {
613
+ request_id: "test-request-id",
614
+ error: "",
615
+ message: "",
616
+ warning: "",
617
+ };
618
+ mockShopeeFetch.mockResolvedValue(mockResponse);
619
+ const result = await productManager.deleteItem({
620
+ item_id: 123456,
621
+ });
622
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/delete_item", {
623
+ method: "POST",
624
+ auth: true,
625
+ body: {
626
+ item_id: 123456,
627
+ },
628
+ });
629
+ expect(result).toEqual(mockResponse);
630
+ expect(result.error).toBe("");
631
+ });
632
+ it("should handle delete item error", async () => {
633
+ const mockResponse = {
634
+ request_id: "test-request-id",
635
+ error: "error_item_not_found",
636
+ message: "Item_id is not found.",
637
+ warning: "",
638
+ };
639
+ mockShopeeFetch.mockResolvedValue(mockResponse);
640
+ const result = await productManager.deleteItem({
641
+ item_id: 999999,
642
+ });
643
+ expect(result.error).toBe("error_item_not_found");
644
+ expect(result.message).toBe("Item_id is not found.");
645
+ });
646
+ });
647
+ describe("unlistItem", () => {
648
+ it("should unlist items successfully", async () => {
649
+ const mockResponse = {
650
+ request_id: "test-request-id",
651
+ error: "",
652
+ message: "",
653
+ response: {
654
+ result: [
655
+ {
656
+ item_id: 123456,
657
+ success: true,
658
+ },
659
+ ],
660
+ },
661
+ };
662
+ mockShopeeFetch.mockResolvedValue(mockResponse);
663
+ const result = await productManager.unlistItem({
664
+ item_list: [
665
+ {
666
+ item_id: 123456,
667
+ unlist: true,
668
+ },
669
+ ],
670
+ });
671
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/unlist_item", {
672
+ method: "POST",
673
+ auth: true,
674
+ body: {
675
+ item_list: [
676
+ {
677
+ item_id: 123456,
678
+ unlist: true,
679
+ },
680
+ ],
681
+ },
682
+ });
683
+ expect(result).toEqual(mockResponse);
684
+ expect(result.response.result?.[0].success).toBe(true);
685
+ });
686
+ it("should list items (unlist=false)", async () => {
687
+ const mockResponse = {
688
+ request_id: "test-request-id",
689
+ error: "",
690
+ message: "",
691
+ response: {
692
+ result: [
693
+ {
694
+ item_id: 123456,
695
+ success: true,
696
+ },
697
+ ],
698
+ },
699
+ };
700
+ mockShopeeFetch.mockResolvedValue(mockResponse);
701
+ const result = await productManager.unlistItem({
702
+ item_list: [
703
+ {
704
+ item_id: 123456,
705
+ unlist: false,
706
+ },
707
+ ],
708
+ });
709
+ expect(result.response.result?.[0].success).toBe(true);
710
+ });
711
+ it("should handle multiple items with mixed results", async () => {
712
+ const mockResponse = {
713
+ request_id: "test-request-id",
714
+ error: "",
715
+ message: "",
716
+ response: {
717
+ result: [
718
+ {
719
+ item_id: 123456,
720
+ success: true,
721
+ },
722
+ {
723
+ item_id: 789012,
724
+ success: false,
725
+ failed_reason: "Item not found",
726
+ },
727
+ ],
728
+ },
729
+ };
730
+ mockShopeeFetch.mockResolvedValue(mockResponse);
731
+ const result = await productManager.unlistItem({
732
+ item_list: [
733
+ {
734
+ item_id: 123456,
735
+ unlist: true,
736
+ },
737
+ {
738
+ item_id: 789012,
739
+ unlist: true,
740
+ },
741
+ ],
742
+ });
743
+ expect(result.response.result).toHaveLength(2);
744
+ expect(result.response.result?.[0].success).toBe(true);
745
+ expect(result.response.result?.[1].success).toBe(false);
746
+ });
747
+ });
748
+ describe("getCategory", () => {
749
+ it("should get category list with default language", async () => {
750
+ const mockResponse = {
751
+ request_id: "test-request-id",
752
+ error: "",
753
+ message: "",
754
+ response: {
755
+ category_list: [
756
+ {
757
+ category_id: 100001,
758
+ parent_category_id: 0,
759
+ category_name: "Electronics",
760
+ has_children: true,
761
+ },
762
+ {
763
+ category_id: 100002,
764
+ parent_category_id: 100001,
765
+ category_name: "Mobile Phones",
766
+ has_children: false,
767
+ },
768
+ ],
769
+ },
770
+ };
771
+ mockShopeeFetch.mockResolvedValue(mockResponse);
772
+ const result = await productManager.getCategory();
773
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_category", {
774
+ method: "GET",
775
+ auth: true,
776
+ params: {},
777
+ });
778
+ expect(result).toEqual(mockResponse);
779
+ expect(result.response.category_list).toHaveLength(2);
780
+ });
781
+ it("should get category list with specific language", async () => {
782
+ const mockResponse = {
783
+ request_id: "test-request-id",
784
+ error: "",
785
+ message: "",
786
+ response: {
787
+ category_list: [
788
+ {
789
+ category_id: 100001,
790
+ parent_category_id: 0,
791
+ category_name: "电子产品",
792
+ has_children: true,
793
+ },
794
+ ],
795
+ },
796
+ };
797
+ mockShopeeFetch.mockResolvedValue(mockResponse);
798
+ const result = await productManager.getCategory({
799
+ language: "zh-hans",
800
+ });
801
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_category", {
802
+ method: "GET",
803
+ auth: true,
804
+ params: {
805
+ language: "zh-hans",
806
+ },
807
+ });
808
+ expect(result.response.category_list[0].category_name).toBe("电子产品");
809
+ });
810
+ it("should handle empty category list", async () => {
811
+ const mockResponse = {
812
+ request_id: "test-request-id",
813
+ error: "",
814
+ message: "",
815
+ response: {
816
+ category_list: [],
817
+ },
818
+ };
819
+ mockShopeeFetch.mockResolvedValue(mockResponse);
820
+ const result = await productManager.getCategory();
821
+ expect(result.response.category_list).toEqual([]);
822
+ });
823
+ });
824
+ describe("addItem", () => {
825
+ it("should add a new item successfully", async () => {
826
+ const mockResponse = {
827
+ request_id: "test-request-id",
828
+ error: "",
829
+ message: "",
830
+ response: {
831
+ item_id: 123456,
832
+ warning: [],
833
+ },
834
+ };
835
+ mockShopeeFetch.mockResolvedValue(mockResponse);
836
+ const result = await productManager.addItem({
837
+ original_price: 99.99,
838
+ description: "Test product description",
839
+ item_name: "Test Product",
840
+ category_id: 100001,
841
+ image: {
842
+ image_id_list: ["img123"],
843
+ },
844
+ });
845
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/add_item", {
846
+ method: "POST",
847
+ auth: true,
848
+ body: expect.objectContaining({
849
+ original_price: 99.99,
850
+ description: "Test product description",
851
+ item_name: "Test Product",
852
+ category_id: 100001,
853
+ }),
854
+ });
855
+ expect(result.response.item_id).toBe(123456);
856
+ });
857
+ });
858
+ describe("updateItem", () => {
859
+ it("should update an item successfully", async () => {
860
+ const mockResponse = {
861
+ request_id: "test-request-id",
862
+ error: "",
863
+ message: "",
864
+ response: {
865
+ item_id: 123456,
866
+ warning: [],
867
+ },
868
+ };
869
+ mockShopeeFetch.mockResolvedValue(mockResponse);
870
+ const result = await productManager.updateItem({
871
+ item_id: 123456,
872
+ item_name: "Updated Product Name",
873
+ original_price: 149.99,
874
+ });
875
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_item", {
876
+ method: "POST",
877
+ auth: true,
878
+ body: {
879
+ item_id: 123456,
880
+ item_name: "Updated Product Name",
881
+ original_price: 149.99,
882
+ },
883
+ });
884
+ expect(result.response.item_id).toBe(123456);
885
+ });
886
+ });
887
+ describe("addModel", () => {
888
+ it("should add models to an item", async () => {
889
+ const mockResponse = {
890
+ request_id: "test-request-id",
891
+ error: "",
892
+ message: "",
893
+ response: {
894
+ model_id_list: [1001, 1002],
895
+ warning: [],
896
+ },
897
+ };
898
+ mockShopeeFetch.mockResolvedValue(mockResponse);
899
+ const result = await productManager.addModel({
900
+ item_id: 123456,
901
+ model_list: [
902
+ {
903
+ tier_index: [0, 0],
904
+ original_price: 99.99,
905
+ normal_stock: 100,
906
+ },
907
+ {
908
+ tier_index: [0, 1],
909
+ original_price: 109.99,
910
+ normal_stock: 50,
911
+ },
912
+ ],
913
+ });
914
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/add_model", {
915
+ method: "POST",
916
+ auth: true,
917
+ body: expect.objectContaining({
918
+ item_id: 123456,
919
+ }),
920
+ });
921
+ expect(result.response.model_id_list).toHaveLength(2);
922
+ });
923
+ });
924
+ describe("updateModel", () => {
925
+ it("should update models successfully", async () => {
926
+ const mockResponse = {
927
+ request_id: "test-request-id",
928
+ error: "",
929
+ message: "",
930
+ response: {
931
+ model_id_list: [1001],
932
+ warning: [],
933
+ },
934
+ };
935
+ mockShopeeFetch.mockResolvedValue(mockResponse);
936
+ const result = await productManager.updateModel({
937
+ item_id: 123456,
938
+ model_list: [
939
+ {
940
+ model_id: 1001,
941
+ original_price: 119.99,
942
+ },
943
+ ],
944
+ });
945
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_model", {
946
+ method: "POST",
947
+ auth: true,
948
+ body: expect.objectContaining({
949
+ item_id: 123456,
950
+ }),
951
+ });
952
+ expect(result.response.model_id_list).toContain(1001);
953
+ });
954
+ });
955
+ describe("deleteModel", () => {
956
+ it("should delete models successfully", async () => {
957
+ const mockResponse = {
958
+ request_id: "test-request-id",
959
+ error: "",
960
+ message: "",
961
+ response: {
962
+ success: true,
963
+ },
964
+ };
965
+ mockShopeeFetch.mockResolvedValue(mockResponse);
966
+ const result = await productManager.deleteModel({
967
+ item_id: 123456,
968
+ model_id_list: [1001, 1002],
969
+ });
970
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/delete_model", {
971
+ method: "POST",
972
+ auth: true,
973
+ body: {
974
+ item_id: 123456,
975
+ model_id_list: [1001, 1002],
976
+ },
977
+ });
978
+ expect(result.response.success).toBe(true);
979
+ });
980
+ });
981
+ describe("initTierVariation", () => {
982
+ it("should initialize tier variations", async () => {
983
+ const mockResponse = {
984
+ request_id: "test-request-id",
985
+ error: "",
986
+ message: "",
987
+ response: {
988
+ model_id_list: [2001, 2002],
989
+ warning: [],
990
+ },
991
+ };
992
+ mockShopeeFetch.mockResolvedValue(mockResponse);
993
+ const result = await productManager.initTierVariation({
994
+ item_id: 123456,
995
+ tier_variation: [
996
+ {
997
+ name: "Color",
998
+ option_list: [{ option: "Red" }, { option: "Blue" }],
999
+ },
1000
+ ],
1001
+ model: [
1002
+ {
1003
+ tier_index: [0],
1004
+ original_price: 99.99,
1005
+ normal_stock: 50,
1006
+ },
1007
+ {
1008
+ tier_index: [1],
1009
+ original_price: 99.99,
1010
+ normal_stock: 50,
1011
+ },
1012
+ ],
1013
+ });
1014
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/init_tier_variation", {
1015
+ method: "POST",
1016
+ auth: true,
1017
+ body: expect.objectContaining({
1018
+ item_id: 123456,
1019
+ }),
1020
+ });
1021
+ expect(result.response.model_id_list).toHaveLength(2);
1022
+ });
1023
+ });
1024
+ describe("updateTierVariation", () => {
1025
+ it("should update tier variations", async () => {
1026
+ const mockResponse = {
1027
+ request_id: "test-request-id",
1028
+ error: "",
1029
+ message: "",
1030
+ warning: "",
1031
+ };
1032
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1033
+ const result = await productManager.updateTierVariation({
1034
+ item_id: 123456,
1035
+ tier_variation: [
1036
+ {
1037
+ name: "Size",
1038
+ option_list: [{ option: "S" }, { option: "M" }, { option: "L" }],
1039
+ },
1040
+ ],
1041
+ });
1042
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_tier_variation", {
1043
+ method: "POST",
1044
+ auth: true,
1045
+ body: expect.objectContaining({
1046
+ item_id: 123456,
1047
+ }),
1048
+ });
1049
+ expect(result.error).toBe("");
1050
+ });
1051
+ });
1052
+ describe("searchItem", () => {
1053
+ it("should search items successfully", async () => {
1054
+ const mockResponse = {
1055
+ request_id: "test-request-id",
1056
+ error: "",
1057
+ message: "",
1058
+ response: {
1059
+ item: [
1060
+ {
1061
+ item_id: 123456,
1062
+ item_status: ItemStatus.NORMAL,
1063
+ update_time: 1234567890,
1064
+ },
1065
+ ],
1066
+ total_count: 1,
1067
+ has_next_page: false,
1068
+ next_offset: 0,
1069
+ },
1070
+ };
1071
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1072
+ const result = await productManager.searchItem({
1073
+ item_name: "Test Product",
1074
+ offset: 0,
1075
+ page_size: 20,
1076
+ });
1077
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/search_item", {
1078
+ method: "GET",
1079
+ auth: true,
1080
+ params: {
1081
+ item_name: "Test Product",
1082
+ offset: 0,
1083
+ page_size: 20,
1084
+ },
1085
+ });
1086
+ expect(result.response.item).toHaveLength(1);
1087
+ });
1088
+ });
1089
+ describe("getItemExtraInfo", () => {
1090
+ it("should get item extra info successfully", async () => {
1091
+ const mockResponse = {
1092
+ request_id: "test-request-id",
1093
+ error: "",
1094
+ message: "",
1095
+ response: {
1096
+ item_list: [
1097
+ {
1098
+ item_id: 123456,
1099
+ sale_info: {
1100
+ sale: 100,
1101
+ sale_7d: 50,
1102
+ sale_30d: 200,
1103
+ },
1104
+ view: 1000,
1105
+ liked_count: 50,
1106
+ cmt_count: 20,
1107
+ },
1108
+ ],
1109
+ },
1110
+ };
1111
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1112
+ const result = await productManager.getItemExtraInfo({
1113
+ item_id_list: [123456, 789012],
1114
+ });
1115
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_extra_info", {
1116
+ method: "GET",
1117
+ auth: true,
1118
+ params: {
1119
+ item_id_list: "123456,789012",
1120
+ },
1121
+ });
1122
+ expect(result.response.item_list[0].sale_info.sale).toBe(100);
1123
+ });
1124
+ });
1125
+ describe("getAttributeTree", () => {
1126
+ it("should get attribute tree for a category", async () => {
1127
+ const mockResponse = {
1128
+ request_id: "test-request-id",
1129
+ error: "",
1130
+ message: "",
1131
+ response: {
1132
+ attribute_list: [
1133
+ {
1134
+ attribute_id: 1001,
1135
+ original_attribute_name: "Brand",
1136
+ is_mandatory: true,
1137
+ input_type: "DROP_DOWN",
1138
+ attribute_value_list: [
1139
+ {
1140
+ value_id: 2001,
1141
+ original_value_name: "Nike",
1142
+ },
1143
+ ],
1144
+ },
1145
+ ],
1146
+ },
1147
+ };
1148
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1149
+ const result = await productManager.getAttributeTree({
1150
+ category_id: 100001,
1151
+ language: "en",
1152
+ });
1153
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_attribute_tree", {
1154
+ method: "GET",
1155
+ auth: true,
1156
+ params: {
1157
+ category_id: 100001,
1158
+ language: "en",
1159
+ },
1160
+ });
1161
+ expect(result.response.attribute_list).toHaveLength(1);
1162
+ });
1163
+ });
1164
+ describe("getBrandList", () => {
1165
+ it("should get brand list successfully", async () => {
1166
+ const mockResponse = {
1167
+ request_id: "test-request-id",
1168
+ error: "",
1169
+ message: "",
1170
+ response: {
1171
+ brand_list: [
1172
+ {
1173
+ brand_id: 1,
1174
+ original_brand_name: "Nike",
1175
+ display_brand_name: "Nike",
1176
+ },
1177
+ {
1178
+ brand_id: 2,
1179
+ original_brand_name: "Adidas",
1180
+ display_brand_name: "Adidas",
1181
+ },
1182
+ ],
1183
+ has_next_page: false,
1184
+ next_offset: 0,
1185
+ is_mandatory: true,
1186
+ input_type: "DROP_DOWN",
1187
+ },
1188
+ };
1189
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1190
+ const result = await productManager.getBrandList({
1191
+ category_id: 100001,
1192
+ offset: 0,
1193
+ page_size: 20,
1194
+ });
1195
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_brand_list", {
1196
+ method: "GET",
1197
+ auth: true,
1198
+ params: {
1199
+ category_id: 100001,
1200
+ offset: 0,
1201
+ page_size: 20,
1202
+ },
1203
+ });
1204
+ expect(result.response.brand_list).toHaveLength(2);
1205
+ });
1206
+ });
1207
+ describe("registerBrand", () => {
1208
+ it("should register a new brand", async () => {
1209
+ const mockResponse = {
1210
+ request_id: "test-request-id",
1211
+ error: "",
1212
+ message: "",
1213
+ response: {
1214
+ brand_id: 12345,
1215
+ original_brand_name: "NewBrand",
1216
+ },
1217
+ };
1218
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1219
+ const result = await productManager.registerBrand({
1220
+ category_id: 100001,
1221
+ original_brand_name: "NewBrand",
1222
+ });
1223
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/register_brand", {
1224
+ method: "POST",
1225
+ auth: true,
1226
+ body: {
1227
+ category_id: 100001,
1228
+ original_brand_name: "NewBrand",
1229
+ },
1230
+ });
1231
+ expect(result.response.brand_id).toBe(12345);
1232
+ });
1233
+ });
1234
+ describe("categoryRecommend", () => {
1235
+ it("should get category recommendations", async () => {
1236
+ const mockResponse = {
1237
+ request_id: "test-request-id",
1238
+ error: "",
1239
+ message: "",
1240
+ response: {
1241
+ category_id_list: [100001, 100002, 100003],
1242
+ },
1243
+ };
1244
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1245
+ const result = await productManager.categoryRecommend({
1246
+ item_name: "Running Shoes",
1247
+ });
1248
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/category_recommend", {
1249
+ method: "GET",
1250
+ auth: true,
1251
+ params: {
1252
+ item_name: "Running Shoes",
1253
+ },
1254
+ });
1255
+ expect(result.response.category_id_list).toHaveLength(3);
1256
+ });
1257
+ });
1258
+ describe("getItemLimit", () => {
1259
+ it("should get item limits for a category", async () => {
1260
+ const mockResponse = {
1261
+ request_id: "test-request-id",
1262
+ error: "",
1263
+ message: "",
1264
+ response: {
1265
+ item_limit: {
1266
+ max_image_count: 9,
1267
+ max_video_count: 1,
1268
+ max_product_title_length: 120,
1269
+ max_description_length: 3000,
1270
+ max_extended_description_length: 25000,
1271
+ is_video_required: false,
1272
+ },
1273
+ },
1274
+ };
1275
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1276
+ const result = await productManager.getItemLimit({
1277
+ category_id: 100001,
1278
+ });
1279
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_limit", {
1280
+ method: "GET",
1281
+ auth: true,
1282
+ params: {
1283
+ category_id: 100001,
1284
+ },
1285
+ });
1286
+ expect(result.response.item_limit.max_image_count).toBe(9);
1287
+ });
1288
+ });
1289
+ describe("getItemPromotion", () => {
1290
+ it("should get item promotion information", async () => {
1291
+ const mockResponse = {
1292
+ request_id: "test-request-id",
1293
+ error: "",
1294
+ message: "",
1295
+ response: {
1296
+ item_promotion_list: [
1297
+ {
1298
+ item_id: 123456,
1299
+ promotion_list: [
1300
+ {
1301
+ promotion_id: 9001,
1302
+ promotion_type: 1,
1303
+ start_time: 1609459200,
1304
+ end_time: 1612137600,
1305
+ },
1306
+ ],
1307
+ },
1308
+ ],
1309
+ },
1310
+ };
1311
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1312
+ const result = await productManager.getItemPromotion({
1313
+ item_id_list: [123456],
1314
+ });
1315
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_promotion", {
1316
+ method: "GET",
1317
+ auth: true,
1318
+ params: {
1319
+ item_id_list: "123456",
1320
+ },
1321
+ });
1322
+ expect(result.response.item_promotion_list[0].promotion_list).toHaveLength(1);
1323
+ });
1324
+ });
1325
+ describe("boostItem", () => {
1326
+ it("should boost items successfully", async () => {
1327
+ const mockResponse = {
1328
+ request_id: "test-request-id",
1329
+ error: "",
1330
+ message: "",
1331
+ response: {
1332
+ failed_item_id_list: [],
1333
+ },
1334
+ };
1335
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1336
+ const result = await productManager.boostItem({
1337
+ item_id_list: [123456, 789012],
1338
+ });
1339
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/boost_item", {
1340
+ method: "POST",
1341
+ auth: true,
1342
+ body: {
1343
+ item_id_list: [123456, 789012],
1344
+ },
1345
+ });
1346
+ expect(result.response.failed_item_id_list).toEqual([]);
1347
+ });
1348
+ });
1349
+ describe("getBoostedList", () => {
1350
+ it("should get list of boosted items", async () => {
1351
+ const mockResponse = {
1352
+ request_id: "test-request-id",
1353
+ error: "",
1354
+ message: "",
1355
+ response: {
1356
+ item_list: [
1357
+ {
1358
+ item_id: 123456,
1359
+ boost_end_time: 1640995200,
1360
+ },
1361
+ ],
1362
+ },
1363
+ };
1364
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1365
+ const result = await productManager.getBoostedList();
1366
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_boosted_list", {
1367
+ method: "GET",
1368
+ auth: true,
1369
+ params: {},
1370
+ });
1371
+ expect(result.response.item_list).toHaveLength(1);
1372
+ });
1373
+ });
1374
+ describe("getVariations", () => {
1375
+ it("should get variations for an item", async () => {
1376
+ const mockResponse = {
1377
+ request_id: "test-request-id",
1378
+ error: "",
1379
+ message: "",
1380
+ response: {
1381
+ tier_variation: [
1382
+ {
1383
+ name: "Color",
1384
+ option_list: [{ option: "Red" }, { option: "Blue" }],
1385
+ },
1386
+ ],
1387
+ },
1388
+ };
1389
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1390
+ const result = await productManager.getVariations({
1391
+ item_id: 123456,
1392
+ category_id: 789,
1393
+ });
1394
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_variations", {
1395
+ method: "GET",
1396
+ auth: true,
1397
+ params: {
1398
+ item_id: 123456,
1399
+ category_id: 789,
1400
+ },
1401
+ });
1402
+ expect(result.response.tier_variation).toHaveLength(1);
1403
+ });
1404
+ });
1405
+ describe("getRecommendAttribute", () => {
1406
+ it("should get recommended attributes", async () => {
1407
+ const mockResponse = {
1408
+ request_id: "test-request-id",
1409
+ error: "",
1410
+ message: "",
1411
+ response: {
1412
+ recommended_attribute_list: [
1413
+ {
1414
+ attribute_id: 1001,
1415
+ recommended_value_list: [
1416
+ {
1417
+ value_id: 2001,
1418
+ original_value_name: "Cotton",
1419
+ },
1420
+ ],
1421
+ },
1422
+ ],
1423
+ },
1424
+ };
1425
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1426
+ const result = await productManager.getRecommendAttribute({
1427
+ category_id: 100001,
1428
+ item_name: "T-Shirt",
1429
+ cover_image_id: 12345,
1430
+ });
1431
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_recommend_attribute", {
1432
+ method: "GET",
1433
+ auth: true,
1434
+ params: {
1435
+ category_id: 100001,
1436
+ item_name: "T-Shirt",
1437
+ cover_image_id: 12345,
1438
+ },
1439
+ });
1440
+ expect(result.response.recommended_attribute_list).toHaveLength(1);
1441
+ });
1442
+ });
1443
+ describe("searchAttributeValueList", () => {
1444
+ it("should search attribute values", async () => {
1445
+ const mockResponse = {
1446
+ request_id: "test-request-id",
1447
+ error: "",
1448
+ message: "",
1449
+ response: {
1450
+ attribute_value_list: [
1451
+ {
1452
+ value_id: 2001,
1453
+ original_value_name: "Cotton",
1454
+ },
1455
+ ],
1456
+ },
1457
+ };
1458
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1459
+ const result = await productManager.searchAttributeValueList({
1460
+ category_id: 100001,
1461
+ attribute_id: 1001,
1462
+ search_value: "Cotton",
1463
+ value_name: "Cotton Soft",
1464
+ cursor: 10,
1465
+ limit: 50,
1466
+ });
1467
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/search_attribute_value_list", {
1468
+ method: "POST",
1469
+ auth: true,
1470
+ body: {
1471
+ category_id: 100001,
1472
+ attribute_id: 1001,
1473
+ search_value: "Cotton",
1474
+ value_name: "Cotton Soft",
1475
+ cursor: 10,
1476
+ limit: 50,
1477
+ },
1478
+ });
1479
+ expect(result.response.attribute_value_list).toHaveLength(1);
1480
+ });
1481
+ });
1482
+ describe("getMainItemList", () => {
1483
+ it("should get main item list successfully", async () => {
1484
+ const mockResponse = {
1485
+ request_id: "test-request-id",
1486
+ error: "",
1487
+ message: "",
1488
+ response: {
1489
+ item: [
1490
+ {
1491
+ item_id: 123456,
1492
+ item_status: ItemStatus.NORMAL,
1493
+ update_time: 1234567890,
1494
+ },
1495
+ ],
1496
+ total_count: 1,
1497
+ has_next_page: false,
1498
+ next_offset: 0,
1499
+ },
1500
+ };
1501
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1502
+ const result = await productManager.getMainItemList({
1503
+ offset: 0,
1504
+ page_size: 20,
1505
+ });
1506
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_main_item_list", {
1507
+ method: "GET",
1508
+ auth: true,
1509
+ params: {
1510
+ offset: 0,
1511
+ page_size: 20,
1512
+ },
1513
+ });
1514
+ expect(result.response.item).toHaveLength(1);
1515
+ });
1516
+ });
1517
+ describe("getItemViolationInfo", () => {
1518
+ it("should get item violation information", async () => {
1519
+ const mockResponse = {
1520
+ request_id: "test-request-id",
1521
+ error: "",
1522
+ message: "",
1523
+ response: {
1524
+ item_violation_list: [
1525
+ {
1526
+ item_id: 123456,
1527
+ violation_list: [
1528
+ {
1529
+ violation_type: "DESCRIPTION",
1530
+ violation_reason: "Prohibited content",
1531
+ violated_item_info: ["description"],
1532
+ },
1533
+ ],
1534
+ },
1535
+ ],
1536
+ },
1537
+ };
1538
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1539
+ const result = await productManager.getItemViolationInfo({
1540
+ item_id_list: [123456],
1541
+ });
1542
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_violation_info", {
1543
+ method: "GET",
1544
+ auth: true,
1545
+ params: {
1546
+ item_id_list: "123456",
1547
+ },
1548
+ });
1549
+ expect(result.response.item_violation_list[0].violation_list).toHaveLength(1);
1550
+ });
1551
+ });
1552
+ describe("getWeightRecommendation", () => {
1553
+ it("should get weight recommendation", async () => {
1554
+ const mockResponse = {
1555
+ request_id: "test-request-id",
1556
+ error: "",
1557
+ message: "",
1558
+ response: {
1559
+ weight: 1.5,
1560
+ },
1561
+ };
1562
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1563
+ const result = await productManager.getWeightRecommendation({
1564
+ category_id: 100001,
1565
+ item_name: "T-Shirt",
1566
+ });
1567
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_weight_recommendation", {
1568
+ method: "POST",
1569
+ auth: true,
1570
+ body: {
1571
+ category_id: 100001,
1572
+ item_name: "T-Shirt",
1573
+ },
1574
+ });
1575
+ expect(result.response.weight).toBe(1.5);
1576
+ });
1577
+ });
1578
+ describe("getDirectItemList", () => {
1579
+ it("should get direct item list", async () => {
1580
+ const mockResponse = {
1581
+ request_id: "test-request-id",
1582
+ error: "",
1583
+ message: "",
1584
+ response: {
1585
+ item: [
1586
+ {
1587
+ item_id: 123456,
1588
+ category_id: 100001,
1589
+ item_name: "Direct Item",
1590
+ item_status: ItemStatus.NORMAL,
1591
+ update_time: 1234567890,
1592
+ },
1593
+ ],
1594
+ total_count: 1,
1595
+ has_next_page: false,
1596
+ next_offset: 0,
1597
+ },
1598
+ };
1599
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1600
+ const result = await productManager.getDirectItemList({
1601
+ offset: 0,
1602
+ page_size: 20,
1603
+ });
1604
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_direct_item_list", {
1605
+ method: "GET",
1606
+ auth: true,
1607
+ params: {
1608
+ offset: 0,
1609
+ page_size: 20,
1610
+ },
1611
+ });
1612
+ expect(result.response.item).toHaveLength(1);
1613
+ });
1614
+ });
1615
+ describe("getItemContentDiagnosisResult", () => {
1616
+ it("should get item content diagnosis results", async () => {
1617
+ const mockResponse = {
1618
+ request_id: "test-request-id",
1619
+ error: "",
1620
+ message: "",
1621
+ response: {
1622
+ item_list: [
1623
+ {
1624
+ item_id: 123456,
1625
+ status: "PASSED",
1626
+ failed_field_list: [],
1627
+ },
1628
+ ],
1629
+ },
1630
+ };
1631
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1632
+ const result = await productManager.getItemContentDiagnosisResult({
1633
+ item_id_list: [123456],
1634
+ });
1635
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_content_diagnosis_result", {
1636
+ method: "POST",
1637
+ auth: true,
1638
+ body: {
1639
+ item_id_list: [123456],
1640
+ },
1641
+ });
1642
+ expect(result.response.item_list[0].status).toBe("PASSED");
1643
+ });
1644
+ });
1645
+ describe("getItemListByContentDiagnosis", () => {
1646
+ it("should get items filtered by content diagnosis", async () => {
1647
+ const mockResponse = {
1648
+ request_id: "test-request-id",
1649
+ error: "",
1650
+ message: "",
1651
+ response: {
1652
+ item: [
1653
+ {
1654
+ item_id: 123456,
1655
+ item_status: ItemStatus.NORMAL,
1656
+ update_time: 1234567890,
1657
+ },
1658
+ ],
1659
+ total_count: 1,
1660
+ has_next_page: false,
1661
+ next_offset: 0,
1662
+ },
1663
+ };
1664
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1665
+ const result = await productManager.getItemListByContentDiagnosis({
1666
+ status: "PASSED",
1667
+ offset: 0,
1668
+ page_size: 20,
1669
+ });
1670
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_item_list_by_content_diagnosis", {
1671
+ method: "POST",
1672
+ auth: true,
1673
+ body: {
1674
+ status: "PASSED",
1675
+ offset: 0,
1676
+ page_size: 20,
1677
+ },
1678
+ });
1679
+ expect(result.response.item).toHaveLength(1);
1680
+ });
1681
+ });
1682
+ // Specialized function tests (simplified due to 'any' types)
1683
+ describe("specialized functions", () => {
1684
+ it("should call addKitItem", async () => {
1685
+ const mockResponse = {
1686
+ request_id: "test-request-id",
1687
+ error: "",
1688
+ message: "",
1689
+ response: { item_id: 123456 },
1690
+ };
1691
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1692
+ const result = await productManager.addKitItem({ item_setting: "data" });
1693
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/add_kit_item", {
1694
+ method: "POST",
1695
+ auth: true,
1696
+ body: { item_setting: "data" },
1697
+ });
1698
+ expect(result.response.item_id).toBe(123456);
1699
+ });
1700
+ it("should call updateKitItem", async () => {
1701
+ const mockResponse = {
1702
+ request_id: "test-request-id",
1703
+ error: "",
1704
+ message: "",
1705
+ warning: "",
1706
+ };
1707
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1708
+ const result = await productManager.updateKitItem({ item_id: 123456 });
1709
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_kit_item", {
1710
+ method: "POST",
1711
+ auth: true,
1712
+ body: { item_id: 123456 },
1713
+ });
1714
+ expect(result.error).toBe("");
1715
+ });
1716
+ it("should call getKitItemInfo", async () => {
1717
+ const mockResponse = {
1718
+ request_id: "test-request-id",
1719
+ error: "",
1720
+ message: "",
1721
+ response: { item_list: [{ item_id: 123456 }] },
1722
+ };
1723
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1724
+ const result = await productManager.getKitItemInfo({
1725
+ item_id_list: [123456],
1726
+ });
1727
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_kit_item_info", {
1728
+ method: "GET",
1729
+ auth: true,
1730
+ params: {
1731
+ item_id_list: "123456",
1732
+ },
1733
+ });
1734
+ expect(result.response.item_list).toHaveLength(1);
1735
+ });
1736
+ it("should call getKitItemLimit", async () => {
1737
+ const mockResponse = {
1738
+ request_id: "test-request-id",
1739
+ error: "",
1740
+ message: "",
1741
+ response: { item_limit: { max_items: 10 } },
1742
+ };
1743
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1744
+ const result = await productManager.getKitItemLimit({
1745
+ category_id: 100001,
1746
+ });
1747
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_kit_item_limit", {
1748
+ method: "GET",
1749
+ auth: true,
1750
+ params: {
1751
+ category_id: 100001,
1752
+ },
1753
+ });
1754
+ expect(result.response.item_limit).toBeDefined();
1755
+ });
1756
+ it("should call generateKitImage", async () => {
1757
+ const mockResponse = {
1758
+ request_id: "test-request-id",
1759
+ error: "",
1760
+ message: "",
1761
+ response: {
1762
+ image_info: { image_id: "img123", image_url: "http://example.com/img.jpg" },
1763
+ },
1764
+ };
1765
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1766
+ const result = await productManager.generateKitImage({
1767
+ image_id_list: ["img1", "img2"],
1768
+ });
1769
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/generate_kit_image", {
1770
+ method: "POST",
1771
+ auth: true,
1772
+ body: {
1773
+ image_id_list: ["img1", "img2"],
1774
+ },
1775
+ });
1776
+ expect(result.response.image_info).toBeDefined();
1777
+ });
1778
+ it("should call addSspItem", async () => {
1779
+ const mockResponse = {
1780
+ request_id: "test-request-id",
1781
+ error: "",
1782
+ message: "",
1783
+ response: { item_id: 123456 },
1784
+ };
1785
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1786
+ const result = await productManager.addSspItem({ item_sku: "data" });
1787
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/add_ssp_item", {
1788
+ method: "POST",
1789
+ auth: true,
1790
+ body: { item_sku: "data" },
1791
+ });
1792
+ expect(result.response.item_id).toBe(123456);
1793
+ });
1794
+ it("should call getSspInfo", async () => {
1795
+ const mockResponse = {
1796
+ request_id: "test-request-id",
1797
+ error: "",
1798
+ message: "",
1799
+ response: { ssp_info: { item_id: 123456 } },
1800
+ };
1801
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1802
+ const result = await productManager.getSspInfo({ item_id: 123456 });
1803
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_ssp_info", {
1804
+ method: "GET",
1805
+ auth: true,
1806
+ params: { item_id: 123456 },
1807
+ });
1808
+ expect(result.response.ssp_info).toBeDefined();
1809
+ });
1810
+ it("should call getSspList", async () => {
1811
+ const mockResponse = {
1812
+ request_id: "test-request-id",
1813
+ error: "",
1814
+ message: "",
1815
+ response: {
1816
+ item_list: [{ item_id: 123456 }],
1817
+ has_next_page: false,
1818
+ next_offset: 0,
1819
+ },
1820
+ };
1821
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1822
+ const result = await productManager.getSspList({ offset: 0, page_size: 20 });
1823
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_ssp_list", {
1824
+ method: "GET",
1825
+ auth: true,
1826
+ params: { offset: 0, page_size: 20 },
1827
+ });
1828
+ expect(result.response.item_list).toHaveLength(1);
1829
+ });
1830
+ it("should call linkSsp", async () => {
1831
+ const mockResponse = {
1832
+ request_id: "test-request-id",
1833
+ error: "",
1834
+ message: "",
1835
+ warning: "",
1836
+ };
1837
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1838
+ const result = await productManager.linkSsp({
1839
+ item_id: 123456,
1840
+ ssp_item_id: 789012,
1841
+ });
1842
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/link_ssp", {
1843
+ method: "POST",
1844
+ auth: true,
1845
+ body: {
1846
+ item_id: 123456,
1847
+ ssp_item_id: 789012,
1848
+ },
1849
+ });
1850
+ expect(result.error).toBe("");
1851
+ });
1852
+ it("should call unlinkSsp", async () => {
1853
+ const mockResponse = {
1854
+ request_id: "test-request-id",
1855
+ error: "",
1856
+ message: "",
1857
+ warning: "",
1858
+ };
1859
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1860
+ const result = await productManager.unlinkSsp({ item_id: 123456 });
1861
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/unlink_ssp", {
1862
+ method: "POST",
1863
+ auth: true,
1864
+ body: { item_id: 123456 },
1865
+ });
1866
+ expect(result.error).toBe("");
1867
+ });
1868
+ it("should call updateSipItemPrice", async () => {
1869
+ const mockResponse = {
1870
+ request_id: "test-request-id",
1871
+ error: "",
1872
+ message: "",
1873
+ warning: "",
1874
+ };
1875
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1876
+ const result = await productManager.updateSipItemPrice({
1877
+ item_id: 123456,
1878
+ sip_item_price: 99.99,
1879
+ });
1880
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/update_sip_item_price", {
1881
+ method: "POST",
1882
+ auth: true,
1883
+ body: {
1884
+ item_id: 123456,
1885
+ sip_item_price: 99.99,
1886
+ },
1887
+ });
1888
+ expect(result.error).toBe("");
1889
+ });
1890
+ it("should call getSizeChartList", async () => {
1891
+ const mockResponse = {
1892
+ request_id: "test-request-id",
1893
+ error: "",
1894
+ message: "",
1895
+ response: {
1896
+ size_chart_list: [{ chart_id: "chart1" }],
1897
+ has_next_page: false,
1898
+ next_offset: 0,
1899
+ },
1900
+ };
1901
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1902
+ const result = await productManager.getSizeChartList();
1903
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_size_chart_list", {
1904
+ method: "GET",
1905
+ auth: true,
1906
+ params: {},
1907
+ });
1908
+ expect(result.response.size_chart_list).toHaveLength(1);
1909
+ });
1910
+ it("should call getSizeChartDetail", async () => {
1911
+ const mockResponse = {
1912
+ request_id: "test-request-id",
1913
+ error: "",
1914
+ message: "",
1915
+ response: { size_chart: { chart_id: "chart1" } },
1916
+ };
1917
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1918
+ const result = await productManager.getSizeChartDetail({
1919
+ size_chart_id: "chart1",
1920
+ });
1921
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_size_chart_detail", {
1922
+ method: "GET",
1923
+ auth: true,
1924
+ params: {
1925
+ size_chart_id: "chart1",
1926
+ },
1927
+ });
1928
+ expect(result.response.size_chart).toBeDefined();
1929
+ });
1930
+ it("should call getAllVehicleList", async () => {
1931
+ const mockResponse = {
1932
+ request_id: "test-request-id",
1933
+ error: "",
1934
+ message: "",
1935
+ response: { vehicle_list: [{ vehicle_id: 1 }] },
1936
+ };
1937
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1938
+ const result = await productManager.getAllVehicleList();
1939
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_all_vehicle_list", {
1940
+ method: "GET",
1941
+ auth: true,
1942
+ params: {},
1943
+ });
1944
+ expect(result.response.vehicle_list).toHaveLength(1);
1945
+ });
1946
+ it("should call getVehicleListByCompatibilityDetail", async () => {
1947
+ const mockResponse = {
1948
+ request_id: "test-request-id",
1949
+ error: "",
1950
+ message: "",
1951
+ response: { vehicle_list: [{ vehicle_id: 1 }] },
1952
+ };
1953
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1954
+ const result = await productManager.getVehicleListByCompatibilityDetail({
1955
+ item_id: 123456,
1956
+ });
1957
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_vehicle_list_by_compatibility_detail", {
1958
+ method: "GET",
1959
+ auth: true,
1960
+ params: {
1961
+ item_id: 123456,
1962
+ },
1963
+ });
1964
+ expect(result.response.vehicle_list).toHaveLength(1);
1965
+ });
1966
+ it("should call getAitemByPitemId", async () => {
1967
+ const mockResponse = {
1968
+ request_id: "test-request-id",
1969
+ error: "",
1970
+ message: "",
1971
+ response: { item_list: [{ item_id: 123456 }] },
1972
+ };
1973
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1974
+ const result = await productManager.getAitemByPitemId({
1975
+ pitem_id_list: [789012],
1976
+ });
1977
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_aitem_by_pitem_id", {
1978
+ method: "GET",
1979
+ auth: true,
1980
+ params: {
1981
+ pitem_id_list: "789012",
1982
+ },
1983
+ });
1984
+ expect(result.response.item_list).toHaveLength(1);
1985
+ });
1986
+ it("should call getDirectShopRecommendedPrice", async () => {
1987
+ const mockResponse = {
1988
+ request_id: "test-request-id",
1989
+ error: "",
1990
+ message: "",
1991
+ response: { recommended_price: 99.99 },
1992
+ };
1993
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1994
+ const result = await productManager.getDirectShopRecommendedPrice({
1995
+ category_id: 100001,
1996
+ item_name: "Test Item",
1997
+ });
1998
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_direct_shop_recommended_price", {
1999
+ method: "GET",
2000
+ auth: true,
2001
+ params: {
2002
+ category_id: 100001,
2003
+ item_name: "Test Item",
2004
+ },
2005
+ });
2006
+ expect(result.response.recommended_price).toBe(99.99);
2007
+ });
2008
+ it("should call getProductCertificationRule", async () => {
2009
+ const mockResponse = {
2010
+ request_id: "test-request-id",
2011
+ error: "",
2012
+ message: "",
2013
+ response: { certification_list: [{ cert_id: 1 }] },
2014
+ };
2015
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2016
+ const result = await productManager.getProductCertificationRule({
2017
+ category_id: 100001,
2018
+ });
2019
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_product_certification_rule", {
2020
+ method: "POST",
2021
+ auth: true,
2022
+ body: {
2023
+ category_id: 100001,
2024
+ },
2025
+ });
2026
+ expect(result.response.certification_list).toHaveLength(1);
2027
+ });
2028
+ it("should call searchUnpackagedModelList", async () => {
2029
+ const mockResponse = {
2030
+ request_id: "test-request-id",
2031
+ error: "",
2032
+ message: "",
2033
+ response: { model_list: [{ model_id: 1001 }] },
2034
+ };
2035
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2036
+ const result = await productManager.searchUnpackagedModelList({
2037
+ item_id: 123456,
2038
+ search_value: "test",
2039
+ });
2040
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/search_unpackaged_model_list", {
2041
+ method: "POST",
2042
+ auth: true,
2043
+ body: {
2044
+ item_id: 123456,
2045
+ search_value: "test",
2046
+ },
2047
+ });
2048
+ expect(result.response.model_list).toHaveLength(1);
2049
+ });
2050
+ });
2051
+ describe("getMartItemMappingById", () => {
2052
+ it("should get mart item mapping by id successfully", async () => {
2053
+ const mockResponse = {
2054
+ request_id: "test-request-id",
2055
+ error: "",
2056
+ message: "",
2057
+ response: {
2058
+ item_mapping_list: [
2059
+ {
2060
+ mart_item_id: 111111,
2061
+ outlet_item_id: 333333,
2062
+ model_mapping: [
2063
+ {
2064
+ mart_model_id: 1001,
2065
+ outlet_model_id: 2001,
2066
+ },
2067
+ ],
2068
+ },
2069
+ ],
2070
+ },
2071
+ };
2072
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2073
+ const result = await productManager.getMartItemMappingById({
2074
+ mart_item_id: 111111,
2075
+ outlet_shop_id_list: [222222, 444444],
2076
+ });
2077
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_mart_item_mapping_by_id", {
2078
+ method: "POST",
2079
+ auth: true,
2080
+ body: {
2081
+ mart_item_id: 111111,
2082
+ outlet_shop_id_list: [222222, 444444],
2083
+ },
2084
+ });
2085
+ expect(result.error).toBe("");
2086
+ expect(result.response?.item_mapping_list).toHaveLength(1);
2087
+ expect(result.response?.item_mapping_list?.[0].mart_item_id).toBe(111111);
2088
+ expect(result.response?.item_mapping_list?.[0].outlet_item_id).toBe(333333);
2089
+ });
2090
+ it("should handle error when getting mart item mapping", async () => {
2091
+ const mockResponse = {
2092
+ request_id: "test-request-id",
2093
+ error: "error_param",
2094
+ message: "Invalid mart_item_id",
2095
+ response: {
2096
+ item_mapping_list: [],
2097
+ },
2098
+ };
2099
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2100
+ const result = await productManager.getMartItemMappingById({
2101
+ mart_item_id: 999999,
2102
+ outlet_shop_id_list: [222222],
2103
+ });
2104
+ expect(result.error).toBe("error_param");
2105
+ expect(result.message).toBe("Invalid mart_item_id");
2106
+ });
2107
+ });
2108
+ describe("getMartItemByOutletItemId", () => {
2109
+ it("should get mart item mapping by outlet item id successfully", async () => {
2110
+ const mockResponse = {
2111
+ request_id: "test-request-id",
2112
+ error: "",
2113
+ message: "",
2114
+ response: {
2115
+ item_mapping_list: [
2116
+ {
2117
+ mart_item_id: 111111,
2118
+ outlet_item_id: 333333,
2119
+ model_mapping: [
2120
+ {
2121
+ mart_model_id: 123,
2122
+ outlet_model_id: 456,
2123
+ },
2124
+ ],
2125
+ },
2126
+ ],
2127
+ },
2128
+ };
2129
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2130
+ const result = await productManager.getMartItemByOutletItemId({
2131
+ outlet_item_id: 333333,
2132
+ });
2133
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/get_mart_item_by_outlet_item_id", {
2134
+ method: "POST",
2135
+ auth: true,
2136
+ body: {
2137
+ outlet_item_id: 333333,
2138
+ },
2139
+ });
2140
+ expect(result.error).toBe("");
2141
+ expect(result.response?.item_mapping_list).toHaveLength(1);
2142
+ expect(result.response?.item_mapping_list?.[0].mart_item_id).toBe(111111);
2143
+ });
2144
+ });
2145
+ describe("publishItemToOutletShop", () => {
2146
+ it("should publish item to outlet shop successfully", async () => {
2147
+ const mockResponse = {
2148
+ request_id: "test-request-id",
2149
+ error: "",
2150
+ message: "",
2151
+ response: {
2152
+ item_id: 333333,
2153
+ },
2154
+ };
2155
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2156
+ const result = await productManager.publishItemToOutletShop({
2157
+ mart_item_id: 111111,
2158
+ outlet_shop_id: 222222,
2159
+ publish_item: {
2160
+ model: [
2161
+ {
2162
+ relate_mart_model_id: 0,
2163
+ original_price: 99.99,
2164
+ seller_stock: [{ stock: 100 }],
2165
+ pre_order: { is_pre_order: false },
2166
+ },
2167
+ ],
2168
+ },
2169
+ });
2170
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/product/publish_item_to_outlet_shop", {
2171
+ method: "POST",
2172
+ auth: true,
2173
+ body: {
2174
+ mart_item_id: 111111,
2175
+ outlet_shop_id: 222222,
2176
+ publish_item: {
2177
+ model: [
2178
+ {
2179
+ relate_mart_model_id: 0,
2180
+ original_price: 99.99,
2181
+ seller_stock: [{ stock: 100 }],
2182
+ pre_order: { is_pre_order: false },
2183
+ },
2184
+ ],
2185
+ },
2186
+ },
2187
+ });
2188
+ expect(result.error).toBe("");
2189
+ expect(result.response?.item_id).toBe(333333);
2190
+ });
2191
+ it("should publish item with full config including logistics and purchase limits", async () => {
2192
+ const mockResponse = {
2193
+ request_id: "test-request-id",
2194
+ error: "",
2195
+ message: "",
2196
+ response: {
2197
+ item_id: 444444,
2198
+ },
2199
+ };
2200
+ mockShopeeFetch.mockResolvedValue(mockResponse);
2201
+ const result = await productManager.publishItemToOutletShop({
2202
+ mart_item_id: 111111,
2203
+ outlet_shop_id: 222222,
2204
+ publish_item: {
2205
+ model: [
2206
+ {
2207
+ relate_mart_model_id: 100001,
2208
+ original_price: 150.0,
2209
+ seller_stock: [{ location_id: "LOC001", stock: 50 }],
2210
+ pre_order: { is_pre_order: false },
2211
+ },
2212
+ {
2213
+ relate_mart_model_id: 100002,
2214
+ original_price: 200.0,
2215
+ seller_stock: [{ location_id: "LOC001", stock: 30 }],
2216
+ pre_order: { is_pre_order: true, days_to_ship: 5 },
2217
+ },
2218
+ ],
2219
+ logistic_info: [
2220
+ {
2221
+ logistic_id: 90001,
2222
+ enabled: true,
2223
+ shipping_fee: 5.0,
2224
+ is_free: false,
2225
+ },
2226
+ ],
2227
+ purchase_limit_info: {
2228
+ min_purchase_limit: 1,
2229
+ max_purchase_limit: { purchase_limit: 10 },
2230
+ },
2231
+ },
2232
+ });
2233
+ expect(result.error).toBe("");
2234
+ expect(result.response?.item_id).toBe(444444);
2235
+ });
2236
+ });
2237
+ describe("Default Params Coverage", () => {
2238
+ it("should cover ProductManager methods with default parameters", async () => {
2239
+ mockShopeeFetch.mockResolvedValue({ response: {} });
2240
+ await productManager.getMainItemList(undefined);
2241
+ await productManager.getDirectItemList(undefined);
2242
+ await productManager.getSspList(undefined);
2243
+ expect(mockShopeeFetch).toHaveBeenCalledTimes(3);
2244
+ });
2245
+ });
2246
+ });
2247
+ //# sourceMappingURL=product.manager.test.js.map