<!doctype html>
<title>MediaStreamTrack and InputDeviceInfo GetCapabilities</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>

const audioProperties = [
  {name: "sampleRate", type: "number"},
  {name: "sampleSize", type: "number"},
  {name: "echoCancellation", type: "boolean"},
  {name: "autoGainControl", type: "boolean"},
  {name: "noiseSuppression", type: "boolean"},
  {name: "latency", type: "number"},
  {name: "channelCount", type: "number"},
  {name: "deviceId", type: "string"},
  {name: "groupId", type: "string"}
];

const videoProperties = [
  {name: "width", type: "number"},
  {name: "height", type: "number"},
  {name: "aspectRatio", type: "number"},
  {name: "frameRate", type: "number"},
  {name: "facingMode", type: "enum-any", validValues: ["user", "environment", "left", "right"]},
  {name: "resizeMode", type: "enum-all", validValues: ["none", "crop-and-scale"]},
  {name: "deviceId", type: "string"},
  {name: "groupId", type: "string"},
];

function verifyBooleanCapability(capability) {
  assert_less_than_equal(capability.length, 2);
  capability.forEach(c => assert_equals(typeof c, "boolean"));
}

function verifyNumberCapability(capability) {
    assert_equals(typeof capability, "object");
    assert_equals(Object.keys(capability).length, 2);
    assert_true(capability.hasOwnProperty('min'));
    assert_true(capability.hasOwnProperty('max'));
    assert_less_than_equal(capability.min, capability.max);
}

// Verify that any value provided by an enum capability is in the set of valid
// values.
function verifyEnumAnyCapability(capability, enumMembers) {
  capability.forEach(c => {
    assert_equals(typeof c, "string");
    assert_in_array(c, enumMembers);
  });
}

// Verify that all required values are supported by a capability.
function verifyEnumAllCapability(capability, enumMembers, testNamePrefix) {
  enumMembers.forEach(member => {
    test(() => {
      assert_in_array(member, capability);
    }, testNamePrefix + " Value: " + member);
  });
}

function testCapabilities(capabilities, property, testNamePrefix) {
  let testName = testNamePrefix + " " + property.name;
  test(() => {
    assert_true(capabilities.hasOwnProperty(property.name));
  }, testName + " property present.");

  const capability = capabilities[property.name];
  testName += " properly supported.";
  if (property.type == "string") {
    test(() => {
      assert_equals(typeof capability, "string");
    }, testName);
  }

  if (property.type == "boolean") {
    test(() => {
      verifyBooleanCapability(capability);
    }, testName);
  }

  if (property.type == "number") {
    test(() => {
      verifyNumberCapability(capability);
    }, testName);
  }

  if (property.type.startsWith("enum")) {
    test(() => {
      verifyEnumAnyCapability(capability, property.validValues);
    }, testName);

    if (property.type == "enum-all") {
      verifyEnumAllCapability(capability, property.validValues, testName);
    }
  }
}

{
  audioProperties.forEach(property => {
    promise_test(async t => {
      const stream = await navigator.mediaDevices.getUserMedia({audio: true});
      t.add_cleanup(() => stream.getAudioTracks()[0].stop());
      const audioCapabilities = stream.getAudioTracks()[0].getCapabilities();
      testCapabilities(audioCapabilities, property, "Audio track getCapabilities()");
    }, "Setup audio MediaStreamTrack getCapabilities() test for " + property.name);
  });

  videoProperties.forEach(property => {
    promise_test(async t => {
      const stream = await navigator.mediaDevices.getUserMedia({video: true});
      t.add_cleanup(() => stream.getVideoTracks()[0].stop());
      const audioCapabilities = stream.getVideoTracks()[0].getCapabilities();
      testCapabilities(audioCapabilities, property, "Video track getCapabilities()");
    }, "Setup video MediaStreamTrack getCapabilities() test for " + property.name);
  });
}

{
  audioProperties.forEach(property => {
    promise_test(async t => {
      const devices = await navigator.mediaDevices.enumerateDevices();
      for (const device of devices) {
        // Test only one device.
        if (device.kind == "audioinput") {
          assert_inherits(device, "getCapabilities");
          const capabilities = device.getCapabilities();
          testCapabilities(capabilities, property, "Audio device getCapabilities()");
          break;
        }
      }
    }, "Setup audio InputDeviceInfo getCapabilities() test for " + property.name);
  });

  videoProperties.forEach(property => {
    promise_test(async t => {
      const devices = await navigator.mediaDevices.enumerateDevices();
      for (const device of devices) {
        // Test only one device.
        if (device.kind == "videoinput") {
          assert_inherits(device, "getCapabilities");
          const capabilities = device.getCapabilities();
          testCapabilities(capabilities, property, "Video device getCapabilities()");
          break;
        }
      }
    }, "Setup video InputDeviceInfo getCapabilities() test for " + property.name);
  });
}
</script>
