mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	Fixes #11832 This lets the user see more options than the three that appear in the typeahead menu, and prevents them from inputting invalid stream names. This change replaces the input field with the dropdown, and updates everything that referred to the classnames of the old input field, so that they now get the data they need from the new dropdown.
		
			
				
	
	
		
			818 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			818 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
const {strict: assert} = require("assert");
 | 
						|
 | 
						|
const {mock_banners} = require("./lib/compose_banner");
 | 
						|
const {$t} = require("./lib/i18n");
 | 
						|
const {mock_esm, zrequire} = require("./lib/namespace");
 | 
						|
const {run_test} = require("./lib/test");
 | 
						|
const blueslip = require("./lib/zblueslip");
 | 
						|
const $ = require("./lib/zjquery");
 | 
						|
const {page_params} = require("./lib/zpage_params");
 | 
						|
 | 
						|
const channel = mock_esm("../src/channel");
 | 
						|
 | 
						|
const compose_actions = zrequire("compose_actions");
 | 
						|
const compose_banner = zrequire("compose_banner");
 | 
						|
const compose_pm_pill = zrequire("compose_pm_pill");
 | 
						|
const compose_state = zrequire("compose_state");
 | 
						|
const compose_validate = zrequire("compose_validate");
 | 
						|
const peer_data = zrequire("peer_data");
 | 
						|
const people = zrequire("people");
 | 
						|
const resolved_topic = zrequire("../shared/src/resolved_topic");
 | 
						|
const settings_config = zrequire("settings_config");
 | 
						|
const settings_data = mock_esm("../src/settings_data");
 | 
						|
const stream_data = zrequire("stream_data");
 | 
						|
const compose_ui = zrequire("compose_ui");
 | 
						|
 | 
						|
let stream_value = "";
 | 
						|
compose_ui.compose_stream_widget = {
 | 
						|
    value() {
 | 
						|
        return stream_value;
 | 
						|
    },
 | 
						|
    render(val) {
 | 
						|
        stream_value = val;
 | 
						|
    },
 | 
						|
};
 | 
						|
 | 
						|
const me = {
 | 
						|
    email: "me@example.com",
 | 
						|
    user_id: 30,
 | 
						|
    full_name: "Me Myself",
 | 
						|
    date_joined: new Date(),
 | 
						|
};
 | 
						|
 | 
						|
const alice = {
 | 
						|
    email: "alice@example.com",
 | 
						|
    user_id: 31,
 | 
						|
    full_name: "Alice",
 | 
						|
};
 | 
						|
 | 
						|
const bob = {
 | 
						|
    email: "bob@example.com",
 | 
						|
    user_id: 32,
 | 
						|
    full_name: "Bob",
 | 
						|
};
 | 
						|
 | 
						|
people.add_active_user(me);
 | 
						|
people.initialize_current_user(me.user_id);
 | 
						|
 | 
						|
people.add_active_user(alice);
 | 
						|
people.add_active_user(bob);
 | 
						|
 | 
						|
const welcome_bot = {
 | 
						|
    email: "welcome-bot@example.com",
 | 
						|
    user_id: 4,
 | 
						|
    full_name: "Welcome Bot",
 | 
						|
    is_bot: true,
 | 
						|
    // cross realm bots have no owner
 | 
						|
};
 | 
						|
 | 
						|
people.add_cross_realm_user(welcome_bot);
 | 
						|
 | 
						|
function test_ui(label, f) {
 | 
						|
    // The sloppy_$ flag lets us re-use setup from prior tests.
 | 
						|
    run_test(label, (helpers) => {
 | 
						|
        $("#compose-textarea").val("some message");
 | 
						|
        f(helpers);
 | 
						|
    });
 | 
						|
}
 | 
						|
 | 
						|
