mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	When we were preparing the conversion to ES modules in 2019, the primary obstacle was that the Node tests extensively relied on the ability to reach into modules and mutate their CommonJS exports in order to mock things. ES module bindings are not mutable, so in commit173c9cee42we added babel-plugin-rewire-ts as a kludgy transpilation-based workaround for this to unblock the conversion. However, babel-plugin-rewire-ts is slow, buggy, nonstandard, confusing, and unmaintained. It’s incompatible with running our ES modules as native ES modules, and prevents us from taking advantage of modern tools for ES modules. So we want to excise all use of __Rewire__ (and the disallow_rewire, override_rewire helper functions that rely on it) from the tests and remove babel-plugin-rewire-ts. Commits64abdc199eande17ba5260a(#20730) prepared for this by letting us see where __Rewire__ is being used. Now we go through and remove most of the uses that are easy to remove without modifying the production code at all. Signed-off-by: Anders Kaseorg <anders@zulip.com>
		
			
				
	
	
		
			504 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			504 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
const {strict: assert} = require("assert");
 | 
						|
 | 
						|
const {mock_esm, set_global, zrequire} = require("../zjsunit/namespace");
 | 
						|
const {run_test} = require("../zjsunit/test");
 | 
						|
const $ = require("../zjsunit/zjquery");
 | 
						|
 | 
						|
const noop = () => {};
 | 
						|
 | 
						|
set_global("document", {
 | 
						|
    to_$: () => $("document-stub"),
 | 
						|
});
 | 
						|
 | 
						|
const channel = mock_esm("../../static/js/channel");
 | 
						|
const compose_fade = mock_esm("../../static/js/compose_fade", {
 | 
						|
    clear_compose: noop,
 | 
						|
});
 | 
						|
const compose_pm_pill = mock_esm("../../static/js/compose_pm_pill");
 | 
						|
const compose_ui = mock_esm("../../static/js/compose_ui", {
 | 
						|
    autosize_textarea: noop,
 | 
						|
    is_full_size: () => false,
 | 
						|
});
 | 
						|
const hash_util = mock_esm("../../static/js/hash_util");
 | 
						|
const narrow_state = mock_esm("../../static/js/narrow_state", {
 | 
						|
    set_compose_defaults: noop,
 | 
						|
});
 | 
						|
mock_esm("../../static/js/notifications", {
 | 
						|
    clear_compose_notifications: noop,
 | 
						|
});
 | 
						|
mock_esm("../../static/js/reload_state", {
 | 
						|
    is_in_progress: () => false,
 | 
						|
});
 | 
						|
mock_esm("../../static/js/recent_topics_util", {
 | 
						|
    is_visible: noop,
 | 
						|
});
 | 
						|
mock_esm("../../static/js/drafts", {
 | 
						|
    update_draft: noop,
 | 
						|
});
 | 
						|
mock_esm("../../static/js/common", {
 | 
						|
    status_classes: "status_classes",
 | 
						|
});
 | 
						|
mock_esm("../../static/js/unread_ops", {
 | 
						|
    notify_server_message_read: noop,
 | 
						|
});
 | 
						|
mock_esm("../../static/js/message_lists", {
 | 
						|
    current: {
 | 
						|
        can_mark_messages_read: () => true,
 | 
						|
    },
 | 
						|
});
 | 
						|
mock_esm("../../static/js/resize", {
 | 
						|
    reset_compose_message_max_height: noop,
 | 
						|
});
 | 
						|
 | 
						|
const people = zrequire("people");
 | 
						|
 | 
						|
const compose = zrequire("compose");
 | 
						|
const compose_state = zrequire("compose_state");
 | 
						|
const compose_actions = zrequire("compose_actions");
 | 
						|
const message_lists = zrequire("message_lists");
 | 
						|
const stream_data = zrequire("stream_data");
 | 
						|
 | 
						|
const start = compose_actions.start;
 | 
						|
const cancel = compose_actions.cancel;
 | 
						|
const get_focus_area = compose_actions._get_focus_area;
 | 
						|
const respond_to_message = compose_actions.respond_to_message;
 | 
						|
const reply_with_mention = compose_actions.reply_with_mention;
 | 
						|
const quote_and_reply = compose_actions.quote_and_reply;
 | 
						|
 | 
						|
function assert_visible(sel) {
 | 
						|
    assert.ok($(sel).visible());
 | 
						|
}
 | 
						|
 | 
						|
function assert_hidden(sel) {
 | 
						|
    assert.ok(!$(sel).visible());
 | 
						|
}
 | 
						|
 | 
						|
function override_private_message_recipient({override}) {
 | 
						|
    let recipient;
 | 
						|
    override(compose_pm_pill, "set_from_emails", (value) => {
 | 
						|
        recipient = value;
 | 
						|
    });
 | 
						|
    override(compose_pm_pill, "get_emails", () => recipient, {unused: false});
 | 
						|
}
 | 
						|
 | 
						|
function test(label, f) {
 | 
						|
    run_test(label, (helpers) => {
 | 
						|
        // We don't test the css calls; we just skip over them.
 | 
						|
        $("#compose").css = () => {};
 | 
						|
        $(".new_message_textarea").css = () => {};
 | 
						|
 | 
						|
        people.init();
 | 
						|
        compose_state.set_message_type(false);
 | 
						|
        f(helpers);
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
test("initial_state", () => {
 | 
						|
    assert.equal(compose_state.composing(), false);
 | 
						|
    assert.equal(compose_state.get_message_type(), false);
 | 
						|
    assert.equal(compose_state.has_message_content(), false);
 | 
						|
});
 | 
						|
 | 
						|
test("start", ({override, override_rewire}) => {
 | 
						|
    override_private_message_recipient({override});
 | 
						|
    override_rewire(compose_actions, "autosize_message_content", () => {});
 | 
						|
    override_rewire(compose_actions, "expand_compose_box", () => {});
 | 
						|
    override_rewire(compose_actions, "set_focus", () => {});
 | 
						|
    override_rewire(compose_actions, "complete_starting_tasks", () => {});
 | 
						|
    override_rewire(compose_actions, "blur_compose_inputs", () => {});
 | 
						|
    override_rewire(compose_actions, "clear_textarea", () => {});
 | 
						|
 | 
						|
    let compose_defaults;
 | 
						|
    override(narrow_state, "set_compose_defaults", () => compose_defaults);
 | 
						|
 | 
						|
    // Start stream message
 | 
						|
    compose_defaults = {
 | 
						|
        stream: "stream1",
 | 
						|
        topic: "topic1",
 | 
						|
    };
 | 
						|
 | 
						|
    let opts = {};
 | 
						|
    start("stream", opts);
 | 
						|
 | 
						|
    assert_visible("#stream-message");
 | 
						|
    assert_hidden("#private-message");
 | 
						|
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "stream1");
 | 
						|
    assert.equal($("#stream_message_recipient_topic").val(), "topic1");
 | 
						|
    assert.equal(compose_state.get_message_type(), "stream");
 | 
						|
    assert.ok(compose_state.composing());
 | 
						|
 | 
						|
    // Autofill stream field for single subscription
 | 
						|
    const denmark = {
 | 
						|
        subscribed: true,
 | 
						|
        color: "blue",
 | 
						|
        name: "Denmark",
 | 
						|
        stream_id: 1,
 | 
						|
    };
 | 
						|
    stream_data.add_sub(denmark);
 | 
						|
 | 
						|
    compose_defaults = {
 | 
						|
        trigger: "new topic button",
 | 
						|
    };
 | 
						|
 | 
						|
    opts = {};
 | 
						|
    start("stream", opts);
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "Denmark");
 | 
						|
    assert.equal($("#stream_message_recipient_topic").val(), "");
 | 
						|
 | 
						|
    compose_defaults = {
 | 
						|
        trigger: "compose_hotkey",
 | 
						|
    };
 | 
						|
 | 
						|
    opts = {};
 | 
						|
    start("stream", opts);
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "Denmark");
 | 
						|
    assert.equal($("#stream_message_recipient_topic").val(), "");
 | 
						|
 | 
						|
    const social = {
 | 
						|
        subscribed: true,
 | 
						|
        color: "red",
 | 
						|
        name: "social",
 | 
						|
        stream_id: 2,
 | 
						|
    };
 | 
						|
    stream_data.add_sub(social);
 | 
						|
 | 
						|
    // More than 1 subscription, do not autofill
 | 
						|
    opts = {};
 | 
						|
    start("stream", opts);
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "");
 | 
						|
    assert.equal($("#stream_message_recipient_topic").val(), "");
 | 
						|
    stream_data.clear_subscriptions();
 | 
						|
 | 
						|
    // Start PM
 | 
						|
    compose_defaults = {
 | 
						|
        private_message_recipient: "foo@example.com",
 | 
						|
    };
 | 
						|
 | 
						|
    opts = {
 | 
						|
        content: "hello",
 | 
						|
    };
 | 
						|
 | 
						|
    start("private", opts);
 | 
						|
 | 
						|
    assert_hidden("#stream-message");
 | 
						|
    assert_visible("#private-message");
 | 
						|
 | 
						|
    assert.equal(compose_state.private_message_recipient(), "foo@example.com");
 | 
						|
    assert.equal($("#compose-textarea").val(), "hello");
 | 
						|
    assert.equal(compose_state.get_message_type(), "private");
 | 
						|
    assert.ok(compose_state.composing());
 | 
						|
 | 
						|
    // Triggered by new private message
 | 
						|
    opts = {
 | 
						|
        trigger: "new private message",
 | 
						|
    };
 | 
						|
 | 
						|
    start("private", opts);
 | 
						|
 | 
						|
    assert.equal(compose_state.private_message_recipient(), "");
 | 
						|
    assert.equal(compose_state.get_message_type(), "private");
 | 
						|
    assert.ok(compose_state.composing());
 | 
						|
 | 
						|
    // Cancel compose.
 | 
						|
    let pill_cleared;
 | 
						|
    compose_pm_pill.clear = () => {
 | 
						|
        pill_cleared = true;
 | 
						|
    };
 | 
						|
 | 
						|
    let abort_xhr_called = false;
 | 
						|
    override_rewire(compose, "abort_xhr", () => {
 | 
						|
        abort_xhr_called = true;
 | 
						|
    });
 | 
						|
 | 
						|
    $("#compose-textarea").set_height(50);
 | 
						|
 | 
						|
    assert_hidden("#compose_controls");
 | 
						|
    cancel();
 | 
						|
    assert.ok(abort_xhr_called);
 | 
						|
    assert.ok(pill_cleared);
 | 
						|
    assert_visible("#compose_controls");
 | 
						|
    assert_hidden("#private-message");
 | 
						|
    assert.ok(!compose_state.composing());
 | 
						|
});
 | 
						|
 | 
						|
