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.

JingleSessionPC.spec.js 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import $ from 'jquery';
  2. import { MockRTC } from '../RTC/MockClasses';
  3. import FeatureFlags from '../flags/FeatureFlags';
  4. import JingleSessionPC from './JingleSessionPC';
  5. import * as JingleSessionState from './JingleSessionState';
  6. import MediaSessionEvents from './MediaSessionEvents';
  7. import { MockChatRoom, MockStropheConnection } from './MockClasses';
  8. /**
  9. * Creates 'content-modify' Jingle IQ.
  10. * @param {string} senders - 'both' or 'none'.
  11. * @param {number|undefined} maxFrameHeight - the receive max video frame height.
  12. * @returns {jQuery}
  13. */
  14. function createContentModify(senders = 'both', maxFrameHeight) {
  15. const modifyContentsIq = $.parseXML(
  16. '<jingle action="content-modify" initiator="peer2" sid="sid12345" xmlns="urn:xmpp:jingle:1">'
  17. + `<content name="video" senders="${senders}">`
  18. + `<max-frame-height xmlns="http://jitsi.org/jitmeet/video">${maxFrameHeight}</max-frame-height>`
  19. + '</content>'
  20. + '</jingle>');
  21. return $(modifyContentsIq).find('>jingle');
  22. }
  23. /**
  24. * Creates 'content-modify' Jingle IQ.
  25. * @returns {jQuery}
  26. */
  27. function createContentModifyForSourceNames() {
  28. const modifyContentsIq = $.parseXML(
  29. '<jingle action="content-modify" initiator="peer2" sid="sid12345" xmlns="urn:xmpp:jingle:1">'
  30. + '<content name="video" senders="both">'
  31. + '<source-frame-height maxHeight="180" sourceName="8d519815-v0" xmlns="http://jitsi.org/jitmeet/video"/>'
  32. + '<source-frame-height maxHeight="2160" sourceName="8d519815-v1" xmlns="http://jitsi.org/jitmeet/video"/>'
  33. + '</content>'
  34. + '</jingle>');
  35. return $(modifyContentsIq).find('>jingle');
  36. }
  37. describe('JingleSessionPC', () => {
  38. let jingleSession;
  39. let connection;
  40. let rtc;
  41. const offerIQ = {
  42. find: () => {
  43. return {
  44. // eslint-disable-next-line no-empty-function
  45. each: () => { }
  46. };
  47. }
  48. };
  49. const SID = 'sid12345';
  50. beforeEach(() => {
  51. connection = new MockStropheConnection();
  52. jingleSession = new JingleSessionPC(
  53. SID,
  54. 'peer1',
  55. 'peer2',
  56. connection,
  57. { },
  58. { },
  59. true,
  60. false);
  61. rtc = new MockRTC();
  62. jingleSession.initialize(
  63. /* ChatRoom */ new MockChatRoom(),
  64. /* RTC */ rtc,
  65. /* Signaling layer */ { },
  66. /* options */ { });
  67. // eslint-disable-next-line no-empty-function
  68. // connection.connect('jid', undefined, () => { }); */
  69. });
  70. describe('send/receive video constraints w/o source-name', () => {
  71. beforeEach(() => {
  72. FeatureFlags.init({ sourceNameSignaling: false });
  73. });
  74. it('sends content-modify with recv frame size', () => {
  75. const sendIQSpy = spyOn(connection, 'sendIQ').and.callThrough();
  76. jingleSession.setReceiverVideoConstraint(180);
  77. expect(jingleSession.getState()).toBe(JingleSessionState.PENDING);
  78. return new Promise((resolve, reject) => {
  79. jingleSession.acceptOffer(
  80. offerIQ,
  81. resolve,
  82. reject,
  83. /* local tracks */ []);
  84. }).then(() => {
  85. expect(jingleSession.getState()).toBe(JingleSessionState.ACTIVE);
  86. // FIXME content-modify is sent before session-accept
  87. expect(sendIQSpy.calls.count()).toBe(2);
  88. expect(sendIQSpy.calls.first().args[0].toString()).toBe(
  89. '<iq to="peer2" type="set" xmlns="jabber:client">'
  90. + '<jingle action="content-modify" initiator="peer2" sid="sid12345" xmlns="urn:xmpp:jingle:1">'
  91. + '<content name="video" senders="both">'
  92. + '<max-frame-height xmlns="http://jitsi.org/jitmeet/video">180</max-frame-height>'
  93. + '</content>'
  94. + '</jingle>'
  95. + '</iq>');
  96. });
  97. });
  98. it('fires an event when remote peer sends content-modify', () => {
  99. let remoteRecvMaxFrameHeight;
  100. const remoteVideoConstraintsListener = session => {
  101. remoteRecvMaxFrameHeight = session.getRemoteRecvMaxFrameHeight();
  102. };
  103. jingleSession.addListener(
  104. MediaSessionEvents.REMOTE_VIDEO_CONSTRAINTS_CHANGED,
  105. remoteVideoConstraintsListener);
  106. return new Promise((resolve, reject) => {
  107. jingleSession.acceptOffer(
  108. offerIQ,
  109. resolve,
  110. reject,
  111. /* local tracks */ []);
  112. }).then(() => {
  113. jingleSession.modifyContents(createContentModify('both', 180));
  114. expect(remoteRecvMaxFrameHeight).toBe(180);
  115. jingleSession.modifyContents(createContentModify('both', 360));
  116. expect(remoteRecvMaxFrameHeight).toBe(360);
  117. jingleSession.modifyContents(createContentModify('both', 180));
  118. expect(remoteRecvMaxFrameHeight).toBe(180);
  119. });
  120. });
  121. });
  122. describe('send/receive video constraints w/ source-name', () => {
  123. beforeEach(() => {
  124. FeatureFlags.init({ sourceNameSignaling: true });
  125. });
  126. it('sends content-modify with recv frame size', () => {
  127. const sendIQSpy = spyOn(connection, 'sendIQ').and.callThrough();
  128. const sourceConstraints = new Map();
  129. sourceConstraints.set('8d519815-v0', 180);
  130. sourceConstraints.set('8d519815-v1', 2160);
  131. jingleSession.setReceiverVideoConstraint(null, sourceConstraints);
  132. expect(jingleSession.getState()).toBe(JingleSessionState.PENDING);
  133. return new Promise((resolve, reject) => {
  134. jingleSession.acceptOffer(
  135. offerIQ,
  136. resolve,
  137. reject,
  138. /* local tracks */ []);
  139. }).then(() => {
  140. expect(jingleSession.getState()).toBe(JingleSessionState.ACTIVE);
  141. // FIXME content-modify is sent before session-accept
  142. expect(sendIQSpy.calls.count()).toBe(2);
  143. expect(sendIQSpy.calls.first().args[0].toString()).toBe(
  144. '<iq to="peer2" type="set" xmlns="jabber:client">'
  145. + '<jingle action="content-modify" initiator="peer2" sid="sid12345" xmlns="urn:xmpp:jingle:1">'
  146. + '<content name="video" senders="both">'
  147. + '<source-frame-height maxHeight="180" sourceName="8d519815-v0"'
  148. + ' xmlns="http://jitsi.org/jitmeet/video"/>'
  149. + '<source-frame-height maxHeight="2160" sourceName="8d519815-v1"'
  150. + ' xmlns="http://jitsi.org/jitmeet/video"/>'
  151. + '</content>'
  152. + '</jingle>'
  153. + '</iq>');
  154. });
  155. });
  156. it('fires an event when remote peer sends content-modify', () => {
  157. let remoteSourcesRecvMaxFrameHeight;
  158. const remoteVideoConstraintsListener = () => {
  159. remoteSourcesRecvMaxFrameHeight = jingleSession.getRemoteSourcesRecvMaxFrameHeight();
  160. };
  161. jingleSession.addListener(
  162. MediaSessionEvents.REMOTE_SOURCE_CONSTRAINTS_CHANGED,
  163. remoteVideoConstraintsListener);
  164. return new Promise((resolve, reject) => {
  165. jingleSession.acceptOffer(
  166. offerIQ,
  167. resolve,
  168. reject,
  169. /* local tracks */ []);
  170. }).then(() => {
  171. jingleSession.modifyContents(createContentModifyForSourceNames());
  172. const v0Height = remoteSourcesRecvMaxFrameHeight[0].maxHeight;
  173. const v1Height = remoteSourcesRecvMaxFrameHeight[1].maxHeight;
  174. expect(v0Height).toBe('180');
  175. expect(v1Height).toBe('2160');
  176. });
  177. });
  178. });
  179. });