You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IceFailedHandling.spec.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import Listenable from '../util/Listenable';
  2. import { nextTick } from '../util/TestUtils';
  3. import IceFailedHandling from './IceFailedHandling';
  4. /**
  5. * Mock conference for the purpose of this test.
  6. */
  7. class MockConference extends Listenable {
  8. /**
  9. * A constructor...
  10. */
  11. constructor() {
  12. super();
  13. this.options = {
  14. config: { }
  15. };
  16. }
  17. }
  18. describe('IceFailedHandling', () => {
  19. let mockConference;
  20. let iceFailedHandling;
  21. let emitEventSpy;
  22. beforeEach(() => {
  23. jasmine.clock().install();
  24. mockConference = new MockConference();
  25. iceFailedHandling = new IceFailedHandling(mockConference);
  26. mockConference.eventEmitter = {
  27. // eslint-disable-next-line no-empty-function
  28. emit: () => { }
  29. };
  30. mockConference.room = {
  31. supportsRestartByTerminate: () => false
  32. };
  33. mockConference.xmpp = {
  34. ping: () => Promise.resolve()
  35. };
  36. emitEventSpy = spyOn(mockConference.eventEmitter, 'emit');
  37. });
  38. afterEach(() => {
  39. jasmine.clock().uninstall();
  40. });
  41. describe('when ICE restarts are disabled', () => {
  42. beforeEach(() => {
  43. mockConference.options.config.enableIceRestart = false;
  44. });
  45. it('emits ICE failed with 2 seconds delay after XMPP ping comes through', () => {
  46. iceFailedHandling.start();
  47. return nextTick() // tick for ping
  48. .then(() => {
  49. expect(emitEventSpy).not.toHaveBeenCalled();
  50. return nextTick(2500); // tick for the 2 sec ice timeout
  51. })
  52. .then(() => {
  53. expect(emitEventSpy).toHaveBeenCalled();
  54. });
  55. });
  56. it('cancel method cancels the ICE failed event', () => {
  57. iceFailedHandling.start();
  58. return nextTick(1000) // tick for ping
  59. .then(() => {
  60. expect(emitEventSpy).not.toHaveBeenCalled();
  61. iceFailedHandling.cancel();
  62. return nextTick(2500); // tick for ice timeout
  63. })
  64. .then(() => {
  65. expect(emitEventSpy).not.toHaveBeenCalled();
  66. });
  67. });
  68. });
  69. describe('when ICE restart are enabled', () => {
  70. let sendIceFailedSpy;
  71. beforeEach(() => {
  72. mockConference.options.config.enableIceRestart = true;
  73. mockConference.jvbJingleSession = {
  74. getIceConnectionState: () => 'failed',
  75. // eslint-disable-next-line no-empty-function
  76. sendIceFailedNotification: () => { }
  77. };
  78. sendIceFailedSpy = spyOn(mockConference.jvbJingleSession, 'sendIceFailedNotification');
  79. });
  80. it('send ICE failed notification to Jicofo', () => {
  81. iceFailedHandling.start();
  82. return nextTick() // tick for ping
  83. .then(() => nextTick(2500)) // tick for ice timeout
  84. .then(() => {
  85. expect(sendIceFailedSpy).toHaveBeenCalled();
  86. });
  87. });
  88. it('not send ICE failed notification to Jicofo if canceled', () => {
  89. iceFailedHandling.start();
  90. // first it send ping which is async - need next tick
  91. return nextTick(1000)
  92. .then(() => {
  93. expect(sendIceFailedSpy).not.toHaveBeenCalled();
  94. iceFailedHandling.cancel();
  95. return nextTick(3000); // tick for ice timeout
  96. })
  97. .then(() => {
  98. expect(sendIceFailedSpy).not.toHaveBeenCalled();
  99. });
  100. });
  101. });
  102. describe('if Jingle session restarts are supported', () => {
  103. let sendSessionTerminateSpy;
  104. beforeEach(() => {
  105. mockConference.options.config.enableIceRestart = undefined;
  106. mockConference.room = {
  107. supportsRestartByTerminate: () => true
  108. };
  109. mockConference.jvbJingleSession = {
  110. getIceConnectionState: () => 'failed',
  111. // eslint-disable-next-line no-empty-function
  112. terminate: () => { }
  113. };
  114. sendSessionTerminateSpy = spyOn(mockConference.jvbJingleSession, 'terminate');
  115. });
  116. it('send "session-terminate" with the request restart attribute', () => {
  117. iceFailedHandling.start();
  118. return nextTick() // tick for ping
  119. .then(() => nextTick(2500)) // tick for ice timeout
  120. .then(() => {
  121. expect(sendSessionTerminateSpy).toHaveBeenCalledWith(
  122. jasmine.any(Function),
  123. jasmine.any(Function), {
  124. reason: 'connectivity-error',
  125. reasonDescription: 'ICE FAILED',
  126. requestRestart: true,
  127. sendSessionTerminate: true
  128. });
  129. });
  130. });
  131. });
  132. describe('when forced reloads are enabled', () => {
  133. beforeEach(() => {
  134. mockConference.options.config.enableIceRestart = undefined;
  135. mockConference.options.config.enableForcedReload = true;
  136. mockConference.room = {
  137. supportsRestartByTerminate: () => true
  138. };
  139. });
  140. it('emits conference restarted when force reloads are enabled', () => {
  141. iceFailedHandling.start();
  142. return nextTick() // tick for ping
  143. .then(() => nextTick(2500)) // tick for ice timeout
  144. .then(() => {
  145. expect(emitEventSpy).toHaveBeenCalled();
  146. });
  147. });
  148. });
  149. });