test("respond_to_message", ({override, override_rewire}) => {
 | 
						|
    override_rewire(compose_actions, "set_focus", () => {});
 | 
						|
    override_rewire(compose_actions, "complete_starting_tasks", () => {});
 | 
						|
    override_rewire(compose_actions, "clear_textarea", () => {});
 | 
						|
    override_private_message_recipient({override});
 | 
						|
 | 
						|
    // Test PM
 | 
						|
    const person = {
 | 
						|
        user_id: 22,
 | 
						|
        email: "alice@example.com",
 | 
						|
        full_name: "Alice",
 | 
						|
    };
 | 
						|
    people.add_active_user(person);
 | 
						|
 | 
						|
    let msg = {
 | 
						|
        type: "private",
 | 
						|
        sender_id: person.user_id,
 | 
						|
    };
 | 
						|
    override(message_lists.current, "selected_message", () => msg);
 | 
						|
 | 
						|
    let opts = {
 | 
						|
        reply_type: "personal",
 | 
						|
    };
 | 
						|
 | 
						|
    respond_to_message(opts);
 | 
						|
    assert.equal(compose_state.private_message_recipient(), "alice@example.com");
 | 
						|
 | 
						|
    // Test stream
 | 
						|
    msg = {
 | 
						|
        type: "stream",
 | 
						|
        stream: "devel",
 | 
						|
        topic: "python",
 | 
						|
    };
 | 
						|
 | 
						|
    opts = {};
 | 
						|
 | 
						|
    respond_to_message(opts);
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "devel");
 | 
						|
});
 | 
						|
 | 
						|
