<!DOCTYPE html>
<html>
<head>
<title>Test background blur support</title>
<link rel="help" href="https://w3c.github.io/mediacapture-extensions/">
</head>
<body>
<h1 class="instructions">Description</h1>
<p class="instructions">This test checks background blur support.</p>
<div id='log'></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
"use strict";

const constraintSet = {
  backgroundBlur: true
};

Object.keys(constraintSet).forEach(property => {
  test(t => {
    const supportedConstraints =
        navigator.mediaDevices.getSupportedConstraints();
    assert_implements_optional(
        supportedConstraints[property],
        `Optional property ${property} not in supported constraints`);
  }, `Test getSupportedConstraints().${property}`);

  promise_test(async t => {
    const supportedConstraints =
        navigator.mediaDevices.getSupportedConstraints();

    const stream = await navigator.mediaDevices.getUserMedia({video: true});
    assert_equals(stream.getAudioTracks().length, 0);
    assert_equals(stream.getVideoTracks().length, 1);
    const [videoTrack] = stream.getVideoTracks();

    assert_equals(typeof videoTrack.getCapabilities, 'function');
    const capabilities = videoTrack.getCapabilities();
    assert_equals(typeof capabilities, 'object');

    if (!supportedConstraints[property]) {
      assert_false(property in capabilities);
    }

    assert_implements_optional(
        property in capabilities,
        `Optional property ${property} not in capabilities`);

    // Accept [false], [false, true], [true] and [true, false].
    assert_array_equals(
        capabilities[property],
        capabilities[property].length == 1
            ? [!!capabilities[property][0]]
            : [!!capabilities[property][0], !capabilities[property][0]]);
  }, `Test getCapabilities().${property}`);

  promise_test(async t => {
    const supportedConstraints =
        navigator.mediaDevices.getSupportedConstraints();

    const stream = await navigator.mediaDevices.getUserMedia({video: true});
    assert_equals(stream.getAudioTracks().length, 0);
    assert_equals(stream.getVideoTracks().length, 1);
    const [videoTrack] = stream.getVideoTracks();

    const capabilities = videoTrack.getCapabilities();

    assert_equals(typeof videoTrack.getSettings, 'function');
    const settings = videoTrack.getSettings();
    assert_equals(typeof settings, 'object');

    if (!supportedConstraints[property] || !(property in capabilities))
      assert_false(property in settings);

    assert_implements_optional(
        property in capabilities,
        `Optional property ${property} not in capabilities`);

    assert_in_array(settings[property], capabilities[property]);
  }, `Test getSettings().${property}`);

  promise_test(async t => {
    const supportedConstraints =
        navigator.mediaDevices.getSupportedConstraints();

    const stream = await navigator.mediaDevices.getUserMedia({video: true});
    assert_equals(stream.getAudioTracks().length, 0);
    assert_equals(stream.getVideoTracks().length, 1);
    const [videoTrack] = stream.getVideoTracks();

    const capabilities = videoTrack.getCapabilities();
    const constraints = {advanced: [{
      [property]: constraintSet[property]
    }]};
    const oldSettings = videoTrack.getSettings();

    if (supportedConstraints[property] && !(property in capabilities)) {
      // The user agent supports |constraints| but |videoTrack| is not capable
      // to apply them.
      await videoTrack.applyConstraints(constraints).then(
        () => {
          assert_unreached('Unexpected success applying constraints');
        },
        error => {});
    } else {
      // The user agent does not support |constraints| and will ignore them or
      // the user agent supports |constraints| and |videoTrack| is capable to
      // apply them.
      await videoTrack.applyConstraints(constraints).then(
        () => {},
        error => {
          assert_unreached(`Error applying constraints: ${error.message}`);
        });
    }

    assert_equals(typeof videoTrack.getConstraints, 'function');
    const appliedConstraints = videoTrack.getConstraints();
    assert_equals(typeof appliedConstraints, 'object');
    const newSettings = videoTrack.getSettings();

    if (!supportedConstraints[property] || !(property in capabilities)) {
      // The user agent does not support |constraints| and ignored them or
      // the user agent supports |constraints| but |videoTrack| was not capable
      // to apply them.
      assert_object_equals(appliedConstraints, {});
    } else {
      // The user agent supports |constraints| and |videoTrack| was capable to
      // apply them.
      assert_object_equals(appliedConstraints, constraints);
    }

    if (!supportedConstraints[property] || !(property in capabilities) ||
        !capabilities[property].includes(constraintSet[property])) {
      // The user agent does not support |constraints| and ignored them or
      // the user agent supports |constraints| but |videoTrack| was not capable
      // to apply them or the user agent supports |constraints| and
      // |videoTrack| was capable to apply them but could not satisfy advanced
      // constraints and skipped them.
      assert_object_equals(newSettings, oldSettings);
    } else {
      // The user agent supports |constraints| and |videoTrack| was capable to
      // apply them and could satisfy advanced constraints.
      assert_equals(newSettings[property], constraintSet[property]);
    }
  }, `Test applyConstraints() with ${property}`);
});
</script>
</body>
</html>
