@easyflow/javascript-sdk 2.1.8 → 2.1.9

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 (94) hide show
  1. package/README.md +71 -7
  2. package/dist/index.d.ts +421 -0
  3. package/package.json +19 -6
  4. package/.babelrc +0 -5
  5. package/.github/workflows/deploy-sdk-cf.yml +0 -49
  6. package/.github/workflows/release-sdk-cdn.yml +0 -144
  7. package/.github/workflows/release-sdk.yml +0 -112
  8. package/.prettierrc +0 -6
  9. package/CDN-DEPLOYMENT.md +0 -175
  10. package/DEMO.md +0 -258
  11. package/DEPLOYMENT.md +0 -224
  12. package/INTEGRATION-GUIDE.md +0 -521
  13. package/coverage/base.css +0 -224
  14. package/coverage/block-navigation.js +0 -87
  15. package/coverage/easyflow-javascript-sdk/index.html +0 -116
  16. package/coverage/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
  17. package/coverage/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
  18. package/coverage/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
  19. package/coverage/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
  20. package/coverage/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
  21. package/coverage/easyflow-javascript-sdk/libs/index.html +0 -266
  22. package/coverage/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
  23. package/coverage/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
  24. package/coverage/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
  25. package/coverage/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
  26. package/coverage/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
  27. package/coverage/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
  28. package/coverage/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
  29. package/coverage/favicon.png +0 -0
  30. package/coverage/index.html +0 -131
  31. package/coverage/lcov-report/base.css +0 -224
  32. package/coverage/lcov-report/block-navigation.js +0 -87
  33. package/coverage/lcov-report/easyflow-javascript-sdk/index.html +0 -116
  34. package/coverage/lcov-report/easyflow-javascript-sdk/libs/constants.mjs.html +0 -268
  35. package/coverage/lcov-report/easyflow-javascript-sdk/libs/errors.mjs.html +0 -271
  36. package/coverage/lcov-report/easyflow-javascript-sdk/libs/exception-handler.mjs.html +0 -148
  37. package/coverage/lcov-report/easyflow-javascript-sdk/libs/fingerprint.mjs.html +0 -895
  38. package/coverage/lcov-report/easyflow-javascript-sdk/libs/http.mjs.html +0 -502
  39. package/coverage/lcov-report/easyflow-javascript-sdk/libs/index.html +0 -266
  40. package/coverage/lcov-report/easyflow-javascript-sdk/libs/logger.mjs.html +0 -568
  41. package/coverage/lcov-report/easyflow-javascript-sdk/libs/sanitizer.mjs.html +0 -1099
  42. package/coverage/lcov-report/easyflow-javascript-sdk/libs/security.mjs.html +0 -733
  43. package/coverage/lcov-report/easyflow-javascript-sdk/libs/types.mjs.html +0 -508
  44. package/coverage/lcov-report/easyflow-javascript-sdk/libs/utils.mjs.html +0 -379
  45. package/coverage/lcov-report/easyflow-javascript-sdk/libs/validator.mjs.html +0 -2623
  46. package/coverage/lcov-report/easyflow-javascript-sdk/sdk.mjs.html +0 -2434
  47. package/coverage/lcov-report/favicon.png +0 -0
  48. package/coverage/lcov-report/index.html +0 -131
  49. package/coverage/lcov-report/prettify.css +0 -1
  50. package/coverage/lcov-report/prettify.js +0 -2
  51. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  52. package/coverage/lcov-report/sorter.js +0 -196
  53. package/coverage/lcov.info +0 -1429
  54. package/coverage/prettify.css +0 -1
  55. package/coverage/prettify.js +0 -2
  56. package/coverage/sort-arrow-sprite.png +0 -0
  57. package/coverage/sorter.js +0 -196
  58. package/dist/435.easyflow-sdk.min.js +0 -1
  59. package/dist/easyflow-sdk.min.js +0 -1
  60. package/dist/easyflow-sdk.min.js.LICENSE.txt +0 -1
  61. package/dist/index.html +0 -756
  62. package/docs/index.html +0 -775
  63. package/examples/lovable-integration.html +0 -410
  64. package/index.html +0 -981
  65. package/jest.config.js +0 -37
  66. package/jsdoc.json +0 -42
  67. package/libs/auto-integration.mjs +0 -333
  68. package/libs/constants.mjs +0 -61
  69. package/libs/constants.spec.js +0 -198
  70. package/libs/errors.mjs +0 -62
  71. package/libs/errors.spec.js +0 -178
  72. package/libs/exception-handler.mjs +0 -21
  73. package/libs/exception-handler.spec.js +0 -237
  74. package/libs/fingerprint.mjs +0 -270
  75. package/libs/http.mjs +0 -163
  76. package/libs/http.spec.js +0 -427
  77. package/libs/integration-wrapper.mjs +0 -285
  78. package/libs/logger.mjs +0 -161
  79. package/libs/logger.spec.js +0 -389
  80. package/libs/sanitizer.mjs +0 -340
  81. package/libs/sanitizer.spec.js +0 -583
  82. package/libs/security.mjs +0 -217
  83. package/libs/types.mjs +0 -141
  84. package/libs/utils.mjs +0 -368
  85. package/libs/utils.spec.js +0 -231
  86. package/libs/validator.mjs +0 -952
  87. package/libs/validator.spec.js +0 -615
  88. package/mocks/offer.mock.js +0 -77
  89. package/scripts/publish-npm.sh +0 -82
  90. package/sdk.mjs +0 -945
  91. package/sdk.spec.js +0 -796
  92. package/test-setup.cjs +0 -211
  93. package/test.html +0 -154
  94. package/webpack.config.cjs +0 -41
