@congminh1254/shopee-sdk 1.6.1 → 1.7.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 (154) 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 +227 -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 +65 -3
  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 +43 -8
  123. package/lib/managers/media.manager.js +75 -7
  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 +113 -6
  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/returns.d.ts +38 -1
  145. package/lib/schemas/shop.d.ts +16 -0
  146. package/lib/schemas/video.d.ts +83 -37
  147. package/lib/schemas/voucher.d.ts +2 -0
  148. package/lib/sdk.js +31 -0
  149. package/lib/sdk.js.map +1 -1
  150. package/lib/storage/custom-token-storage.js +2 -0
  151. package/lib/storage/custom-token-storage.js.map +1 -1
  152. package/lib/version.d.ts +1 -1
  153. package/lib/version.js +1 -1
  154. package/package.json +3 -3
@@ -0,0 +1,1016 @@
1
+ import { jest } from "@jest/globals";
2
+ import { AdsManager } from "../../managers/ads.manager.js";
3
+ import { ShopeeRegion } from "../../schemas/region.js";
4
+ import { ShopeeFetch } from "../../fetch.js";
5
+ // Mock ShopeeFetch.fetch static method
6
+ const mockFetch = jest.fn();
7
+ ShopeeFetch.fetch = mockFetch;
8
+ describe("AdsManager", () => {
9
+ let adsManager;
10
+ let mockConfig;
11
+ const mockShopeeFetch = mockFetch;
12
+ beforeEach(() => {
13
+ jest.clearAllMocks();
14
+ mockConfig = {
15
+ partner_id: 12345,
16
+ partner_key: "test_partner_key",
17
+ shop_id: 67890,
18
+ region: ShopeeRegion.GLOBAL,
19
+ base_url: "https://partner.test-stable.shopeemobile.com/api/v2",
20
+ };
21
+ adsManager = new AdsManager(mockConfig);
22
+ });
23
+ describe("getTotalBalance", () => {
24
+ it("should get total balance successfully", async () => {
25
+ const mockResponse = {
26
+ request_id: "test-request-id",
27
+ error: "",
28
+ message: "",
29
+ response: {
30
+ data_timestamp: 1609459200,
31
+ total_balance: 1000.5,
32
+ },
33
+ };
34
+ mockShopeeFetch.mockResolvedValue(mockResponse);
35
+ const result = await adsManager.getTotalBalance();
36
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_total_balance", {
37
+ method: "GET",
38
+ auth: true,
39
+ });
40
+ expect(result.error).toBe("");
41
+ expect(result.response.total_balance).toBe(1000.5);
42
+ });
43
+ it("should handle warning in response", async () => {
44
+ const mockResponse = {
45
+ request_id: "test-request-id",
46
+ error: "",
47
+ message: "",
48
+ response: {
49
+ data_timestamp: 1609459200,
50
+ total_balance: 500,
51
+ },
52
+ warning: "Some data may be delayed",
53
+ };
54
+ mockShopeeFetch.mockResolvedValue(mockResponse);
55
+ const result = await adsManager.getTotalBalance();
56
+ expect(result.warning).toBe("Some data may be delayed");
57
+ });
58
+ });
59
+ describe("getShopToggleInfo", () => {
60
+ it("should get shop toggle info successfully", async () => {
61
+ const mockResponse = {
62
+ request_id: "test-request-id",
63
+ error: "",
64
+ message: "",
65
+ response: {
66
+ data_timestamp: 1609459200,
67
+ auto_top_up: true,
68
+ campaign_surge: false,
69
+ },
70
+ };
71
+ mockShopeeFetch.mockResolvedValue(mockResponse);
72
+ const result = await adsManager.getShopToggleInfo();
73
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_shop_toggle_info", {
74
+ method: "GET",
75
+ auth: true,
76
+ });
77
+ expect(result.error).toBe("");
78
+ expect(result.response.auto_top_up).toBe(true);
79
+ expect(result.response.campaign_surge).toBe(false);
80
+ });
81
+ });
82
+ describe("getRecommendedKeywordList", () => {
83
+ it("should get recommended keyword list successfully", async () => {
84
+ const mockResponse = {
85
+ request_id: "test-request-id",
86
+ error: "",
87
+ message: "",
88
+ response: {
89
+ item_id: 123456,
90
+ suggested_keywords: [
91
+ {
92
+ keyword: "phone case",
93
+ quality_score: 8.5,
94
+ search_volume: 10000,
95
+ suggested_bid: 0.25,
96
+ },
97
+ {
98
+ keyword: "iphone case",
99
+ quality_score: 9.0,
100
+ search_volume: 15000,
101
+ suggested_bid: 0.3,
102
+ },
103
+ ],
104
+ },
105
+ };
106
+ mockShopeeFetch.mockResolvedValue(mockResponse);
107
+ const result = await adsManager.getRecommendedKeywordList({
108
+ item_id: 123456,
109
+ });
110
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_recommended_keyword_list", {
111
+ method: "GET",
112
+ auth: true,
113
+ params: {
114
+ item_id: 123456,
115
+ },
116
+ });
117
+ expect(result.error).toBe("");
118
+ expect(result.response.suggested_keywords).toHaveLength(2);
119
+ expect(result.response.suggested_keywords[0].keyword).toBe("phone case");
120
+ });
121
+ it("should handle optional input_keyword parameter", async () => {
122
+ const mockResponse = {
123
+ request_id: "test-request-id",
124
+ error: "",
125
+ message: "",
126
+ response: {
127
+ item_id: 123456,
128
+ input_keyword: "phone",
129
+ suggested_keywords: [],
130
+ },
131
+ };
132
+ mockShopeeFetch.mockResolvedValue(mockResponse);
133
+ const result = await adsManager.getRecommendedKeywordList({
134
+ item_id: 123456,
135
+ input_keyword: "phone",
136
+ });
137
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_recommended_keyword_list", {
138
+ method: "GET",
139
+ auth: true,
140
+ params: {
141
+ item_id: 123456,
142
+ input_keyword: "phone",
143
+ },
144
+ });
145
+ expect(result.response.input_keyword).toBe("phone");
146
+ });
147
+ });
148
+ describe("getRecommendedItemList", () => {
149
+ it("should get recommended item list successfully", async () => {
150
+ const mockResponse = {
151
+ request_id: "test-request-id",
152
+ error: "",
153
+ message: "",
154
+ response: [
155
+ {
156
+ item_id: 123456,
157
+ item_status_list: ["active"],
158
+ sku_tag_list: ["best_selling"],
159
+ ongoing_ad_type_list: ["search_ads"],
160
+ },
161
+ {
162
+ item_id: 789012,
163
+ item_status_list: ["active"],
164
+ sku_tag_list: ["best_roi"],
165
+ ongoing_ad_type_list: [],
166
+ },
167
+ ],
168
+ };
169
+ mockShopeeFetch.mockResolvedValue(mockResponse);
170
+ const result = await adsManager.getRecommendedItemList();
171
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_recommended_item_list", {
172
+ method: "GET",
173
+ auth: true,
174
+ });
175
+ expect(result.error).toBe("");
176
+ expect(result.response).toHaveLength(2);
177
+ expect(result.response[0].sku_tag_list).toContain("best_selling");
178
+ });
179
+ });
180
+ describe("getAllCpcAdsHourlyPerformance", () => {
181
+ it("should get hourly performance data successfully", async () => {
182
+ const mockResponse = {
183
+ request_id: "test-request-id",
184
+ error: "",
185
+ message: "",
186
+ response: [
187
+ {
188
+ hour: 10,
189
+ date: "01-01-2021",
190
+ impression: 1000,
191
+ clicks: 50,
192
+ ctr: 0.05,
193
+ direct_order: 5,
194
+ broad_order: 10,
195
+ direct_conversions: 5,
196
+ broad_conversions: 10,
197
+ direct_item_sold: 5,
198
+ broad_item_sold: 10,
199
+ direct_gmv: 250.0,
200
+ broad_gmv: 500.0,
201
+ expense: 25.5,
202
+ cost_per_conversion: 5.1,
203
+ direct_roas: 9.8,
204
+ broad_roas: 19.6,
205
+ },
206
+ ],
207
+ };
208
+ mockShopeeFetch.mockResolvedValue(mockResponse);
209
+ const result = await adsManager.getAllCpcAdsHourlyPerformance({
210
+ performance_date: "01-01-2021",
211
+ });
212
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_all_cpc_ads_hourly_performance", {
213
+ method: "GET",
214
+ auth: true,
215
+ params: {
216
+ performance_date: "01-01-2021",
217
+ },
218
+ });
219
+ expect(result.error).toBe("");
220
+ expect(result.response).toHaveLength(1);
221
+ expect(result.response[0].impression).toBe(1000);
222
+ });
223
+ });
224
+ describe("getAllCpcAdsDailyPerformance", () => {
225
+ it("should get daily performance data successfully", async () => {
226
+ const mockResponse = {
227
+ request_id: "test-request-id",
228
+ error: "",
229
+ message: "",
230
+ response: [
231
+ {
232
+ date: "2021-01-01",
233
+ impression: 24000,
234
+ clicks: 1200,
235
+ ctr: 0.05,
236
+ direct_order: 120,
237
+ broad_order: 240,
238
+ direct_conversions: 120,
239
+ broad_conversions: 240,
240
+ direct_item_sold: 120,
241
+ broad_item_sold: 240,
242
+ direct_gmv: 6000.0,
243
+ broad_gmv: 12000.0,
244
+ expense: 600.0,
245
+ cost_per_conversion: 5.0,
246
+ direct_roas: 10.0,
247
+ broad_roas: 20.0,
248
+ },
249
+ ],
250
+ };
251
+ mockShopeeFetch.mockResolvedValue(mockResponse);
252
+ const result = await adsManager.getAllCpcAdsDailyPerformance({
253
+ start_date: "2021-01-01",
254
+ end_date: "2021-01-31",
255
+ });
256
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_all_cpc_ads_daily_performance", {
257
+ method: "GET",
258
+ auth: true,
259
+ params: {
260
+ start_date: "2021-01-01",
261
+ end_date: "2021-01-31",
262
+ },
263
+ });
264
+ expect(result.error).toBe("");
265
+ expect(result.response[0].impression).toBe(24000);
266
+ });
267
+ });
268
+ describe("getProductCampaignDailyPerformance", () => {
269
+ it("should get product campaign daily performance successfully", async () => {
270
+ const mockResponse = {
271
+ request_id: "test-request-id",
272
+ error: "",
273
+ message: "",
274
+ response: [
275
+ {
276
+ shop_id: 12345,
277
+ region: "SG",
278
+ campaign_list: [
279
+ {
280
+ campaign_id: 1001,
281
+ ad_type: "manual",
282
+ campaign_placement: "search",
283
+ ad_name: "Test Ad",
284
+ metrics_list: [
285
+ {
286
+ date: "01-01-2021",
287
+ impression: 5000,
288
+ clicks: 250,
289
+ ctr: 5.0,
290
+ expense: 125.0,
291
+ broad_gmv: 1250.0,
292
+ broad_order: 25,
293
+ broad_order_amount: 25,
294
+ broad_roi: 10.0,
295
+ broad_cir: 10.0,
296
+ cr: 10.0,
297
+ cpc: 0.5,
298
+ direct_order: 25,
299
+ direct_order_amount: 25,
300
+ direct_gmv: 1250.0,
301
+ direct_roi: 10.0,
302
+ direct_cir: 10.0,
303
+ direct_cr: 10.0,
304
+ cpdc: 5.0,
305
+ },
306
+ ],
307
+ },
308
+ ],
309
+ },
310
+ ],
311
+ };
312
+ mockShopeeFetch.mockResolvedValue(mockResponse);
313
+ const result = await adsManager.getProductCampaignDailyPerformance({
314
+ start_date: "2021-01-01",
315
+ end_date: "2021-01-31",
316
+ campaign_id_list: "1001",
317
+ });
318
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_product_campaign_daily_performance", {
319
+ method: "GET",
320
+ auth: true,
321
+ params: {
322
+ start_date: "2021-01-01",
323
+ end_date: "2021-01-31",
324
+ campaign_id_list: "1001",
325
+ },
326
+ });
327
+ expect(result.error).toBe("");
328
+ expect(result.response[0].campaign_list[0].campaign_id).toBe(1001);
329
+ });
330
+ });
331
+ describe("getProductCampaignHourlyPerformance", () => {
332
+ it("should get product campaign hourly performance successfully", async () => {
333
+ const mockResponse = {
334
+ request_id: "test-request-id",
335
+ error: "",
336
+ message: "",
337
+ response: [
338
+ {
339
+ shop_id: 12345,
340
+ region: "SG",
341
+ campaign_list: [
342
+ {
343
+ campaign_id: 1001,
344
+ ad_type: "manual",
345
+ campaign_placement: "search",
346
+ ad_name: "Test Ad",
347
+ metrics_list: [
348
+ {
349
+ hour: 15,
350
+ date: "01-01-2021",
351
+ impression: 200,
352
+ clicks: 10,
353
+ ctr: 5.0,
354
+ expense: 5.0,
355
+ broad_gmv: 50.0,
356
+ broad_order: 1,
357
+ broad_order_amount: 1,
358
+ broad_roi: 10.0,
359
+ broad_cir: 10.0,
360
+ cr: 10.0,
361
+ cpc: 0.5,
362
+ direct_order: 1,
363
+ direct_order_amount: 1,
364
+ direct_gmv: 50.0,
365
+ direct_roi: 10.0,
366
+ direct_cir: 10.0,
367
+ direct_cr: 10.0,
368
+ cpdc: 5.0,
369
+ },
370
+ ],
371
+ },
372
+ ],
373
+ },
374
+ ],
375
+ };
376
+ mockShopeeFetch.mockResolvedValue(mockResponse);
377
+ const result = await adsManager.getProductCampaignHourlyPerformance({
378
+ performance_date: "2021-01-01",
379
+ campaign_id_list: "1001",
380
+ });
381
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_product_campaign_hourly_performance", {
382
+ method: "GET",
383
+ auth: true,
384
+ params: {
385
+ performance_date: "2021-01-01",
386
+ campaign_id_list: "1001",
387
+ },
388
+ });
389
+ expect(result.response[0].campaign_list[0].metrics_list[0].hour).toBe(15);
390
+ });
391
+ });
392
+ describe("getProductLevelCampaignIdList", () => {
393
+ it("should get product level campaign ID list successfully", async () => {
394
+ const mockResponse = {
395
+ request_id: "test-request-id",
396
+ error: "",
397
+ message: "",
398
+ response: {
399
+ shop_id: 12345,
400
+ region: "SG",
401
+ has_next_page: false,
402
+ campaign_list: [
403
+ { ad_type: "manual", campaign_id: 1001 },
404
+ { ad_type: "manual", campaign_id: 1002 },
405
+ { ad_type: "manual", campaign_id: 1003 },
406
+ ],
407
+ },
408
+ };
409
+ mockShopeeFetch.mockResolvedValue(mockResponse);
410
+ const result = await adsManager.getProductLevelCampaignIdList();
411
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_product_level_campaign_id_list", {
412
+ method: "GET",
413
+ auth: true,
414
+ });
415
+ expect(result.error).toBe("");
416
+ expect(result.response.campaign_list).toHaveLength(3);
417
+ expect(result.response.campaign_list[0].campaign_id).toBe(1001);
418
+ });
419
+ });
420
+ describe("getProductLevelCampaignSettingInfo", () => {
421
+ it("should get product level campaign setting info successfully", async () => {
422
+ const mockResponse = {
423
+ request_id: "test-request-id",
424
+ error: "",
425
+ message: "",
426
+ response: {
427
+ shop_id: 12345,
428
+ region: "SG",
429
+ campaign_list: [
430
+ {
431
+ campaign_id: 1001,
432
+ common_info: {
433
+ ad_type: "manual",
434
+ ad_name: "Summer Sale",
435
+ campaign_status: "ongoing",
436
+ bidding_method: "manual",
437
+ campaign_placement: "search",
438
+ campaign_budget: 100.0,
439
+ campaign_duration: {
440
+ start_time: 1609459200,
441
+ end_time: 0,
442
+ },
443
+ item_id_list: [12345],
444
+ },
445
+ },
446
+ ],
447
+ },
448
+ };
449
+ mockShopeeFetch.mockResolvedValue(mockResponse);
450
+ const result = await adsManager.getProductLevelCampaignSettingInfo({
451
+ info_type_list: "1",
452
+ campaign_id_list: "1001",
453
+ });
454
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_product_level_campaign_setting_info", {
455
+ method: "GET",
456
+ auth: true,
457
+ params: {
458
+ info_type_list: "1",
459
+ campaign_id_list: "1001",
460
+ },
461
+ });
462
+ expect(result.error).toBe("");
463
+ expect(result.response.campaign_list[0].common_info?.ad_name).toBe("Summer Sale");
464
+ });
465
+ });
466
+ describe("getProductRecommendedRoiTarget", () => {
467
+ it("should get product recommended ROI target successfully", async () => {
468
+ const mockResponse = {
469
+ request_id: "test-request-id",
470
+ error: "",
471
+ message: "",
472
+ response: {
473
+ lower_bound: {
474
+ value: 3.5,
475
+ percentile: 80,
476
+ },
477
+ exact: {
478
+ value: 5.9,
479
+ percentile: 50,
480
+ },
481
+ upper_bound: {
482
+ value: 8.0,
483
+ percentile: 20,
484
+ },
485
+ },
486
+ };
487
+ mockShopeeFetch.mockResolvedValue(mockResponse);
488
+ const result = await adsManager.getProductRecommendedRoiTarget({
489
+ item_id: 123456,
490
+ reference_id: "test-ref-id",
491
+ });
492
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_product_recommended_roi_target", {
493
+ method: "GET",
494
+ auth: true,
495
+ params: {
496
+ item_id: 123456,
497
+ reference_id: "test-ref-id",
498
+ },
499
+ });
500
+ expect(result.error).toBe("");
501
+ expect(result.response.exact.value).toBe(5.9);
502
+ });
503
+ });
504
+ describe("checkCreateGmsProductCampaignEligibility", () => {
505
+ it("should check eligibility successfully when eligible", async () => {
506
+ const mockResponse = {
507
+ request_id: "test-request-id",
508
+ error: "",
509
+ message: "",
510
+ response: {
511
+ is_eligible: true,
512
+ },
513
+ };
514
+ mockShopeeFetch.mockResolvedValue(mockResponse);
515
+ const result = await adsManager.checkCreateGmsProductCampaignEligibility();
516
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/check_create_gms_product_campaign_eligibility", {
517
+ method: "GET",
518
+ auth: true,
519
+ });
520
+ expect(result.error).toBe("");
521
+ expect(result.response.is_eligible).toBe(true);
522
+ });
523
+ it("should check eligibility with reason when not eligible", async () => {
524
+ const mockResponse = {
525
+ request_id: "test-request-id",
526
+ error: "",
527
+ message: "",
528
+ response: {
529
+ is_eligible: false,
530
+ reason: "active_campaign",
531
+ },
532
+ };
533
+ mockShopeeFetch.mockResolvedValue(mockResponse);
534
+ const result = await adsManager.checkCreateGmsProductCampaignEligibility();
535
+ expect(result.response.is_eligible).toBe(false);
536
+ expect(result.response.reason).toBe("active_campaign");
537
+ });
538
+ });
539
+ describe("createGmsProductCampaign", () => {
540
+ it("should create GMS product campaign successfully", async () => {
541
+ const mockResponse = {
542
+ request_id: "test-request-id",
543
+ error: "",
544
+ message: "",
545
+ response: {
546
+ campaign_id: 111222,
547
+ },
548
+ };
549
+ mockShopeeFetch.mockResolvedValue(mockResponse);
550
+ const result = await adsManager.createGmsProductCampaign({
551
+ start_date: "01-01-2024",
552
+ end_date: "31-01-2024",
553
+ daily_budget: 200.0,
554
+ reference_id: "gms-ref-001",
555
+ roas_target: 5.5,
556
+ });
557
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/create_gms_product_campaign", {
558
+ method: "POST",
559
+ auth: true,
560
+ body: {
561
+ start_date: "01-01-2024",
562
+ end_date: "31-01-2024",
563
+ daily_budget: 200.0,
564
+ reference_id: "gms-ref-001",
565
+ roas_target: 5.5,
566
+ },
567
+ });
568
+ expect(result.error).toBe("");
569
+ expect(result.response.campaign_id).toBe(111222);
570
+ });
571
+ });
572
+ describe("createManualProductAds", () => {
573
+ it("should create manual product ads with auto bidding", async () => {
574
+ const mockResponse = {
575
+ request_id: "test-request-id",
576
+ error: "",
577
+ message: "",
578
+ response: {
579
+ campaign_id: 333444,
580
+ },
581
+ };
582
+ mockShopeeFetch.mockResolvedValue(mockResponse);
583
+ const result = await adsManager.createManualProductAds({
584
+ reference_id: "manual-ref-001",
585
+ budget: 150.0,
586
+ start_date: "01-01-2024",
587
+ bidding_method: "auto",
588
+ item_id: 123456,
589
+ roas_target: 3.0,
590
+ });
591
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/create_manual_product_ads", {
592
+ method: "POST",
593
+ auth: true,
594
+ body: {
595
+ reference_id: "manual-ref-001",
596
+ budget: 150.0,
597
+ start_date: "01-01-2024",
598
+ bidding_method: "auto",
599
+ item_id: 123456,
600
+ roas_target: 3.0,
601
+ },
602
+ });
603
+ expect(result.error).toBe("");
604
+ expect(result.response.campaign_id).toBe(333444);
605
+ });
606
+ it("should create manual product ads with manual bidding and keywords", async () => {
607
+ const mockResponse = {
608
+ request_id: "test-request-id",
609
+ error: "",
610
+ message: "",
611
+ response: {
612
+ campaign_id: 333445,
613
+ },
614
+ };
615
+ mockShopeeFetch.mockResolvedValue(mockResponse);
616
+ const result = await adsManager.createManualProductAds({
617
+ reference_id: "manual-ref-002",
618
+ budget: 100.0,
619
+ start_date: "01-01-2024",
620
+ bidding_method: "manual",
621
+ item_id: 789012,
622
+ selected_keywords: [
623
+ {
624
+ keyword: "phone case",
625
+ match_type: "exact",
626
+ bid_price_per_click: 0.5,
627
+ },
628
+ ],
629
+ enhanced_cpc: true,
630
+ });
631
+ expect(result.response.campaign_id).toBe(333445);
632
+ });
633
+ });
634
+ describe("editGmsItemProductCampaign", () => {
635
+ it("should add items to GMS campaign successfully", async () => {
636
+ const mockResponse = {
637
+ request_id: "test-request-id",
638
+ error: "",
639
+ message: "",
640
+ response: {
641
+ campaign_id: 111222,
642
+ },
643
+ };
644
+ mockShopeeFetch.mockResolvedValue(mockResponse);
645
+ const result = await adsManager.editGmsItemProductCampaign({
646
+ campaign_id: 111222,
647
+ edit_action: "add",
648
+ item_id_list: [123456, 789012],
649
+ });
650
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/edit_gms_item_product_campaign", {
651
+ method: "POST",
652
+ auth: true,
653
+ body: {
654
+ campaign_id: 111222,
655
+ edit_action: "add",
656
+ item_id_list: [123456, 789012],
657
+ },
658
+ });
659
+ expect(result.error).toBe("");
660
+ expect(result.response.campaign_id).toBe(111222);
661
+ });
662
+ it("should remove items from GMS campaign successfully", async () => {
663
+ const mockResponse = {
664
+ request_id: "test-request-id",
665
+ error: "",
666
+ message: "",
667
+ response: {
668
+ campaign_id: 111222,
669
+ },
670
+ };
671
+ mockShopeeFetch.mockResolvedValue(mockResponse);
672
+ const result = await adsManager.editGmsItemProductCampaign({
673
+ campaign_id: 111222,
674
+ edit_action: "remove",
675
+ item_id_list: [789012],
676
+ });
677
+ expect(result.response.campaign_id).toBe(111222);
678
+ });
679
+ });
680
+ describe("editGmsProductCampaign", () => {
681
+ it("should edit GMS product campaign successfully", async () => {
682
+ const mockResponse = {
683
+ request_id: "test-request-id",
684
+ error: "",
685
+ message: "",
686
+ response: {
687
+ campaign_id: 111222,
688
+ },
689
+ };
690
+ mockShopeeFetch.mockResolvedValue(mockResponse);
691
+ const result = await adsManager.editGmsProductCampaign({
692
+ campaign_id: 111222,
693
+ edit_action: "budget",
694
+ daily_budget: 300.0,
695
+ reference_id: "test-ref-gms-123",
696
+ });
697
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/edit_gms_product_campaign", {
698
+ method: "POST",
699
+ auth: true,
700
+ body: {
701
+ campaign_id: 111222,
702
+ edit_action: "budget",
703
+ daily_budget: 300.0,
704
+ reference_id: "test-ref-gms-123",
705
+ },
706
+ });
707
+ expect(result.error).toBe("");
708
+ expect(result.response.campaign_id).toBe(111222);
709
+ });
710
+ });
711
+ describe("editManualProductAdKeywords", () => {
712
+ it("should add keywords to manual product ads successfully", async () => {
713
+ const mockResponse = {
714
+ request_id: "test-request-id",
715
+ error: "",
716
+ message: "",
717
+ response: {
718
+ campaign_id: 333444,
719
+ },
720
+ };
721
+ mockShopeeFetch.mockResolvedValue(mockResponse);
722
+ const result = await adsManager.editManualProductAdKeywords({
723
+ reference_id: "keyword-ref-001",
724
+ campaign_id: 333444,
725
+ edit_action: "add",
726
+ selected_keywords: [
727
+ {
728
+ keyword: "wireless earbuds",
729
+ match_type: "broad",
730
+ bid_price_per_click: 0.75,
731
+ },
732
+ ],
733
+ });
734
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/edit_manual_product_ad_keywords", {
735
+ method: "POST",
736
+ auth: true,
737
+ body: {
738
+ reference_id: "keyword-ref-001",
739
+ campaign_id: 333444,
740
+ edit_action: "add",
741
+ selected_keywords: [
742
+ {
743
+ keyword: "wireless earbuds",
744
+ match_type: "broad",
745
+ bid_price_per_click: 0.75,
746
+ },
747
+ ],
748
+ },
749
+ });
750
+ expect(result.error).toBe("");
751
+ expect(result.response.campaign_id).toBe(333444);
752
+ });
753
+ });
754
+ describe("editManualProductAds", () => {
755
+ it("should edit manual product ads successfully", async () => {
756
+ const mockResponse = {
757
+ request_id: "test-request-id",
758
+ error: "",
759
+ message: "",
760
+ response: {
761
+ campaign_id: 333444,
762
+ },
763
+ };
764
+ mockShopeeFetch.mockResolvedValue(mockResponse);
765
+ const result = await adsManager.editManualProductAds({
766
+ reference_id: "edit-manual-ref-001",
767
+ campaign_id: 333444,
768
+ edit_action: "budget",
769
+ budget: 250.0,
770
+ });
771
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/edit_manual_product_ads", {
772
+ method: "POST",
773
+ auth: true,
774
+ body: {
775
+ reference_id: "edit-manual-ref-001",
776
+ campaign_id: 333444,
777
+ edit_action: "budget",
778
+ budget: 250.0,
779
+ },
780
+ });
781
+ expect(result.error).toBe("");
782
+ expect(result.response.campaign_id).toBe(333444);
783
+ });
784
+ });
785
+ describe("getAdsFacilShopRate", () => {
786
+ it("should get ads facil shop rate successfully", async () => {
787
+ const mockResponse = {
788
+ request_id: "test-request-id",
789
+ error: "",
790
+ message: "",
791
+ response: {
792
+ shop_rate: 0.05,
793
+ },
794
+ };
795
+ mockShopeeFetch.mockResolvedValue(mockResponse);
796
+ const result = await adsManager.getAdsFacilShopRate();
797
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_ads_facil_shop_rate", {
798
+ method: "GET",
799
+ auth: true,
800
+ });
801
+ expect(result.error).toBe("");
802
+ expect(result.response.shop_rate).toBe(0.05);
803
+ });
804
+ });
805
+ describe("getCreateProductAdBudgetSuggestion", () => {
806
+ it("should get budget suggestion for auto product ads", async () => {
807
+ const mockResponse = {
808
+ request_id: "test-request-id",
809
+ error: "",
810
+ message: "",
811
+ response: {
812
+ budget: {
813
+ min_budget: 50.0,
814
+ max_budget: 500.0,
815
+ recommended_budget: 150.0,
816
+ },
817
+ },
818
+ };
819
+ mockShopeeFetch.mockResolvedValue(mockResponse);
820
+ const result = await adsManager.getCreateProductAdBudgetSuggestion({
821
+ reference_id: "budget-ref-001",
822
+ product_selection: "auto",
823
+ campaign_placement: "all",
824
+ bidding_method: "auto",
825
+ });
826
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_create_product_ad_budget_suggestion", {
827
+ method: "GET",
828
+ auth: true,
829
+ params: {
830
+ reference_id: "budget-ref-001",
831
+ product_selection: "auto",
832
+ campaign_placement: "all",
833
+ bidding_method: "auto",
834
+ },
835
+ });
836
+ expect(result.error).toBe("");
837
+ expect(result.response.budget.recommended_budget).toBe(150.0);
838
+ });
839
+ it("should get budget suggestion for manual product ads", async () => {
840
+ const mockResponse = {
841
+ request_id: "test-request-id",
842
+ error: "",
843
+ message: "",
844
+ response: {
845
+ budget: {
846
+ min_budget: 30.0,
847
+ max_budget: 300.0,
848
+ recommended_budget: 100.0,
849
+ },
850
+ },
851
+ };
852
+ mockShopeeFetch.mockResolvedValue(mockResponse);
853
+ const result = await adsManager.getCreateProductAdBudgetSuggestion({
854
+ reference_id: "budget-ref-002",
855
+ product_selection: "manual",
856
+ campaign_placement: "search",
857
+ bidding_method: "manual",
858
+ item_id: 123456,
859
+ enhanced_cpc: "true",
860
+ });
861
+ expect(result.response.budget.min_budget).toBe(30.0);
862
+ });
863
+ });
864
+ describe("getGmsCampaignPerformance", () => {
865
+ it("should get GMS campaign performance successfully", async () => {
866
+ const mockResponse = {
867
+ request_id: "test-request-id",
868
+ error: "",
869
+ message: "",
870
+ response: {
871
+ campaign_id: 111222,
872
+ report: {
873
+ impression: 10000,
874
+ clicks: 500,
875
+ ctr: 5.0,
876
+ expense: 250.0,
877
+ gmv: 2500.0,
878
+ roas: 10.0,
879
+ orders: 100,
880
+ },
881
+ },
882
+ };
883
+ mockShopeeFetch.mockResolvedValue(mockResponse);
884
+ const result = await adsManager.getGmsCampaignPerformance({
885
+ campaign_id: 111222,
886
+ start_date: "01-01-2024",
887
+ end_date: "31-01-2024",
888
+ });
889
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_gms_campaign_performance", {
890
+ method: "POST",
891
+ auth: true,
892
+ body: {
893
+ campaign_id: 111222,
894
+ start_date: "01-01-2024",
895
+ end_date: "31-01-2024",
896
+ },
897
+ });
898
+ expect(result.error).toBe("");
899
+ expect(result.response.campaign_id).toBe(111222);
900
+ expect(result.response.report.roas).toBe(10.0);
901
+ });
902
+ });
903
+ describe("getGmsItemPerformance", () => {
904
+ it("should get GMS item performance successfully", async () => {
905
+ const mockResponse = {
906
+ request_id: "test-request-id",
907
+ error: "",
908
+ message: "",
909
+ response: {
910
+ campaign_id: 111222,
911
+ result_list: [
912
+ {
913
+ item_id: 123456,
914
+ impression: 5000,
915
+ clicks: 250,
916
+ ctr: 5.0,
917
+ expense: 125.0,
918
+ gmv: 1250.0,
919
+ roas: 10.0,
920
+ orders: 50,
921
+ },
922
+ {
923
+ item_id: 789012,
924
+ impression: 5000,
925
+ clicks: 250,
926
+ ctr: 5.0,
927
+ expense: 125.0,
928
+ gmv: 1250.0,
929
+ roas: 10.0,
930
+ orders: 50,
931
+ },
932
+ ],
933
+ total: 2,
934
+ has_next_page: false,
935
+ },
936
+ };
937
+ mockShopeeFetch.mockResolvedValue(mockResponse);
938
+ const result = await adsManager.getGmsItemPerformance({
939
+ campaign_id: 111222,
940
+ start_date: "01-01-2024",
941
+ end_date: "31-01-2024",
942
+ offset: 0,
943
+ limit: 50,
944
+ });
945
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/get_gms_item_performance", {
946
+ method: "POST",
947
+ auth: true,
948
+ body: {
949
+ campaign_id: 111222,
950
+ start_date: "01-01-2024",
951
+ end_date: "31-01-2024",
952
+ offset: 0,
953
+ limit: 50,
954
+ },
955
+ });
956
+ expect(result.error).toBe("");
957
+ expect(result.response.result_list).toHaveLength(2);
958
+ expect(result.response.total).toBe(2);
959
+ expect(result.response.has_next_page).toBe(false);
960
+ });
961
+ });
962
+ describe("listGmsUserDeletedItem", () => {
963
+ it("should list GMS user deleted items successfully", async () => {
964
+ const mockResponse = {
965
+ request_id: "test-request-id",
966
+ error: "",
967
+ message: "",
968
+ response: {
969
+ campaign_id: 111222,
970
+ item_id_list: [123456, 789012],
971
+ total: 2,
972
+ has_next_page: false,
973
+ },
974
+ };
975
+ mockShopeeFetch.mockResolvedValue(mockResponse);
976
+ const result = await adsManager.listGmsUserDeletedItem({
977
+ offset: 0,
978
+ limit: 50,
979
+ });
980
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/list_gms_user_deleted_item", {
981
+ method: "POST",
982
+ auth: true,
983
+ body: {
984
+ offset: 0,
985
+ limit: 50,
986
+ },
987
+ });
988
+ expect(result.error).toBe("");
989
+ expect(result.response.item_id_list).toHaveLength(2);
990
+ expect(result.response.total).toBe(2);
991
+ });
992
+ it("should list GMS user deleted items without parameters", async () => {
993
+ const mockResponse = {
994
+ request_id: "test-request-id",
995
+ error: "",
996
+ message: "",
997
+ response: {
998
+ campaign_id: 111222,
999
+ item_id_list: [],
1000
+ total: 0,
1001
+ has_next_page: false,
1002
+ },
1003
+ };
1004
+ mockShopeeFetch.mockResolvedValue(mockResponse);
1005
+ const result = await adsManager.listGmsUserDeletedItem();
1006
+ expect(mockShopeeFetch).toHaveBeenCalledWith(mockConfig, "/ads/list_gms_user_deleted_item", {
1007
+ method: "POST",
1008
+ auth: true,
1009
+ body: {},
1010
+ });
1011
+ expect(result.error).toBe("");
1012
+ expect(result.response.item_id_list).toHaveLength(0);
1013
+ });
1014
+ });
1015
+ });
1016
+ //# sourceMappingURL=ads.manager.test.js.map