test("reply_with_mention", ({override, override_rewire}) => {
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
    override_rewire(compose_actions, "set_focus", () => {});
 | 
						|
    override_rewire(compose_actions, "complete_starting_tasks", () => {});
 | 
						|
    override_rewire(compose_actions, "clear_textarea", () => {});
 | 
						|
    override_private_message_recipient({override});
 | 
						|
 | 
						|
    const msg = {
 | 
						|
        type: "stream",
 | 
						|
        stream: "devel",
 | 
						|
        topic: "python",
 | 
						|
        sender_full_name: "Bob Roberts",
 | 
						|
        sender_id: 40,
 | 
						|
    };
 | 
						|
    override(message_lists.current, "selected_message", () => msg);
 | 
						|
 | 
						|
    let syntax_to_insert;
 | 
						|
    override(compose_ui, "insert_syntax_and_focus", (syntax) => {
 | 
						|
        syntax_to_insert = syntax;
 | 
						|
    });
 | 
						|
 | 
						|
    const opts = {};
 | 
						|
 | 
						|
    reply_with_mention(opts);
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "devel");
 | 
						|
    assert.equal(syntax_to_insert, "@**Bob Roberts**");
 | 
						|
 | 
						|
    // Test for extended mention syntax
 | 
						|
    const bob_1 = {
 | 
						|
        user_id: 30,
 | 
						|
        email: "bob1@example.com",
 | 
						|
        full_name: "Bob Roberts",
 | 
						|
    };
 | 
						|
    people.add_active_user(bob_1);
 | 
						|
    const bob_2 = {
 | 
						|
        user_id: 40,
 | 
						|
        email: "bob2@example.com",
 | 
						|
        full_name: "Bob Roberts",
 | 
						|
    };
 | 
						|
    people.add_active_user(bob_2);
 | 
						|
 | 
						|
    reply_with_mention(opts);
 | 
						|
    assert.equal($("#stream_message_recipient_stream").val(), "devel");
 | 
						|
    assert.equal(syntax_to_insert, "@**Bob Roberts|40**");
 | 
						|
});
 | 
						|
 | 
						|
