@webex/calling 3.10.0-next.11 → 3.10.0-next.13

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.
@@ -581,20 +581,227 @@ describe('Registration Tests', function () {
581
581
  }, _callee9);
582
582
  })));
583
583
  });
584
- describe('Registration failover tests', function () {
585
- it('verify unreachable primary with reachable backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
584
+ describe('restorePreviousRegistration 429 handling tests', function () {
585
+ beforeEach(function () {
586
+ jest.useFakeTimers();
587
+ });
588
+ afterEach(function () {
589
+ jest.clearAllTimers();
590
+ jest.clearAllMocks();
591
+ jest.useRealTimers();
592
+ });
593
+ it('should schedule retry when 429 with retry-after < 60 seconds during reconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee0() {
594
+ var failurePayload429Small;
586
595
  return _regenerator.default.wrap(function _callee0$(_context0) {
587
596
  while (1) switch (_context0.prev = _context0.next) {
597
+ case 0:
598
+ restartSpy = jest.spyOn(reg, 'restartRegistration');
599
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
600
+ failurePayload429Small = {
601
+ statusCode: 429,
602
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
603
+ headers: {
604
+ 'retry-after': 30
605
+ }
606
+ };
607
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
608
+ _context0.next = 6;
609
+ return reg.reconnectOnFailure(_constants.RECONNECT_ON_FAILURE_UTIL);
610
+ case 6:
611
+ // This call is being used to set the retry-after value
612
+ // Verify restore is invoked first and retry-after captured before scheduling
613
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
614
+ expect(restartSpy).not.toBeCalled();
615
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
616
+
617
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
618
+ _context0.next = 12;
619
+ return flushPromises();
620
+ case 12:
621
+ expect(restartSpy).toHaveBeenCalledTimes(1);
622
+ expect(restartSpy).toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
623
+ case 14:
624
+ case "end":
625
+ return _context0.stop();
626
+ }
627
+ }, _callee0);
628
+ })));
629
+ it('should try backup servers when 429 with retry-after >= 60 seconds on primary during reconnect', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
630
+ var attemptRegistrationWithServersSpy, failurePayload429Small;
631
+ return _regenerator.default.wrap(function _callee1$(_context1) {
632
+ while (1) switch (_context1.prev = _context1.next) {
633
+ case 0:
634
+ // Setup: Register successfully with primary first
635
+ attemptRegistrationWithServersSpy = jest.spyOn(reg, 'attemptRegistrationWithServers');
636
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
637
+ failurePayload429Small = {
638
+ statusCode: 429,
639
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
640
+ headers: {
641
+ 'retry-after': 100
642
+ }
643
+ };
644
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
645
+ _context1.next = 6;
646
+ return reg.reconnectOnFailure(_constants.RECONNECT_ON_FAILURE_UTIL);
647
+ case 6:
648
+ // This call is being used to trigger the retry
649
+ // Verify restore gets invoked, 429 with retry-after is observed and captured
650
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
651
+ expect(retry429Spy).toBeCalledOnceWith(100, _constants.RECONNECT_ON_FAILURE_UTIL);
652
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
653
+ _context1.next = 11;
654
+ return flushPromises();
655
+ case 11:
656
+ expect(attemptRegistrationWithServersSpy).toHaveBeenCalledTimes(2);
657
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(1, _constants.RECONNECT_ON_FAILURE_UTIL, [mobiusUris.primary[0]]);
658
+ // Immediately try backup servers when retry-after >= 60 seconds on primary
659
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(2, _constants.RECONNECT_ON_FAILURE_UTIL, mobiusUris.backup);
660
+ expect(restartSpy).not.toHaveBeenCalledTimes(1);
661
+ expect(restartSpy).not.toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
662
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
663
+ case 17:
664
+ case "end":
665
+ return _context1.stop();
666
+ }
667
+ }, _callee1);
668
+ })));
669
+ it('should restart registration with primary if we get 429 while on backup', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
670
+ var attemptRegistrationWithServersSpy, failurePayload429Small;
671
+ return _regenerator.default.wrap(function _callee10$(_context10) {
672
+ while (1) switch (_context10.prev = _context10.next) {
673
+ case 0:
674
+ // Setup: Register successfully with primary first
675
+ restartSpy = jest.spyOn(reg, 'restartRegistration');
676
+ attemptRegistrationWithServersSpy = jest.spyOn(reg, 'attemptRegistrationWithServers');
677
+ reg.setActiveMobiusUrl(mobiusUris.backup[0]);
678
+ failurePayload429Small = {
679
+ statusCode: 429,
680
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
681
+ headers: {
682
+ 'retry-after': 100
683
+ }
684
+ };
685
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload).mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
686
+ _context10.next = 7;
687
+ return reg.reconnectOnFailure(_constants.RECONNECT_ON_FAILURE_UTIL);
688
+ case 7:
689
+ // This call is being used to trigger the retry
690
+ // Verify restore path taken first and 429 handling captured
691
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
692
+ expect(retry429Spy).toBeCalledOnceWith(100, _constants.RECONNECT_ON_FAILURE_UTIL);
693
+ // No failover scheduling expected in this path
694
+ expect(failoverSpy).not.toBeCalled();
695
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
696
+ _context10.next = 13;
697
+ return flushPromises();
698
+ case 13:
699
+ expect(attemptRegistrationWithServersSpy).toHaveBeenCalledTimes(2);
700
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(1, _constants.RECONNECT_ON_FAILURE_UTIL, [mobiusUris.backup[0]]);
701
+ // Immediately try primary servers when retry-after >= 60 seconds on backup
702
+ expect(restartSpy).toHaveBeenCalledTimes(1);
703
+ expect(restartSpy).toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
704
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(2, _constants.RECONNECT_ON_FAILURE_UTIL, [mobiusUris.primary[0]]);
705
+ case 18:
706
+ case "end":
707
+ return _context10.stop();
708
+ }
709
+ }, _callee10);
710
+ })));
711
+ });
712
+ describe('handleConnectionRestoration 429 handling tests', function () {
713
+ beforeEach(function () {
714
+ jest.useFakeTimers();
715
+ });
716
+ afterEach(function () {
717
+ jest.clearAllTimers();
718
+ jest.clearAllMocks();
719
+ jest.useRealTimers();
720
+ });
721
+ it('should schedule retry when 429 with retry-after < 60 seconds during handleConnectionRestoration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
722
+ var failurePayload429Small;
723
+ return _regenerator.default.wrap(function _callee11$(_context11) {
724
+ while (1) switch (_context11.prev = _context11.next) {
725
+ case 0:
726
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
727
+ failurePayload429Small = {
728
+ statusCode: 429,
729
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
730
+ headers: {
731
+ 'retry-after': 30
732
+ }
733
+ };
734
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload).mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
735
+ _context11.next = 5;
736
+ return reg.handleConnectionRestoration(true);
737
+ case 5:
738
+ expect(restoreSpy).toBeCalledOnceWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
739
+ expect(restartSpy).not.toBeCalled();
740
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
741
+
742
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
743
+ _context11.next = 11;
744
+ return flushPromises();
745
+ case 11:
746
+ expect(restartSpy).toHaveBeenCalledTimes(1);
747
+ expect(restartSpy).toHaveBeenCalledWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
748
+ case 13:
749
+ case "end":
750
+ return _context11.stop();
751
+ }
752
+ }, _callee11);
753
+ })));
754
+ it('should try backup servers when 429 with retry-after >= 60 seconds on primary during handleConnectionRestoration', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
755
+ var attemptRegistrationWithServersSpy, failurePayload429Small;
756
+ return _regenerator.default.wrap(function _callee12$(_context12) {
757
+ while (1) switch (_context12.prev = _context12.next) {
758
+ case 0:
759
+ attemptRegistrationWithServersSpy = jest.spyOn(reg, 'attemptRegistrationWithServers');
760
+ reg.setActiveMobiusUrl(mobiusUris.primary[0]);
761
+ failurePayload429Small = {
762
+ statusCode: 429,
763
+ body: _constants.RECONNECT_ON_FAILURE_UTIL,
764
+ headers: {
765
+ 'retry-after': 100
766
+ }
767
+ };
768
+ webex.request.mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload).mockRejectedValueOnce(failurePayload429Small).mockResolvedValueOnce(successPayload);
769
+ _context12.next = 6;
770
+ return reg.handleConnectionRestoration(true);
771
+ case 6:
772
+ expect(restoreSpy).toBeCalledOnceWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
773
+ expect(retry429Spy).toBeCalledOnceWith(100, _constants.METHODS.HANDLE_CONNECTION_RESTORATION);
774
+ jest.advanceTimersByTime(40 * _constants.SEC_TO_MSEC_MFACTOR);
775
+ _context12.next = 11;
776
+ return flushPromises();
777
+ case 11:
778
+ expect(attemptRegistrationWithServersSpy).toHaveBeenCalledTimes(2);
779
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(1, _constants.METHODS.HANDLE_CONNECTION_RESTORATION, [mobiusUris.primary[0]]);
780
+ // Immediately try backup servers when retry-after >= 60 seconds on primary
781
+ expect(attemptRegistrationWithServersSpy).toHaveBeenNthCalledWith(2, _constants.METHODS.HANDLE_CONNECTION_RESTORATION, mobiusUris.backup);
782
+ expect(restartSpy).not.toHaveBeenCalledTimes(1);
783
+ expect(restartSpy).not.toHaveBeenCalledWith(_constants.METHODS.HANDLE_CONNECTION_RESTORATION);
784
+ case 16:
785
+ case "end":
786
+ return _context12.stop();
787
+ }
788
+ }, _callee12);
789
+ })));
790
+ });
791
+ describe('Registration failover tests', function () {
792
+ it('verify unreachable primary with reachable backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
793
+ return _regenerator.default.wrap(function _callee13$(_context13) {
794
+ while (1) switch (_context13.prev = _context13.next) {
588
795
  case 0:
589
796
  jest.useFakeTimers();
590
797
  // try the primary twice and register successfully with backup servers
591
798
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
592
799
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
593
- _context0.next = 5;
800
+ _context13.next = 5;
594
801
  return reg.triggerRegistration();
595
802
  case 5:
596
803
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
597
- _context0.next = 8;
804
+ _context13.next = 8;
598
805
  return flushPromises();
599
806
  case 8:
600
807
  expect(webex.request).toBeCalledTimes(3);
@@ -612,13 +819,13 @@ describe('Registration Tests', function () {
612
819
  expect(metricSpy).toHaveBeenNthCalledWith(3, _types5.METRIC_EVENT.REGISTRATION, _types5.REG_ACTION.REGISTER, _types5.METRIC_TYPE.BEHAVIORAL, _constants.FAILOVER_UTIL, 'BACKUP', 'webex-js-sdk_06bafdd0-2f9b-4cd7-b438-9c0d95ecec9b_15', undefined, undefined);
613
820
  case 14:
614
821
  case "end":
615
- return _context0.stop();
822
+ return _context13.stop();
616
823
  }
617
- }, _callee0);
824
+ }, _callee13);
618
825
  })));