package/sdk.spec.js DELETED
@@ -1,796 +0,0 @@
1
- import { beforeEach, describe, expect, jest, test } from '@jest/globals'
2
-
3
- await jest.unstable_mockModule('./libs/security.mjs', () => ({
4
- RateLimiter: jest.fn().mockImplementation(() => ({
5
- checkLimit: jest.fn().mockResolvedValue(undefined),
6
- })),
7
- SECURITY_CONFIG: {
8
- PRODUCTION_MODE: false,
9
- },
10
- }))
11
-
12
- await jest.unstable_mockModule('./libs/logger.mjs', () => ({
13
- SecureLogger: jest.fn().mockImplementation(() => ({
14
- info: jest.fn(),
15
- error: jest.fn(),
16
- })),
17
- }))
18
-
19
- await jest.unstable_mockModule('./libs/http.mjs', () => ({
20
- callSecureApi: jest.fn(),
21
- }))
22
-
23
- await jest.unstable_mockModule('./libs/sanitizer.mjs', () => ({
24
- Sanitizer: {
25
- sanitizeInput: jest.fn((input) => {
26
- if (input === '' || input === null || input === undefined) {
27
- return ''
28
- }
29
- return input
30
- }),
31
- sanitizeCreditCard: jest.fn((card) => card),
32
- },
33
- sanitizeOrderData: jest.fn((data) => data),
34
- }))
35
-
36
- await jest.unstable_mockModule('./libs/utils.mjs', () => ({
37
- findPaymentByMethod: jest.fn(),
38
- isValidBankBilletPayment: jest.fn(),
39
- isValidPixPayment: jest.fn(),
40
- mapCreditCardIfNeeded: jest.fn((data) => data),
41
- }))
42
-
43
- await jest.unstable_mockModule('./libs/validator.mjs', () => ({
44
- Validator: {
45
- validateOrderData: jest.fn(),
46
- validateChargeItemsData: jest.fn(),
47
- validateCreditCardData: jest.fn(),
48
- validateBusinessId: jest.fn(),
49
- validateOfferId: jest.fn(),
50
- validateOrderId: jest.fn(),
51
- validateCreditCardToken: jest.fn(),
52
- validateCustomer: jest.fn(),
53
- validatePagination: jest.fn(),
54
- validateEmail: jest.fn(),
55
- validateCPF: jest.fn(),
56
- validateCNPJ: jest.fn(),
57
- validateLegalDocument: jest.fn(),
58
- validatePhone: jest.fn(),
59
- validateAddress: jest.fn(),
60
- validateCustomerId: jest.fn(),
61
- validateCreditCardId: jest.fn(),
62
- },
63
- }))
64
-
65
- const { EasyflowSDK, PAYMENT_METHODS } = await import('./sdk.mjs')
66
- const { SecurityError, ValidationError, NetworkError } = await import(
67
- './libs/errors.mjs'
68
- )
69
- const { callSecureApi } = await import('./libs/http.mjs')
70
- const { Sanitizer } = await import('./libs/sanitizer.mjs')
71
- const { findPaymentByMethod, isValidBankBilletPayment, isValidPixPayment } =
72
- await import('./libs/utils.mjs')
73
-
74
- describe('EasyflowSDK', () => {
75
- let sdk
76
- let mockCallSecureApi
77
-
78
- beforeEach(() => {
79
- jest.clearAllMocks()
80
- mockCallSecureApi = callSecureApi
81
- })
82
-
83
- describe('constructor', () => {
84
- test('should create SDK instance with string businessId', () => {
85
- sdk = new EasyflowSDK('test-business-id')
86
- expect(sdk.config.businessId).toBe('test-business-id')
87
- })
88
-
89
- test('should create SDK instance with object config', () => {
90
- sdk = new EasyflowSDK({ businessId: 'test-business-id' })
91
- expect(sdk.config.businessId).toBe('test-business-id')
92
- })
93
-
94
- test('should throw SecurityError when businessId is missing', () => {
95
- expect(() => new EasyflowSDK()).toThrow(SecurityError)
96
- expect(() => new EasyflowSDK({})).toThrow(SecurityError)
97
- })
98
-
99
- test('should have correct static version', () => {
100
- expect(EasyflowSDK.version).toBeDefined()
101
- expect(EasyflowSDK.version).toMatch(/^\d+\.\d+\.\d+$/)
102
- })
103
- })
104
-
105
- describe('getOffer', () => {
106
- beforeEach(() => {
107
- sdk = new EasyflowSDK('test-business-id')
108
- Sanitizer.sanitizeInput.mockImplementation(
109
- (input) => input || 'offer-123'
110
- )
111
- })
112
-
113
- test('should successfully get offer', async () => {
114
- const mockOffer = { id: 'offer-123', items: [{ id: 'item-1' }] }
115
- mockCallSecureApi.mockResolvedValue({ data: mockOffer })
116
-
117
- const result = await sdk.getOffer('offer-123')
118
-
119
- expect(result).toEqual(mockOffer)
120
- expect(mockCallSecureApi).toHaveBeenCalledWith(
121
- 'get-offer',
122
- { offerId: 'offer-123' },
123
- {}
124
- )
125
- })
126
-
127
- test('should throw ValidationError for invalid offerId', async () => {
128
- Sanitizer.sanitizeInput.mockReturnValue('')
129
-
130
- await expect(sdk.getOffer('')).rejects.toThrow(ValidationError)
131
- })
132
-
133
- test('should throw NetworkError when API returns error', async () => {
134
- mockCallSecureApi.mockResolvedValue({ error: 'API Error' })
135
-
136
- await expect(sdk.getOffer('offer-123')).rejects.toThrow(
137
- NetworkError
138
- )
139
- })
140
-
141
- test('should throw ValidationError when offer not found', async () => {
142
- mockCallSecureApi.mockResolvedValue({ data: null })
143
-
144
- await expect(sdk.getOffer('offer-123')).rejects.toThrow(
145
- ValidationError
146
- )
147
- })
148
- })
149
-
150
- describe('placeOrder', () => {
151
- beforeEach(() => {
152
- sdk = new EasyflowSDK('test-business-id')
153
- Sanitizer.sanitizeInput.mockImplementation((input) => input)
154
- })
155
-
156
- test('should successfully place order', async () => {
157
- const mockOffer = { id: 'offer-123', items: [{ id: 'item-1' }] }
158
- const orderData = {
159
- payments: [{ method: 'credit-card', numberInstallments: 1 }],
160
- }
161
- mockCallSecureApi
162
- .mockResolvedValueOnce({ data: mockOffer })
163
- .mockResolvedValueOnce({ data: { orderId: 'order-123' } })
164
- const result = await sdk.placeOrder('offer-123', orderData)
165
- expect(result).toBe('order-123')
166
- expect(mockCallSecureApi).toHaveBeenCalledTimes(2)
167
- })
168
-
169
- test('should throw ValidationError for invalid offerId', async () => {
170
- Sanitizer.sanitizeInput.mockReturnValue('')
171
-
172
- await expect(sdk.placeOrder('', { payments: [] })).rejects.toThrow(
173
- ValidationError
174
- )
175
- })
176
-
177
- test('should throw ValidationError when offer has no items', async () => {
178
- mockCallSecureApi.mockResolvedValue({ data: { items: [] } })
179
-
180
- await expect(
181
- sdk.placeOrder('offer-123', { payments: [] })
182
- ).rejects.toThrow(ValidationError)
183
- })
184
- })
185
-
186
- describe('getOrder', () => {
187
- beforeEach(() => {
188
- sdk = new EasyflowSDK('test-business-id')
189
- Sanitizer.sanitizeInput.mockImplementation((input) => input)
190
- })
191
-
192
- test('should successfully get order', async () => {
193
- const mockOrder = { id: 'order-123', status: 'pending' }
194
- mockCallSecureApi.mockResolvedValue({ data: mockOrder })
195
- const result = await sdk.getOrder('order-123', {
196
- 'x-fingerprint': 'test-fingerprint',
197
- })
198
- expect(result).toEqual(mockOrder)
199
- expect(mockCallSecureApi).toHaveBeenCalledWith(
200
- 'get-order',
201
- {
202
- orderId: 'order-123',
203
- },
204
- { 'x-fingerprint': 'test-fingerprint' }
205
- )
206
- })
207
- })
208
-
209
- describe('getBankBillet', () => {
210
- beforeEach(() => {
211
- sdk = new EasyflowSDK('test-business-id')
212
- Sanitizer.sanitizeInput.mockImplementation((input) => input)
213
- })
214
-
215
- test('should successfully get bank billet', async () => {
216
- const mockOrder = {
217
- payments: [
218
- {
219
- method: 'bank-billet',
220
- bankBillet: { link: 'test-link' },
221
- },
222
- ],
223
- }
224
-
225
- mockCallSecureApi.mockResolvedValue({ data: mockOrder })
226
- findPaymentByMethod.mockReturnValue({
227
- bankBillet: { link: 'test-link' },
228
- })
229
- isValidBankBilletPayment.mockReturnValue(true)
230
-
231
- const result = await sdk.getBankBillet('order-123')
232
-
233
- expect(result).toEqual({ link: 'test-link' })
234
- })
235
-
236
- test('should return null when bank billet not found', async () => {
237
- const mockOrder = { payments: [] }
238
- mockCallSecureApi.mockResolvedValue({ data: mockOrder })
239
- findPaymentByMethod.mockReturnValue(null)
240
-
241
- const result = await sdk.getBankBillet('order-123')
242
-
243
- expect(result).toBeNull()
244
- })
245
-
246
- test('should throw ValidationError for invalid orderId', async () => {
247
- Sanitizer.sanitizeInput.mockReturnValue('')
248
-
249
- await expect(sdk.getBankBillet('')).rejects.toThrow(ValidationError)
250
- })
251
- })
252
-
253
- describe('charge', () => {
254
- beforeEach(() => {
255
- sdk = new EasyflowSDK('test-business-id')
256
- Sanitizer.sanitizeInput.mockImplementation(
257
- (input) => input || 'test-business-id'
258
- )
259
- })
260
-
261
- test('should successfully process charge', async () => {
262
- const chargeData = {
263
- items: [{ name: 'Product', price: 1000 }],
264
- payments: [{ method: 'pix', numberInstallments: 1 }],
265
- }
266
- mockCallSecureApi.mockImplementation((target, payload) => {
267
- if (target === 'charge') {
268
- if (!payload.businessId)
269
- payload.businessId = 'test-business-id'
270
- return Promise.resolve({ data: { orderId: 'order-123' } })
271
- }
272
- return Promise.resolve({})
273
- })
274
- const result = await sdk.charge(chargeData)
275
- expect(result).toBe('order-123')
276
- expect(mockCallSecureApi).toHaveBeenCalledWith(
277
- 'charge',
278
- expect.objectContaining({
279
- businessId: 'test-business-id',
280
- items: chargeData.items,
281
- payments: chargeData.payments,
282
- }),
283
- {}
284
- )
285
- })
286
-
287
- test('should throw NetworkError when API returns error', async () => {
288
- const chargeData = {
289
- items: [{ name: 'Product', price: 1000 }],
290
- payments: [{ method: 'pix', numberInstallments: 1 }],
291
- }
292
-
293
- mockCallSecureApi.mockResolvedValue({ error: 'Charge failed' })
294
-
295
- await expect(sdk.charge(chargeData)).rejects.toThrow(NetworkError)
296
- })
297
- })
298
-
299
- describe('encrypt', () => {
300
- beforeEach(() => {
301
- sdk = new EasyflowSDK('test-business-id')
302
- })
303
-
304
- test('should successfully encrypt credit card', async () => {
305
- const creditCard = {
306
- cardNumber: '4111111111111111',
307
- holderName: 'John Doe',
308
- month: '12',
309
- year: '2025',
310
- cvv: '123',
311
- }
312
-
313
- mockCallSecureApi.mockResolvedValue({
314
- data: { token: 'encrypted-token' },
315
- })
316
-
317
- const result = await sdk.encrypt(creditCard)
318
-
319
- expect(result).toBe('encrypted-token')
320
- expect(mockCallSecureApi).toHaveBeenCalledWith(
321
- 'encrypt',
322
- creditCard,
323
- {}
324
- )
325
- })
326
-
327
- test('should throw NetworkError when API returns error', async () => {
328
- const creditCard = {
329
- cardNumber: '4111111111111111',
330
- holderName: 'John Doe',
331
- month: '12',
332
- year: '2025',
333
- cvv: '123',
334
- }
335
-
336
- mockCallSecureApi.mockResolvedValue({ error: 'Encryption failed' })
337
-
338
- await expect(sdk.encrypt(creditCard)).rejects.toThrow(NetworkError)
339
- })
340
- })
341
-
342
- describe('getPix', () => {
343
- beforeEach(() => {
344
- sdk = new EasyflowSDK('test-business-id')
345
- Sanitizer.sanitizeInput.mockImplementation((input) => input)
346
- })
347
-
348
- it('should get PIX data for order with PIX payment', async () => {
349
- const mockOrder = {
350
- payments: [
351
- {
352
- method: 'pix',
353
- pix: {
354
- qrCode: 'base64-qr-code',
355
- copyAndPasteCode: 'pix-code',
356
- },
357
- },
358
- ],
359
- }
360
-
361
- mockCallSecureApi.mockResolvedValue({ data: mockOrder })
362
- findPaymentByMethod.mockReturnValue({
363
- pix: {
364
- qrCode: 'base64-qr-code',
365
- copyAndPasteCode: 'pix-code',
366
- },
367
- })
368
- isValidPixPayment.mockReturnValue(true)
369
-
370
- const result = await sdk.getPix('order-123')
371
-
372
- expect(result).toEqual({
373
- qrCode: 'base64-qr-code',
374
- copyAndPasteCode: 'pix-code',
375
- })
376
- expect(mockCallSecureApi).toHaveBeenCalledWith(
377
- 'get-order',
378
- { orderId: 'order-123' },
379
- {}
380
- )
381
- })
382
-
383
- it('should return null for order without PIX payment', async () => {
384
- const mockOrder = {
385
- payments: [
386
- {
387
- method: 'credit-card',
388
- creditCard: { number: '4111111111111111' },
389
- },
390
- ],
391
- }
392
-
393
- mockCallSecureApi.mockResolvedValue({ data: mockOrder })
394
- findPaymentByMethod.mockReturnValue(null)
395
-
396
- const result = await sdk.getPix('order-123')
397
-
398
- expect(result).toBeNull()
399
- })
400
-
401
- it('should throw error for invalid order ID', async () => {
402
- Sanitizer.sanitizeInput.mockReturnValue('')
403
-
404
- await expect(sdk.getPix('')).rejects.toThrow('Invalid order ID')
405
- })
406
- })
407
-
408
- describe('Customer Management', () => {
409
- beforeEach(() => {
410
- Sanitizer.sanitizeInput.mockImplementation((input) => {
411
- if (input === 'test-business-id') {
412
- return 'test-business-id'
413
- }
414
- if (input === '' || input === null || input === undefined) {
415
- return ''
416
- }
417
- return input
418
- })
419
- sdk = new EasyflowSDK('test-business-id')
420
- })
421
-
422
- describe('createCustomer', () => {
423
- it('should create a new customer successfully', async () => {
424
- const customerData = {
425
- name: 'John Doe',
426
- email: 'john@example.com',
427
- document: { type: 'CPF', number: '12345678901' },
428
- phone: {
429
- areaCode: '+55',
430
- ddd: '11',
431
- number: '999999999',
432
- isMobile: true,
433
- },
434
- }
435
-
436
- const mockResponse = {
437
- data: {
438
- customer: {
439
- id: '550e8400-e29b-41d4-a716-446655440000',
440
- ...customerData,
441
- business: {
442
- id: 'business-123',
443
- name: 'Test Business',
444
- },
445
- },
446
- },
447
- }
448
-
449
- mockCallSecureApi.mockResolvedValue(mockResponse)
450
-
451
- const result = await sdk.createCustomer(customerData)
452
-
453
- expect(result).toEqual(mockResponse.data.customer)
454
- expect(mockCallSecureApi).toHaveBeenCalledWith(
455
- 'create-customer',
456
- {
457
- ...customerData,
458
- businessId: 'test-business-id',
459
- },
460
- {}
461
- )
462
- })
463
-
464
- it('should throw error when customer data is missing', async () => {
465
- await expect(sdk.createCustomer(null)).rejects.toThrow(
466
- 'Customer data is required'
467
- )
468
- await expect(sdk.createCustomer('')).rejects.toThrow(
469
- 'Customer data is required'
470
- )
471
- })
472
-
473
- it('should throw error when API returns error', async () => {
474
- mockCallSecureApi.mockResolvedValue({ error: 'API Error' })
475
-
476
- await expect(
477
- sdk.createCustomer({ name: 'John' })
478
- ).rejects.toThrow('API Error')
479
- })
480
- })
481
-
482
- describe('getCustomer', () => {
483
- it('should get customer by ID successfully', async () => {
484
- const mockCustomer = {
485
- id: '550e8400-e29b-41d4-a716-446655440000',
486
- name: 'John Doe',
487
- email: 'john@example.com',
488
- document: {
489
- type: 'CPF',
490
- number: '12345678901',
491
- },
492
- }
493
-
494
- mockCallSecureApi.mockResolvedValue({
495
- data: { customer: mockCustomer },
496
- })
497
-
498
- const result = await sdk.getCustomer(
499
- '550e8400-e29b-41d4-a716-446655440000'
500
- )
501
-
502
- expect(result).toEqual(mockCustomer)
503
- expect(mockCallSecureApi).toHaveBeenCalledWith(
504
- 'get-customer',
505
- {
506
- customerId: '550e8400-e29b-41d4-a716-446655440000',
507
- businessId: 'test-business-id',
508
- },
509
- {}
510
- )
511
- })
512
-
513
- it('should throw error for invalid customer ID', async () => {
514
- Sanitizer.sanitizeInput.mockReturnValue('')
515
-
516
- await expect(sdk.getCustomer('')).rejects.toThrow(
517
- 'Invalid customer ID'
518
- )
519
- })
520
-
521
- it('should throw error when customer not found', async () => {
522
- mockCallSecureApi.mockResolvedValue({ data: null })
523
-
524
- await expect(
525
- sdk.getCustomer('550e8400-e29b-41d4-a716-446655440000')
526
- ).rejects.toThrow('Customer not found')
527
- })
528
- })
529
-
530
- describe('updateCustomer', () => {
531
- it('should update customer successfully', async () => {
532
- const updateData = {
533
- name: 'John Updated',
534
- email: 'john.updated@example.com',
535
- }
536
-
537
- const mockResponse = { data: { updated: true } }
538
- mockCallSecureApi.mockResolvedValue(mockResponse)
539
-
540
- const result = await sdk.updateCustomer(
541
- '550e8400-e29b-41d4-a716-446655440000',
542
- updateData
543
- )
544
-
545
- expect(result).toEqual({ updated: true })
546
- expect(mockCallSecureApi).toHaveBeenCalledWith(
547
- 'update-customer',
548
- {
549
- customerId: '550e8400-e29b-41d4-a716-446655440000',
550
- businessId: 'test-business-id',
551
- ...updateData,
552
- },
553
- {}
554
- )
555
- })
556
-
557
- it('should throw error for invalid customer ID', async () => {
558
- Sanitizer.sanitizeInput.mockReturnValue('')
559
-
560
- await expect(
561
- sdk.updateCustomer('', { name: 'John' })
562
- ).rejects.toThrow('Invalid customer ID')
563
- })
564
-
565
- it('should throw error when update data is missing', async () => {
566
- await expect(
567
- sdk.updateCustomer(
568
- '550e8400-e29b-41d4-a716-446655440000',
569
- null
570
- )
571
- ).rejects.toThrow('Customer update data is required')
572
- })
573
- })
574
- })
575
-
576
- describe('Credit Card Management', () => {
577
- beforeEach(() => {
578
- Sanitizer.sanitizeInput.mockImplementation((input) => {
579
- if (input === 'test-business-id') {
580
- return 'test-business-id'
581
- }
582
- if (input === '' || input === null || input === undefined) {
583
- return ''
584
- }
585
- return input
586
- })
587
- sdk = new EasyflowSDK('test-business-id')
588
- })
589
-
590
- describe('addCreditCard', () => {
591
- it('should add credit card successfully', async () => {
592
- const mockResponse = {
593
- data: {
594
- creditCardId: 'card-123',
595
- creditCard: { creditCardId: 'card-123' },
596
- },
597
- }
598
- mockCallSecureApi.mockResolvedValue(mockResponse)
599
-
600
- const result = await sdk.addCreditCard(
601
- 'customer-1234567890123456',
602
- 'encrypted-token-456'
603
- )
604
-
605
- expect(result).toEqual({ creditCardId: 'card-123' })
606
- expect(mockCallSecureApi).toHaveBeenCalledWith(
607
- 'add-credit-card',
608
- {
609
- customerId: 'customer-1234567890123456',
610
- businessId: 'test-business-id',
611
- creditCardToken: 'encrypted-token-456',
612
- },
613
- {}
614
- )
615
- })
616
-
617
- it('should throw error for invalid customer ID', async () => {
618
- Sanitizer.sanitizeInput.mockImplementation((input) => {
619
- if (input === 'test-business-id') return 'test-business-id'
620
- if (input === '') return ''
621
- return input
622
- })
623
-
624
- await expect(sdk.addCreditCard('', 'token')).rejects.toThrow(
625
- 'Invalid customer ID'
626
- )
627
- })
628
-
629
- it('should throw error for invalid credit card token', async () => {
630
- Sanitizer.sanitizeInput.mockImplementation((input) => {
631
- if (input === 'test-business-id') return 'test-business-id'
632
- if (input === '550e8400-e29b-41d4-a716-446655440000')
633
- return '550e8400-e29b-41d4-a716-446655440000'
634
- if (input === '') return ''
635
- return input
636
- })
637
-
638
- await expect(
639
- sdk.addCreditCard(
640
- '550e8400-e29b-41d4-a716-446655440000',
641
- ''
642
- )
643
- ).rejects.toThrow('Invalid credit card token')
644
- })
645
-
646
- it('should throw error when API returns error', async () => {
647
- mockCallSecureApi.mockResolvedValue({ error: 'API Error' })
648
-
649
- await expect(
650
- sdk.addCreditCard(
651
- '550e8400-e29b-41d4-a716-446655440000',
652
- 'token'
653
- )
654
- ).rejects.toThrow('API Error')
655
- })
656
- })
657
-
658
- describe('removeCreditCard', () => {
659
- it('should remove credit card successfully', async () => {
660
- const mockResponse = { data: { removed: true } }
661
- mockCallSecureApi.mockResolvedValue(mockResponse)
662
-
663
- const result = await sdk.removeCreditCard(
664
- '550e8400-e29b-41d4-a716-446655440000',
665
- 'card-456'
666
- )
667
-
668
- expect(result).toEqual({ removed: true })
669
- expect(mockCallSecureApi).toHaveBeenCalledWith(
670
- 'delete-credit-card',
671
- {
672
- customerId: '550e8400-e29b-41d4-a716-446655440000',
673
- businessId: 'test-business-id',
674
- creditCardId: 'card-456',
675
- },
676
- {}
677
- )
678
- })
679
-
680
- it('should throw error for invalid customer ID', async () => {
681
- Sanitizer.sanitizeInput.mockImplementation((input) => {
682
- if (input === 'test-business-id') return 'test-business-id'
683
- if (input === '') return ''
684
- return input
685
- })
686
-
687
- await expect(
688
- sdk.removeCreditCard('', 'card-456')
689
- ).rejects.toThrow('Invalid customer ID')
690
- })
691
-
692
- it('should throw error for invalid credit card ID', async () => {
693
- Sanitizer.sanitizeInput.mockImplementation((input) => {
694
- if (input === 'test-business-id') return 'test-business-id'
695
- if (input === '550e8400-e29b-41d4-a716-446655440000')
696
- return '550e8400-e29b-41d4-a716-446655440000'
697
- if (input === '') return ''
698
- return input
699
- })
700
-
701
- await expect(
702
- sdk.removeCreditCard(
703
- '550e8400-e29b-41d4-a716-446655440000',
704
- ''
705
- )
706
- ).rejects.toThrow('Invalid credit card ID')
707
- })
708
- })
709
-
710
- describe('getCreditCard', () => {
711
- it('should get credit card successfully', async () => {
712
- const mockResponse = {
713
- data: {
714
- creditCard: {
715
- creditCardId: 'card-456',
716
- brand: 'Visa',
717
- last4Numbers: '1111',
718
- expiresAtMonth: '12',
719
- expiresAtYear: '2025',
720
- },
721
- },
722
- }
723
- mockCallSecureApi.mockResolvedValue(mockResponse)
724
-
725
- const result = await sdk.getCreditCard(
726
- '550e8400-e29b-41d4-a716-446655440000',
727
- 'card-456'
728
- )
729
-
730
- expect(result).toEqual({
731
- creditCardId: 'card-456',
732
- brand: 'Visa',
733
- last4Numbers: '1111',
734
- expiresAtMonth: '12',
735
- expiresAtYear: '2025',
736
- })
737
- expect(mockCallSecureApi).toHaveBeenCalledWith(
738
- 'get-credit-card',
739
- {
740
- customerId: '550e8400-e29b-41d4-a716-446655440000',
741
- businessId: 'test-business-id',
742
- creditCardId: 'card-456',
743
- },
744
- {}
745
- )
746
- })
747
-
748
- it('should throw error for invalid customer ID', async () => {
749
- Sanitizer.sanitizeInput.mockImplementation((input) => {
750
- if (input === 'test-business-id') return 'test-business-id'
751
- if (input === '') return ''
752
- return input
753
- })
754
-
755
- await expect(sdk.getCreditCard('', 'card-456')).rejects.toThrow(
756
- 'Invalid customer ID'
757
- )
758
- })
759
-
760
- it('should throw error for invalid credit card ID', async () => {
761
- Sanitizer.sanitizeInput.mockImplementation((input) => {
762
- if (input === 'test-business-id') return 'test-business-id'
763
- if (input === '550e8400-e29b-41d4-a716-446655440000')
764
- return '550e8400-e29b-41d4-a716-446655440000'
765
- if (input === '') return ''
766
- return input
767
- })
768
-
769
- await expect(
770
- sdk.getCreditCard(
771
- '550e8400-e29b-41d4-a716-446655440000',
772
- ''
773
- )
774
- ).rejects.toThrow('Invalid credit card ID')
775
- })
776
-
777
- it('should throw error when credit card not found', async () => {
778
- const mockResponse = { data: null }
779
- mockCallSecureApi.mockResolvedValue(mockResponse)
780
-
781
- await expect(
782
- sdk.getCreditCard('customer-1234567890123456', 'card-456')
783
- ).rejects.toThrow('Credit card not found')
784
- })
785
- })
786
- })
787
-
788
- describe('PAYMENT_METHODS', () => {
789
- test('should export payment methods constants', () => {
790
- expect(PAYMENT_METHODS).toBeDefined()
791
- expect(PAYMENT_METHODS.CREDIT_CARD).toBe('credit-card')
792
- expect(PAYMENT_METHODS.PIX).toBe('pix')
793
- expect(PAYMENT_METHODS.BANK_BILLET).toBe('bank-billet')
794
- })
795
- })
796
- })