<!DOCTYPE HTML>
<html>
<head>
  <title>Test for Vibrator</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>

<!-- Although we can't test that the vibrator works properly, we can test that
     navigator.vibrate throws an exception where appropriate. -->

<script class="testbody" type="text/javascript">
function testNavigatorVibrate(testCase) {
  result = navigator.vibrate(testCase.value);
  is(result, true, `vibrate(${testCase.value}) must succeed.`);
}

function testNotificationVibrate(testCase) {
  var notification = new Notification('Test notification', {
    body: 'test vibrate',
    vibrate: testCase.value,
  });

  isDeeply(notification.vibrate, testCase.expected, `vibrate = ${testCase.value} should be accepted.`);
}

const MAX_VIBRATE_MS = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_ms');
const MAX_VIBRATE_LIST_LEN = SpecialPowers.getIntPref('dom.vibrator.max_vibrate_list_len');
const TESTCASES = [
  {
    value: null,
    expected: [0],
  },{
    value: undefined,
    expected: [],
  },{
    // -1 will be converted to the highest unsigned long then clamped.
    value: -1,
    expected: [MAX_VIBRATE_MS],
  },{
    value: 'a',
    expected: [0],
  },{
    // -1 will be converted to the highest unsigned long then clamped.
    value: [100, -1],
    expected: [100, MAX_VIBRATE_MS],
  },{
    value: [100, 'a'],
    expected: [100, 0],
  },{
    // If we pass a vibration pattern with a value higher than max_vibrate_ms or a
    // pattern longer than max_vibrate_list_len, the call should succeed but the
    // pattern should be modified to match the restrictions.

    // Values will be clamped to dom.vibrator.max_vibrate_ms.
    value: MAX_VIBRATE_MS + 1,
    expected: [MAX_VIBRATE_MS],
  },{
    value: [MAX_VIBRATE_MS + 1],
    expected: [MAX_VIBRATE_MS],
  },{
    // The array will be truncated to have a length equal to dom.vibrator.max_vibrate_list_len.
    value: new Array(MAX_VIBRATE_LIST_LEN + 1).fill(0),
    expected: new Array(MAX_VIBRATE_LIST_LEN).fill(0),
  },{
    value: 0,
    expected: [0],
  },{
    value: [],
    expected: [],
  },{
    value: '1000',
    expected: [1000],
  },{
    value: 1000,
    expected: [1000],
  },{
    value: 1000.1,
    expected: [1000],
  },{
    value: [0, 0, 0],
    expected: [0, 0, 0],
  },{
    value: ['1000', 1000],
    expected: [1000, 1000],
  },{
    value: [1000, 1000],
    expected: [1000, 1000],
  },{
    value: [1000, 1000.1],
    expected: [1000, 1000],
  }
];

function testWith(tester) {
  for (let testCase of TESTCASES) {
    tester(testCase);
  }
}

add_task(async function test_notification_vibrate_enabled() {
  await SpecialPowers.pushPrefEnv({"set": [['dom.webnotifications.vibrate.enabled', true]]});

  testWith(testNotificationVibrate);
});

add_task(async function test_vibrator_vibrate() {
  await SpecialPowers.pushPermissions([{type: 'vibration', allow: true, context: document}]);
  await SpecialPowers.pushPrefEnv({"set": [['dom.vibrator.enabled', true]]});

  testWith(testNavigatorVibrate);

  await SpecialPowers.pushPrefEnv({"set": [['dom.vibrator.enabled', false]]});

  testWith(testNavigatorVibrate);
});

add_task(async function test_vibrate_many_times() {
  await SpecialPowers.pushPermissions([{type: 'vibration', allow: true, context: document}]);
  await SpecialPowers.pushPrefEnv({"set": [['dom.vibrator.enabled', true]]});

 // The following loop shouldn't cause us to crash.  See bug 701716.
 for (var i = 0; i < 10000; i++) {
   navigator.vibrate([100, 100]);
 }
 ok(true, "Didn't crash after issuing a lot of vibrate() calls.");
});

add_task(async function test_notification_vibrate_silent() {
  await SpecialPowers.pushPrefEnv({"set": [['dom.webnotifications.vibrate.enabled', true],
      ['dom.webnotifications.silent.enabled', true]]});

  try {
    var notification = new Notification('Test notification', {
      body: 'test vibrate',
      vibrate: [100, 100],
      silent: true,
    });
    ok(false, "The above should throw if vibrate is enabled");
  } catch (error) {
    is(error.name, "TypeError", "A silent notification with a vibrate param should throw a TypeError");
  }
});

</script>
</body>
</html>