test("quote_and_reply", ({disallow, override, override_rewire}) => {
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
    const steve = {
 | 
						|
        user_id: 90,
 | 
						|
        email: "steve@example.com",
 | 
						|
        full_name: "Steve Stephenson",
 | 
						|
    };
 | 
						|
    people.add_active_user(steve);
 | 
						|
 | 
						|
    override_rewire(compose_actions, "set_focus", () => {});
 | 
						|
    override_rewire(compose_actions, "complete_starting_tasks", () => {});
 | 
						|
    override_rewire(compose_actions, "clear_textarea", () => {});
 | 
						|
    override_private_message_recipient({override});
 | 
						|
 | 
						|
    let selected_message;
 | 
						|
    override(message_lists.current, "selected_message", () => selected_message);
 | 
						|
 | 
						|
    let expected_replacement;
 | 
						|
    let replaced;
 | 
						|
    override(compose_ui, "replace_syntax", (syntax, replacement) => {
 | 
						|
        assert.equal(syntax, "translated: [Quoting…]");
 | 
						|
        assert.equal(replacement, expected_replacement);
 | 
						|
        replaced = true;
 | 
						|
    });
 | 
						|
 | 
						|
    selected_message = {
 | 
						|
        type: "stream",
 | 
						|
        stream: "devel",
 | 
						|
        topic: "python",
 | 
						|
        sender_full_name: "Steve Stephenson",
 | 
						|
        sender_id: 90,
 | 
						|
    };
 | 
						|
    hash_util.by_conversation_and_time_url = () =>
 | 
						|
        "https://chat.zulip.org/#narrow/stream/92-learning/topic/Tornado";
 | 
						|
 | 
						|
    let success_function;
 | 
						|
    override(channel, "get", (opts) => {
 | 
						|
        success_function = opts.success;
 | 
						|
    });
 | 
						|
 | 
						|
    override(message_lists.current, "selected_id", () => 100);
 | 
						|
 | 
						|
    override(compose_ui, "insert_syntax_and_focus", (syntax) => {
 | 
						|
        assert.equal(syntax, "translated: [Quoting…]\n");
 | 
						|
    });
 | 
						|
 | 
						|
    const opts = {
 | 
						|
        reply_type: "personal",
 | 
						|
    };
 | 
						|
 | 
						|
    $("#compose-textarea").caret = noop;
 | 
						|
 | 
						|
    replaced = false;
 | 
						|
    expected_replacement =
 | 
						|
        "translated: @_**Steve Stephenson|90** [said](https://chat.zulip.org/#narrow/stream/92-learning/topic/Tornado):\n```quote\nTesting.\n```";
 | 
						|
 | 
						|
    quote_and_reply(opts);
 | 
						|
 | 
						|
    success_function({
 | 
						|
        raw_content: "Testing.",
 | 
						|
    });
 | 
						|
    assert.ok(replaced);
 | 
						|
 | 
						|
    selected_message = {
 | 
						|
        type: "stream",
 | 
						|
        stream: "devel",
 | 
						|
        topic: "test",
 | 
						|
        sender_full_name: "Steve Stephenson",
 | 
						|
        sender_id: 90,
 | 
						|
        raw_content: "Testing.",
 | 
						|
    };
 | 
						|
 | 
						|
    replaced = false;
 | 
						|
    disallow(channel, "get");
 | 
						|
    quote_and_reply(opts);
 | 
						|
    assert.ok(replaced);
 | 
						|
 | 
						|
    selected_message = {
 | 
						|
        type: "stream",
 | 
						|
        stream: "devel",
 | 
						|
        topic: "test",
 | 
						|
        sender_full_name: "Steve Stephenson",
 | 
						|
        sender_id: 90,
 | 
						|
        raw_content: "```\nmultiline code block\nshoudln't mess with quotes\n```",
 | 
						|
    };
 | 
						|
 | 
						|
    replaced = false;
 | 
						|
    expected_replacement =
 | 
						|
        "translated: @_**Steve Stephenson|90** [said](https://chat.zulip.org/#narrow/stream/92-learning/topic/Tornado):\n````quote\n```\nmultiline code block\nshoudln't mess with quotes\n```\n````";
 | 
						|
    quote_and_reply(opts);
 | 
						|
    assert.ok(replaced);
 | 
						|
});
 | 
						|
 | 
						|
