"use strict"; const {strict: assert} = require("assert"); const {set_global, zrequire} = require("./lib/namespace"); const {run_test} = require("./lib/test"); const $ = require("./lib/zjquery"); const {page_params, user_settings} = require("./lib/zpage_params"); // Dependencies set_global("document", { hasFocus() { return true; }, }); const _navigator = { userAgent: "Mozilla/5.0 AppleWebKit/537.36 Chrome/64.0.3282.167 Safari/537.36", }; set_global("navigator", _navigator); const user_topics = zrequire("user_topics"); const stream_data = zrequire("stream_data"); const spoilers = zrequire("spoilers"); spoilers.hide_spoilers_in_notification = () => {}; const notifications = zrequire("notifications"); // Not muted streams const general = { subscribed: true, name: "general", stream_id: 10, is_muted: false, wildcard_mentions_notify: null, }; // Muted streams const muted = { subscribed: true, name: "muted", stream_id: 20, is_muted: true, wildcard_mentions_notify: null, }; stream_data.add_sub(general); stream_data.add_sub(muted); user_topics.update_user_topics( general.stream_id, "muted topic", user_topics.all_visibility_policies.MUTED, ); function test(label, f) { run_test(label, (helpers) => { page_params.is_admin = false; page_params.realm_users = []; user_settings.enable_desktop_notifications = true; user_settings.enable_sounds = true; user_settings.wildcard_mentions_notify = true; user_settings.notification_sound = "ding"; f(helpers); }); } test("message_is_notifiable", () => { // A notification is sent if both message_is_notifiable(message) // and the appropriate should_send_*_notification function return // true. // Case 1: If the message was sent by this user, // DO NOT notify the user // In this test, all other circumstances should trigger notification // EXCEPT sent_by_me, which should trump them let message = { id: muted.stream_id, content: "message number 1", sent_by_me: true, notification_sent: false, mentioned: true, mentioned_me_directly: true, type: "stream", stream: "general", stream_id: general.stream_id, topic: "whatever", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); // Not notifiable because it was sent by the current user assert.equal(notifications.message_is_notifiable(message), false); // Case 2: If the user has already been sent a notification about this message, // DO NOT notify the user // In this test, all other circumstances should trigger notification // EXCEPT notification_sent, which should trump them // (ie: it mentions user, it's not muted, etc) message = { id: general.stream_id, content: "message number 2", sent_by_me: false, notification_sent: true, mentioned: true, mentioned_me_directly: true, type: "stream", stream: "general", stream_id: general.stream_id, topic: "whatever", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), false); // Case 3: If a message mentions the user directly, // DO notify the user // Mentioning trumps muting message = { id: 30, content: "message number 3", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: true, type: "stream", stream: "muted", stream_id: muted.stream_id, topic: "topic_three", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), true); // Case 4: // Mentioning should trigger notification in unmuted topic message = { id: 40, content: "message number 4", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: true, type: "stream", stream: "general", stream_id: general.stream_id, topic: "vanilla", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), true); // Case 5: // Wildcard mention should trigger notification in unmuted topic // if wildcard_mentions_notify message = { id: 40, content: "message number 4", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: false, type: "stream", stream: "general", stream_id: general.stream_id, topic: "vanilla", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), true); // But not if it's disabled user_settings.wildcard_mentions_notify = false; assert.equal(notifications.should_send_desktop_notification(message), false); assert.equal(notifications.should_send_audible_notification(message), false); assert.equal(notifications.message_is_notifiable(message), true); // And the stream-level setting overrides the global setting general.wildcard_mentions_notify = true; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), true); // Reset state user_settings.wildcard_mentions_notify = true; general.wildcard_mentions_notify = null; // Case 6: If a message is in a muted stream // and does not mention the user DIRECTLY (i.e. wildcard mention), // DO NOT notify the user message = { id: 50, content: "message number 5", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: false, type: "stream", stream: "muted", stream_id: muted.stream_id, topic: "whatever", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), false); // Case 7: If a message is in a muted stream // and does mention the user DIRECTLY, // DO notify the user message = { id: 50, content: "message number 5", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: true, type: "stream", stream: "muted", stream_id: muted.stream_id, topic: "whatever", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), true); // Case 8: If a message is in a muted topic // and does not mention the user DIRECTLY (i.e. wildcard mention), // DO NOT notify the user message = { id: 50, content: "message number 6", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: false, type: "stream", stream: "general", stream_id: general.stream_id, topic: "muted topic", }; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), true); assert.equal(notifications.message_is_notifiable(message), false); // Case 9: If `None` is selected as the notification sound, send no // audible notification, no matter what other user configurations are. message = { id: 50, content: "message number 7", sent_by_me: false, notification_sent: false, mentioned: true, mentioned_me_directly: true, type: "stream", stream: "general", stream_id: general.stream_id, topic: "whatever", }; user_settings.notification_sound = "none"; assert.equal(notifications.should_send_desktop_notification(message), true); assert.equal(notifications.should_send_audible_notification(message), false); assert.equal(notifications.message_is_notifiable(message), true); // Reset state user_settings.notification_sound = "ding"; // If none of the above cases apply // (ie: topic is not muted, message does not mention user, // no notification sent before, message not sent by user), // return true to pass it to notifications settings, which will return false. message = { id: 60, content: "message number 8", sent_by_me: false, notification_sent: false, mentioned: false, mentioned_me_directly: false, type: "stream", stream: "general", stream_id: general.stream_id, topic: "whatever", }; assert.equal(notifications.should_send_desktop_notification(message), false); assert.equal(notifications.should_send_audible_notification(message), false); assert.equal(notifications.message_is_notifiable(message), true); }); test("basic_notifications", () => { $("