619
- it('cc: verify unreachable primary with reachable backup server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee1() {
620
- return _regenerator.default.wrap(function _callee1$(_context1) {
621
- while (1) switch (_context1.prev = _context1.next) {
826
+ it('cc: verify unreachable primary with reachable backup server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
827
+ return _regenerator.default.wrap(function _callee14$(_context14) {
828
+ while (1) switch (_context14.prev = _context14.next) {
622
829
  case 0:
623
830
  setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
624
831
  indicator: _types.ServiceIndicator.CONTACT_CENTER
@@ -626,11 +833,11 @@ describe('Registration Tests', function () {
626
833
  jest.useFakeTimers();
627
834
  webex.request.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
628
835
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
629
- _context1.next = 6;
836
+ _context14.next = 6;
630
837
  return reg.triggerRegistration();
631
838
  case 6:
632
839
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
633
- _context1.next = 9;
840
+ _context14.next = 9;
634
841
  return flushPromises();
635
842
  case 9:
636
843
  expect(webex.request).toBeCalledTimes(3);
@@ -647,27 +854,27 @@ describe('Registration Tests', function () {
647
854
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
648
855
  case 14:
649
856
  case "end":
650
- return _context1.stop();
857
+ return _context14.stop();
651
858
  }
652
- }, _callee1);
859
+ }, _callee14);
653
860
  })));
654
- it('verify unreachable primary and backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee10() {
655
- return _regenerator.default.wrap(function _callee10$(_context10) {
656
- while (1) switch (_context10.prev = _context10.next) {
861
+ it('verify unreachable primary and backup servers', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
862
+ return _regenerator.default.wrap(function _callee15$(_context15) {
863
+ while (1) switch (_context15.prev = _context15.next) {
657
864
  case 0:
658
865
  jest.useFakeTimers();
659
866
  // try the primary twice and register successfully with backup servers
660
867
  webex.request.mockRejectedValue(failurePayload);
661
868
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.IDLE);
662
- _context10.next = 5;
869
+ _context15.next = 5;
663
870
  return reg.triggerRegistration();
664
871
  case 5:
665
872
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
666
- _context10.next = 8;
873
+ _context15.next = 8;
667
874
  return flushPromises();
668
875
  case 8:
669
876
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
670
- _context10.next = 11;
877
+ _context15.next = 11;
671
878
  return flushPromises();
672
879
  case 11:
673
880
  /*
@@ -692,27 +899,27 @@ describe('Registration Tests', function () {
692
899
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
693
900
  case 17:
694
901
  case "end":
695
- return _context10.stop();
902
+ return _context15.stop();
696
903
  }
697
- }, _callee10);
904
+ }, _callee15);
698
905
  })));
699
906
  });
700
907
  describe('Registration failback tests', function () {
701
908
  var isPrimaryActiveSpy;
702
- beforeEach(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee11() {
703
- return _regenerator.default.wrap(function _callee11$(_context11) {
704
- while (1) switch (_context11.prev = _context11.next) {
909
+ beforeEach(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
910
+ return _regenerator.default.wrap(function _callee16$(_context16) {
911
+ while (1) switch (_context16.prev = _context16.next) {
705
912
  case 0:
706
913
  isPrimaryActiveSpy = jest.spyOn(reg, 'isPrimaryActive');
707
914
  isPrimaryActiveSpy.mockReturnValue(true);
708
915
  /* keep keepalive as active so that it wont interfere with the failback tests */
709
916
  jest.useFakeTimers();
710
917
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockRejectedValueOnce(failurePayload).mockResolvedValueOnce(successPayload);
711
- _context11.next = 6;
918
+ _context16.next = 6;
712
919
  return reg.triggerRegistration();
713
920
  case 6:
714
921
  jest.advanceTimersByTime(_constants.REG_TRY_BACKUP_TIMER_VAL_IN_SEC * _constants.SEC_TO_MSEC_MFACTOR);
715
- _context11.next = 9;
922
+ _context16.next = 9;
716
923
  return flushPromises();
717
924
  case 9:
718
925
  reg.rehomingIntervalMin = _constants.DEFAULT_REHOMING_INTERVAL_MIN;
@@ -726,17 +933,17 @@ describe('Registration Tests', function () {
726
933
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
727
934
  case 14:
728
935
  case "end":
729
- return _context11.stop();
936
+ return _context16.stop();
730
937
  }
731
- }, _callee11);
938
+ }, _callee16);
732
939
  })));
733
940
  afterEach(function () {
734
941
  jest.clearAllTimers();
735
942
  jest.clearAllMocks();
736
943
  });
737
- it('verify 429 error with failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee12() {
738
- return _regenerator.default.wrap(function _callee12$(_context12) {
739
- while (1) switch (_context12.prev = _context12.next) {
944
+ it('verify 429 error with failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee17() {
945
+ return _regenerator.default.wrap(function _callee17$(_context17) {
946
+ while (1) switch (_context17.prev = _context17.next) {
740
947
  case 0:
741
948
  // delete should be successful
742
949
  global.fetch = jest.fn(function () {
@@ -746,11 +953,13 @@ describe('Registration Tests', function () {
746
953
  }
747
954
  });
748
955
  });
749
- postRegistrationSpy.mockRejectedValue(failurePayload429Two);
956
+
957
+ // Mock to fail twice with 429 (once for executeFailback, once for restorePreviousRegistration)
958
+ postRegistrationSpy.mockRejectedValueOnce(failurePayload429Two).mockRejectedValueOnce(failurePayload429Two);
750
959
 
751
960
  /* Wait for failback to be triggered. */
752
961
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
753
- _context12.next = 5;
962
+ _context17.next = 5;
754
963
  return flushPromises();
755
964
  case 5:
756
965
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
@@ -758,32 +967,35 @@ describe('Registration Tests', function () {
758
967
  file: _constants.REGISTRATION_FILE
759
968
  });
760
969
  jest.advanceTimersByTime(10000);
761
- _context12.next = 9;
970
+ _context17.next = 9;
762
971
  return flushPromises();
763
972
  case 9:
764
973
  expect(retry429Spy).toBeCalledWith(failurePayload429Two.headers['retry-after'], 'executeFailback');
765
- expect(reg.failback429RetryAttempts).toBe(0);
974
+ // After handling 429 during failback, the counter is incremented to 1
975
+ expect(reg.failback429RetryAttempts).toBe(1);
766
976
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.INACTIVE);
767
977
  expect(restoreSpy).toBeCalledOnceWith(_constants.REG_429_RETRY_UTIL);
768
- expect(restartSpy).toBeCalledOnceWith(_constants.REG_429_RETRY_UTIL);
769
- expect(reg.failbackTimer).toBe(undefined);
978
+ // restartRegistration is not called immediately because 429 with retry-after < 60
979
+ // schedules a delayed retry instead
980
+ expect(restartSpy).not.toBeCalled();
981
+ expect(reg.failbackTimer).not.toBe(undefined); // Timer is set in handle429Retry
770
982
  expect(reg.rehomingIntervalMin).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MIN);
771
983
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
772
984
  case 17:
773
985
  case "end":
774
- return _context12.stop();
986
+ return _context17.stop();
775
987
  }
776
- }, _callee12);
988
+ }, _callee17);
777
989
  })));