test("get_focus_area", () => {
 | 
						|
    assert.equal(get_focus_area("private", {}), "#private_message_recipient");
 | 
						|
    assert.equal(
 | 
						|
        get_focus_area("private", {
 | 
						|
            private_message_recipient: "bob@example.com",
 | 
						|
        }),
 | 
						|
        "#compose-textarea",
 | 
						|
    );
 | 
						|
    assert.equal(get_focus_area("stream", {}), "#stream_message_recipient_stream");
 | 
						|
    assert.equal(get_focus_area("stream", {stream: "fun"}), "#stream_message_recipient_topic");
 | 
						|
    assert.equal(get_focus_area("stream", {stream: "fun", topic: "more"}), "#compose-textarea");
 | 
						|
    assert.equal(
 | 
						|
        get_focus_area("stream", {stream: "fun", topic: "more", trigger: "new topic button"}),
 | 
						|
        "#stream_message_recipient_topic",
 | 
						|
    );
 | 
						|
});
 | 
						|
 | 
						|
test("focus_in_empty_compose", () => {
 | 
						|
    document.activeElement = {id: "compose-textarea"};
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
    $("#compose-textarea").val("");
 | 
						|
    assert.ok(compose_state.focus_in_empty_compose());
 | 
						|
 | 
						|
    compose_state.set_message_type(false);
 | 
						|
    assert.ok(!compose_state.focus_in_empty_compose());
 | 
						|
 | 
						|
    $("#compose-textarea").val("foo");
 | 
						|
    assert.ok(!compose_state.focus_in_empty_compose());
 | 
						|
 | 
						|
    $("#compose-textarea").trigger("blur");
 | 
						|
    assert.ok(!compose_state.focus_in_empty_compose());
 | 
						|
});
 | 
						|
 | 
						|
