@purchasely/cordova-plugin-purchasely 5.7.2 → 6.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/__tests__/Purchasely.test.js +307 -92
- package/example/config.xml +0 -10
- package/example/e2e/README.md +44 -0
- package/example/e2e/helpers/driver.js +70 -0
- package/example/e2e/package.json +19 -0
- package/example/e2e/specs/bridge.e2e.js +51 -0
- package/example/e2e/specs/dismiss.e2e.js +37 -0
- package/example/e2e/tools/ci_run_e2e.sh +49 -0
- package/example/e2e/tools/ci_run_e2e_ios.sh +46 -0
- package/example/e2e/wdio.android.conf.js +21 -0
- package/example/e2e/wdio.ios.conf.js +19 -0
- package/example/e2e/wdio.shared.conf.js +28 -0
- package/example/package-lock.json +66 -209
- package/example/package.json +9 -5
- package/example/www/index.html +1 -7
- package/example/www/js/index.js +113 -92
- package/package.json +1 -1
- package/plugin.xml +3 -22
- package/src/android/PurchaselyPlugin.kt +529 -440
- package/src/ios/CDVPurchasely+Events.h +1 -1
- package/src/ios/CDVPurchasely+UserAttributes.h +1 -1
- package/src/ios/CDVPurchasely+UserAttributes.m +2 -0
- package/src/ios/CDVPurchasely.h +21 -16
- package/src/ios/CDVPurchasely.m +493 -257
- package/www/Purchasely.js +208 -40
- package/src/android/PLYProductActivity.kt +0 -168
- package/src/android/PLYSubscriptionsActivity.java +0 -37
- package/src/android/activity_ply_product_activity.xml +0 -6
- package/src/android/activity_ply_subscriptions_activity.xml +0 -6
- package/src/android/theme_purchasely_fullscreen.xml +0 -6
- package/src/android/theme_purchasely_fullscreen_v23.xml +0 -6
- package/src/android/theme_purchasely_fullscreen_v23_light_status_bar.xml +0 -7
package/README.md
CHANGED
|
@@ -10,15 +10,19 @@ cordova plugin add @purchasely/cordova-plugin-purchasely
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
+
> **Upgrading from 5.x?** See [MIGRATION-v6.md](../MIGRATION-v6.md).
|
|
14
|
+
|
|
13
15
|
```js
|
|
14
|
-
Purchasely.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Purchasely.start(
|
|
17
|
+
{
|
|
18
|
+
apiKey: 'API_KEY',
|
|
19
|
+
stores: [Purchasely.Store.google], // Android stores: Store.google, Store.huawei, Store.amazon
|
|
20
|
+
appUserId: null, // your user id
|
|
21
|
+
logLevel: Purchasely.LogLevel.DEBUG, // should be warning or error in production
|
|
22
|
+
runningMode: Purchasely.RunningMode.full // observer or full (defaults to observer)
|
|
23
|
+
},
|
|
20
24
|
(isConfigured) => {
|
|
21
|
-
if(isConfigured) // you can use the SDK like display a paywall or make a purchase
|
|
25
|
+
if(isConfigured) {} // you can use the SDK like display a paywall or make a purchase
|
|
22
26
|
},
|
|
23
27
|
(error) => {
|
|
24
28
|
console.log(error);
|
|
@@ -28,7 +32,7 @@ Purchasely.startWithAPIKey(
|
|
|
28
32
|
Purchasely.presentPresentationWithIdentifier(
|
|
29
33
|
'my_presentation_id', // may be null
|
|
30
34
|
'my_content_id', // may be null
|
|
31
|
-
|
|
35
|
+
Purchasely.TransitionType.fullScreen, // display mode
|
|
32
36
|
(callback) => {
|
|
33
37
|
console.log(callback);
|
|
34
38
|
if(callback.result == Purchasely.PurchaseResult.CANCELLED) {
|
|
@@ -97,24 +97,82 @@ describe('Purchasely', () => {
|
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
describe('RunningMode', () => {
|
|
100
|
-
it('should
|
|
101
|
-
expect(Purchasely.RunningMode.
|
|
102
|
-
expect(Purchasely.RunningMode.full).toBe(
|
|
100
|
+
it('should expose the Purchasely 6.0 running modes by name', () => {
|
|
101
|
+
expect(Purchasely.RunningMode.observer).toBe('observer');
|
|
102
|
+
expect(Purchasely.RunningMode.full).toBe('full');
|
|
103
103
|
});
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
-
describe('
|
|
107
|
-
it('should have correct
|
|
108
|
-
expect(Purchasely.
|
|
109
|
-
expect(Purchasely.
|
|
110
|
-
expect(Purchasely.
|
|
111
|
-
expect(Purchasely.
|
|
112
|
-
expect(Purchasely.
|
|
113
|
-
expect(Purchasely.
|
|
114
|
-
expect(Purchasely.
|
|
115
|
-
expect(Purchasely.
|
|
116
|
-
expect(Purchasely.
|
|
117
|
-
expect(Purchasely.
|
|
106
|
+
describe('PresentationAction', () => {
|
|
107
|
+
it('should have correct presentation action values', () => {
|
|
108
|
+
expect(Purchasely.PresentationAction.close).toBe('close');
|
|
109
|
+
expect(Purchasely.PresentationAction.close_all).toBe('close_all');
|
|
110
|
+
expect(Purchasely.PresentationAction.login).toBe('login');
|
|
111
|
+
expect(Purchasely.PresentationAction.navigate).toBe('navigate');
|
|
112
|
+
expect(Purchasely.PresentationAction.purchase).toBe('purchase');
|
|
113
|
+
expect(Purchasely.PresentationAction.restore).toBe('restore');
|
|
114
|
+
expect(Purchasely.PresentationAction.open_presentation).toBe('open_presentation');
|
|
115
|
+
expect(Purchasely.PresentationAction.open_placement).toBe('open_placement');
|
|
116
|
+
expect(Purchasely.PresentationAction.promo_code).toBe('promo_code');
|
|
117
|
+
expect(Purchasely.PresentationAction.web_checkout).toBe('web_checkout');
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe('InterceptResult', () => {
|
|
122
|
+
it('should have correct intercept result values', () => {
|
|
123
|
+
expect(Purchasely.InterceptResult.success).toBe('success');
|
|
124
|
+
expect(Purchasely.InterceptResult.failed).toBe('failed');
|
|
125
|
+
expect(Purchasely.InterceptResult.notHandled).toBe('notHandled');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('PresentationType', () => {
|
|
130
|
+
it('should have correct presentation type values', () => {
|
|
131
|
+
expect(Purchasely.PresentationType.normal).toBe(0);
|
|
132
|
+
expect(Purchasely.PresentationType.fallback).toBe(1);
|
|
133
|
+
expect(Purchasely.PresentationType.deactivated).toBe(2);
|
|
134
|
+
expect(Purchasely.PresentationType.client).toBe(3);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('CloseReason', () => {
|
|
139
|
+
it('should have correct close reason values', () => {
|
|
140
|
+
expect(Purchasely.CloseReason.button).toBe('button');
|
|
141
|
+
expect(Purchasely.CloseReason.backSystem).toBe('back_system');
|
|
142
|
+
expect(Purchasely.CloseReason.programmatic).toBe('programmatic');
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('TransitionType', () => {
|
|
147
|
+
it('should have correct transition type values', () => {
|
|
148
|
+
expect(Purchasely.TransitionType.fullScreen).toBe('fullScreen');
|
|
149
|
+
expect(Purchasely.TransitionType.modal).toBe('modal');
|
|
150
|
+
expect(Purchasely.TransitionType.drawer).toBe('drawer');
|
|
151
|
+
expect(Purchasely.TransitionType.popin).toBe('popin');
|
|
152
|
+
expect(Purchasely.TransitionType.push).toBe('push');
|
|
153
|
+
expect(Purchasely.TransitionType.inlinePaywall).toBe('inlinePaywall');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('DimensionType', () => {
|
|
158
|
+
it('should have correct dimension type values', () => {
|
|
159
|
+
expect(Purchasely.DimensionType.pixel).toBe('pixel');
|
|
160
|
+
expect(Purchasely.DimensionType.percentage).toBe('percentage');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe('Store', () => {
|
|
165
|
+
it('should have correct store values', () => {
|
|
166
|
+
expect(Purchasely.Store.google).toBe('Google');
|
|
167
|
+
expect(Purchasely.Store.huawei).toBe('Huawei');
|
|
168
|
+
expect(Purchasely.Store.amazon).toBe('Amazon');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe('StorekitVersion', () => {
|
|
173
|
+
it('should have correct storekit version values', () => {
|
|
174
|
+
expect(Purchasely.StorekitVersion.storeKit1).toBe('storeKit1');
|
|
175
|
+
expect(Purchasely.StorekitVersion.storeKit2).toBe('storeKit2');
|
|
118
176
|
});
|
|
119
177
|
});
|
|
120
178
|
|
|
@@ -135,18 +193,39 @@ describe('Purchasely', () => {
|
|
|
135
193
|
});
|
|
136
194
|
|
|
137
195
|
describe('start', () => {
|
|
138
|
-
it('should call exec with
|
|
196
|
+
it('should call exec with a single options object (with sdkVersion appended)', () => {
|
|
139
197
|
const success = jest.fn();
|
|
140
198
|
const error = jest.fn();
|
|
141
199
|
|
|
142
|
-
Purchasely.start(
|
|
200
|
+
Purchasely.start(
|
|
201
|
+
{
|
|
202
|
+
apiKey: 'API_KEY',
|
|
203
|
+
stores: [Purchasely.Store.google],
|
|
204
|
+
storeKit1: false,
|
|
205
|
+
appUserId: 'user123',
|
|
206
|
+
logLevel: Purchasely.LogLevel.INFO,
|
|
207
|
+
runningMode: Purchasely.RunningMode.full
|
|
208
|
+
},
|
|
209
|
+
success,
|
|
210
|
+
error
|
|
211
|
+
);
|
|
143
212
|
|
|
144
213
|
expect(mockExec).toHaveBeenCalledWith(
|
|
145
214
|
success,
|
|
146
215
|
error,
|
|
147
216
|
'Purchasely',
|
|
148
217
|
'start',
|
|
149
|
-
[
|
|
218
|
+
[
|
|
219
|
+
{
|
|
220
|
+
apiKey: 'API_KEY',
|
|
221
|
+
stores: ['Google'],
|
|
222
|
+
storeKit1: false,
|
|
223
|
+
appUserId: 'user123',
|
|
224
|
+
logLevel: 1,
|
|
225
|
+
runningMode: 'full',
|
|
226
|
+
sdkVersion: '5.6.2'
|
|
227
|
+
}
|
|
228
|
+
]
|
|
150
229
|
);
|
|
151
230
|
});
|
|
152
231
|
});
|
|
@@ -270,33 +349,56 @@ describe('Purchasely', () => {
|
|
|
270
349
|
});
|
|
271
350
|
});
|
|
272
351
|
|
|
273
|
-
describe('
|
|
352
|
+
describe('allowDeeplink', () => {
|
|
274
353
|
it('should call exec with correct parameters', () => {
|
|
275
|
-
Purchasely.
|
|
354
|
+
Purchasely.allowDeeplink(true);
|
|
276
355
|
|
|
277
356
|
expect(mockExec).toHaveBeenCalledWith(
|
|
278
357
|
expect.any(Function),
|
|
279
358
|
expect.any(Function),
|
|
280
359
|
'Purchasely',
|
|
281
|
-
'
|
|
360
|
+
'allowDeeplink',
|
|
282
361
|
[true]
|
|
283
362
|
);
|
|
284
363
|
});
|
|
285
364
|
});
|
|
286
365
|
|
|
287
|
-
describe('
|
|
366
|
+
describe('allowCampaigns', () => {
|
|
367
|
+
it('should call exec with correct parameters', () => {
|
|
368
|
+
Purchasely.allowCampaigns(false);
|
|
369
|
+
|
|
370
|
+
expect(mockExec).toHaveBeenCalledWith(
|
|
371
|
+
expect.any(Function),
|
|
372
|
+
expect.any(Function),
|
|
373
|
+
'Purchasely',
|
|
374
|
+
'allowCampaigns',
|
|
375
|
+
[false]
|
|
376
|
+
);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
describe('setDefaultPresentationDismissHandler', () => {
|
|
288
381
|
it('should call exec with correct parameters', () => {
|
|
289
382
|
const success = jest.fn();
|
|
290
383
|
const error = jest.fn();
|
|
291
384
|
|
|
292
|
-
Purchasely.
|
|
385
|
+
Purchasely.setDefaultPresentationDismissHandler(success, error);
|
|
293
386
|
|
|
294
|
-
expect(mockExec).toHaveBeenCalledWith(success, error, 'Purchasely', '
|
|
387
|
+
expect(mockExec).toHaveBeenCalledWith(success, error, 'Purchasely', 'setDefaultPresentationDismissHandler', []);
|
|
295
388
|
});
|
|
296
389
|
});
|
|
297
390
|
|
|
298
391
|
describe('synchronize', () => {
|
|
299
|
-
it('should call exec with
|
|
392
|
+
it('should call exec with the provided callbacks', () => {
|
|
393
|
+
const success = jest.fn();
|
|
394
|
+
const error = jest.fn();
|
|
395
|
+
|
|
396
|
+
Purchasely.synchronize(success, error);
|
|
397
|
+
|
|
398
|
+
expect(mockExec).toHaveBeenCalledWith(success, error, 'Purchasely', 'synchronize', []);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it('should default callbacks when none provided', () => {
|
|
300
402
|
Purchasely.synchronize();
|
|
301
403
|
|
|
302
404
|
expect(mockExec).toHaveBeenCalledWith(
|
|
@@ -310,69 +412,116 @@ describe('Purchasely', () => {
|
|
|
310
412
|
});
|
|
311
413
|
|
|
312
414
|
describe('presentPresentationWithIdentifier', () => {
|
|
313
|
-
it('should
|
|
415
|
+
it('should pass a display-mode string as a transition object', () => {
|
|
416
|
+
const success = jest.fn();
|
|
417
|
+
const error = jest.fn();
|
|
418
|
+
|
|
419
|
+
Purchasely.presentPresentationWithIdentifier('presentation1', 'content1', Purchasely.TransitionType.drawer, success, error);
|
|
420
|
+
|
|
421
|
+
expect(mockExec).toHaveBeenCalledWith(
|
|
422
|
+
expect.any(Function),
|
|
423
|
+
error,
|
|
424
|
+
'Purchasely',
|
|
425
|
+
'presentPresentationWithIdentifier',
|
|
426
|
+
['presentation1', 'content1', { type: 'drawer' }]
|
|
427
|
+
);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('should normalize a legacy isFullscreen=true to fullScreen', () => {
|
|
314
431
|
const success = jest.fn();
|
|
315
432
|
const error = jest.fn();
|
|
316
433
|
|
|
317
434
|
Purchasely.presentPresentationWithIdentifier('presentation1', 'content1', true, success, error);
|
|
318
435
|
|
|
319
436
|
expect(mockExec).toHaveBeenCalledWith(
|
|
320
|
-
|
|
437
|
+
expect.any(Function),
|
|
321
438
|
error,
|
|
322
439
|
'Purchasely',
|
|
323
440
|
'presentPresentationWithIdentifier',
|
|
324
|
-
['presentation1', 'content1',
|
|
441
|
+
['presentation1', 'content1', { type: 'fullScreen' }]
|
|
442
|
+
);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
it('should pass a full transition object (dimensions/dismissible) through unchanged', () => {
|
|
446
|
+
const success = jest.fn();
|
|
447
|
+
const error = jest.fn();
|
|
448
|
+
const transition = { type: 'drawer', dismissible: false, height: { type: 'percentage', value: 0.8 } };
|
|
449
|
+
|
|
450
|
+
Purchasely.presentPresentationWithIdentifier('presentation1', null, transition, success, error);
|
|
451
|
+
|
|
452
|
+
expect(mockExec).toHaveBeenCalledWith(
|
|
453
|
+
expect.any(Function),
|
|
454
|
+
error,
|
|
455
|
+
'Purchasely',
|
|
456
|
+
'presentPresentationWithIdentifier',
|
|
457
|
+
['presentation1', null, transition]
|
|
325
458
|
);
|
|
326
459
|
});
|
|
327
460
|
});
|
|
328
461
|
|
|
329
462
|
describe('presentPresentationForPlacement', () => {
|
|
330
|
-
it('should
|
|
463
|
+
it('should normalize a legacy isFullscreen=false to modal', () => {
|
|
331
464
|
const success = jest.fn();
|
|
332
465
|
const error = jest.fn();
|
|
333
466
|
|
|
334
467
|
Purchasely.presentPresentationForPlacement('placement1', 'content1', false, success, error);
|
|
335
468
|
|
|
336
469
|
expect(mockExec).toHaveBeenCalledWith(
|
|
337
|
-
|
|
470
|
+
expect.any(Function),
|
|
338
471
|
error,
|
|
339
472
|
'Purchasely',
|
|
340
473
|
'presentPresentationForPlacement',
|
|
341
|
-
['placement1', 'content1',
|
|
474
|
+
['placement1', 'content1', { type: 'modal' }]
|
|
342
475
|
);
|
|
343
476
|
});
|
|
344
477
|
});
|
|
345
478
|
|
|
346
|
-
describe('
|
|
347
|
-
it('should
|
|
479
|
+
describe('presentPresentationForDefault', () => {
|
|
480
|
+
it('should present the default presentation with a transition object', () => {
|
|
348
481
|
const success = jest.fn();
|
|
349
482
|
const error = jest.fn();
|
|
350
483
|
|
|
351
|
-
Purchasely.
|
|
484
|
+
Purchasely.presentPresentationForDefault('content1', Purchasely.TransitionType.fullScreen, success, error);
|
|
352
485
|
|
|
353
486
|
expect(mockExec).toHaveBeenCalledWith(
|
|
354
|
-
|
|
487
|
+
expect.any(Function),
|
|
355
488
|
error,
|
|
356
489
|
'Purchasely',
|
|
357
|
-
'
|
|
358
|
-
['
|
|
490
|
+
'presentPresentationForDefault',
|
|
491
|
+
['content1', { type: 'fullScreen' }]
|
|
359
492
|
);
|
|
360
493
|
});
|
|
361
494
|
});
|
|
362
495
|
|
|
363
|
-
describe('
|
|
364
|
-
it('
|
|
496
|
+
describe('presentation lifecycle callbacks', () => {
|
|
497
|
+
it('routes presented/closeRequested envelopes to callbacks and the final outcome to success', () => {
|
|
365
498
|
const success = jest.fn();
|
|
366
|
-
const
|
|
499
|
+
const onPresented = jest.fn();
|
|
500
|
+
const onCloseRequested = jest.fn();
|
|
501
|
+
|
|
502
|
+
Purchasely.presentPresentationForPlacement('p', null, 'fullScreen', success, jest.fn(), { onPresented, onCloseRequested });
|
|
367
503
|
|
|
368
|
-
|
|
504
|
+
const dispatch = mockExec.mock.calls[0][0];
|
|
505
|
+
dispatch({ event: 'presented', presentation: { screenId: 's' } });
|
|
506
|
+
dispatch({ event: 'closeRequested' });
|
|
507
|
+
dispatch({ result: 1, purchaseResult: 'cancelled', closeReason: 'button' });
|
|
508
|
+
|
|
509
|
+
expect(onPresented).toHaveBeenCalledWith({ screenId: 's' }, null);
|
|
510
|
+
expect(onCloseRequested).toHaveBeenCalledTimes(1);
|
|
511
|
+
expect(success).toHaveBeenCalledWith({ result: 1, purchaseResult: 'cancelled', closeReason: 'button' });
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
describe('removeDefaultPresentationDismissHandler', () => {
|
|
516
|
+
it('should call exec with correct parameters', () => {
|
|
517
|
+
Purchasely.removeDefaultPresentationDismissHandler();
|
|
369
518
|
|
|
370
519
|
expect(mockExec).toHaveBeenCalledWith(
|
|
371
|
-
|
|
372
|
-
|
|
520
|
+
expect.any(Function),
|
|
521
|
+
expect.any(Function),
|
|
373
522
|
'Purchasely',
|
|
374
|
-
'
|
|
375
|
-
[
|
|
523
|
+
'removeDefaultPresentationDismissHandler',
|
|
524
|
+
[]
|
|
376
525
|
);
|
|
377
526
|
});
|
|
378
527
|
});
|
|
@@ -411,34 +560,37 @@ describe('Purchasely', () => {
|
|
|
411
560
|
});
|
|
412
561
|
});
|
|
413
562
|
|
|
414
|
-
describe('
|
|
415
|
-
it('should call exec with
|
|
563
|
+
describe('fetchPresentationForDefault', () => {
|
|
564
|
+
it('should call exec with both ids null', () => {
|
|
416
565
|
const success = jest.fn();
|
|
417
566
|
const error = jest.fn();
|
|
418
|
-
const presentation = { id: 'test' };
|
|
419
567
|
|
|
420
|
-
Purchasely.
|
|
568
|
+
Purchasely.fetchPresentationForDefault('content1', success, error);
|
|
421
569
|
|
|
422
570
|
expect(mockExec).toHaveBeenCalledWith(
|
|
423
571
|
success,
|
|
424
572
|
error,
|
|
425
573
|
'Purchasely',
|
|
426
|
-
'
|
|
427
|
-
[
|
|
574
|
+
'fetchPresentation',
|
|
575
|
+
[null, null, 'content1']
|
|
428
576
|
);
|
|
429
577
|
});
|
|
430
578
|
});
|
|
431
579
|
|
|
432
|
-
describe('
|
|
433
|
-
it('should call exec with
|
|
434
|
-
|
|
580
|
+
describe('presentPresentation', () => {
|
|
581
|
+
it('should call exec with a transition object', () => {
|
|
582
|
+
const success = jest.fn();
|
|
583
|
+
const error = jest.fn();
|
|
584
|
+
const presentation = { id: 'test' };
|
|
585
|
+
|
|
586
|
+
Purchasely.presentPresentation(presentation, Purchasely.TransitionType.fullScreen, '#FFFFFF', success, error);
|
|
435
587
|
|
|
436
588
|
expect(mockExec).toHaveBeenCalledWith(
|
|
437
589
|
expect.any(Function),
|
|
438
|
-
|
|
590
|
+
error,
|
|
439
591
|
'Purchasely',
|
|
440
|
-
'
|
|
441
|
-
[]
|
|
592
|
+
'presentPresentation',
|
|
593
|
+
[presentation, { type: 'fullScreen' }, '#FFFFFF']
|
|
442
594
|
);
|
|
443
595
|
});
|
|
444
596
|
});
|
|
@@ -493,18 +645,18 @@ describe('Purchasely', () => {
|
|
|
493
645
|
});
|
|
494
646
|
});
|
|
495
647
|
|
|
496
|
-
describe('
|
|
648
|
+
describe('handleDeeplink', () => {
|
|
497
649
|
it('should call exec with correct parameters', () => {
|
|
498
650
|
const success = jest.fn();
|
|
499
651
|
const error = jest.fn();
|
|
500
652
|
|
|
501
|
-
Purchasely.
|
|
653
|
+
Purchasely.handleDeeplink('https://example.com/deeplink', success, error);
|
|
502
654
|
|
|
503
655
|
expect(mockExec).toHaveBeenCalledWith(
|
|
504
656
|
success,
|
|
505
657
|
error,
|
|
506
658
|
'Purchasely',
|
|
507
|
-
'
|
|
659
|
+
'handleDeeplink',
|
|
508
660
|
['https://example.com/deeplink']
|
|
509
661
|
);
|
|
510
662
|
});
|
|
@@ -559,36 +711,113 @@ describe('Purchasely', () => {
|
|
|
559
711
|
});
|
|
560
712
|
});
|
|
561
713
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
714
|
+
// Flush pending microtasks (the interceptor result is reported through a Promise chain).
|
|
715
|
+
const flush = () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
716
|
+
|
|
717
|
+
// Returns the native success callback exec() was given for a registerActionInterceptor(kind).
|
|
718
|
+
const nativeInterceptorFor = (kind) => {
|
|
719
|
+
const call = mockExec.mock.calls.find(
|
|
720
|
+
(c) => c[3] === 'registerActionInterceptor' && c[4][0] === kind
|
|
721
|
+
);
|
|
722
|
+
return call && call[0];
|
|
723
|
+
};
|
|
565
724
|
|
|
566
|
-
|
|
725
|
+
describe('interceptAction (v6 per-action)', () => {
|
|
726
|
+
it('registers a native interceptor for the given kind', () => {
|
|
727
|
+
Purchasely.interceptAction('purchase', jest.fn());
|
|
567
728
|
|
|
568
729
|
expect(mockExec).toHaveBeenCalledWith(
|
|
569
|
-
|
|
730
|
+
expect.any(Function),
|
|
570
731
|
expect.any(Function),
|
|
571
732
|
'Purchasely',
|
|
572
|
-
'
|
|
573
|
-
[]
|
|
733
|
+
'registerActionInterceptor',
|
|
734
|
+
['purchase']
|
|
735
|
+
);
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
it('invokes the handler with (info, parameters) and reports its result', async () => {
|
|
739
|
+
const handler = jest.fn().mockReturnValue(Purchasely.InterceptResult.success);
|
|
740
|
+
Purchasely.interceptAction('purchase', handler);
|
|
741
|
+
const nativeSuccess = nativeInterceptorFor('purchase');
|
|
742
|
+
mockExec.mockClear();
|
|
743
|
+
|
|
744
|
+
const event = {
|
|
745
|
+
action: 'purchase',
|
|
746
|
+
callbackId: 'purchase#1',
|
|
747
|
+
info: { contentId: 'c1' },
|
|
748
|
+
parameters: { plan: 'p1' },
|
|
749
|
+
};
|
|
750
|
+
nativeSuccess(event);
|
|
751
|
+
await flush();
|
|
752
|
+
|
|
753
|
+
expect(handler).toHaveBeenCalledWith(event.info, event.parameters);
|
|
754
|
+
expect(mockExec).toHaveBeenCalledWith(
|
|
755
|
+
expect.any(Function),
|
|
756
|
+
expect.any(Function),
|
|
757
|
+
'Purchasely',
|
|
758
|
+
'completeActionInterceptor',
|
|
759
|
+
['purchase#1', 'success']
|
|
760
|
+
);
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
it('ignores events whose action does not match the registered kind', async () => {
|
|
764
|
+
const handler = jest.fn();
|
|
765
|
+
Purchasely.interceptAction('restore', handler);
|
|
766
|
+
const nativeSuccess = nativeInterceptorFor('restore');
|
|
767
|
+
|
|
768
|
+
nativeSuccess({ action: 'purchase', callbackId: 'purchase#2' });
|
|
769
|
+
await flush();
|
|
770
|
+
|
|
771
|
+
expect(handler).not.toHaveBeenCalled();
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('reports failed when the handler throws', async () => {
|
|
775
|
+
Purchasely.interceptAction('purchase', () => { throw new Error('boom'); });
|
|
776
|
+
const nativeSuccess = nativeInterceptorFor('purchase');
|
|
777
|
+
mockExec.mockClear();
|
|
778
|
+
|
|
779
|
+
nativeSuccess({ action: 'purchase', callbackId: 'purchase#3' });
|
|
780
|
+
await flush();
|
|
781
|
+
|
|
782
|
+
expect(mockExec).toHaveBeenCalledWith(
|
|
783
|
+
expect.any(Function),
|
|
784
|
+
expect.any(Function),
|
|
785
|
+
'Purchasely',
|
|
786
|
+
'completeActionInterceptor',
|
|
787
|
+
['purchase#3', 'failed']
|
|
574
788
|
);
|
|
575
789
|
});
|
|
576
790
|
});
|
|
577
791
|
|
|
578
|
-
describe('
|
|
579
|
-
it('
|
|
580
|
-
Purchasely.
|
|
792
|
+
describe('removeActionInterceptor', () => {
|
|
793
|
+
it('unregisters a single kind', () => {
|
|
794
|
+
Purchasely.removeActionInterceptor('purchase');
|
|
581
795
|
|
|
582
796
|
expect(mockExec).toHaveBeenCalledWith(
|
|
583
797
|
expect.any(Function),
|
|
584
798
|
expect.any(Function),
|
|
585
799
|
'Purchasely',
|
|
586
|
-
'
|
|
587
|
-
[
|
|
800
|
+
'unregisterActionInterceptor',
|
|
801
|
+
['purchase']
|
|
588
802
|
);
|
|
589
803
|
});
|
|
590
804
|
});
|
|
591
805
|
|
|
806
|
+
describe('removeAllActionInterceptors', () => {
|
|
807
|
+
it('unregisters every registered kind', () => {
|
|
808
|
+
Purchasely.interceptAction('purchase', jest.fn());
|
|
809
|
+
Purchasely.interceptAction('restore', jest.fn());
|
|
810
|
+
mockExec.mockClear();
|
|
811
|
+
|
|
812
|
+
Purchasely.removeAllActionInterceptors();
|
|
813
|
+
|
|
814
|
+
const unregistered = mockExec.mock.calls
|
|
815
|
+
.filter((c) => c[3] === 'unregisterActionInterceptor')
|
|
816
|
+
.map((c) => c[4][0]);
|
|
817
|
+
expect(unregistered).toEqual(expect.arrayContaining(['purchase', 'restore']));
|
|
818
|
+
});
|
|
819
|
+
});
|
|
820
|
+
|
|
592
821
|
describe('userDidConsumeSubscriptionContent', () => {
|
|
593
822
|
it('should call exec with correct parameters', () => {
|
|
594
823
|
Purchasely.userDidConsumeSubscriptionContent();
|
|
@@ -651,43 +880,29 @@ describe('Purchasely', () => {
|
|
|
651
880
|
});
|
|
652
881
|
});
|
|
653
882
|
|
|
654
|
-
describe('
|
|
655
|
-
it('should call exec with correct parameters', () => {
|
|
656
|
-
Purchasely.showPresentation();
|
|
657
|
-
|
|
658
|
-
expect(mockExec).toHaveBeenCalledWith(
|
|
659
|
-
expect.any(Function),
|
|
660
|
-
expect.any(Function),
|
|
661
|
-
'Purchasely',
|
|
662
|
-
'showPresentation',
|
|
663
|
-
[]
|
|
664
|
-
);
|
|
665
|
-
});
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
describe('hidePresentation', () => {
|
|
883
|
+
describe('closePresentation', () => {
|
|
669
884
|
it('should call exec with correct parameters', () => {
|
|
670
|
-
Purchasely.
|
|
885
|
+
Purchasely.closePresentation();
|
|
671
886
|
|
|
672
887
|
expect(mockExec).toHaveBeenCalledWith(
|
|
673
888
|
expect.any(Function),
|
|
674
889
|
expect.any(Function),
|
|
675
890
|
'Purchasely',
|
|
676
|
-
'
|
|
891
|
+
'closePresentation',
|
|
677
892
|
[]
|
|
678
893
|
);
|
|
679
894
|
});
|
|
680
895
|
});
|
|
681
896
|
|
|
682
|
-
describe('
|
|
897
|
+
describe('backPresentation', () => {
|
|
683
898
|
it('should call exec with correct parameters', () => {
|
|
684
|
-
Purchasely.
|
|
899
|
+
Purchasely.backPresentation();
|
|
685
900
|
|
|
686
901
|
expect(mockExec).toHaveBeenCalledWith(
|
|
687
902
|
expect.any(Function),
|
|
688
903
|
expect.any(Function),
|
|
689
904
|
'Purchasely',
|
|
690
|
-
'
|
|
905
|
+
'backPresentation',
|
|
691
906
|
[]
|
|
692
907
|
);
|
|
693
908
|
});
|
package/example/config.xml
CHANGED
|
@@ -19,16 +19,6 @@
|
|
|
19
19
|
<allow-intent href="market:*" />
|
|
20
20
|
<preference name="GradlePluginKotlinEnabled" value="true" />
|
|
21
21
|
<preference name="GradlePluginKotlinVersion" value="2.1.21" />
|
|
22
|
-
<!--<edit-config
|
|
23
|
-
file="AndroidManifest.xml"
|
|
24
|
-
target="/manifest/application/activity[@android:name='cordova.plugin.purchasely.PLYProductActivity']"
|
|
25
|
-
mode="overwrite">
|
|
26
|
-
<activity
|
|
27
|
-
android:label="PLYProductActivity"
|
|
28
|
-
android:name="cordova.plugin.purchasely.PLYProductActivity"
|
|
29
|
-
android:theme="@style/Theme.Purchasely.Fullscreen">
|
|
30
|
-
</activity>
|
|
31
|
-
</edit-config>-->
|
|
32
22
|
</platform>
|
|
33
23
|
<platform name="ios">
|
|
34
24
|
<allow-intent href="itms:*" />
|