778
- it('verify unsuccessful failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee13() {
779
- return _regenerator.default.wrap(function _callee13$(_context13) {
780
- while (1) switch (_context13.prev = _context13.next) {
990
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee18() {
991
+ return _regenerator.default.wrap(function _callee18$(_context18) {
992
+ while (1) switch (_context18.prev = _context18.next) {
781
993
  case 0:
782
994
  postRegistrationSpy.mockRejectedValue(failurePayload);
783
995
 
784
996
  /* Wait for failback to be triggered. */
785
997
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
786
- _context13.next = 4;
998
+ _context18.next = 4;
787
999
  return flushPromises();
788
1000
  case 4:
789
1001
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
@@ -798,14 +1010,14 @@ describe('Registration Tests', function () {
798
1010
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
799
1011
  case 11:
800
1012
  case "end":
801
- return _context13.stop();
1013
+ return _context18.stop();
802
1014
  }
803
- }, _callee13);
1015
+ }, _callee18);
804
1016
  })));
805
- it('verify unsuccessful failback to primary after initial registration with backup: Restore failure with final error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee14() {
1017
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore failure with final error', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee19() {
806
1018
  var finalErrorPayload;
807
- return _regenerator.default.wrap(function _callee14$(_context14) {
808
- while (1) switch (_context14.prev = _context14.next) {
1019
+ return _regenerator.default.wrap(function _callee19$(_context19) {
1020
+ while (1) switch (_context19.prev = _context19.next) {
809
1021
  case 0:
810
1022
  finalErrorPayload = {
811
1023
  statusCode: 401,
@@ -815,7 +1027,7 @@ describe('Registration Tests', function () {
815
1027
  postRegistrationSpy.mockRejectedValue(finalErrorPayload).mockRejectedValueOnce(failurePayload);
816
1028
  /* Wait for failback to be triggered. */
817
1029
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
818
- _context14.next = 6;
1030
+ _context19.next = 6;
819
1031
  return flushPromises();
820
1032
  case 6:
821
1033
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
@@ -830,19 +1042,19 @@ describe('Registration Tests', function () {
830
1042
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
831
1043
  case 13:
832
1044
  case "end":
833
- return _context14.stop();
1045
+ return _context19.stop();
834
1046
  }
835
- }, _callee14);
1047
+ }, _callee19);
836
1048
  })));
837
- it('verify unsuccessful failback to primary after initial registration with backup: Restore success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee15() {
838
- return _regenerator.default.wrap(function _callee15$(_context15) {
839
- while (1) switch (_context15.prev = _context15.next) {
1049
+ it('verify unsuccessful failback to primary after initial registration with backup: Restore success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee20() {
1050
+ return _regenerator.default.wrap(function _callee20$(_context20) {
1051
+ while (1) switch (_context20.prev = _context20.next) {
840
1052
  case 0:
841
1053
  postRegistrationSpy.mockRejectedValueOnce(failurePayload).mockResolvedValue(successPayload);
842
1054
 
843
1055
  /* Wait for failback to be triggered. */
844
1056
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
845
- _context15.next = 4;
1057
+ _context20.next = 4;
846
1058
  return flushPromises();
847
1059
  case 4:
848
1060
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
@@ -858,19 +1070,19 @@ describe('Registration Tests', function () {
858
1070
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
859
1071
  case 11:
860
1072
  case "end":
861
- return _context15.stop();
1073
+ return _context20.stop();
862
1074
  }
863
- }, _callee15);
1075
+ }, _callee20);
864
1076
  })));
865
- it('verify successful failback to primary after initial registration with backup', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee16() {
866
- return _regenerator.default.wrap(function _callee16$(_context16) {
867
- while (1) switch (_context16.prev = _context16.next) {
1077
+ it('verify successful failback to primary after initial registration with backup', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee21() {
1078
+ return _regenerator.default.wrap(function _callee21$(_context21) {
1079
+ while (1) switch (_context21.prev = _context21.next) {
868
1080
  case 0:
869
1081
  postRegistrationSpy.mockResolvedValue(successPayload);
870
1082
 
871
1083
  /* Wait for failback to be triggered. */
872
1084
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
873
- _context16.next = 4;
1085
+ _context21.next = 4;
874
1086
  return flushPromises();
875
1087
  case 4:
876
1088
  expect(infoSpy).toBeCalledWith("Attempting failback to primary.", {
@@ -888,13 +1100,13 @@ describe('Registration Tests', function () {
888
1100
  expect(reg.rehomingIntervalMax).toBe(_registerFixtures.mockPostResponse.rehomingIntervalMax);
889
1101
  case 12:
890
1102
  case "end":
891
- return _context16.stop();
1103
+ return _context21.stop();
892
1104
  }
893
- }, _callee16);
1105
+ }, _callee21);
894
1106
  })));
895
- it('verify unsuccessful failback attempt due to active call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee17() {
896
- return _regenerator.default.wrap(function _callee17$(_context17) {
897
- while (1) switch (_context17.prev = _context17.next) {
1107
+ it('verify unsuccessful failback attempt due to active call', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee22() {
1108
+ return _regenerator.default.wrap(function _callee22$(_context22) {
1109
+ while (1) switch (_context22.prev = _context22.next) {
898
1110
  case 0:
899
1111
  /** create a new call */
900
1112
  reg.callManager.createCall();
@@ -903,7 +1115,7 @@ describe('Registration Tests', function () {
903
1115
 
904
1116
  /* Wait for failback to be triggered. */
905
1117
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
906
- _context17.next = 6;
1118
+ _context22.next = 6;
907
1119
  return flushPromises();
908
1120
  case 6:
909
1121
  expect(infoSpy).toBeCalledWith("Active calls present or primary Mobius is down, deferring failback to next cycle.", {
@@ -925,19 +1137,19 @@ describe('Registration Tests', function () {
925
1137
  expect(reg.rehomingIntervalMax).toBe(_constants.DEFAULT_REHOMING_INTERVAL_MAX);
926
1138
  case 15:
927
1139
  case "end":
928
- return _context17.stop();
1140
+ return _context22.stop();
929
1141
  }
930
- }, _callee17);
1142
+ }, _callee22);
931
1143
  })));
932
- it('verify unsuccessful failback attempt due to primary server being down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee18() {
933
- return _regenerator.default.wrap(function _callee18$(_context18) {
934
- while (1) switch (_context18.prev = _context18.next) {
1144
+ it('verify unsuccessful failback attempt due to primary server being down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee23() {
1145
+ return _regenerator.default.wrap(function _callee23$(_context23) {
1146
+ while (1) switch (_context23.prev = _context23.next) {
935
1147
  case 0:
936
1148
  isPrimaryActiveSpy.mockReturnValue(false);
937
1149
 
938
1150
  /* Wait for failback to be triggered. */
939
1151
  jest.advanceTimersByTime(reg.rehomingIntervalMax * _constants.MINUTES_TO_SEC_MFACTOR * _constants.SEC_TO_MSEC_MFACTOR);
940
- _context18.next = 4;
1152
+ _context23.next = 4;
941
1153
  return flushPromises();
942
1154
  case 4:
943
1155
  expect(infoSpy).toBeCalledWith("Active calls present or primary Mobius is down, deferring failback to next cycle.", {
@@ -951,34 +1163,34 @@ describe('Registration Tests', function () {
951
1163
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
952
1164
  case 8:
953
1165
  case "end":
954
- return _context18.stop();
1166
+ return _context23.stop();
955
1167
  }
956
- }, _callee18);
1168
+ }, _callee23);
957
1169
  })));
958
1170
  });
959
1171
 
960
1172
  // Keep-alive related test cases
961
1173
  describe('Keep-alive Tests', function () {
962
1174
  var beforeEachSetupForKeepalive = /*#__PURE__*/function () {
963
- var _ref19 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee19() {
964
- return _regenerator.default.wrap(function _callee19$(_context19) {
965
- while (1) switch (_context19.prev = _context19.next) {
1175
+ var _ref24 = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee24() {
1176
+ return _regenerator.default.wrap(function _callee24$(_context24) {
1177
+ while (1) switch (_context24.prev = _context24.next) {
966
1178
  case 0:
967
1179
  postRegistrationSpy.mockResolvedValueOnce(successPayload);
968
1180
  jest.useFakeTimers();
969
- _context19.next = 4;
1181
+ _context24.next = 4;
970
1182
  return reg.triggerRegistration();
971
1183
  case 4:
972
1184
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
973
1185
  expect(reg.webWorker).toBeDefined();
974
1186
  case 6:
975
1187
  case "end":
976
- return _context19.stop();
1188
+ return _context24.stop();
977
1189
  }
978
- }, _callee19);
1190
+ }, _callee24);
979
1191
  }));
980
1192
  return function beforeEachSetupForKeepalive() {
981
- return _ref19.apply(this, arguments);
1193
+ return _ref24.apply(this, arguments);
982
1194
  };
983
1195
  }();
984
1196
  afterEach(function () {
@@ -991,13 +1203,13 @@ describe('Registration Tests', function () {
991
1203
  call.end();
992
1204
  });
993
1205
  });
994
- it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee20() {
1206
+ it('verify successful keep-alive cases', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee25() {
995
1207
  var postMessageSpy;
996
- return _regenerator.default.wrap(function _callee20$(_context20) {
997
- while (1) switch (_context20.prev = _context20.next) {
1208
+ return _regenerator.default.wrap(function _callee25$(_context25) {
1209
+ while (1) switch (_context25.prev = _context25.next) {
998
1210
  case 0:
999
1211
  postMessageSpy = jest.spyOn(Worker.prototype, 'postMessage');
1000
- _context20.next = 3;
1212
+ _context25.next = 3;
1001
1213
  return beforeEachSetupForKeepalive();
1002
1214
  case 3:
1003
1215
  expect(reg.webWorker).toBeDefined();
@@ -1018,16 +1230,16 @@ describe('Registration Tests', function () {
1018
1230
  expect(lineEmitter).toBeCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1019
1231
  case 7:
1020
1232
  case "end":
1021
- return _context20.stop();
1233
+ return _context25.stop();
1022
1234
  }
1023
- }, _callee20);
1235
+ }, _callee25);
1024
1236
  })));
1025
- it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee21() {
1237
+ it('verify failure keep-alive cases: Retry Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee26() {
1026
1238
  var worker;
1027
- return _regenerator.default.wrap(function _callee21$(_context21) {
1028
- while (1) switch (_context21.prev = _context21.next) {
1239
+ return _regenerator.default.wrap(function _callee26$(_context26) {
1240
+ while (1) switch (_context26.prev = _context26.next) {
1029
1241
  case 0:
1030
- _context21.next = 2;
1242
+ _context26.next = 2;
1031
1243
  return beforeEachSetupForKeepalive();
1032
1244
  case 2:
1033
1245
  worker = reg.webWorker;
@@ -1050,16 +1262,16 @@ describe('Registration Tests', function () {
1050
1262
  expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.RECONNECTED);
1051
1263
  case 7:
1052
1264
  case "end":
1053
- return _context21.stop();
1265
+ return _context26.stop();
1054
1266
  }
1055
- }, _callee21);
1267
+ }, _callee26);
1056
1268
  })));
1057
- it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee22() {
1269
+ it('verify failure keep-alive cases: Restore failure', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee27() {
1058
1270
  var reconnectSpy, restoreSpy, restartRegSpy, RETRY_COUNT_THRESHOLD, failureEvent;
1059
- return _regenerator.default.wrap(function _callee22$(_context22) {
1060
- while (1) switch (_context22.prev = _context22.next) {
1271
+ return _regenerator.default.wrap(function _callee27$(_context27) {
1272
+ while (1) switch (_context27.prev = _context27.next) {
1061
1273
  case 0:
1062
- _context22.next = 2;
1274
+ _context27.next = 2;
1063
1275
  return beforeEachSetupForKeepalive();
1064
1276
  case 2:
1065
1277
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
@@ -1086,14 +1298,14 @@ describe('Registration Tests', function () {
1086
1298
  }
1087
1299
  };
1088
1300
  reg.webWorker.onmessage(failureEvent);
1089
- _context22.next = 14;
1301
+ _context27.next = 14;
1090
1302
  return flushPromises();
1091
1303
  case 14:
1092
1304
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.INACTIVE);
1093
1305
  expect(lineEmitter).toHaveBeenCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1094
- expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1095
- expect(restoreSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1096
- expect(restartRegSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1306
+ expect(reconnectSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1307
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1308
+ expect(restartRegSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1097
1309
  jest.useRealTimers();
1098
1310
  expect(warnSpy).toHaveBeenCalledWith('Keep-alive missed 5 times. Status -> 503 ', expect.objectContaining({
1099
1311
  file: _constants.REGISTRATION_FILE,
@@ -1101,16 +1313,16 @@ describe('Registration Tests', function () {
1101
1313
  }));
1102
1314
  case 21:
1103
1315
  case "end":
1104
- return _context22.stop();
1316
+ return _context27.stop();
1105
1317
  }
1106
- }, _callee22);
1318
+ }, _callee27);
1107
1319
  })));
1108
- it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee23() {
1320
+ it('verify failure keep-alive cases: Restore Success', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee28() {
1109
1321
  var reconnectSpy, url;
1110
- return _regenerator.default.wrap(function _callee23$(_context23) {
1111
- while (1) switch (_context23.prev = _context23.next) {
1322
+ return _regenerator.default.wrap(function _callee28$(_context28) {
1323
+ while (1) switch (_context28.prev = _context28.next) {
1112
1324
  case 0:
1113
- _context23.next = 2;
1325
+ _context28.next = 2;
1114
1326
  return beforeEachSetupForKeepalive();
1115
1327
  case 2:
1116
1328
  expect(reg.webWorker).toBeDefined();
@@ -1126,16 +1338,16 @@ describe('Registration Tests', function () {
1126
1338
  }
1127
1339
  });
1128
1340
  jest.advanceTimersByTime(1000);
1129
- _context23.next = 9;
1341
+ _context28.next = 9;
1130
1342
  return flushPromises();
1131
1343
  case 9:
1132
1344
  expect(reg.webWorker).toBeUndefined();
1133
- expect(reconnectSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1345
+ expect(reconnectSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1134
1346
  webex.request.mockResolvedValueOnce(successPayload);
1135
- _context23.next = 14;
1347
+ _context28.next = 14;
1136
1348
  return reg.triggerRegistration();
1137
1349
  case 14:
1138
- _context23.next = 16;
1350
+ _context28.next = 16;
1139
1351
  return flushPromises();
1140
1352
  case 16:
1141
1353
  expect(reg.webWorker).toBeDefined();
@@ -1148,27 +1360,27 @@ describe('Registration Tests', function () {
1148
1360
 
1149
1361
  // Advance timers and flush any remaining promises.
1150
1362
  jest.advanceTimersByTime(1000);
1151
- _context23.next = 21;
1363
+ _context28.next = 21;
1152
1364
  return flushPromises();
1153
1365
  case 21:
1154
1366
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1155
1367
  // reconnectSpy should have been called only once.
1156
1368
  expect(reconnectSpy).toBeCalledTimes(1);
1157
- expect(restoreSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1158
- expect(restartSpy).toBeCalledOnceWith(reg.startKeepaliveTimer.name);
1369
+ expect(restoreSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1370
+ expect(restartSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1159
1371
  // Active Mobius URL should remain unchanged.
1160
1372
  expect(reg.getActiveMobiusUrl()).toStrictEqual(url);
1161
1373
  case 26:
1162
1374
  case "end":
1163
- return _context23.stop();
1375
+ return _context28.stop();
1164
1376
  }
1165
- }, _callee23);
1377
+ }, _callee28);
1166
1378
  })));
1167
- it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee24() {
1168
- return _regenerator.default.wrap(function _callee24$(_context24) {
1169
- while (1) switch (_context24.prev = _context24.next) {
1379
+ it('verify failure followed by recovery of keepalive', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee29() {
1380
+ return _regenerator.default.wrap(function _callee29$(_context29) {
1381
+ while (1) switch (_context29.prev = _context29.next) {
1170
1382
  case 0:
1171
- _context24.next = 2;
1383
+ _context29.next = 2;
1172
1384
  return beforeEachSetupForKeepalive();
1173
1385
  case 2:
1174
1386
  expect(reg.getStatus()).toBe(_types.RegistrationStatus.ACTIVE);
@@ -1181,15 +1393,15 @@ describe('Registration Tests', function () {
1181
1393
  keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1182
1394
  }
1183
1395
  });
1184
- _context24.next = 8;
1396
+ _context29.next = 8;
1185
1397
  return flushPromises();
1186
1398
  case 8:
1187
1399
  expect(reg.webWorker).toBeUndefined();
1188
1400
  expect(handleErrorSpy).toBeCalledTimes(3);
1189
- _context24.next = 12;
1401
+ _context29.next = 12;
1190
1402
  return reg.triggerRegistration();
1191
1403
  case 12:
1192
- _context24.next = 14;
1404
+ _context29.next = 14;
1193
1405
  return flushPromises();
1194
1406
  case 14:
1195
1407
  expect(reg.webWorker).toBeDefined();
@@ -1199,7 +1411,7 @@ describe('Registration Tests', function () {
1199
1411
  statusCode: 200
1200
1412
  }
1201
1413
  });
1202
- _context24.next = 18;
1414
+ _context29.next = 18;
1203
1415
  return flushPromises();
1204
1416
  case 18:
1205
1417
  // In a complete failure‐then-recovery scenario, we expect another failure event to have been handled.
@@ -1211,16 +1423,16 @@ describe('Registration Tests', function () {
1211
1423
  keepAliveRetryCount: reg.isCCFlow ? 4 : 5
1212
1424
  }
1213
1425
  });
1214
- _context24.next = 21;
1426
+ _context29.next = 21;
1215
1427
  return flushPromises();
1216
1428
  case 21:
1217
1429
  expect(handleErrorSpy).toBeCalledTimes(4);
1218
1430
 
1219
1431
  // And then re-register successfully:
1220
- _context24.next = 24;
1432
+ _context29.next = 24;
1221
1433
  return reg.triggerRegistration();
1222
1434
  case 24:
1223
- _context24.next = 26;
1435
+ _context29.next = 26;
1224
1436
  return flushPromises();
1225
1437
  case 26:
1226
1438
  expect(reg.webWorker).toBeDefined();
@@ -1230,31 +1442,31 @@ describe('Registration Tests', function () {
1230
1442
  statusCode: 200
1231
1443
  }
1232
1444
  });
1233
- _context24.next = 30;
1445
+ _context29.next = 30;
1234
1446
  return flushPromises();
1235
1447
  case 30:
1236
1448
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1237
1449
  expect(reg.webWorker).toBeDefined();
1238
1450
  case 32:
1239
1451
  case "end":
1240
- return _context24.stop();
1452
+ return _context29.stop();
1241
1453
  }
1242
- }, _callee24);
1454
+ }, _callee29);
1243
1455
  })));
1244
- it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee25() {
1456
+ it('cc: verify failover to backup server after 4 keep alive failure with primary server', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee30() {
1245
1457
  var clearKeepaliveSpy, reconnectSpy;
1246
- return _regenerator.default.wrap(function _callee25$(_context25) {
1247
- while (1) switch (_context25.prev = _context25.next) {
1458
+ return _regenerator.default.wrap(function _callee30$(_context30) {
1459
+ while (1) switch (_context30.prev = _context30.next) {
1248
1460
  case 0:
1249
1461
  // Register with contact center service
1250
1462
  setupRegistration(_objectSpread(_objectSpread({}, MockServiceData), {}, {
1251
1463
  indicator: _types.ServiceIndicator.CONTACT_CENTER
1252
1464
  }));
1253
- _context25.next = 3;
1465
+ _context30.next = 3;
1254
1466
  return beforeEachSetupForKeepalive();
1255
1467
  case 3:
1256
1468
  webex.request.mockResolvedValueOnce(successPayload);
1257
- _context25.next = 6;
1469
+ _context30.next = 6;
1258
1470
  return reg.triggerRegistration();
1259
1471
  case 6:
1260
1472
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
@@ -1274,28 +1486,28 @@ describe('Registration Tests', function () {
1274
1486
  });
1275
1487
 
1276
1488
  // Wait for any asynchronous actions to complete
1277
- _context25.next = 13;
1489
+ _context30.next = 13;
1278
1490
  return flushPromises();
1279
1491
  case 13:
1280
1492
  // Verify that the keepalive timer was cleared and reconnectOnFailure was triggered
1281
1493
  expect(clearKeepaliveSpy).toHaveBeenCalled();
1282
- expect(reconnectSpy).toHaveBeenCalledWith(reg.startKeepaliveTimer.name);
1494
+ expect(reconnectSpy).toHaveBeenCalledWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1283
1495
 
1284
1496
  // Verify that the active Mobius URL has been updated to the backup server and registration is active
1285
1497
  expect(reg.getActiveMobiusUrl()).toEqual(mobiusUris.backup[0]);
1286
1498
  expect(reg.getStatus()).toEqual(_types.RegistrationStatus.ACTIVE);
1287
1499
  case 17:
1288
1500
  case "end":
1289
- return _context25.stop();
1501
+ return _context30.stop();
1290
1502
  }
1291
- }, _callee25);
1503
+ }, _callee30);
1292
1504
  })));
1293
- it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee26() {
1505
+ it('verify failure keep-alive case with active call present: Restore Success after call ends', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee31() {
1294
1506
  var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy, threshold, failureEvent;
1295
- return _regenerator.default.wrap(function _callee26$(_context26) {
1296
- while (1) switch (_context26.prev = _context26.next) {
1507
+ return _regenerator.default.wrap(function _callee31$(_context31) {
1508
+ while (1) switch (_context31.prev = _context31.next) {
1297
1509
  case 0:
1298
- _context26.next = 2;
1510
+ _context31.next = 2;
1299
1511
  return beforeEachSetupForKeepalive();
1300
1512
  case 2:
1301
1513
  reconnectSpy = jest.spyOn(reg, 'reconnectOnFailure');
@@ -1315,7 +1527,7 @@ describe('Registration Tests', function () {
1315
1527
  }
1316
1528
  };
1317
1529
  reg.webWorker.onmessage(failureEvent);
1318
- _context26.next = 13;
1530
+ _context31.next = 13;
1319
1531
  return flushPromises();
1320
1532
  case 13:
1321
1533
  // At this point, clearKeepaliveTimer was called so the worker is terminated.
@@ -1325,7 +1537,7 @@ describe('Registration Tests', function () {
1325
1537
  expect(lineEmitter).lastCalledWith(_types4.LINE_EVENTS.UNREGISTERED);
1326
1538
  expect(reg.keepaliveTimer).toStrictEqual(undefined);
1327
1539
  expect(reg.failbackTimer).toStrictEqual(undefined);
1328
- expect(reconnectSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1540
+ expect(reconnectSpy).toBeCalledOnceWith(_constants.RECONNECT_ON_FAILURE_UTIL);
1329
1541
  expect(restoreSpy).not.toBeCalled();
1330
1542
  expect(restartRegSpy).not.toBeCalled();
1331
1543
  expect(reg.reconnectPending).toStrictEqual(true);
@@ -1340,10 +1552,10 @@ describe('Registration Tests', function () {
1340
1552
  webex.request.mockResolvedValueOnce(successPayload);
1341
1553
 
1342
1554
  // Call reconnectOnFailure manually. With no active calls, this should trigger re-registration.
1343
- _context26.next = 29;
1555
+ _context31.next = 29;
1344
1556
  return reg.reconnectOnFailure(_constants.CALLS_CLEARED_HANDLER_UTIL);
1345
1557
  case 29:
1346
- _context26.next = 31;
1558
+ _context31.next = 31;
1347
1559
  return flushPromises();
1348
1560
  case 31:
1349
1561
  expect((0, _keys.default)(reg.callManager.getActiveCalls()).length).toBe(0);
@@ -1356,16 +1568,16 @@ describe('Registration Tests', function () {
1356
1568
  expect(reg.reconnectPending).toStrictEqual(false);
1357
1569
  case 38:
1358
1570
  case "end":
1359
- return _context26.stop();
1571
+ return _context31.stop();
1360
1572
  }
1361
- }, _callee26);
1573
+ }, _callee31);
1362
1574
  })));
1363
- it('checks for keep-alive failure with final error: 404', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee27() {
1575
+ it('checks for keep-alive failure with final error: 404', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee32() {
1364
1576
  var reconnectSpy, restoreSpy, restartRegSpy, clearTimerSpy, handle404CbSpy, registerSpy;
1365
- return _regenerator.default.wrap(function _callee27$(_context27) {
1366
- while (1) switch (_context27.prev = _context27.next) {
1577
+ return _regenerator.default.wrap(function _callee32$(_context32) {
1578
+ while (1) switch (_context32.prev = _context32.next) {
1367
1579
  case 0:
1368
- _context27.next = 2;
1580
+ _context32.next = 2;
1369
1581
  return beforeEachSetupForKeepalive();
1370
1582
  case 2:
1371
1583
  webex.request.mockResolvedValueOnce(successPayload);
@@ -1384,7 +1596,7 @@ describe('Registration Tests', function () {
1384
1596
  keepAliveRetryCount: 1
1385
1597
  }
1386
1598
  });
1387
- _context27.next = 12;
1599
+ _context32.next = 12;
1388
1600
  return flushPromises();
1389
1601
  case 12:
1390
1602
  expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 404 ', expect.objectContaining({
@@ -1408,17 +1620,17 @@ describe('Registration Tests', function () {
1408
1620
  expect(registerSpy).toBeCalledOnceWith(_constants.KEEPALIVE_UTIL);
1409
1621
  case 23:
1410
1622
  case "end":
1411
- return _context27.stop();
1623
+ return _context32.stop();
1412
1624
  }
1413
- }, _callee27);
1625
+ }, _callee32);
1414
1626
  })));
1415
- it('checks for keep-alive failure with 429', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee28() {
1627
+ it('checks for keep-alive failure with 429', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee33() {
1416
1628
  var _reg$deviceInfo$devic;
1417
1629
  var keepaliveSpy, postMessageSpy, clearTimerSpy, retry429Spy;
1418
- return _regenerator.default.wrap(function _callee28$(_context28) {
1419
- while (1) switch (_context28.prev = _context28.next) {
1630
+ return _regenerator.default.wrap(function _callee33$(_context33) {
1631
+ while (1) switch (_context33.prev = _context33.next) {
1420
1632
  case 0:
1421
- _context28.next = 2;
1633
+ _context33.next = 2;
1422
1634
  return beforeEachSetupForKeepalive();
1423
1635
  case 2:
1424
1636
  keepaliveSpy = jest.spyOn(reg, 'startKeepaliveTimer');
@@ -1437,7 +1649,7 @@ describe('Registration Tests', function () {
1437
1649
  keepAliveRetryCount: 1
1438
1650
  }
1439
1651
  });
1440
- _context28.next = 9;
1652
+ _context33.next = 9;
1441
1653
  return flushPromises();
1442
1654
  case 9:
1443
1655
  expect(warnSpy).toBeCalledWith('Keep-alive missed 1 times. Status -> 429 ', expect.objectContaining({
@@ -1459,7 +1671,7 @@ describe('Registration Tests', function () {
1459
1671
  expect(reg.keepaliveTimer).toBe(undefined);
1460
1672
  expect(reg.webWorker).toBeUndefined();
1461
1673
  jest.advanceTimersByTime(20 * _constants.SEC_TO_MSEC_MFACTOR);
1462
- _context28.next = 19;
1674
+ _context33.next = 19;
1463
1675
  return flushPromises();
1464
1676
  case 19:
1465
1677
  expect(keepaliveSpy).toBeCalledOnceWith((_reg$deviceInfo$devic = reg.deviceInfo.device) === null || _reg$deviceInfo$devic === void 0 ? void 0 : _reg$deviceInfo$devic.uri, reg.deviceInfo.keepaliveInterval, 'UNKNOWN');
@@ -1478,25 +1690,97 @@ describe('Registration Tests', function () {
1478
1690
  }));
1479
1691
  case 23:
1480
1692
  case "end":
1481
- return _context28.stop();
1693
+ return _context33.stop();
1482
1694
  }
1483
- }, _callee28);
1695
+ }, _callee33);
1696
+ })));
1697
+ it('ensure retryAfter is set when 429 occurs during failover retry', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee34() {
1698
+ var retry429Spy;
1699
+ return _regenerator.default.wrap(function _callee34$(_context34) {
1700
+ while (1) switch (_context34.prev = _context34.next) {
1701
+ case 0:
1702
+ _context34.next = 2;
1703
+ return beforeEachSetupForKeepalive();
1704
+ case 2:
1705
+ // Simulate loss of registration so failover path attempts a new registration
1706
+ reg.clearKeepaliveTimer();
1707
+ reg.setStatus(_types.RegistrationStatus.INACTIVE);
1708
+ retry429Spy = jest.spyOn(reg, 'handle429Retry'); // Make the failover interval deterministic and simulate 429 on the failover attempt
1709
+ jest.spyOn(reg, 'getRegRetryInterval').mockReturnValueOnce(33);
1710
+ webex.request.mockRejectedValueOnce(failurePayload429One);
1711
+
1712
+ // Directly schedule the failover attempt
1713
+ _context34.next = 9;
1714
+ return reg.startFailoverTimer();
1715
+ case 9:
1716
+ jest.advanceTimersByTime(33 * _constants.SEC_TO_MSEC_MFACTOR);
1717
+ _context34.next = 12;
1718
+ return flushPromises();
1719
+ case 12:
1720
+ expect(retry429Spy).toBeCalledWith(failurePayload429One.headers['retry-after'], 'startFailoverTimer');
1721
+ expect(reg.retryAfter).toEqual(failurePayload429One.headers['retry-after']);
1722
+ jest.useRealTimers();
1723
+ case 15:
1724
+ case "end":
1725
+ return _context34.stop();
1726
+ }
1727
+ }, _callee34);
1728
+ })));
1729
+ it('sets retryAfter when reconnectOnFailure caller receives 429 after keepalive threshold miss', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee35() {
1730
+ var retry429Spy, threshold;
1731
+ return _regenerator.default.wrap(function _callee35$(_context35) {
1732
+ while (1) switch (_context35.prev = _context35.next) {
1733
+ case 0:
1734
+ _context35.next = 2;
1735
+ return beforeEachSetupForKeepalive();
1736
+ case 2:
1737
+ retry429Spy = jest.spyOn(reg, 'handle429Retry'); // On reconnectOnFailure(RECONNECT_ON_FAILURE_UTIL) first restore attempt, make registration respond with 429 (retry-after: 20)
1738
+ webex.request.mockRejectedValueOnce({
1739
+ statusCode: 429,
1740
+ body: _registerFixtures.mockPostResponse,
1741
+ headers: {
1742
+ 'retry-after': 20
1743
+ }
1744
+ });
1745
+
1746
+ // Trigger the keepalive failure at threshold to route to reconnectOnFailure(RECONNECT_ON_FAILURE_UTIL)
1747
+ threshold = reg.isCCFlow ? 4 : 5;
1748
+ reg.webWorker.onmessage({
1749
+ data: {
1750
+ type: _types.WorkerMessageType.KEEPALIVE_FAILURE,
1751
+ err: {
1752
+ statusCode: 503
1753
+ },
1754
+ keepAliveRetryCount: threshold
1755
+ }
1756
+ });
1757
+ _context35.next = 8;
1758
+ return flushPromises();
1759
+ case 8:
1760
+ // handle429Retry is called with caller 'reconnectOnFailure' → else branch executes and sets retryAfter
1761
+ expect(retry429Spy).toBeCalledOnceWith(20, _constants.RECONNECT_ON_FAILURE_UTIL);
1762
+ expect(reg.retryAfter).toEqual(undefined); // Clear retryAfter after 429 retry
1763
+ case 10:
1764
+ case "end":
1765
+ return _context35.stop();
1766
+ }
1767
+ }, _callee35);
1484
1768
  })));
1485
1769
  });
1486
1770
  describe('Primary server status checks', function () {
1487
- it('success: primary server status to be up', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee29() {
1771
+ it('success: primary server status to be up', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee36() {
1488
1772
  var pingSuccessPayload, status;
1489
- return _regenerator.default.wrap(function _callee29$(_context29) {
1490
- while (1) switch (_context29.prev = _context29.next) {
1773
+ return _regenerator.default.wrap(function _callee36$(_context36) {
1774
+ while (1) switch (_context36.prev = _context36.next) {
1491
1775
  case 0:
1492
1776
  pingSuccessPayload = {
1493
1777
  statusCode: 200
1494
1778
  };
1495
1779
  webex.request.mockResolvedValue(pingSuccessPayload);
1496
- _context29.next = 4;
1780
+ _context36.next = 4;
1497
1781
  return reg.isPrimaryActive();
1498
1782
  case 4:
1499
- status = _context29.sent;
1783
+ status = _context36.sent;
1500
1784
  expect(webex.request).toBeCalledWith(_objectSpread({
1501
1785
  method: 'GET',
1502
1786
  uri: "https://mobius-dfw.webex.com/api/v1/ping"
@@ -1504,23 +1788,23 @@ describe('Registration Tests', function () {
1504
1788
  expect(status).toEqual(true);
1505
1789
  case 7:
1506
1790
  case "end":
1507
- return _context29.stop();
1791
+ return _context36.stop();
1508
1792
  }
1509
- }, _callee29);
1793
+ }, _callee36);
1510
1794
  })));
1511
- it('failed: primary server status to be down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee30() {
1795
+ it('failed: primary server status to be down', /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee37() {
1512
1796
  var pingFailurePayload, status;
1513
- return _regenerator.default.wrap(function _callee30$(_context30) {
1514
- while (1) switch (_context30.prev = _context30.next) {
1797
+ return _regenerator.default.wrap(function _callee37$(_context37) {
1798
+ while (1) switch (_context37.prev = _context37.next) {
1515
1799
  case 0:
1516
1800
  pingFailurePayload = {
1517
1801
  statusCode: 500
1518
1802
  };
1519
1803
  webex.request.mockResolvedValue(pingFailurePayload);
1520
- _context30.next = 4;
1804
+ _context37.next = 4;
1521
1805
  return reg.isPrimaryActive();
1522
1806
  case 4:
1523
- status = _context30.sent;
1807
+ status = _context37.sent;
1524
1808
  expect(webex.request).toBeCalledWith(_objectSpread({
1525
1809
  method: 'GET',
1526
1810
  uri: "https://mobius-dfw.webex.com/api/v1/ping"
@@ -1528,9 +1812,9 @@ describe('Registration Tests', function () {
1528
1812
  expect(status).toEqual(false);
1529
1813
  case 7:
1530
1814
  case "end":
1531
- return _context30.stop();
1815
+ return _context37.stop();
1532
1816
  }
1533
- }, _callee30);
1817
+ }, _callee37);
1534
1818
  })));
1535
1819
  });
1536
1820
  });