| <!doctype html> | 
 | <meta charset=utf-8> | 
 | <title>RTCPeerConnection.prototype.setRemoteDescription</title> | 
 | <script src="/resources/testharness.js"></script> | 
 | <script src="/resources/testharnessreport.js"></script> | 
 | <script src="RTCPeerConnection-helper.js"></script> | 
 | <script> | 
 |  'use strict'; | 
 |  | 
 |  // Test is based on the following editor draft: | 
 |  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html | 
 |  | 
 |  // The following helper functions are called from RTCPeerConnection-helper.js: | 
 |  // generateOffer() | 
 |  // generateAnswer() | 
 |  // assert_session_desc_not_equals() | 
 |  // assert_session_desc_equals() | 
 |  // test_state_change_event() | 
 |  | 
 |  /* | 
 |  4.3.2. Interface Definition | 
 |  [Constructor(optional RTCConfiguration configuration)] | 
 |  interface RTCPeerConnection : EventTarget { | 
 |  Promise<void> setRemoteDescription( | 
 |  RTCSessionDescriptionInit description); | 
 |  | 
 |  readonly attribute RTCSessionDescription? remoteDescription; | 
 |  readonly attribute RTCSessionDescription? currentRemoteDescription; | 
 |  readonly attribute RTCSessionDescription? pendingRemoteDescription; | 
 |  ... | 
 |  }; | 
 |  | 
 |  4.6.2. RTCSessionDescription Class | 
 |  dictionary RTCSessionDescriptionInit { | 
 |  required RTCSdpType type; | 
 |  DOMString sdp = ""; | 
 |  }; | 
 |  | 
 |  4.6.1. RTCSdpType | 
 |  enum RTCSdpType { | 
 |  "offer", | 
 |  "pranswer", | 
 |  "answer", | 
 |  "rollback" | 
 |  }; | 
 |  */ | 
 |  | 
 |  /* | 
 |  4.6.1. enum RTCSdpType | 
 |  */ | 
 |  promise_test(t => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  | 
 |  // SDP is validated after WebIDL validation | 
 |  return promise_rejects(t, new TypeError(), | 
 |  pc.setRemoteDescription({ | 
 |  type: 'bogus', | 
 |  sdp: 'bogus' | 
 |  })); | 
 |  }, 'setRemoteDescription with invalid type and invalid SDP should reject with TypeError') | 
 |  | 
 |  promise_test(t => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  | 
 |  // SDP is validated after validating type | 
 |  return promise_rejects(t, 'InvalidStateError', | 
 |  pc.setRemoteDescription({ | 
 |  type: 'answer', | 
 |  sdp: 'invalid' | 
 |  })); | 
 |  }, 'setRemoteDescription() with invalid SDP and stable state should reject with InvalidStateError') | 
 |  | 
 |  /* Operations after returning to stable state */ | 
 |  | 
 |  promise_test(t => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  const pc2 = new RTCPeerConnection(); | 
 |  | 
 |  test_state_change_event(t, pc, | 
 |  ['have-remote-offer', 'stable', 'have-remote-offer']); | 
 |  | 
 |  return generateOffer({ audio: true }) | 
 |  .then(offer1 => | 
 |  pc.setRemoteDescription(offer1) | 
 |  .then(() => pc.createAnswer()) | 
 |  .then(answer => pc.setLocalDescription(answer)) | 
 |  .then(() => generateOffer({ data: true })) | 
 |  .then(offer2 => | 
 |  pc.setRemoteDescription(offer2) | 
 |  .then(() => { | 
 |  assert_equals(pc.signalingState, 'have-remote-offer'); | 
 |  assert_session_desc_not_equals(offer1, offer2); | 
 |  assert_session_desc_equals(pc.remoteDescription, offer2); | 
 |  assert_session_desc_equals(pc.currentRemoteDescription, offer1); | 
 |  assert_session_desc_equals(pc.pendingRemoteDescription, offer2); | 
 |  }))); | 
 |  }, 'Calling setRemoteDescription() again after one round of remote-offer/local-answer should succeed'); | 
 |  | 
 |  promise_test(t => { | 
 |  const pc = new RTCPeerConnection(); | 
 |  | 
 |  test_state_change_event(t, pc, | 
 |  ['have-local-offer', 'stable', 'have-remote-offer']); | 
 |  | 
 |  return pc.createOffer({ offerToReceiveAudio: true }) | 
 |  .then(offer => | 
 |  pc.setLocalDescription(offer) | 
 |  .then(() => generateAnswer(offer))) | 
 |  .then(answer => | 
 |  pc.setRemoteDescription(answer) | 
 |  .then(() => generateOffer({ data: true })) | 
 |  .then(offer => | 
 |  pc.setRemoteDescription(offer) | 
 |  .then(() => { | 
 |  assert_equals(pc.signalingState, 'have-remote-offer'); | 
 |  assert_session_desc_equals(pc.remoteDescription, offer); | 
 |  assert_session_desc_equals(pc.currentRemoteDescription, answer); | 
 |  assert_session_desc_equals(pc.pendingRemoteDescription, offer); | 
 |  }))); | 
 |  }, 'Switching role from offerer to answerer after going back to stable state should succeed'); | 
 |  | 
 |  /* | 
 |  TODO | 
 |  4.3.2. setRemoteDescription | 
 |  - If an a=identity attribute is present in the session description, the browser | 
 |  validates the identity assertion. | 
 |  */ | 
 |  | 
 | </script> |