<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>

// This test verifies that ImageCapture can be created (or not) with different
// Media Stream Track types (audio, video).

function makeAsyncTest(modifyTrack, message) {
  async_test(function(test) {

    const gotStream = test.step_func(function(stream) {
      assert_equals(stream.getAudioTracks().length, 0);
      assert_equals(stream.getVideoTracks().length, 1);

      var videoTrack = stream.getVideoTracks()[0];
      assert_equals(videoTrack.readyState, 'live');
      assert_true(videoTrack.enabled);
      assert_false(videoTrack.muted);

      var capturer = new ImageCapture(videoTrack);
      assert_equals(capturer.track, videoTrack);

      modifyTrack(videoTrack);

      promise_rejects(test,
                      'InvalidStateError',
                      capturer.grabFrame(),
                      'Should throw InvalidStateError.')
        .then(() => test.done());
    });

    const onError = test.unreached_func('Error creating MediaStream.');
    navigator.mediaDevices.getUserMedia({video: true})
    .then(gotStream)
    .catch(onError);

  }, message);
}

var disableTrack = function(videoTrack) {
  // grabFrame() is rejected if the associated video track is disabled.
  videoTrack.enabled = false;
};

var stopTrack = function(videoTrack) {
  // grabFrame() is rejected if the associated video track is ended.
  videoTrack.stop();
  assert_equals(videoTrack.readyState, 'ended');
};

// Create the rejection tests. Note that grabFrame() would also be rejected if
// the video Track was muted but that's a read-only property of the Track.
makeAsyncTest(disableTrack, 'grabFrame() of a disabled Track');
makeAsyncTest(stopTrack, 'grabFrame() of an ended Track');


var testAudio = async_test(function() {
  navigator.mediaDevices.getUserMedia({audio:true})
  .then(
    this.step_func(function(stream) {
      assert_equals(stream.getAudioTracks().length, 1);
      assert_equals(stream.getVideoTracks().length, 0);
      assert_throws("NotSupportedError",
                    function() {
                      var capturer = new ImageCapture(stream.getAudioTracks()[0]);
                    },
                    'an ImageCapturer can only be created from a video track');

      this.done();
    }))
    .catch(
    this.unreached_func('Error creating MediaStream.'));
}, 'verifies that an ImageCapture cannot be created out of an Audio Track');

var testParameter = test(function() {
  const invalidParameters = [
    "invalid",
    null,
    123,
    {},
    "",
    true
  ];
  assert_throws(new TypeError(),
                function() { var capturer = new ImageCapture(); },
               'an ImageCapturer can not be created with no parameter');
  invalidParameters.map(parameter => {
    assert_throws(new TypeError(),
                  function() { var capturer = new ImageCapture(parameter); },
                 `an ImageCapturer can not be created with a ${parameter} parameter`);
  });
}, 'throw "TypeError" if parameter is not MediaStreamTrack.');

</script>
