cozy-harvest-lib 13.1.0 → 13.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [13.2.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@13.1.0...cozy-harvest-lib@13.2.0) (2023-02-08)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add triggers realtime to ConnectionFlow ([b46616e](https://github.com/cozy/cozy-libs/commit/b46616ee9212af7609d8497eae7027cf50c7a63d))
12
+
13
+
14
+
15
+
16
+
6
17
  # [13.1.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@13.0.1...cozy-harvest-lib@13.1.0) (2023-02-03)
7
18
 
8
19
 
@@ -174,6 +174,8 @@ export var ConnectionFlow = /*#__PURE__*/function () {
174
174
  this.handleAccountUpdated = this.handleAccountUpdated.bind(this);
175
175
  this.handleCurrentJobUpdated = this.handleCurrentJobUpdated.bind(this);
176
176
  this.handleTriggerJobUpdated = this.handleTriggerJobUpdated.bind(this);
177
+ this.handleTriggerDeleted = this.handleTriggerDeleted.bind(this);
178
+ this.handleTriggerCreated = this.handleTriggerCreated.bind(this);
177
179
  this.handleAccountTwoFA = this.handleAccountTwoFA.bind(this);
178
180
  this.launch = this.launch.bind(this);
179
181
  this.sendTwoFACode = this.sendTwoFACode.bind(this);
@@ -188,6 +190,7 @@ export var ConnectionFlow = /*#__PURE__*/function () {
188
190
  this.realtime = client.plugins.realtime;
189
191
  this.watchCurrentJobIfTriggerIsAlreadyRunning();
190
192
  this.watchTriggerJobs();
193
+ this.watchTriggers();
191
194
  }
192
195
 
193
196
  _createClass(ConnectionFlow, [{
@@ -682,6 +685,30 @@ export var ConnectionFlow = /*#__PURE__*/function () {
682
685
 
683
686
  return handleFormSubmit;
684
687
  }()
688
+ }, {
689
+ key: "handleTriggerCreated",
690
+ value: function handleTriggerCreated(trigger) {
691
+ var _trigger$message;
692
+
693
+ if (this.konnector.slug !== (trigger === null || trigger === void 0 ? void 0 : (_trigger$message = trigger.message) === null || _trigger$message === void 0 ? void 0 : _trigger$message.konnector) || this.trigger !== null) {
694
+ return; // filter out trigger associated to konnector or if a current trigger already exists
695
+ }
696
+
697
+ this.trigger = trigger; // @ts-ignore
698
+
699
+ this.emit(UPDATE_EVENT);
700
+ }
701
+ }, {
702
+ key: "handleTriggerDeleted",
703
+ value: function handleTriggerDeleted(trigger) {
704
+ var _this$trigger;
705
+
706
+ if (((_this$trigger = this.trigger) === null || _this$trigger === void 0 ? void 0 : _this$trigger._id) !== (trigger === null || trigger === void 0 ? void 0 : trigger._id)) return; // filter out trigger associated to current trigger
707
+
708
+ this.reset(); // @ts-ignore
709
+
710
+ this.emit(UPDATE_EVENT);
711
+ }
685
712
  }, {
686
713
  key: "handleAccountUpdated",
687
714
  value: function handleAccountUpdated(account) {
@@ -717,9 +744,9 @@ export var ConnectionFlow = /*#__PURE__*/function () {
717
744
  }, {
718
745
  key: "handleTriggerJobUpdated",
719
746
  value: function handleTriggerJobUpdated(job) {
720
- var _this$trigger, _this$job;
747
+ var _this$trigger2, _this$job;
721
748
 
722
- if (job.trigger_id !== ((_this$trigger = this.trigger) === null || _this$trigger === void 0 ? void 0 : _this$trigger._id)) return; // filter out jobs associated to other triggers
749
+ if (job.trigger_id !== ((_this$trigger2 = this.trigger) === null || _this$trigger2 === void 0 ? void 0 : _this$trigger2._id)) return; // filter out jobs associated to other triggers
723
750
 
724
751
  if (job._id === ((_this$job = this.job) === null || _this$job === void 0 ? void 0 : _this$job._id)) return; // if the event is associated to a job we are already watchin, ignore it. No need to refetch the current trigger in this case
725
752
 
@@ -842,7 +869,7 @@ export var ConnectionFlow = /*#__PURE__*/function () {
842
869
  key: "ensureDefaultFolderPathInAccount",
843
870
  value: function () {
844
871
  var _ensureDefaultFolderPathInAccount = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9(client, _ref5) {
845
- var _trigger$message;
872
+ var _trigger$message2;
846
873
 
847
874
  var trigger, account, konnector, folderId, folder, result, savedAccount;
848
875
  return _regeneratorRuntime.wrap(function _callee9$(_context9) {
@@ -851,7 +878,7 @@ export var ConnectionFlow = /*#__PURE__*/function () {
851
878
  case 0:
852
879
  trigger = _ref5.trigger, account = _ref5.account, konnector = _ref5.konnector;
853
880
  // @ts-ignore the message property does not exist in TriggersDoctype
854
- folderId = trigger === null || trigger === void 0 ? void 0 : (_trigger$message = trigger.message) === null || _trigger$message === void 0 ? void 0 : _trigger$message.folder_to_save;
881
+ folderId = trigger === null || trigger === void 0 ? void 0 : (_trigger$message2 = trigger.message) === null || _trigger$message2 === void 0 ? void 0 : _trigger$message2.folder_to_save;
855
882
 
856
883
  if (folderId) {
857
884
  _context9.next = 4;
@@ -999,17 +1026,27 @@ export var ConnectionFlow = /*#__PURE__*/function () {
999
1026
  }, {
1000
1027
  key: "watchCurrentJobIfTriggerIsAlreadyRunning",
1001
1028
  value: function watchCurrentJobIfTriggerIsAlreadyRunning() {
1002
- var _this$trigger2, _this$trigger2$curren;
1029
+ var _this$trigger3, _this$trigger3$curren;
1003
1030
 
1004
- if (((_this$trigger2 = this.trigger) === null || _this$trigger2 === void 0 ? void 0 : (_this$trigger2$curren = _this$trigger2.current_state) === null || _this$trigger2$curren === void 0 ? void 0 : _this$trigger2$curren.status) === 'running') {
1005
- var _this$trigger3, _this$trigger3$curren;
1031
+ if (((_this$trigger3 = this.trigger) === null || _this$trigger3 === void 0 ? void 0 : (_this$trigger3$curren = _this$trigger3.current_state) === null || _this$trigger3$curren === void 0 ? void 0 : _this$trigger3$curren.status) === 'running') {
1032
+ var _this$trigger4, _this$trigger4$curren;
1006
1033
 
1007
1034
  this.job = {
1008
- _id: (_this$trigger3 = this.trigger) === null || _this$trigger3 === void 0 ? void 0 : (_this$trigger3$curren = _this$trigger3.current_state) === null || _this$trigger3$curren === void 0 ? void 0 : _this$trigger3$curren.last_executed_job_id
1035
+ _id: (_this$trigger4 = this.trigger) === null || _this$trigger4 === void 0 ? void 0 : (_this$trigger4$curren = _this$trigger4.current_state) === null || _this$trigger4$curren === void 0 ? void 0 : _this$trigger4$curren.last_executed_job_id
1009
1036
  };
1010
1037
  this.watchJob();
1011
1038
  }
1012
1039
  }
1040
+ /**
1041
+ * Watch all triggers
1042
+ */
1043
+
1044
+ }, {
1045
+ key: "watchTriggers",
1046
+ value: function watchTriggers() {
1047
+ this.realtime.subscribe('deleted', 'io.cozy.triggers', this.handleTriggerDeleted);
1048
+ this.realtime.subscribe('created', 'io.cozy.triggers', this.handleTriggerCreated);
1049
+ }
1013
1050
  /**
1014
1051
  * Watch all jobs related to the current trigger
1015
1052
  */
@@ -1018,10 +1055,10 @@ export var ConnectionFlow = /*#__PURE__*/function () {
1018
1055
  key: "watchTriggerJobs",
1019
1056
  value: function watchTriggerJobs() {
1020
1057
  if (this.trigger) {
1021
- var _this$trigger4;
1058
+ var _this$trigger5;
1022
1059
 
1023
1060
  // When the trigger comes from realtime, cozy-stack does not add the current_state to the object. So we need to request the stack to get it
1024
- if (!((_this$trigger4 = this.trigger) !== null && _this$trigger4 !== void 0 && _this$trigger4.current_state)) {
1061
+ if (!((_this$trigger5 = this.trigger) !== null && _this$trigger5 !== void 0 && _this$trigger5.current_state)) {
1025
1062
  this.refetchTrigger();
1026
1063
  }
1027
1064
 
@@ -1097,6 +1134,8 @@ export var ConnectionFlow = /*#__PURE__*/function () {
1097
1134
  value: function unsubscribeAllConnectionFlowRealtime() {
1098
1135
  this.realtime.unsubscribe('updated', JOBS_DOCTYPE, this.handleTriggerJobUpdated);
1099
1136
  this.realtime.unsubscribe('updated', JOBS_DOCTYPE, this.job._id, this.handleCurrentJobUpdated.bind(this));
1137
+ this.realtime.unsubscribe('deleted', 'io.cozy.triggers', this.handleTriggerDeleted);
1138
+ this.realtime.unsubscribe('created', 'io.cozy.triggers', this.handleTriggerCreated);
1100
1139
  }
1101
1140
  }, {
1102
1141
  key: "unwatch",
@@ -333,6 +333,101 @@ describe('ConnectionFlow', function () {
333
333
  }
334
334
  }, _callee7);
335
335
  })));
336
+ describe('handleTriggerCreated', function () {
337
+ it('should add a new trigger if there is no current trigger and the trigger parameter is associated with the current connector', function () {
338
+ var _setup2 = setup({
339
+ trigger: null
340
+ }),
341
+ flow = _setup2.flow;
342
+
343
+ var _flow$getState = flow.getState(),
344
+ initialTrigger = _flow$getState.trigger;
345
+
346
+ expect(initialTrigger).toBeNull();
347
+ realtimeMock.events.emit(realtimeMock.key('created', 'io.cozy.triggers'), _objectSpread({}, fixtures.createdTrigger));
348
+
349
+ var _flow$getState2 = flow.getState(),
350
+ trigger = _flow$getState2.trigger;
351
+
352
+ expect(trigger).toEqual(fixtures.createdTrigger);
353
+ });
354
+ it('should not add a new trigger if there is no current trigger and the trigger parameter is not associated with the current connector', function () {
355
+ var _setup3 = setup({
356
+ trigger: null
357
+ }),
358
+ flow = _setup3.flow;
359
+
360
+ var _flow$getState3 = flow.getState(),
361
+ initialTrigger = _flow$getState3.trigger;
362
+
363
+ expect(initialTrigger).toBeNull();
364
+ realtimeMock.events.emit(realtimeMock.key('created', 'io.cozy.triggers'), _objectSpread(_objectSpread({}, fixtures.createdTrigger), {}, {
365
+ message: _objectSpread(_objectSpread({}, fixtures.createdTrigger.message), {}, {
366
+ konnector: 'other-connector-slug'
367
+ })
368
+ }));
369
+
370
+ var _flow$getState4 = flow.getState(),
371
+ trigger = _flow$getState4.trigger;
372
+
373
+ expect(trigger).toEqual(null);
374
+ });
375
+ it('should not overwrite the current trigger if it already exists, even if the trigger parameter is associated with the current connector', function () {
376
+ var _setup4 = setup({
377
+ trigger: fixtures.createdTrigger
378
+ }),
379
+ flow = _setup4.flow;
380
+
381
+ var _flow$getState5 = flow.getState(),
382
+ initialTrigger = _flow$getState5.trigger;
383
+
384
+ expect(initialTrigger).toEqual(fixtures.createdTrigger);
385
+ realtimeMock.events.emit(realtimeMock.key('created', 'io.cozy.triggers'), _objectSpread({}, fixtures.createdTriggerWithFolder));
386
+
387
+ var _flow$getState6 = flow.getState(),
388
+ trigger = _flow$getState6.trigger;
389
+
390
+ expect(trigger).toEqual(fixtures.createdTrigger);
391
+ });
392
+ });
393
+ describe('handleTriggerDeleted', function () {
394
+ it('should remove the trigger if it has the same current trigger', function () {
395
+ var _setup5 = setup({
396
+ trigger: fixtures.createdTrigger
397
+ }),
398
+ flow = _setup5.flow;
399
+
400
+ var _flow$getState7 = flow.getState(),
401
+ initialTrigger = _flow$getState7.trigger;
402
+
403
+ expect(initialTrigger).toEqual(fixtures.createdTrigger);
404
+ realtimeMock.events.emit(realtimeMock.key('deleted', 'io.cozy.triggers'), _objectSpread({}, fixtures.createdTrigger));
405
+
406
+ var _flow$getState8 = flow.getState(),
407
+ trigger = _flow$getState8.trigger;
408
+
409
+ expect(trigger).toBeNull();
410
+ });
411
+ it('should not delete the trigger if it does not have the same current trigger', function () {
412
+ var _setup6 = setup({
413
+ trigger: fixtures.createdTrigger
414
+ }),
415
+ flow = _setup6.flow;
416
+
417
+ var _flow$getState9 = flow.getState(),
418
+ initialTrigger = _flow$getState9.trigger;
419
+
420
+ expect(initialTrigger).toEqual(fixtures.createdTrigger);
421
+ realtimeMock.events.emit(realtimeMock.key('deleted', 'io.cozy.triggers'), _objectSpread(_objectSpread({}, fixtures.createdTrigger), {}, {
422
+ _id: 'another-created-trigger-id'
423
+ }));
424
+
425
+ var _flow$getState10 = flow.getState(),
426
+ trigger = _flow$getState10.trigger;
427
+
428
+ expect(trigger).toEqual(fixtures.createdTrigger);
429
+ });
430
+ });
336
431
  });
337
432
  describe('getState', function () {
338
433
  beforeAll(function () {
@@ -346,73 +441,73 @@ describe('ConnectionFlow', function () {
346
441
  jest.clearAllMocks();
347
442
  });
348
443
  it('should return error if not running', function () {
349
- var _setup2 = setup({
444
+ var _setup7 = setup({
350
445
  trigger: fixtures.erroredTrigger
351
446
  }),
352
- flow = _setup2.flow;
447
+ flow = _setup7.flow;
353
448
 
354
- var _flow$getState = flow.getState(),
355
- error = _flow$getState.error;
449
+ var _flow$getState11 = flow.getState(),
450
+ error = _flow$getState11.error;
356
451
 
357
452
  expect(error).toEqual(new KonnectorJobError('last error message'));
358
453
  });
359
454
  it('should not return error while running', function () {
360
- var _setup3 = setup({
455
+ var _setup8 = setup({
361
456
  trigger: fixtures.runningTrigger
362
457
  }),
363
- flow = _setup3.flow;
458
+ flow = _setup8.flow;
364
459
 
365
460
  flow.setState({
366
461
  accountError: 'error to hide'
367
462
  });
368
463
 
369
- var _flow$getState2 = flow.getState(),
370
- error = _flow$getState2.error;
464
+ var _flow$getState12 = flow.getState(),
465
+ error = _flow$getState12.error;
371
466
 
372
467
  expect(error).toBe(false);
373
468
  });
374
469
  it('should not return error while expecting a trigger launch', function () {
375
- var _setup4 = setup({
470
+ var _setup9 = setup({
376
471
  trigger: fixtures.erroredTrigger
377
472
  }),
378
- flow = _setup4.flow;
473
+ flow = _setup9.flow;
379
474
 
380
475
  flow.setState({
381
476
  status: EXPECTING_TRIGGER_LAUNCH
382
477
  });
383
478
 
384
- var _flow$getState3 = flow.getState(),
385
- error = _flow$getState3.error;
479
+ var _flow$getState13 = flow.getState(),
480
+ error = _flow$getState13.error;
386
481
 
387
482
  expect(error).toBe(false);
388
483
  });
389
484
  it('should return expectingTriggerLaunch while expecting a trigger launch', function () {
390
- var _setup5 = setup({
485
+ var _setup10 = setup({
391
486
  trigger: fixtures.erroredTrigger
392
487
  }),
393
- flow = _setup5.flow;
488
+ flow = _setup10.flow;
394
489
 
395
490
  flow.setState({
396
491
  status: EXPECTING_TRIGGER_LAUNCH
397
492
  });
398
493
 
399
- var _flow$getState4 = flow.getState(),
400
- expectingTriggerLaunch = _flow$getState4.expectingTriggerLaunch;
494
+ var _flow$getState14 = flow.getState(),
495
+ expectingTriggerLaunch = _flow$getState14.expectingTriggerLaunch;
401
496
 
402
497
  expect(expectingTriggerLaunch).toBe(true);
403
498
  });
404
499
  it('should not return expectingTriggerLaunch if not expecting a trigger launch', function () {
405
- var _setup6 = setup({
500
+ var _setup11 = setup({
406
501
  trigger: fixtures.erroredTrigger
407
502
  }),
408
- flow = _setup6.flow;
503
+ flow = _setup11.flow;
409
504
 
410
505
  flow.setState({
411
506
  status: ERRORED
412
507
  });
413
508
 
414
- var _flow$getState5 = flow.getState(),
415
- expectingTriggerLaunch = _flow$getState5.expectingTriggerLaunch;
509
+ var _flow$getState15 = flow.getState(),
510
+ expectingTriggerLaunch = _flow$getState15.expectingTriggerLaunch;
416
511
 
417
512
  expect(expectingTriggerLaunch).toBe(false);
418
513
  });
@@ -433,13 +528,13 @@ describe('ConnectionFlow', function () {
433
528
  jest.clearAllMocks();
434
529
  });
435
530
  it('should render as submitting when there is no account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
436
- var _setup7, flow, submitPromise;
531
+ var _setup12, flow, submitPromise;
437
532
 
438
533
  return _regeneratorRuntime.wrap(function _callee8$(_context8) {
439
534
  while (1) {
440
535
  switch (_context8.prev = _context8.next) {
441
536
  case 0:
442
- _setup7 = setup(), flow = _setup7.flow;
537
+ _setup12 = setup(), flow = _setup12.flow;
443
538
  submitPromise = setupSubmit(flow);
444
539
  expect(isSubmitting(flow)).toBe(true);
445
540
  _context8.next = 5;
@@ -453,13 +548,13 @@ describe('ConnectionFlow', function () {
453
548
  }, _callee8);
454
549
  })));
455
550
  it('should render as submitting when there is an account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
456
- var _setup8, flow, submitPromise;
551
+ var _setup13, flow, submitPromise;
457
552
 
458
553
  return _regeneratorRuntime.wrap(function _callee9$(_context9) {
459
554
  while (1) {
460
555
  switch (_context9.prev = _context9.next) {
461
556
  case 0:
462
- _setup8 = setup(), flow = _setup8.flow;
557
+ _setup13 = setup(), flow = _setup13.flow;
463
558
  submitPromise = setupSubmit(flow);
464
559
  expect(isSubmitting(flow)).toBe(true);
465
560
  _context9.next = 5;
@@ -473,13 +568,13 @@ describe('ConnectionFlow', function () {
473
568
  }, _callee9);
474
569
  })));
475
570
  it('should stop being rendered as submitting on error', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
476
- var _setup9, flow, originalError;
571
+ var _setup14, flow, originalError;
477
572
 
478
573
  return _regeneratorRuntime.wrap(function _callee10$(_context10) {
479
574
  while (1) {
480
575
  switch (_context10.prev = _context10.next) {
481
576
  case 0:
482
- _setup9 = setup(), flow = _setup9.flow;
577
+ _setup14 = setup(), flow = _setup14.flow;
483
578
  originalError = new Error();
484
579
  mockVaultClient.isLocked.mockReset().mockImplementationOnce(function () {
485
580
  var wrapped = new Error('fakeerror');
@@ -511,13 +606,13 @@ describe('ConnectionFlow', function () {
511
606
  }, _callee10, null, [[3, 9]]);
512
607
  })));
513
608
  it('should call saveAccount without account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
514
- var _setup10, flow, client;
609
+ var _setup15, flow, client;
515
610
 
516
611
  return _regeneratorRuntime.wrap(function _callee11$(_context11) {
517
612
  while (1) {
518
613
  switch (_context11.prev = _context11.next) {
519
614
  case 0:
520
- _setup10 = setup(), flow = _setup10.flow, client = _setup10.client;
615
+ _setup15 = setup(), flow = _setup15.flow, client = _setup15.client;
521
616
  _context11.next = 3;
522
617
  return setupSubmit(flow);
523
618
 
@@ -532,13 +627,13 @@ describe('ConnectionFlow', function () {
532
627
  }, _callee11);
533
628
  })));
534
629
  it('should call saveAccount with account (no password provided)', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
535
- var _setup11, flow, client;
630
+ var _setup16, flow, client;
536
631
 
537
632
  return _regeneratorRuntime.wrap(function _callee12$(_context12) {
538
633
  while (1) {
539
634
  switch (_context12.prev = _context12.next) {
540
635
  case 0:
541
- _setup11 = setup(), flow = _setup11.flow, client = _setup11.client;
636
+ _setup16 = setup(), flow = _setup16.flow, client = _setup16.client;
542
637
  mockVaultClient.decrypt.mockResolvedValueOnce({
543
638
  login: {
544
639
  username: 'username',
@@ -565,13 +660,13 @@ describe('ConnectionFlow', function () {
565
660
  }, _callee12);
566
661
  })));
567
662
  it('should call saveAccount with account with RESET_SESSION state if passphrase changed', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
568
- var _setup12, flow, client;
663
+ var _setup17, flow, client;
569
664
 
570
665
  return _regeneratorRuntime.wrap(function _callee13$(_context13) {
571
666
  while (1) {
572
667
  switch (_context13.prev = _context13.next) {
573
668
  case 0:
574
- _setup12 = setup(), flow = _setup12.flow, client = _setup12.client;
669
+ _setup17 = setup(), flow = _setup17.flow, client = _setup17.client;
575
670
  _context13.next = 3;
576
671
  return setupSubmit(flow, {
577
672
  userCredentials: {
@@ -595,13 +690,13 @@ describe('ConnectionFlow', function () {
595
690
  }, _callee13);
596
691
  })));
597
692
  it('should call saveAccount with account with RESET_SESSION state if password changed', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee14() {
598
- var _setup13, flow;
693
+ var _setup18, flow;
599
694
 
600
695
  return _regeneratorRuntime.wrap(function _callee14$(_context14) {
601
696
  while (1) {
602
697
  switch (_context14.prev = _context14.next) {
603
698
  case 0:
604
- _setup13 = setup(), flow = _setup13.flow;
699
+ _setup18 = setup(), flow = _setup18.flow;
605
700
  mockVaultClient.decrypt.mockResolvedValueOnce({
606
701
  login: {
607
702
  username: 'username',
@@ -633,13 +728,13 @@ describe('ConnectionFlow', function () {
633
728
  }, _callee14);
634
729
  })));
635
730
  it('should call ensureTriggerAndLaunch with account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee15() {
636
- var _setup14, flow, client;
731
+ var _setup19, flow, client;
637
732
 
638
733
  return _regeneratorRuntime.wrap(function _callee15$(_context15) {
639
734
  while (1) {
640
735
  switch (_context15.prev = _context15.next) {
641
736
  case 0:
642
- _setup14 = setup(), flow = _setup14.flow, client = _setup14.client;
737
+ _setup19 = setup(), flow = _setup19.flow, client = _setup19.client;
643
738
  jest.spyOn(flow, 'ensureTriggerAndLaunch').mockResolvedValue(fixtures.launchedJob);
644
739
  _context15.next = 4;
645
740
  return setupSubmit(flow, {
@@ -661,13 +756,13 @@ describe('ConnectionFlow', function () {
661
756
  }, _callee15);
662
757
  })));
663
758
  it('should call ensureTriggerAndLaunch without account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee16() {
664
- var _setup15, flow, client;
759
+ var _setup20, flow, client;
665
760
 
666
761
  return _regeneratorRuntime.wrap(function _callee16$(_context16) {
667
762
  while (1) {
668
763
  switch (_context16.prev = _context16.next) {
669
764
  case 0:
670
- _setup15 = setup(), flow = _setup15.flow, client = _setup15.client;
765
+ _setup20 = setup(), flow = _setup20.flow, client = _setup20.client;
671
766
  jest.spyOn(flow, 'ensureTriggerAndLaunch').mockResolvedValue(fixtures.launchedJob);
672
767
  _context16.next = 4;
673
768
  return setupSubmit(flow, {
@@ -703,7 +798,7 @@ describe('ConnectionFlow', function () {
703
798
  }
704
799
  };
705
800
  it('should use custom konnector policy', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee17() {
706
- var _setup16, flow, client;
801
+ var _setup21, flow, client;
707
802
 
708
803
  return _regeneratorRuntime.wrap(function _callee17$(_context17) {
709
804
  while (1) {
@@ -715,7 +810,7 @@ describe('ConnectionFlow', function () {
715
810
  });
716
811
  });
717
812
  biKonnectorPolicy.onAccountCreation.mockReset().mockReturnValue(onAccountCreationResult);
718
- _setup16 = setup(), flow = _setup16.flow, client = _setup16.client;
813
+ _setup21 = setup(), flow = _setup21.flow, client = _setup21.client;
719
814
  jest.spyOn(flow, 'ensureTriggerAndLaunch').mockResolvedValue(fixtures.launchedJob);
720
815
  _context17.next = 6;
721
816
  return setupSubmit(flow, {
@@ -751,13 +846,13 @@ describe('ConnectionFlow', function () {
751
846
  jest.clearAllMocks();
752
847
  });
753
848
  it('should launch trigger without account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee18() {
754
- var _setup17, flow, client;
849
+ var _setup22, flow, client;
755
850
 
756
851
  return _regeneratorRuntime.wrap(function _callee18$(_context18) {
757
852
  while (1) {
758
853
  switch (_context18.prev = _context18.next) {
759
854
  case 0:
760
- _setup17 = setup(), flow = _setup17.flow, client = _setup17.client;
855
+ _setup22 = setup(), flow = _setup22.flow, client = _setup22.client;
761
856
  _context18.next = 3;
762
857
  return flow.ensureTriggerAndLaunch(client, {
763
858
  trigger: fixtures.createdTrigger,
@@ -776,13 +871,13 @@ describe('ConnectionFlow', function () {
776
871
  }, _callee18);
777
872
  })));
778
873
  it('should launch trigger with account', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee19() {
779
- var _setup18, flow, client;
874
+ var _setup23, flow, client;
780
875
 
781
876
  return _regeneratorRuntime.wrap(function _callee19$(_context19) {
782
877
  while (1) {
783
878
  switch (_context19.prev = _context19.next) {
784
879
  case 0:
785
- _setup18 = setup(), flow = _setup18.flow, client = _setup18.client;
880
+ _setup23 = setup(), flow = _setup23.flow, client = _setup23.client;
786
881
  ensureTrigger.mockResolvedValue(fixtures.existingTrigger);
787
882
  _context19.next = 4;
788
883
  return flow.ensureTriggerAndLaunch(client, {
@@ -803,13 +898,13 @@ describe('ConnectionFlow', function () {
803
898
  }, _callee19);
804
899
  })));
805
900
  it('should keep internal trigger up-to-date', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee20() {
806
- var _setup19, flow, client, trigger;
901
+ var _setup24, flow, client, trigger;
807
902
 
808
903
  return _regeneratorRuntime.wrap(function _callee20$(_context20) {
809
904
  while (1) {
810
905
  switch (_context20.prev = _context20.next) {
811
906
  case 0:
812
- _setup19 = setup(), flow = _setup19.flow, client = _setup19.client;
907
+ _setup24 = setup(), flow = _setup24.flow, client = _setup24.client;
813
908
  trigger = _objectSpread({}, fixtures.existingTrigger);
814
909
  ensureTrigger.mockResolvedValue(trigger);
815
910
  _context20.next = 5;
@@ -833,13 +928,13 @@ describe('ConnectionFlow', function () {
833
928
  }, _callee20);
834
929
  })));
835
930
  it('should not create trigger when one is passed as prop', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee21() {
836
- var _setup20, flow, client;
931
+ var _setup25, flow, client;
837
932
 
838
933
  return _regeneratorRuntime.wrap(function _callee21$(_context21) {
839
934
  while (1) {
840
935
  switch (_context21.prev = _context21.next) {
841
936
  case 0:
842
- _setup20 = setup(), flow = _setup20.flow, client = _setup20.client;
937
+ _setup25 = setup(), flow = _setup25.flow, client = _setup25.client;
843
938
  _context21.next = 3;
844
939
  return flow.ensureTriggerAndLaunch(client, {
845
940
  trigger: fixtures.existingTrigger,
@@ -860,13 +955,13 @@ describe('ConnectionFlow', function () {
860
955
  }, _callee21);
861
956
  })));
862
957
  it('should keep updated account in state', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee22() {
863
- var _setup21, flow, client;
958
+ var _setup26, flow, client;
864
959
 
865
960
  return _regeneratorRuntime.wrap(function _callee22$(_context22) {
866
961
  while (1) {
867
962
  switch (_context22.prev = _context22.next) {
868
963
  case 0:
869
- _setup21 = setup(), flow = _setup21.flow, client = _setup21.client;
964
+ _setup26 = setup(), flow = _setup26.flow, client = _setup26.client;
870
965
  prepareTriggerAccount.mockResolvedValue(fixtures.updatedAccount);
871
966
  _context22.next = 4;
872
967
  return flow.ensureTriggerAndLaunch(client, {
@@ -886,13 +981,13 @@ describe('ConnectionFlow', function () {
886
981
  }, _callee22);
887
982
  })));
888
983
  it('should add the defaultFolderPath to the account when needed', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee25() {
889
- var _setup22, flow, client;
984
+ var _setup27, flow, client;
890
985
 
891
986
  return _regeneratorRuntime.wrap(function _callee25$(_context25) {
892
987
  while (1) {
893
988
  switch (_context25.prev = _context25.next) {
894
989
  case 0:
895
- _setup22 = setup(), flow = _setup22.flow, client = _setup22.client;
990
+ _setup27 = setup(), flow = _setup27.flow, client = _setup27.client;
896
991
  prepareTriggerAccount.mockResolvedValue(fixtures.updatedAccount);
897
992
  ensureTrigger.mockImplementation( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee23() {
898
993
  return _regeneratorRuntime.wrap(function _callee23$(_context23) {
@@ -948,13 +1043,13 @@ describe('ConnectionFlow', function () {
948
1043
  }, _callee25);
949
1044
  })));
950
1045
  it('should return unmodified account trigger folder does not exist', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee26() {
951
- var _setup23, flow, client;
1046
+ var _setup28, flow, client;
952
1047
 
953
1048
  return _regeneratorRuntime.wrap(function _callee26$(_context26) {
954
1049
  while (1) {
955
1050
  switch (_context26.prev = _context26.next) {
956
1051
  case 0:
957
- _setup23 = setup(), flow = _setup23.flow, client = _setup23.client;
1052
+ _setup28 = setup(), flow = _setup28.flow, client = _setup28.client;
958
1053
  prepareTriggerAccount.mockResolvedValue(fixtures.updatedAccount);
959
1054
  ensureTrigger.mockResolvedValue(fixtures.createdTriggerWithFolder.attributes);
960
1055
  client.query.mockRejectedValue(new Error('404'));
@@ -978,13 +1073,13 @@ describe('ConnectionFlow', function () {
978
1073
  }, _callee26);
979
1074
  })));
980
1075
  it('should call the launcher when needed', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee28() {
981
- var _setup24, client, flow;
1076
+ var _setup29, client, flow;
982
1077
 
983
1078
  return _regeneratorRuntime.wrap(function _callee28$(_context28) {
984
1079
  while (1) {
985
1080
  switch (_context28.prev = _context28.next) {
986
1081
  case 0:
987
- _setup24 = setup(), client = _setup24.client;
1082
+ _setup29 = setup(), client = _setup29.client;
988
1083
  flow = new ConnectionFlow(client, fixtures.existingTrigger, fixtures.clientKonnector);
989
1084
  window.cozy = {
990
1085
  ClientConnectorLauncher: 'react-native'
@@ -1038,10 +1133,10 @@ describe('ConnectionFlow', function () {
1038
1133
  });
1039
1134
  describe('expectTriggerLaunch', function () {
1040
1135
  it('removes account errors', function () {
1041
- var _setup25 = setup({
1136
+ var _setup30 = setup({
1042
1137
  trigger: fixtures.erroredTrigger
1043
1138
  }),
1044
- flow = _setup25.flow;
1139
+ flow = _setup30.flow;
1045
1140
 
1046
1141
  flow.setState({
1047
1142
  accountError: 'error to hide'
@@ -1050,31 +1145,31 @@ describe('ConnectionFlow', function () {
1050
1145
  konnector: fixtures.konnector
1051
1146
  });
1052
1147
 
1053
- var _flow$getState6 = flow.getState(),
1054
- accountError = _flow$getState6.accountError;
1148
+ var _flow$getState16 = flow.getState(),
1149
+ accountError = _flow$getState16.accountError;
1055
1150
 
1056
1151
  expect(accountError).toBe(null);
1057
1152
  });
1058
1153
  it('sets the flow status to EXPECTING_TRIGGER_LAUNCH', function () {
1059
- var _setup26 = setup({
1154
+ var _setup31 = setup({
1060
1155
  trigger: fixtures.runningTrigger
1061
1156
  }),
1062
- flow = _setup26.flow;
1157
+ flow = _setup31.flow;
1063
1158
 
1064
1159
  flow.expectTriggerLaunch({
1065
1160
  konnector: fixtures.konnector
1066
1161
  });
1067
1162
 
1068
- var _flow$getState7 = flow.getState(),
1069
- status = _flow$getState7.status;
1163
+ var _flow$getState17 = flow.getState(),
1164
+ status = _flow$getState17.status;
1070
1165
 
1071
1166
  expect(status).toBe(EXPECTING_TRIGGER_LAUNCH);
1072
1167
  });
1073
1168
  it('starts watching for konnector jobs creation', function () {
1074
- var _setup27 = setup({
1169
+ var _setup32 = setup({
1075
1170
  trigger: fixtures.erroredTrigger
1076
1171
  }),
1077
- flow = _setup27.flow;
1172
+ flow = _setup32.flow;
1078
1173
 
1079
1174
  flow.expectTriggerLaunch({
1080
1175
  konnector: fixtures.konnector
@@ -1094,15 +1189,15 @@ describe('ConnectionFlow', function () {
1094
1189
  };
1095
1190
 
1096
1191
  it('stops watching for konnector jobs creation', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee29() {
1097
- var _setup28, flow, job;
1192
+ var _setup33, flow, job;
1098
1193
 
1099
1194
  return _regeneratorRuntime.wrap(function _callee29$(_context29) {
1100
1195
  while (1) {
1101
1196
  switch (_context29.prev = _context29.next) {
1102
1197
  case 0:
1103
- _setup28 = setup({
1198
+ _setup33 = setup({
1104
1199
  trigger: fixtures.erroredTrigger
1105
- }), flow = _setup28.flow;
1200
+ }), flow = _setup33.flow;
1106
1201
  flow.expectTriggerLaunch({
1107
1202
  konnector: fixtures.konnector
1108
1203
  });
@@ -1118,10 +1213,10 @@ describe('ConnectionFlow', function () {
1118
1213
  }, _callee29);
1119
1214
  })));
1120
1215
  it('starts watching for updates on the job itself', function () {
1121
- var _setup29 = setup({
1216
+ var _setup34 = setup({
1122
1217
  trigger: fixtures.erroredTrigger
1123
1218
  }),
1124
- flow = _setup29.flow;
1219
+ flow = _setup34.flow;
1125
1220
 
1126
1221
  flow.expectTriggerLaunch({
1127
1222
  konnector: fixtures.konnector
@@ -13,6 +13,10 @@ var konnectorFixture = {
13
13
  domain: 'https://budget-insight.com'
14
14
  }
15
15
  };
16
+ var realtimeMock = {
17
+ subscribe: jest.fn(),
18
+ unsubscribe: jest.fn()
19
+ };
16
20
 
17
21
  var DumbTriggerStatus = function DumbTriggerStatus(_ref) {
18
22
  var flowState = _ref.flowState;
@@ -23,6 +27,9 @@ var TriggerStatus = withConnectionFlow()(DumbTriggerStatus);
23
27
  describe('with connection flow', function () {
24
28
  it('should update correctly', function () {
25
29
  var client = new CozyClient({});
30
+ client.plugins = {
31
+ realtime: realtimeMock
32
+ };
26
33
  var flow = new ConnectionFlow(client, null, konnectorFixture);
27
34
  var root = mount( /*#__PURE__*/React.createElement(TriggerStatus, {
28
35
  flow: flow
@@ -33,6 +33,10 @@ jest.mock('./jobUtils', function () {
33
33
  waitForRealtimeEvent: jest.fn()
34
34
  };
35
35
  });
36
+ var realtimeMock = {
37
+ subscribe: jest.fn(),
38
+ unsubscribe: jest.fn()
39
+ };
36
40
  var TEST_BANK_COZY_ID = '100000';
37
41
  var konnector = {
38
42
  slug: 'boursorama83',
@@ -72,6 +76,9 @@ describe('handleOAuthAccount', function () {
72
76
  client = new CozyClient({
73
77
  uri: 'http://testcozy.mycozy.cloud'
74
78
  });
79
+ client.plugins = {
80
+ realtime: realtimeMock
81
+ };
75
82
  flow = new ConnectionFlow(client, null, konnector);
76
83
  flow.account = account;
77
84
  flow.handleFormSubmit = jest.fn();
@@ -105,7 +112,7 @@ describe('handleOAuthAccount', function () {
105
112
  }
106
113
  };
107
114
  t = jest.fn();
108
- _context2.next = 9;
115
+ _context2.next = 10;
109
116
  return handleOAuthAccount({
110
117
  account: account,
111
118
  flow: flow,
@@ -114,7 +121,7 @@ describe('handleOAuthAccount', function () {
114
121
  t: t
115
122
  });
116
123
 
117
- case 9:
124
+ case 10:
118
125
  expect(flow.handleFormSubmit).toHaveBeenCalledWith({
119
126
  client: client,
120
127
  konnector: konnector,
@@ -134,7 +141,7 @@ describe('handleOAuthAccount', function () {
134
141
  })
135
142
  });
136
143
 
137
- case 10:
144
+ case 11:
138
145
  case "end":
139
146
  return _context2.stop();
140
147
  }
@@ -150,6 +157,9 @@ describe('handleOAuthAccount', function () {
150
157
  client = new CozyClient({
151
158
  uri: 'http://testcozy.mycozy.cloud'
152
159
  });
160
+ client.plugins = {
161
+ realtime: realtimeMock
162
+ };
153
163
  flow = new ConnectionFlow(client, null, konnector);
154
164
  flow.account = account;
155
165
  flow.handleFormSubmit = jest.fn();
@@ -164,7 +174,7 @@ describe('handleOAuthAccount', function () {
164
174
  }
165
175
  };
166
176
  t = jest.fn();
167
- _context3.next = 9;
177
+ _context3.next = 10;
168
178
  return handleOAuthAccount({
169
179
  account: account,
170
180
  flow: flow,
@@ -174,13 +184,13 @@ describe('handleOAuthAccount', function () {
174
184
  t: t
175
185
  });
176
186
 
177
- case 9:
187
+ case 10:
178
188
  result = _context3.sent;
179
189
  expect(flow.handleFormSubmit).not.toHaveBeenCalled();
180
190
  expect(flow.saveAccount).not.toHaveBeenCalled();
181
191
  expect(result).toEqual(true);
182
192
 
183
- case 13:
193
+ case 14:
184
194
  case "end":
185
195
  return _context3.stop();
186
196
  }
@@ -193,6 +203,9 @@ describe('checkBIConnection', function () {
193
203
  var client = new CozyClient({
194
204
  uri: 'http://testcozy.mycozy.cloud'
195
205
  });
206
+ client.plugins = {
207
+ realtime: realtimeMock
208
+ };
196
209
  var flow = new ConnectionFlow(client, null, konnector);
197
210
  jest.spyOn(client, 'query').mockImplementation( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
198
211
  return _regeneratorRuntime.wrap(function _callee4$(_context4) {
@@ -349,6 +362,9 @@ describe('refreshContracts', function () {
349
362
  client = new CozyClient({
350
363
  uri: 'http://testcozy.mycozy.cloud'
351
364
  });
365
+ client.plugins = {
366
+ realtime: realtimeMock
367
+ };
352
368
  client.store.dispatch = jest.fn();
353
369
  client.query = jest.fn().mockResolvedValueOnce({
354
370
  data: {
@@ -399,14 +415,14 @@ describe('refreshContracts', function () {
399
415
  disabled: null
400
416
  }]
401
417
  });
402
- _context7.next = 6;
418
+ _context7.next = 7;
403
419
  return refreshContracts({
404
420
  client: client,
405
421
  konnector: konnector,
406
422
  account: {}
407
423
  });
408
424
 
409
- case 6:
425
+ case 7:
410
426
  expect(client.store.dispatch).toHaveBeenCalledTimes(4);
411
427
  expect(client.store.dispatch).toHaveBeenNthCalledWith(1, {
412
428
  definition: {},
@@ -465,7 +481,7 @@ describe('refreshContracts', function () {
465
481
  type: 'RECEIVE_MUTATION_RESULT'
466
482
  });
467
483
 
468
- case 11:
484
+ case 12:
469
485
  case "end":
470
486
  return _context7.stop();
471
487
  }
@@ -1144,6 +1144,9 @@ describe('handleOAuthAccount', function () {
1144
1144
  client = new CozyClient({
1145
1145
  uri: 'http://testcozy.mycozy.cloud'
1146
1146
  });
1147
+ client.plugins = {
1148
+ realtime: realtimeMock
1149
+ };
1147
1150
  flow = new ConnectionFlow(client, null, konnector);
1148
1151
  flow.account = account;
1149
1152
  flow.handleFormSubmit = jest.fn();
@@ -1177,7 +1180,7 @@ describe('handleOAuthAccount', function () {
1177
1180
  }
1178
1181
  };
1179
1182
  t = jest.fn();
1180
- _context27.next = 9;
1183
+ _context27.next = 10;
1181
1184
  return handleOAuthAccount({
1182
1185
  account: account,
1183
1186
  flow: flow,
@@ -1186,7 +1189,7 @@ describe('handleOAuthAccount', function () {
1186
1189
  t: t
1187
1190
  });
1188
1191
 
1189
- case 9:
1192
+ case 10:
1190
1193
  expect(flow.handleFormSubmit).toHaveBeenCalledWith({
1191
1194
  client: client,
1192
1195
  konnector: konnector,
@@ -1206,7 +1209,7 @@ describe('handleOAuthAccount', function () {
1206
1209
  })
1207
1210
  });
1208
1211
 
1209
- case 10:
1212
+ case 11:
1210
1213
  case "end":
1211
1214
  return _context27.stop();
1212
1215
  }
@@ -1224,6 +1227,9 @@ describe('setSync', function () {
1224
1227
  client = new CozyClient({
1225
1228
  uri: 'http://testcozy.mycozy.cloud'
1226
1229
  });
1230
+ client.plugins = {
1231
+ realtime: realtimeMock
1232
+ };
1227
1233
  flow = new ConnectionFlow(client, null, konnector);
1228
1234
  flow.account = account;
1229
1235
  flow.handleFormSubmit = jest.fn();
@@ -1268,7 +1274,7 @@ describe('setSync', function () {
1268
1274
  code: tempToken
1269
1275
  });
1270
1276
  setBIConnectionSyncStatus = jest.fn();
1271
- _context29.next = 14;
1277
+ _context29.next = 15;
1272
1278
  return setSync({
1273
1279
  client: client,
1274
1280
  account: account,
@@ -1279,11 +1285,11 @@ describe('setSync', function () {
1279
1285
  setBIConnectionSyncStatus: setBIConnectionSyncStatus
1280
1286
  });
1281
1287
 
1282
- case 14:
1288
+ case 15:
1283
1289
  expect(setBIConnectionSyncStatus).toHaveBeenCalledWith(expect.any(Object), // config
1284
1290
  biConnId, biContractId, false, tempToken);
1285
1291
 
1286
- case 15:
1292
+ case 16:
1287
1293
  case "end":
1288
1294
  return _context29.stop();
1289
1295
  }
@@ -1301,6 +1307,9 @@ describe('updateBIConnectionFromFlow', function () {
1301
1307
  client = new CozyClient({
1302
1308
  uri: 'http://testcozy.mycozy.cloud'
1303
1309
  });
1310
+ client.plugins = {
1311
+ realtime: realtimeMock
1312
+ };
1304
1313
  biConnId = 'conn-1337';
1305
1314
  account = {
1306
1315
  data: {
@@ -1323,17 +1332,17 @@ describe('updateBIConnectionFromFlow', function () {
1323
1332
  connectionData = {
1324
1333
  login: '1234'
1325
1334
  };
1326
- _context30.next = 10;
1335
+ _context30.next = 11;
1327
1336
  return updateBIConnectionFromFlow(flow, connectionData);
1328
1337
 
1329
- case 10:
1338
+ case 11:
1330
1339
  expect(updateBIConnection).toHaveBeenCalledWith({
1331
1340
  url: 'https://bi-endpoint.biapi.pro'
1332
1341
  }, 'conn-1337', {
1333
1342
  login: '1234'
1334
1343
  }, 'temporary-token');
1335
1344
 
1336
- case 11:
1345
+ case 12:
1337
1346
  case "end":
1338
1347
  return _context30.stop();
1339
1348
  }
@@ -1346,6 +1355,9 @@ describe('sendTwoFACode', function () {
1346
1355
  var client = new CozyClient({
1347
1356
  uri: 'http://testcozy.mycozy.cloud'
1348
1357
  });
1358
+ client.plugins = {
1359
+ realtime: realtimeMock
1360
+ };
1349
1361
  var biConnId = 'conn-1337';
1350
1362
  var account = {
1351
1363
  data: {
@@ -1366,6 +1378,9 @@ describe('sendTwoFACode', function () {
1366
1378
  var client = new CozyClient({
1367
1379
  uri: 'http://testcozy.mycozy.cloud'
1368
1380
  });
1381
+ client.plugins = {
1382
+ realtime: realtimeMock
1383
+ };
1369
1384
  var biConnId = 'conn-1337';
1370
1385
  var account = {
1371
1386
  data: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-harvest-lib",
3
- "version": "13.1.0",
3
+ "version": "13.2.0",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -88,5 +88,5 @@
88
88
  "react-router-dom": ">=4.3.1"
89
89
  },
90
90
  "sideEffects": false,
91
- "gitHead": "ddd16c7b3d80e78054ce1f0dca5e2afd32d88043"
91
+ "gitHead": "e1f2d46c0533326b3d72cc9b9effcef4a7367dcc"
92
92
  }
@@ -164,6 +164,8 @@ export class ConnectionFlow {
164
164
  this.handleAccountUpdated = this.handleAccountUpdated.bind(this)
165
165
  this.handleCurrentJobUpdated = this.handleCurrentJobUpdated.bind(this)
166
166
  this.handleTriggerJobUpdated = this.handleTriggerJobUpdated.bind(this)
167
+ this.handleTriggerDeleted = this.handleTriggerDeleted.bind(this)
168
+ this.handleTriggerCreated = this.handleTriggerCreated.bind(this)
167
169
  this.handleAccountTwoFA = this.handleAccountTwoFA.bind(this)
168
170
  this.launch = this.launch.bind(this)
169
171
  this.sendTwoFACode = this.sendTwoFACode.bind(this)
@@ -183,6 +185,7 @@ export class ConnectionFlow {
183
185
 
184
186
  this.watchCurrentJobIfTriggerIsAlreadyRunning()
185
187
  this.watchTriggerJobs()
188
+ this.watchTriggers()
186
189
  }
187
190
 
188
191
  getTwoFACodeProvider() {
@@ -479,6 +482,27 @@ export class ConnectionFlow {
479
482
  }
480
483
  }
481
484
 
485
+ handleTriggerCreated(trigger) {
486
+ if (
487
+ this.konnector.slug !== trigger?.message?.konnector ||
488
+ this.trigger !== null
489
+ ) {
490
+ return // filter out trigger associated to konnector or if a current trigger already exists
491
+ }
492
+
493
+ this.trigger = trigger
494
+ // @ts-ignore
495
+ this.emit(UPDATE_EVENT)
496
+ }
497
+
498
+ handleTriggerDeleted(trigger) {
499
+ if (this.trigger?._id !== trigger?._id) return // filter out trigger associated to current trigger
500
+
501
+ this.reset()
502
+ // @ts-ignore
503
+ this.emit(UPDATE_EVENT)
504
+ }
505
+
482
506
  handleAccountUpdated(account) {
483
507
  const prevAccount = this.account
484
508
 
@@ -663,6 +687,22 @@ export class ConnectionFlow {
663
687
  }
664
688
  }
665
689
 
690
+ /**
691
+ * Watch all triggers
692
+ */
693
+ watchTriggers() {
694
+ this.realtime.subscribe(
695
+ 'deleted',
696
+ 'io.cozy.triggers',
697
+ this.handleTriggerDeleted
698
+ )
699
+ this.realtime.subscribe(
700
+ 'created',
701
+ 'io.cozy.triggers',
702
+ this.handleTriggerCreated
703
+ )
704
+ }
705
+
666
706
  /**
667
707
  * Watch all jobs related to the current trigger
668
708
  */
@@ -727,6 +767,16 @@ export class ConnectionFlow {
727
767
  this.job._id,
728
768
  this.handleCurrentJobUpdated.bind(this)
729
769
  )
770
+ this.realtime.unsubscribe(
771
+ 'deleted',
772
+ 'io.cozy.triggers',
773
+ this.handleTriggerDeleted
774
+ )
775
+ this.realtime.unsubscribe(
776
+ 'created',
777
+ 'io.cozy.triggers',
778
+ this.handleTriggerCreated
779
+ )
730
780
  }
731
781
 
732
782
  unwatch() {
@@ -201,6 +201,100 @@ describe('ConnectionFlow', () => {
201
201
  _id: 'running-job-id'
202
202
  })
203
203
  })
204
+
205
+ describe('handleTriggerCreated', () => {
206
+ it('should add a new trigger if there is no current trigger and the trigger parameter is associated with the current connector', () => {
207
+ const { flow } = setup({ trigger: null })
208
+ const { trigger: initialTrigger } = flow.getState()
209
+
210
+ expect(initialTrigger).toBeNull()
211
+
212
+ realtimeMock.events.emit(
213
+ realtimeMock.key('created', 'io.cozy.triggers'),
214
+ {
215
+ ...fixtures.createdTrigger
216
+ }
217
+ )
218
+ const { trigger } = flow.getState()
219
+
220
+ expect(trigger).toEqual(fixtures.createdTrigger)
221
+ })
222
+
223
+ it('should not add a new trigger if there is no current trigger and the trigger parameter is not associated with the current connector', () => {
224
+ const { flow } = setup({ trigger: null })
225
+ const { trigger: initialTrigger } = flow.getState()
226
+
227
+ expect(initialTrigger).toBeNull()
228
+
229
+ realtimeMock.events.emit(
230
+ realtimeMock.key('created', 'io.cozy.triggers'),
231
+ {
232
+ ...fixtures.createdTrigger,
233
+ message: {
234
+ ...fixtures.createdTrigger.message,
235
+ konnector: 'other-connector-slug'
236
+ }
237
+ }
238
+ )
239
+ const { trigger } = flow.getState()
240
+
241
+ expect(trigger).toEqual(null)
242
+ })
243
+
244
+ it('should not overwrite the current trigger if it already exists, even if the trigger parameter is associated with the current connector', () => {
245
+ const { flow } = setup({ trigger: fixtures.createdTrigger })
246
+ const { trigger: initialTrigger } = flow.getState()
247
+
248
+ expect(initialTrigger).toEqual(fixtures.createdTrigger)
249
+
250
+ realtimeMock.events.emit(
251
+ realtimeMock.key('created', 'io.cozy.triggers'),
252
+ {
253
+ ...fixtures.createdTriggerWithFolder
254
+ }
255
+ )
256
+ const { trigger } = flow.getState()
257
+
258
+ expect(trigger).toEqual(fixtures.createdTrigger)
259
+ })
260
+ })
261
+
262
+ describe('handleTriggerDeleted', () => {
263
+ it('should remove the trigger if it has the same current trigger', () => {
264
+ const { flow } = setup({ trigger: fixtures.createdTrigger })
265
+ const { trigger: initialTrigger } = flow.getState()
266
+
267
+ expect(initialTrigger).toEqual(fixtures.createdTrigger)
268
+
269
+ realtimeMock.events.emit(
270
+ realtimeMock.key('deleted', 'io.cozy.triggers'),
271
+ {
272
+ ...fixtures.createdTrigger
273
+ }
274
+ )
275
+ const { trigger } = flow.getState()
276
+
277
+ expect(trigger).toBeNull()
278
+ })
279
+
280
+ it('should not delete the trigger if it does not have the same current trigger', () => {
281
+ const { flow } = setup({ trigger: fixtures.createdTrigger })
282
+ const { trigger: initialTrigger } = flow.getState()
283
+
284
+ expect(initialTrigger).toEqual(fixtures.createdTrigger)
285
+
286
+ realtimeMock.events.emit(
287
+ realtimeMock.key('deleted', 'io.cozy.triggers'),
288
+ {
289
+ ...fixtures.createdTrigger,
290
+ _id: 'another-created-trigger-id'
291
+ }
292
+ )
293
+ const { trigger } = flow.getState()
294
+
295
+ expect(trigger).toEqual(fixtures.createdTrigger)
296
+ })
297
+ })
204
298
  })
205
299
 
206
300
  describe('getState', () => {
@@ -15,6 +15,11 @@ const konnectorFixture = {
15
15
  }
16
16
  }
17
17
 
18
+ const realtimeMock = {
19
+ subscribe: jest.fn(),
20
+ unsubscribe: jest.fn()
21
+ }
22
+
18
23
  const DumbTriggerStatus = ({ flowState }) => {
19
24
  return <div>{flowState.status.toString()}</div>
20
25
  }
@@ -24,6 +29,7 @@ const TriggerStatus = withConnectionFlow()(DumbTriggerStatus)
24
29
  describe('with connection flow', () => {
25
30
  it('should update correctly', () => {
26
31
  const client = new CozyClient({})
32
+ client.plugins = { realtime: realtimeMock }
27
33
  const flow = new ConnectionFlow(client, null, konnectorFixture)
28
34
  const root = mount(<TriggerStatus flow={flow} />)
29
35
  expect(root.find('div').text()).toBe('IDLE')
@@ -29,6 +29,11 @@ jest.mock('./jobUtils', () => ({
29
29
  waitForRealtimeEvent: jest.fn()
30
30
  }))
31
31
 
32
+ const realtimeMock = {
33
+ subscribe: jest.fn(),
34
+ unsubscribe: jest.fn()
35
+ }
36
+
32
37
  const TEST_BANK_COZY_ID = '100000'
33
38
 
34
39
  const konnector = {
@@ -70,6 +75,7 @@ describe('handleOAuthAccount', () => {
70
75
  const client = new CozyClient({
71
76
  uri: 'http://testcozy.mycozy.cloud'
72
77
  })
78
+ client.plugins = { realtime: realtimeMock }
73
79
  const flow = new ConnectionFlow(client, null, konnector)
74
80
  flow.account = account
75
81
  flow.handleFormSubmit = jest.fn()
@@ -98,6 +104,7 @@ describe('handleOAuthAccount', () => {
98
104
  const client = new CozyClient({
99
105
  uri: 'http://testcozy.mycozy.cloud'
100
106
  })
107
+ client.plugins = { realtime: realtimeMock }
101
108
  const flow = new ConnectionFlow(client, null, konnector)
102
109
  flow.account = account
103
110
  flow.handleFormSubmit = jest.fn()
@@ -123,6 +130,7 @@ describe('checkBIConnection', () => {
123
130
  const client = new CozyClient({
124
131
  uri: 'http://testcozy.mycozy.cloud'
125
132
  })
133
+ client.plugins = { realtime: realtimeMock }
126
134
  const flow = new ConnectionFlow(client, null, konnector)
127
135
  jest.spyOn(client, 'query').mockImplementation(async () => ({ data: [] }))
128
136
 
@@ -211,6 +219,7 @@ describe('refreshContracts', () => {
211
219
  const client = new CozyClient({
212
220
  uri: 'http://testcozy.mycozy.cloud'
213
221
  })
222
+ client.plugins = { realtime: realtimeMock }
214
223
  client.store.dispatch = jest.fn()
215
224
  client.query = jest
216
225
  .fn()
@@ -789,6 +789,7 @@ describe('handleOAuthAccount', () => {
789
789
  const client = new CozyClient({
790
790
  uri: 'http://testcozy.mycozy.cloud'
791
791
  })
792
+ client.plugins = { realtime: realtimeMock }
792
793
  const flow = new ConnectionFlow(client, null, konnector)
793
794
  flow.account = account
794
795
  flow.handleFormSubmit = jest.fn()
@@ -820,6 +821,7 @@ describe('setSync', () => {
820
821
  const client = new CozyClient({
821
822
  uri: 'http://testcozy.mycozy.cloud'
822
823
  })
824
+ client.plugins = { realtime: realtimeMock }
823
825
  const flow = new ConnectionFlow(client, null, konnector)
824
826
  flow.account = account
825
827
  flow.handleFormSubmit = jest.fn()
@@ -857,6 +859,7 @@ describe('updateBIConnectionFromFlow', () => {
857
859
  const client = new CozyClient({
858
860
  uri: 'http://testcozy.mycozy.cloud'
859
861
  })
862
+ client.plugins = { realtime: realtimeMock }
860
863
  const biConnId = 'conn-1337'
861
864
  const account = { data: { auth: { bi: { connId: biConnId } } } }
862
865
  const flow = new ConnectionFlow(client, null, konnector)
@@ -886,6 +889,7 @@ describe('sendTwoFACode', () => {
886
889
  const client = new CozyClient({
887
890
  uri: 'http://testcozy.mycozy.cloud'
888
891
  })
892
+ client.plugins = { realtime: realtimeMock }
889
893
  const biConnId = 'conn-1337'
890
894
  const account = { data: { auth: { bi: { connId: biConnId } } } }
891
895
  const flow = new ConnectionFlow(client, null, konnector)
@@ -899,6 +903,7 @@ describe('sendTwoFACode', () => {
899
903
  const client = new CozyClient({
900
904
  uri: 'http://testcozy.mycozy.cloud'
901
905
  })
906
+ client.plugins = { realtime: realtimeMock }
902
907
  const biConnId = 'conn-1337'
903
908
  const account = { data: { auth: { bi: { connId: biConnId } } } }
904
909
  const flow = new ConnectionFlow(client, null, konnector)
package/test/fixtures.js CHANGED
@@ -123,6 +123,10 @@ const fixtures = {
123
123
  status: 'done',
124
124
  last_executed_job_id: 'old-job-id'
125
125
  },
126
+ message: {
127
+ account: 'updated-account-id',
128
+ konnector: 'konnectest'
129
+ },
126
130
  attributes: {
127
131
  arguments: '0 0 0 * * 0',
128
132
  type: '@cron',
@@ -140,6 +144,10 @@ const fixtures = {
140
144
  status: 'errored',
141
145
  last_error: 'last error message'
142
146
  },
147
+ message: {
148
+ account: 'updated-account-id',
149
+ konnector: 'konnectest'
150
+ },
143
151
  attributes: {
144
152
  arguments: '0 0 0 * * 0',
145
153
  type: '@cron',
@@ -158,6 +166,10 @@ const fixtures = {
158
166
  status: 'running',
159
167
  last_executed_job_id: 'running-job-id'
160
168
  },
169
+ message: {
170
+ account: 'updated-account-id',
171
+ konnector: 'konnectest'
172
+ },
161
173
  attributes: {
162
174
  arguments: '0 0 0 * * 0',
163
175
  type: '@cron',
@@ -171,6 +183,11 @@ const fixtures = {
171
183
  createdTriggerWithFolder: {
172
184
  id: 'created-trigger-id',
173
185
  _type: 'io.cozy.triggers',
186
+ message: {
187
+ account: 'updated-account-id',
188
+ konnector: 'konnectest',
189
+ folder_to_save: 'folder-id'
190
+ },
174
191
  attributes: {
175
192
  arguments: '0 0 0 * * 0',
176
193
  type: '@cron',