<!doctype html>
<html>
  <head>
    <title>Notifications: The Notification object exposes the expected properties.</title>
    <script src="../resources/testharness.js"></script>
    <script src="../resources/testharnessreport.js"></script>
  </head>
  <body>
    <script>
      // Tests that the Notification object exposes the properties per the
      // semantics defined by the specification. When the test is being ran
      // manually, grant Notification permission first.
      test(function () {
          assert_greater_than_equal(Notification.maxActions, 0);
          var oldMaxActions = Notification.maxActions;
          Notification.maxActions++;
          assert_equals(Notification.maxActions, oldMaxActions, 'Notification.maxActions should be immutable.');

          var options = {
                dir: "rtl",
                lang: "nl-NL",
                body: "Hallo, wereld!",
                tag: "notification",
                image: "http://localhost/image.jpg",
                icon: "http://localhost/my_icon.png",
                badge: "http://localhost/badge.png",
                timestamp: 621046800000,
                silent: true,
                requireInteraction: true,
                data: "my data",
                actions: []
            };

            var notification = new Notification("My Notification", options);

            assert_equals(notification.title, "My Notification");
            assert_equals(notification.dir, options.dir);
            assert_equals(notification.lang, options.lang);
            assert_equals(notification.body, options.body);
            assert_equals(notification.tag, options.tag);
            assert_equals(notification.image, options.image);
            assert_equals(notification.icon, options.icon);
            assert_equals(notification.badge, options.badge);
            assert_equals(notification.timestamp, options.timestamp);
            assert_true(notification.silent);
            assert_true(notification.requireInteraction);
            assert_equals(notification.data, options.data);
            assert_array_equals(notification.actions, options.actions);

            // The `actions` field should be immutable.
            assert_throws(null, () => notification.actions.push(null));

            notification.actions.foo = 'bar';
            assert_false(notification.actions.hasOwnProperty('foo'));

            var emptyNotification = new Notification("My Notification");

            assert_equals(emptyNotification.title, "My Notification");
            assert_equals(emptyNotification.dir, "auto");
            assert_equals(emptyNotification.lang, "");
            assert_equals(emptyNotification.body, "");
            assert_equals(emptyNotification.tag, "");
            assert_equals(emptyNotification.image, "");
            assert_equals(emptyNotification.icon, "");
            assert_equals(emptyNotification.badge, "");
            assert_array_equals(emptyNotification.vibrate, []);
            assert_false(emptyNotification.silent);
            assert_false(emptyNotification.requireInteraction);
            assert_equals(emptyNotification.data, null);
            assert_array_equals(emptyNotification.actions, []);

            var timeDifference = Math.abs(Date.now() - emptyNotification.timestamp);
            assert_true(timeDifference < 16);  // 16 is not significant, just to reduce flakiness.

            var equalNotification = new Notification("My Notification", {
                vibrate: [50, 10, 50, 10, 50],
                data: { hello: "World!" }
            });

            // Test equality of the object attributes.
            assert_equals(equalNotification.data, equalNotification.data, '`data` object equality');
            assert_equals(equalNotification.vibrate, equalNotification.vibrate, '`vibrate` object equality');

            var serializedUrlNotification = new Notification("My Notification", {
                image: "https://example.com/image.jpg",
                icon: "https://example.com/icon.png",
                badge: "https://example.com/badge.png"
            });

            // Icon URLs should be returned in serialized form.
            assert_equals(serializedUrlNotification.image, "https://example.com/image.jpg");
            assert_equals(serializedUrlNotification.icon, "https://example.com/icon.png");
            assert_equals(serializedUrlNotification.badge, "https://example.com/badge.png");

            var noTagNotification = new Notification("My Notification"),
                emptyTagNotification = new Notification("My Notification", { tag: "" });

            // Setting an empty string as the tag should be equal to not setting the tag at all.
            assert_equals(noTagNotification.tag, emptyTagNotification.tag);

            var vibrateNotification = new Notification("My Notification", {
                vibrate: 1000
            });

            // vibrate pattern should be returned in serialized form.
            assert_array_equals(vibrateNotification.vibrate, [1000]);

            // The `vibrate` property should be immutable.
            assert_throws(null, () => vibrateNotification.vibrate.push(1000));

            vibrateNotification.vibrate[0] = 2000;
            assert_equals(vibrateNotification.vibrate[0], 1000);

            // Tests that it must be a valid vibration sequence.
            var pattern = new Array(100, 200, 300);
            var sequenceVibrateNotification = new Notification("My Notification", {
                vibrate: pattern
            });
            assert_array_equals(sequenceVibrateNotification.vibrate, pattern);

            // Invalid vibrate pattern should be reset to 0.
            var invalidVibrateNotification = new Notification("My Notification", {
                vibrate: [100, 200, "invalid"]
            });
            assert_array_equals(invalidVibrateNotification.vibrate, [100, 200, 0]);

            // Notification actions should only be supported for persistent notifications.
            assert_throws(new TypeError(), function() {
                new Notification("My Notification", {
                    actions: [{ action: "foo", title: "Foo" }]
                });
            }, 'Providing non-empty `actions` for a non-persistent notification should throw a TypeError.');

            // Notification actions should only support the placeholder attribute if they are type text.
            assert_throws(new TypeError(), function() {
                new Notification("My Notification", {
                    actions: [{ action: "foo", title: "Foo", placeholder: "I'm sorry, Dave." }]
                });
            }, 'Providing a placeholder for an action that is not type text should throw a TypeError.');

            // Notification actions should not accept invalid types.
            assert_throws(new TypeError(), function() {
                new Notification("My Notification", {
                    actions: [{ type: "blah", action: "foo", title: "Foo" }]
                });
            }, 'Providing an invalid type for an action should throw a TypeError.');

      }, 'Checks the properties exposed on the Notification object.');
    </script>
  </body>
</html>