test("on_narrow", ({override, override_rewire}) => {
 | 
						|
    let narrowed_by_topic_reply;
 | 
						|
    override(narrow_state, "narrowed_by_topic_reply", () => narrowed_by_topic_reply);
 | 
						|
 | 
						|
    let narrowed_by_pm_reply;
 | 
						|
    override(narrow_state, "narrowed_by_pm_reply", () => narrowed_by_pm_reply);
 | 
						|
 | 
						|
    let cancel_called = false;
 | 
						|
    override_rewire(compose_actions, "cancel", () => {
 | 
						|
        cancel_called = true;
 | 
						|
    });
 | 
						|
    compose_actions.on_narrow({
 | 
						|
        force_close: true,
 | 
						|
    });
 | 
						|
    assert.ok(cancel_called);
 | 
						|
 | 
						|
    let on_topic_narrow_called = false;
 | 
						|
    override_rewire(compose_actions, "on_topic_narrow", () => {
 | 
						|
        on_topic_narrow_called = true;
 | 
						|
    });
 | 
						|
    narrowed_by_topic_reply = true;
 | 
						|
    compose_actions.on_narrow({
 | 
						|
        force_close: false,
 | 
						|
    });
 | 
						|
    assert.ok(on_topic_narrow_called);
 | 
						|
 | 
						|
    let update_message_list_called = false;
 | 
						|
    narrowed_by_topic_reply = false;
 | 
						|
    compose_fade.update_message_list = () => {
 | 
						|
        update_message_list_called = true;
 | 
						|
    };
 | 
						|
    compose_state.message_content("foo");
 | 
						|
    compose_actions.on_narrow({
 | 
						|
        force_close: false,
 | 
						|
    });
 | 
						|
    assert.ok(update_message_list_called);
 | 
						|
 | 
						|
    compose_state.message_content("");
 | 
						|
    let start_called = false;
 | 
						|
    override_rewire(compose_actions, "start", () => {
 | 
						|
        start_called = true;
 | 
						|
    });
 | 
						|
    narrowed_by_pm_reply = true;
 | 
						|
    compose_actions.on_narrow({
 | 
						|
        force_close: false,
 | 
						|
        trigger: "not-search",
 | 
						|
        private_message_recipient: "not@empty.com",
 | 
						|
    });
 | 
						|
    assert.ok(start_called);
 | 
						|
 | 
						|
    start_called = false;
 | 
						|
    compose_actions.on_narrow({
 | 
						|
        force_close: false,
 | 
						|
        trigger: "search",
 | 
						|
        private_message_recipient: "",
 | 
						|
    });
 | 
						|
    assert.ok(!start_called);
 | 
						|
 | 
						|
    narrowed_by_pm_reply = false;
 | 
						|
    cancel_called = false;
 | 
						|
    compose_actions.on_narrow({
 | 
						|
        force_close: false,
 | 
						|
    });
 | 
						|
    assert.ok(cancel_called);
 | 
						|
});
 |