test_ui("validate_stream_message_address_info", ({mock_template}) => {
 | 
						|
    mock_banners();
 | 
						|
    const sub = {
 | 
						|
        stream_id: 101,
 | 
						|
        name: "social",
 | 
						|
        subscribed: true,
 | 
						|
    };
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    assert.ok(compose_validate.validate_stream_message_address_info("social"));
 | 
						|
 | 
						|
    sub.subscribed = false;
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    $("#compose_banners .user_not_subscribed").length = 0;
 | 
						|
    let user_not_subscribed_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", true, (data, html) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.user_not_subscribed);
 | 
						|
        user_not_subscribed_rendered = true;
 | 
						|
        return html;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate_stream_message_address_info("social"));
 | 
						|
    assert.ok(user_not_subscribed_rendered);
 | 
						|
 | 
						|
    page_params.narrow_stream = false;
 | 
						|
    channel.post = (payload) => {
 | 
						|
        assert.equal(payload.data.stream, "social");
 | 
						|
        payload.data.subscribed = true;
 | 
						|
        payload.success(payload.data);
 | 
						|
    };
 | 
						|
    assert.ok(compose_validate.validate_stream_message_address_info("social"));
 | 
						|
 | 
						|
    sub.name = "Frontend";
 | 
						|
    sub.stream_id = 102;
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    channel.post = (payload) => {
 | 
						|
        assert.equal(payload.data.stream, "Frontend");
 | 
						|
        payload.data.subscribed = false;
 | 
						|
        payload.success(payload.data);
 | 
						|
    };
 | 
						|
    user_not_subscribed_rendered = false;
 | 
						|
    assert.ok(!compose_validate.validate_stream_message_address_info("Frontend"));
 | 
						|
    assert.ok(user_not_subscribed_rendered);
 | 
						|
 | 
						|
    let stream_does_not_exist_rendered = false;
 | 
						|
    mock_template("compose_banner/stream_does_not_exist_error.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.stream_does_not_exist);
 | 
						|
        assert.equal(data.stream_name, "Frontend");
 | 
						|
        stream_does_not_exist_rendered = true;
 | 
						|
    });
 | 
						|
    channel.post = (payload) => {
 | 
						|
        assert.equal(payload.data.stream, "Frontend");
 | 
						|
        payload.error({status: 404});
 | 
						|
    };
 | 
						|
    assert.ok(!compose_validate.validate_stream_message_address_info("Frontend"));
 | 
						|
    assert.ok(stream_does_not_exist_rendered);
 | 
						|
 | 
						|
    let subscription_error_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, "subscription_error");
 | 
						|
        assert.equal(data.banner_text, $t({defaultMessage: "Error checking subscription."}));
 | 
						|
        subscription_error_rendered = true;
 | 
						|
    });
 | 
						|
    channel.post = (payload) => {
 | 
						|
        assert.equal(payload.data.stream, "social");
 | 
						|
        payload.error({status: 500});
 | 
						|
    };
 | 
						|
    assert.ok(!compose_validate.validate_stream_message_address_info("social"));
 | 
						|
    assert.ok(subscription_error_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("validate", ({mock_template}) => {
 | 
						|
    compose_actions.update_placeholder_text = () => {};
 | 
						|
    compose_ui.on_compose_select_stream_update = () => {};
 | 
						|
 | 
						|
    function initialize_pm_pill() {
 | 
						|
        $.clear_all_elements();
 | 
						|
 | 
						|
        $("#compose-send-button").prop("disabled", false);
 | 
						|
        $("#compose-send-button").trigger("focus");
 | 
						|
        $("#compose-send-button .loader").hide();
 | 
						|
 | 
						|
        const $pm_pill_container = $.create("fake-pm-pill-container");
 | 
						|
        $("#private_message_recipient")[0] = {};
 | 
						|
        $("#private_message_recipient").set_parent($pm_pill_container);
 | 
						|
        $pm_pill_container.set_find_results(".input", $("#private_message_recipient"));
 | 
						|
        $("#private_message_recipient").before = () => {};
 | 
						|
 | 
						|
        compose_pm_pill.initialize();
 | 
						|
 | 
						|
        $("#zephyr-mirror-error").is = () => {};
 | 
						|
 | 
						|
        mock_template("input_pill.hbs", false, () => "<div>pill-html</div>");
 | 
						|
 | 
						|
        mock_banners();
 | 
						|
    }
 | 
						|
 | 
						|
    function add_content_to_compose_box() {
 | 
						|
        $("#compose-textarea").val("foobarfoobar");
 | 
						|
    }
 | 
						|
 | 
						|
    // test validating private messages
 | 
						|
    compose_state.set_message_type("private");
 | 
						|
 | 
						|
    initialize_pm_pill();
 | 
						|
    add_content_to_compose_box();
 | 
						|
    compose_state.private_message_recipient("");
 | 
						|
    let pm_recipient_error_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.missing_private_message_recipient);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({defaultMessage: "Please specify at least one valid recipient."}),
 | 
						|
        );
 | 
						|
        pm_recipient_error_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(pm_recipient_error_rendered);
 | 
						|
 | 
						|
    pm_recipient_error_rendered = false;
 | 
						|
 | 
						|
    people.add_active_user(bob);
 | 
						|
    compose_state.private_message_recipient("bob@example.com");
 | 
						|
    assert.ok(compose_validate.validate());
 | 
						|
    assert.ok(!pm_recipient_error_rendered);
 | 
						|
 | 
						|
    people.deactivate(bob);
 | 
						|
    let deactivated_user_error_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.deactivated_user);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({defaultMessage: "You cannot send messages to deactivated users."}),
 | 
						|
        );
 | 
						|
        deactivated_user_error_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(deactivated_user_error_rendered);
 | 
						|
 | 
						|
    page_params.realm_is_zephyr_mirror_realm = true;
 | 
						|
    assert.ok(compose_validate.validate());
 | 
						|
    page_params.realm_is_zephyr_mirror_realm = false;
 | 
						|
 | 
						|
    initialize_pm_pill();
 | 
						|
    add_content_to_compose_box();
 | 
						|
    compose_state.private_message_recipient("welcome-bot@example.com");
 | 
						|
    assert.ok(compose_validate.validate());
 | 
						|
 | 
						|
    let zephyr_error_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        if (data.classname === compose_banner.CLASSNAMES.zephyr_not_running) {
 | 
						|
            assert.equal(
 | 
						|
                data.banner_text,
 | 
						|
                $t({
 | 
						|
                    defaultMessage:
 | 
						|
                        "You need to be running Zephyr mirroring in order to send messages!",
 | 
						|
                }),
 | 
						|
            );
 | 
						|
            zephyr_error_rendered = true;
 | 
						|
        }
 | 
						|
    });
 | 
						|
    initialize_pm_pill();
 | 
						|
    compose_state.private_message_recipient("welcome-bot@example.com");
 | 
						|
    $("#compose-textarea").toggleClass = (classname, value) => {
 | 
						|
        assert.equal(classname, "invalid");
 | 
						|
        assert.equal(value, true);
 | 
						|
    };
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(!$("#compose-send-button .loader").visible());
 | 
						|
    assert.equal($("#compose-send-button").prop("disabled"), false);
 | 
						|
    compose_validate.validate();
 | 
						|
 | 
						|
    add_content_to_compose_box();
 | 
						|
    let zephyr_checked = false;
 | 
						|
    $("#zephyr-mirror-error").is = (arg) => {
 | 
						|
        assert.equal(arg, ":visible");
 | 
						|
        zephyr_checked = true;
 | 
						|
        return true;
 | 
						|
    };
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(zephyr_checked);
 | 
						|
    assert.ok(zephyr_error_rendered);
 | 
						|
 | 
						|
    initialize_pm_pill();
 | 
						|
    add_content_to_compose_box();
 | 
						|
 | 
						|
    // test validating stream messages
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
    compose_state.set_stream_name("");
 | 
						|
    let empty_stream_error_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.missing_stream);
 | 
						|
        assert.equal(data.banner_text, $t({defaultMessage: "Please specify a stream."}));
 | 
						|
        empty_stream_error_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(empty_stream_error_rendered);
 | 
						|
 | 
						|
    compose_state.set_stream_name("Denmark");
 | 
						|
    page_params.realm_mandatory_topics = true;
 | 
						|
    compose_state.topic("");
 | 
						|
    let missing_topic_error_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.topic_missing);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({defaultMessage: "Topics are required in this organization."}),
 | 
						|
        );
 | 
						|
        missing_topic_error_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(missing_topic_error_rendered);
 | 
						|
 | 
						|
    missing_topic_error_rendered = false;
 | 
						|
    compose_state.topic("(no topic)");
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(missing_topic_error_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("get_invalid_recipient_emails", ({override_rewire}) => {
 | 
						|
    const welcome_bot = {
 | 
						|
        email: "welcome-bot@example.com",
 | 
						|
        user_id: 124,
 | 
						|
        full_name: "Welcome Bot",
 | 
						|
    };
 | 
						|
 | 
						|
    page_params.user_id = me.user_id;
 | 
						|
 | 
						|
    const params = {};
 | 
						|
    params.realm_users = [];
 | 
						|
    params.realm_non_active_users = [];
 | 
						|
    params.cross_realm_bots = [welcome_bot];
 | 
						|
 | 
						|
    people.initialize(page_params.user_id, params);
 | 
						|
 | 
						|
    override_rewire(compose_state, "private_message_recipient", () => "welcome-bot@example.com");
 | 
						|
    assert.deepEqual(compose_validate.get_invalid_recipient_emails(), []);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("test_wildcard_mention_allowed", () => {
 | 
						|
    page_params.user_id = me.user_id;
 | 
						|
 | 
						|
    page_params.realm_wildcard_mention_policy =
 | 
						|
        settings_config.wildcard_mention_policy_values.by_everyone.code;
 | 
						|
    page_params.is_guest = true;
 | 
						|
    page_params.is_admin = false;
 | 
						|
    assert.ok(compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.realm_wildcard_mention_policy =
 | 
						|
        settings_config.wildcard_mention_policy_values.nobody.code;
 | 
						|
    page_params.is_admin = true;
 | 
						|
    assert.ok(!compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.realm_wildcard_mention_policy =
 | 
						|
        settings_config.wildcard_mention_policy_values.by_members.code;
 | 
						|
    page_params.is_guest = true;
 | 
						|
    page_params.is_admin = false;
 | 
						|
    assert.ok(!compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.is_guest = false;
 | 
						|
    assert.ok(compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.realm_wildcard_mention_policy =
 | 
						|
        settings_config.wildcard_mention_policy_values.by_moderators_only.code;
 | 
						|
    page_params.is_moderator = false;
 | 
						|
    assert.ok(!compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.is_moderator = true;
 | 
						|
    assert.ok(compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.realm_wildcard_mention_policy =
 | 
						|
        settings_config.wildcard_mention_policy_values.by_admins_only.code;
 | 
						|
    page_params.is_admin = false;
 | 
						|
    assert.ok(!compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    // TODO: Add a by_admins_only case when we implement stream-level administrators.
 | 
						|
 | 
						|
    page_params.is_admin = true;
 | 
						|
    assert.ok(compose_validate.wildcard_mention_allowed());
 | 
						|
 | 
						|
    page_params.realm_wildcard_mention_policy =
 | 
						|
        settings_config.wildcard_mention_policy_values.by_full_members.code;
 | 
						|
    const person = people.get_by_user_id(page_params.user_id);
 | 
						|
    person.date_joined = new Date(Date.now());
 | 
						|
    page_params.realm_waiting_period_threshold = 10;
 | 
						|
 | 
						|
    assert.ok(compose_validate.wildcard_mention_allowed());
 | 
						|
    page_params.is_admin = false;
 | 
						|
    assert.ok(!compose_validate.wildcard_mention_allowed());
 | 
						|
});
 | 
						|
 | 
						|
test_ui("validate_stream_message", ({override_rewire, mock_template}) => {
 | 
						|
    // This test is in kind of continuation to test_validate but since it is
 | 
						|
    // primarily used to get coverage over functions called from validate()
 | 
						|
    // we are separating it up in different test. Though their relative position
 | 
						|
    // of execution should not be changed.
 | 
						|
    mock_banners();
 | 
						|
    $("#compose_banners .wildcard_warning").length = 0;
 | 
						|
    page_params.user_id = me.user_id;
 | 
						|
    page_params.realm_mandatory_topics = false;
 | 
						|
    const sub = {
 | 
						|
        stream_id: 101,
 | 
						|
        name: "social",
 | 
						|
        subscribed: true,
 | 
						|
    };
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    compose_state.set_stream_name("social");
 | 
						|
    assert.ok(compose_validate.validate());
 | 
						|
    assert.ok(!$("#compose-all-everyone").visible());
 | 
						|
 | 
						|
    peer_data.get_subscriber_count = (stream_id) => {
 | 
						|
        assert.equal(stream_id, 101);
 | 
						|
        return 16;
 | 
						|
    };
 | 
						|
    let wildcard_warning_rendered = false;
 | 
						|
    $("#compose_banner_area .wildcard_warning").length = 0;
 | 
						|
    mock_template("compose_banner/wildcard_warning.hbs", false, (data) => {
 | 
						|
        wildcard_warning_rendered = true;
 | 
						|
        assert.equal(data.subscriber_count, 16);
 | 
						|
    });
 | 
						|
 | 
						|
    override_rewire(compose_validate, "wildcard_mention_allowed", () => true);
 | 
						|
    compose_state.message_content("Hey @**all**");
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.equal($("#compose-send-button").prop("disabled"), false);
 | 
						|
    assert.ok(wildcard_warning_rendered);
 | 
						|
 | 
						|
    let wildcards_not_allowed_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.wildcards_not_allowed);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({
 | 
						|
                defaultMessage:
 | 
						|
                    "You do not have permission to use wildcard mentions in this stream.",
 | 
						|
            }),
 | 
						|
        );
 | 
						|
        wildcards_not_allowed_rendered = true;
 | 
						|
    });
 | 
						|
    override_rewire(compose_validate, "wildcard_mention_allowed", () => false);
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(wildcards_not_allowed_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("test_validate_stream_message_post_policy_admin_only", ({mock_template}) => {
 | 
						|
    // This test is in continuation with test_validate but it has been separated out
 | 
						|
    // for better readability. Their relative position of execution should not be changed.
 | 
						|
    // Although the position with respect to test_validate_stream_message does not matter
 | 
						|
    // as different stream is used for this test.
 | 
						|
    mock_banners();
 | 
						|
    page_params.is_admin = false;
 | 
						|
    const sub = {
 | 
						|
        stream_id: 102,
 | 
						|
        name: "stream102",
 | 
						|
        subscribed: true,
 | 
						|
        stream_post_policy: stream_data.stream_post_policy_values.admins.code,
 | 
						|
    };
 | 
						|
 | 
						|
    compose_state.topic("topic102");
 | 
						|
    compose_state.set_stream_name("stream102");
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
 | 
						|
    let banner_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({
 | 
						|
                defaultMessage: "You do not have permission to post in this stream.",
 | 
						|
            }),
 | 
						|
        );
 | 
						|
        banner_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
 | 
						|
    // Reset error message.
 | 
						|
    compose_state.set_stream_name("social");
 | 
						|
 | 
						|
    page_params.is_admin = false;
 | 
						|
    page_params.is_guest = true;
 | 
						|
 | 
						|
    compose_state.topic("topic102");
 | 
						|
    compose_state.set_stream_name("stream102");
 | 
						|
    banner_rendered = false;
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("test_validate_stream_message_post_policy_moderators_only", ({mock_template}) => {
 | 
						|
    mock_banners();
 | 
						|
    page_params.is_admin = false;
 | 
						|
    page_params.is_moderator = false;
 | 
						|
    page_params.is_guest = false;
 | 
						|
 | 
						|
    const sub = {
 | 
						|
        stream_id: 104,
 | 
						|
        name: "stream104",
 | 
						|
        subscribed: true,
 | 
						|
        stream_post_policy: stream_data.stream_post_policy_values.moderators.code,
 | 
						|
    };
 | 
						|
 | 
						|
    compose_state.topic("topic104");
 | 
						|
    compose_state.set_stream_name("stream104");
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    let banner_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({
 | 
						|
                defaultMessage: "You do not have permission to post in this stream.",
 | 
						|
            }),
 | 
						|
        );
 | 
						|
        banner_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
    // Reset error message.
 | 
						|
    compose_state.set_stream_name("social");
 | 
						|
 | 
						|
    page_params.is_guest = true;
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("test_validate_stream_message_post_policy_full_members_only", ({mock_template}) => {
 | 
						|
    mock_banners();
 | 
						|
    page_params.is_admin = false;
 | 
						|
    page_params.is_guest = true;
 | 
						|
    const sub = {
 | 
						|
        stream_id: 103,
 | 
						|
        name: "stream103",
 | 
						|
        subscribed: true,
 | 
						|
        stream_post_policy: stream_data.stream_post_policy_values.non_new_members.code,
 | 
						|
    };
 | 
						|
 | 
						|
    compose_state.topic("topic103");
 | 
						|
    compose_state.set_stream_name("stream103");
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    let banner_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.no_post_permissions);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({
 | 
						|
                defaultMessage: "You do not have permission to post in this stream.",
 | 
						|
            }),
 | 
						|
        );
 | 
						|
        banner_rendered = true;
 | 
						|
    });
 | 
						|
    assert.ok(!compose_validate.validate());
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("test_check_overflow_text", ({mock_template}) => {
 | 
						|
    mock_banners();
 | 
						|
    page_params.max_message_length = 10000;
 | 
						|
 | 
						|
    const $textarea = $("#compose-textarea");
 | 
						|
    const $indicator = $("#compose_limit_indicator");
 | 
						|
    const $send_button = $("#compose-send-button");
 | 
						|
    let banner_rendered = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.message_too_long);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({
 | 
						|
                defaultMessage: "Message length shouldn't be greater than 10000 characters.",
 | 
						|
            }),
 | 
						|
        );
 | 
						|
        banner_rendered = true;
 | 
						|
    });
 | 
						|
 | 
						|
    // Indicator should show red colored text
 | 
						|
    $textarea.val("a".repeat(10000 + 1));
 | 
						|
    compose_validate.check_overflow_text();
 | 
						|
    assert.ok($indicator.hasClass("over_limit"));
 | 
						|
    assert.equal($indicator.text(), "10001/10000");
 | 
						|
    assert.ok($textarea.hasClass("over_limit"));
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
    assert.ok($send_button.prop("disabled"));
 | 
						|
 | 
						|
    // Indicator should show orange colored text
 | 
						|
    banner_rendered = false;
 | 
						|
    $textarea.val("a".repeat(9000 + 1));
 | 
						|
    compose_validate.check_overflow_text();
 | 
						|
    assert.ok(!$indicator.hasClass("over_limit"));
 | 
						|
    assert.equal($indicator.text(), "9001/10000");
 | 
						|
    assert.ok(!$textarea.hasClass("over_limit"));
 | 
						|
    assert.ok(!$send_button.prop("disabled"));
 | 
						|
    assert.ok(!banner_rendered);
 | 
						|
 | 
						|
    // Indicator must be empty
 | 
						|
    banner_rendered = false;
 | 
						|
    $textarea.val("a".repeat(9000));
 | 
						|
    compose_validate.check_overflow_text();
 | 
						|
    assert.ok(!$indicator.hasClass("over_limit"));
 | 
						|
    assert.equal($indicator.text(), "");
 | 
						|
    assert.ok(!$textarea.hasClass("over_limit"));
 | 
						|
    assert.ok(!banner_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("needs_subscribe_warning", () => {
 | 
						|
    const invalid_user_id = 999;
 | 
						|
 | 
						|
    const test_bot = {
 | 
						|
        full_name: "Test Bot",
 | 
						|
        email: "test-bot@example.com",
 | 
						|
        user_id: 135,
 | 
						|
        is_bot: true,
 | 
						|
    };
 | 
						|
    people.add_active_user(test_bot);
 | 
						|
 | 
						|
    const sub = {
 | 
						|
        stream_id: 110,
 | 
						|
        name: "stream",
 | 
						|
    };
 | 
						|
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    peer_data.set_subscribers(sub.stream_id, [bob.user_id, me.user_id]);
 | 
						|
 | 
						|
    blueslip.expect("error", "Unknown user_id in get_by_user_id: 999");
 | 
						|
    // Test with an invalid user id.
 | 
						|
    assert.equal(compose_validate.needs_subscribe_warning(invalid_user_id, sub.stream_id), false);
 | 
						|
 | 
						|
    // Test with bot user.
 | 
						|
    assert.equal(compose_validate.needs_subscribe_warning(test_bot.user_id, sub.stream_id), false);
 | 
						|
 | 
						|
    // Test when user is subscribed to the stream.
 | 
						|
    assert.equal(compose_validate.needs_subscribe_warning(bob.user_id, sub.stream_id), false);
 | 
						|
 | 
						|
    peer_data.remove_subscriber(sub.stream_id, bob.user_id);
 | 
						|
    // Test when the user is not subscribed.
 | 
						|
    assert.equal(compose_validate.needs_subscribe_warning(bob.user_id, sub.stream_id), true);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("warn_if_private_stream_is_linked", ({mock_template}) => {
 | 
						|
    const test_sub = {
 | 
						|
        name: compose_state.stream_name(),
 | 
						|
        stream_id: 99,
 | 
						|
    };
 | 
						|
 | 
						|
    stream_data.add_sub(test_sub);
 | 
						|
    peer_data.set_subscribers(test_sub.stream_id, [1, 2]);
 | 
						|
 | 
						|
    let denmark = {
 | 
						|
        stream_id: 100,
 | 
						|
        name: "Denmark",
 | 
						|
    };
 | 
						|
    stream_data.add_sub(denmark);
 | 
						|
 | 
						|
    peer_data.set_subscribers(denmark.stream_id, [1, 2, 3]);
 | 
						|
 | 
						|
    let banner_rendered = false;
 | 
						|
    mock_template("compose_banner/private_stream_warning.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.private_stream_warning);
 | 
						|
        assert.equal(data.stream_name, "Denmark");
 | 
						|
        banner_rendered = true;
 | 
						|
        return "private_stream_warning_stub";
 | 
						|
    });
 | 
						|
 | 
						|
    function test_noop_case(invite_only) {
 | 
						|
        banner_rendered = false;
 | 
						|
        compose_state.set_message_type("stream");
 | 
						|
        denmark.invite_only = invite_only;
 | 
						|
        compose_validate.warn_if_private_stream_is_linked(denmark);
 | 
						|
        assert.ok(!banner_rendered);
 | 
						|
    }
 | 
						|
 | 
						|
    test_noop_case(false);
 | 
						|
    // invite_only=true and current compose stream subscribers are a subset
 | 
						|
    // of mentioned_stream subscribers.
 | 
						|
    test_noop_case(true);
 | 
						|
 | 
						|
    $("#compose_private").hide();
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
 | 
						|
    denmark = {
 | 
						|
        invite_only: true,
 | 
						|
        name: "Denmark",
 | 
						|
        stream_id: 22,
 | 
						|
    };
 | 
						|
    stream_data.add_sub(denmark);
 | 
						|
    banner_rendered = false;
 | 
						|
    compose_validate.warn_if_private_stream_is_linked(denmark);
 | 
						|
    assert.ok(banner_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
 | 
						|
    stream_value = "";
 | 
						|
    override(settings_data, "user_can_subscribe_other_users", () => true);
 | 
						|
 | 
						|
    let mentioned_details = {
 | 
						|
        email: "foo@bar.com",
 | 
						|
    };
 | 
						|
 | 
						|
    let new_banner_rendered = false;
 | 
						|
    mock_template("compose_banner/not_subscribed_warning.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.recipient_not_subscribed);
 | 
						|
        assert.equal(data.user_id, 34);
 | 
						|
        assert.equal(data.stream_id, 111);
 | 
						|
        assert.equal(data.name, "Foo Barson");
 | 
						|
        new_banner_rendered = true;
 | 
						|
    });
 | 
						|
 | 
						|
    function test_noop_case(is_private, is_zephyr_mirror, is_broadcast) {
 | 
						|
        new_banner_rendered = false;
 | 
						|
        const msg_type = is_private ? "private" : "stream";
 | 
						|
        compose_state.set_message_type(msg_type);
 | 
						|
        page_params.realm_is_zephyr_mirror_realm = is_zephyr_mirror;
 | 
						|
        mentioned_details.is_broadcast = is_broadcast;
 | 
						|
        compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details);
 | 
						|
        assert.ok(!new_banner_rendered);
 | 
						|
    }
 | 
						|
 | 
						|
    test_noop_case(true, false, false);
 | 
						|
    test_noop_case(false, true, false);
 | 
						|
    test_noop_case(false, false, true);
 | 
						|
 | 
						|
    $("#compose_invite_users").hide();
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
    page_params.realm_is_zephyr_mirror_realm = false;
 | 
						|
 | 
						|
    // Test with empty stream name in compose box. It should return noop.
 | 
						|
    new_banner_rendered = false;
 | 
						|
    assert.equal(compose_state.stream_name(), "");
 | 
						|
    compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details);
 | 
						|
    assert.ok(!new_banner_rendered);
 | 
						|
 | 
						|
    compose_state.set_stream_name("random");
 | 
						|
    const sub = {
 | 
						|
        stream_id: 111,
 | 
						|
        name: "random",
 | 
						|
    };
 | 
						|
 | 
						|
    // Test with invalid stream in compose box. It should return noop.
 | 
						|
    new_banner_rendered = false;
 | 
						|
    compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details);
 | 
						|
    assert.ok(!new_banner_rendered);
 | 
						|
 | 
						|
    // Test mentioning a user that should gets a warning.
 | 
						|
    mentioned_details = {
 | 
						|
        email: "foo@bar.com",
 | 
						|
        user_id: 34,
 | 
						|
        full_name: "Foo Barson",
 | 
						|
    };
 | 
						|
    people.add_active_user(mentioned_details);
 | 
						|
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
    new_banner_rendered = false;
 | 
						|
    $("#compose_banners .recipient_not_subscribed").length = 0;
 | 
						|
    compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details);
 | 
						|
    assert.ok(new_banner_rendered);
 | 
						|
 | 
						|
    // Simulate that the row was added to the DOM.
 | 
						|
    const $warning_row = $("#compose_banners .recipient_not_subscribed");
 | 
						|
    $warning_row.data = (key) =>
 | 
						|
        ({
 | 
						|
            "user-id": "34",
 | 
						|
            "stream-id": "111",
 | 
						|
        }[key]);
 | 
						|
    $("#compose_banners .recipient_not_subscribed").length = 1;
 | 
						|
    $("#compose_banners .recipient_not_subscribed")[0] = $warning_row;
 | 
						|
 | 
						|
    // Now try to mention the same person again. The template should
 | 
						|
    // not render.
 | 
						|
    new_banner_rendered = false;
 | 
						|
    compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details);
 | 
						|
    assert.ok(!new_banner_rendered);
 | 
						|
});
 | 
						|
 | 
						|
test_ui("test warn_if_topic_resolved", ({override, mock_template}) => {
 | 
						|
    mock_banners();
 | 
						|
    $("#compose_banners .topic_resolved").length = 0;
 | 
						|
    override(settings_data, "user_can_move_messages_to_another_topic", () => true);
 | 
						|
 | 
						|
    let error_shown = false;
 | 
						|
    mock_template("compose_banner/compose_banner.hbs", false, (data) => {
 | 
						|
        assert.equal(data.classname, compose_banner.CLASSNAMES.topic_resolved);
 | 
						|
        assert.equal(
 | 
						|
            data.banner_text,
 | 
						|
            $t({
 | 
						|
                defaultMessage:
 | 
						|
                    "You are sending a message to a resolved topic. You can send as-is or unresolve the topic first.",
 | 
						|
            }),
 | 
						|
        );
 | 
						|
        error_shown = true;
 | 
						|
        return "topic_resolved_warning_stub";
 | 
						|
    });
 | 
						|
 | 
						|
    const sub = {
 | 
						|
        stream_id: 111,
 | 
						|
        name: "random",
 | 
						|
    };
 | 
						|
    stream_data.add_sub(sub);
 | 
						|
 | 
						|
    compose_state.set_message_type("stream");
 | 
						|
    compose_state.set_stream_name("Do not exist");
 | 
						|
    compose_state.topic(resolved_topic.resolve_name("hello"));
 | 
						|
    compose_state.message_content("content");
 | 
						|
 | 
						|
    error_shown = false;
 | 
						|
    compose_validate.warn_if_topic_resolved(true);
 | 
						|
    assert.ok(!error_shown);
 | 
						|
 | 
						|
    compose_state.set_stream_name("random");
 | 
						|
 | 
						|
    // Show the warning now as stream also exists
 | 
						|
    error_shown = false;
 | 
						|
    compose_validate.warn_if_topic_resolved(true);
 | 
						|
    assert.ok(error_shown);
 | 
						|
 | 
						|
    // We reset the state to be able to show the banner again
 | 
						|
    compose_state.set_recipient_viewed_topic_resolved_banner(false);
 | 
						|
 | 
						|
    // Call it again with false; this should do the same thing.
 | 
						|
    error_shown = false;
 | 
						|
    compose_validate.warn_if_topic_resolved(false);
 | 
						|
    assert.ok(error_shown);
 | 
						|
 | 
						|
    // Call the func again. This should not show the error because
 | 
						|
    // we have already shown the error once for this topic.
 | 
						|
    error_shown = false;
 | 
						|
    compose_validate.warn_if_topic_resolved(false);
 | 
						|
    assert.ok(!error_shown);
 | 
						|
 | 
						|
    compose_state.topic("hello");
 | 
						|
 | 
						|
    // The warning will be cleared now
 | 
						|
    error_shown = false;
 | 
						|
    compose_validate.warn_if_topic_resolved(true);
 | 
						|
    assert.ok(!error_shown);
 | 
						|
 | 
						|
    // Calling with false won't do anything.
 | 
						|
    error_shown = false;
 | 
						|
    compose_validate.warn_if_topic_resolved(false);
 | 
						|
    assert.ok(!error_shown);
 | 
						|
});
 |