<!doctype html>
<html>
<head>
<title>getUserMedia: test that mediaDevices.getUserMedia is present</title>
<link rel="author" title="Dr Alex Gouaillard" href="mailto:agouaillard@gmail.com"/>
<link rel="help" href="https://w3c.github.io/mediacapture-main/#mediadevices-interface-extensions">
<meta name='assert' content='Check that the mediaDevices.getUserMedia() method is present.'/>
</head>
<body>
<h1 class="instructions">Description</h1>
<p class="instructions">This test checks for the presence of the
<code>navigator.mediaDevices.getUserMedia</code> method.</p>
<div id='log'></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
test(function () {
  assert_true(undefined !== navigator.mediaDevices.getUserMedia, "navigator.mediaDevices.getUserMedia exists.");
  // TODO: do some stuff with it
  assert_true(undefined !== navigator.mediaDevices.getSupportedConstraints, "navigator.mediaDevices.getSupportedConstraints exists.");
  var list = navigator.mediaDevices.getSupportedConstraints();
  // TODO: we are supposed to check that all values returned can be used in a constraint ....
  // NOTE: the current list of attributes that may or may not be here
  // ...   FF for example has many no tin that list, should we fail if an attribute is present but not listed in the specs?
  //   list.width
  //   list.height
  //   list.aspectRatio
  //   list.frameRate
  //   list.facingMode
  //   list.volume
  //   list.sampleRate
  //   list.sampleSize
  //   list.echoCancellation
  //   list.latency
  //   list.channelCount
  //   list.deviceId
  //   list.groupId
  }, "mediaDevices.getUserMedia() is present on navigator");

promise_test(async t => {
  assert_true(navigator.mediaDevices.getSupportedConstraints()["groupId"],
    "groupId should be supported");
  const devices = await navigator.mediaDevices.enumerateDevices();
  for (const device of devices) {
    await navigator.mediaDevices.getUserMedia(
        {video: {groupId: {exact: device.groupId}}}).then(stream => {
      const found_device = devices.find(({deviceId}) =>
        deviceId == stream.getTracks()[0].getSettings().deviceId);
      assert_not_equals(found_device, undefined);
      assert_equals(found_device.kind, "videoinput");
      assert_equals(found_device.groupId, device.groupId);
      stream.getTracks().forEach(t => t.stop());
    }, error => {
      assert_equals(error.name, "OverconstrainedError");
      assert_equals(error.constraint, "groupId");
      const found_device = devices.find(element =>
        element.kind == "videoinput" && element.groupId == device.groupId);
      assert_equals(found_device, undefined);
    });
  }
}, 'groupId is correctly supported by getUserMedia() for video devices');

promise_test(async t => {
  assert_true(navigator.mediaDevices.getSupportedConstraints()["groupId"],
    "groupId should be supported");
  const devices = await navigator.mediaDevices.enumerateDevices();
  for (const device of devices) {
    await navigator.mediaDevices.getUserMedia(
        {audio: {groupId: {exact: device.groupId}}}).then(stream => {
      const found_device = devices.find(({deviceId}) =>
        deviceId == stream.getTracks()[0].getSettings().deviceId);
      assert_not_equals(found_device, undefined);
      assert_equals(found_device.kind, "audioinput");
      assert_equals(found_device.groupId, device.groupId);
      stream.getTracks().forEach(t => t.stop());
    }, error => {
      assert_equals(error.name, "OverconstrainedError");
      assert_equals(error.constraint, "groupId");
      const found_device = devices.find(element =>
        element.kind == "audioinput" && element.groupId == device.groupId);
      assert_equals(found_device, undefined);
    });
  }
}, 'groupId is correctly supported by getUserMedia() for audio devices');

promise_test(async t => {
  assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"],
    "resizeMode should be supported");
  const stream = await navigator.mediaDevices.getUserMedia(
      { video: {resizeMode: {exact: 'none'}}});
  const [track] = stream.getVideoTracks();
  t.add_cleanup(() => track.stop());
  assert_equals(track.getSettings().resizeMode, 'none');
}, 'getUserMedia() supports setting none as resizeMode.');

promise_test(async t => {
  assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"],
    "resizeMode should be supported");
  const stream = await navigator.mediaDevices.getUserMedia(
      { video: {resizeMode: {exact: 'crop-and-scale'}}});
  const [track] = stream.getVideoTracks();
  t.add_cleanup(() => track.stop());
  assert_equals(track.getSettings().resizeMode, 'crop-and-scale');
}, 'getUserMedia() supports setting crop-and-scale as resizeMode.');

promise_test(async t => {
  assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"],
    "resizeMode should be supported");
  try {
    const stream = await navigator.mediaDevices.getUserMedia(
        { video: {resizeMode: {exact: 'INVALID'}}});
    t.add_cleanup(() => stream.getVideoTracks()[0].stop());
    t.unreached_func('getUserMedia() should fail with invalid resizeMode')();
  } catch (e) {
    assert_equals(e.name, 'OverconstrainedError');
    assert_equals(e.constraint, 'resizeMode');
  }
}, 'getUserMedia() fails with exact invalid resizeMode.');
</script>
</body>
</html>
