narrow: Add frontend support for `dm:` narrow and `/dm/...` URL.

Adds support in the web app for `dm` operator. This will deprecate
the `pm-with` operator, but existing links/URLs are still supported
for backwards-compatilibity.

This commit updates the web app default behaviors to default to
the new narrow/URLs `dm/...` and `/#narrow/dm/...` when navigating
and searching in the app.

There is some general clean up of references to private messages
or PMs to be either direct messages or DMs in these changes.

The general API changelog and documentation updates will be done
in a final commit in the series of commits that adds support for
the various new direct message narrows.
This commit is contained in:
Lauryn Menard 2023-04-11 21:04:33 +02:00 committed by Tim Abbott
parent d379020726
commit 0f7341dd48
36 changed files with 520 additions and 415 deletions

View File

@ -14,11 +14,14 @@ async function expect_home(page: Page): Promise<void> {
["Verona > test", ["verona test a", "verona test b"]],
["Verona > other topic", ["verona other topic c"]],
["Denmark > test", ["denmark message"]],
["You and Cordelia, Lear's daughter, King Hamlet", ["group pm a", "group pm b"]],
["You and Cordelia, Lear's daughter", ["pm c"]],
[
"You and Cordelia, Lear's daughter, King Hamlet",
["group direct message a", "group direct message b"],
],
["You and Cordelia, Lear's daughter", ["direct message c"]],
["Verona > test", ["verona test d"]],
["You and Cordelia, Lear's daughter, King Hamlet", ["group pm d"]],
["You and Cordelia, Lear's daughter", ["pm e"]],
["You and Cordelia, Lear's daughter, King Hamlet", ["group direct message d"]],
["You and Cordelia, Lear's daughter", ["direct message e"]],
]);
}
@ -59,12 +62,12 @@ async function expect_test_topic(page: Page): Promise<void> {
]);
}
async function expect_huddle(page: Page): Promise<void> {
async function expect_group_direct_messages(page: Page): Promise<void> {
await page.waitForSelector("#zfilt", {visible: true});
await common.check_messages_sent(page, "zfilt", [
[
"You and Cordelia, Lear's daughter, King Hamlet",
["group pm a", "group pm b", "group pm d"],
["group direct message a", "group direct message b", "group direct message d"],
],
]);
assert.strictEqual(
@ -73,10 +76,10 @@ async function expect_huddle(page: Page): Promise<void> {
);
}
async function expect_cordelia_private_narrow(page: Page): Promise<void> {
async function expect_cordelia_direct_messages(page: Page): Promise<void> {
await page.waitForSelector("#zfilt", {visible: true});
await common.check_messages_sent(page, "zfilt", [
["You and Cordelia, Lear's daughter", ["pm c", "pm e"]],
["You and Cordelia, Lear's daughter", ["direct message c", "direct message e"]],
]);
}
@ -120,7 +123,7 @@ async function test_navigations_from_home(page: Page): Promise<void> {
await page.click(
`#zhome [title="Narrow to your direct messages with Cordelia, Lear's daughter, King Hamlet"]`,
);
await expect_huddle(page);
await expect_group_direct_messages(page);
await un_narrow(page);
await expect_home(page);
@ -200,7 +203,7 @@ async function search_tests(page: Page): Promise<void> {
page,
"Cordelia",
"Direct",
expect_cordelia_private_narrow,
expect_cordelia_direct_messages,
"Cordelia, Lear's daughter - Zulip Dev - Zulip",
);
@ -242,7 +245,7 @@ async function search_tests(page: Page): Promise<void> {
await search_and_check(
page,
"pm-with:dummyuser@zulip.com",
"dm:dummyuser@zulip.com",
"",
expect_non_existing_user,
"Invalid user - Zulip Dev - Zulip",
@ -250,20 +253,23 @@ async function search_tests(page: Page): Promise<void> {
await search_and_check(
page,
"pm-with:dummyuser@zulip.com,dummyuser2@zulip.com",
"dm:dummyuser@zulip.com,dummyuser2@zulip.com",
"",
expect_non_existing_users,
"Invalid users - Zulip Dev - Zulip",
);
}
async function expect_all_pm(page: Page): Promise<void> {
async function expect_all_direct_messages(page: Page): Promise<void> {
await page.waitForSelector("#zfilt", {visible: true});
await common.check_messages_sent(page, "zfilt", [
["You and Cordelia, Lear's daughter, King Hamlet", ["group pm a", "group pm b"]],
["You and Cordelia, Lear's daughter", ["pm c"]],
["You and Cordelia, Lear's daughter, King Hamlet", ["group pm d"]],
["You and Cordelia, Lear's daughter", ["pm e"]],
[
"You and Cordelia, Lear's daughter, King Hamlet",
["group direct message a", "group direct message b"],
],
["You and Cordelia, Lear's daughter", ["direct message c"]],
["You and Cordelia, Lear's daughter, King Hamlet", ["group direct message d"]],
["You and Cordelia, Lear's daughter", ["direct message e"]],
]);
assert.strictEqual(
await common.get_text_from_selector(page, "#left_bar_compose_stream_button_big"),
@ -284,7 +290,7 @@ async function test_narrow_by_clicking_the_left_sidebar(page: Page): Promise<voi
const all_private_messages_icon = "#show_all_private_messages";
await page.waitForSelector(all_private_messages_icon, {visible: true});
await page.click(all_private_messages_icon);
await expect_all_pm(page);
await expect_all_direct_messages(page);
await un_narrow(page);
}
@ -442,10 +448,10 @@ async function test_users_search(page: Page): Promise<void> {
await assert_not_selected(page, "aaron");
await assert_not_selected(page, "Desdemona");
// arrow up and press Enter. We should be taken to pms with Cordelia, Lear's daughter
// arrow up and press Enter. We should be taken to direct messages with Cordelia, Lear's daughter
await arrow(page, "Up");
await page.keyboard.press("Enter");
await expect_cordelia_private_narrow(page);
await expect_cordelia_direct_messages(page);
}
async function test_narrow_public_streams(page: Page): Promise<void> {
@ -480,12 +486,12 @@ async function message_basic_tests(page: Page): Promise<void> {
{stream: "Verona", topic: "test", content: "verona test b"},
{stream: "Verona", topic: "other topic", content: "verona other topic c"},
{stream: "Denmark", topic: "test", content: "denmark message"},
{recipient: "cordelia@zulip.com, hamlet@zulip.com", content: "group pm a"},
{recipient: "cordelia@zulip.com, hamlet@zulip.com", content: "group pm b"},
{recipient: "cordelia@zulip.com", content: "pm c"},
{recipient: "cordelia@zulip.com, hamlet@zulip.com", content: "group direct message a"},
{recipient: "cordelia@zulip.com, hamlet@zulip.com", content: "group direct message b"},
{recipient: "cordelia@zulip.com", content: "direct message c"},
{stream: "Verona", topic: "test", content: "verona test d"},
{recipient: "cordelia@zulip.com, hamlet@zulip.com", content: "group pm d"},
{recipient: "cordelia@zulip.com", content: "pm e"},
{recipient: "cordelia@zulip.com, hamlet@zulip.com", content: "group direct message d"},
{recipient: "cordelia@zulip.com", content: "direct message e"},
]);
await expect_home(page);

View File

@ -278,7 +278,7 @@ export function narrow_for_user_id(opts) {
const person = people.get_by_user_id(opts.user_id);
const email = person.email;
narrow.by("pm-with", email, {trigger: "sidebar"});
narrow.by("dm", email, {trigger: "sidebar"});
user_filter.clear_and_hide_search();
}

View File

@ -307,10 +307,9 @@ export function restore_draft(draft_id) {
}
} else {
if (compose_args.private_message_recipient !== "") {
narrow.activate(
[{operator: "pm-with", operand: compose_args.private_message_recipient}],
{trigger: "restore draft"},
);
narrow.activate([{operator: "dm", operand: compose_args.private_message_recipient}], {
trigger: "restore draft",
});
}
}

View File

@ -175,7 +175,7 @@ function message_matches_search_term(message, operator, operand) {
// message, but it is implicit by the fact that the current user has access to the message.
}
case "pm-with": {
case "dm": {
// TODO: use user_ids, not emails here
if (message.type !== "private") {
return false;
@ -212,6 +212,11 @@ export class Filter {
static canonicalize_operator(operator) {
operator = operator.toLowerCase();
if (operator === "pm-with") {
// "pm-with:" was renamed to "dm:"
return "dm";
}
if (operator === "from") {
return "sender";
}
@ -245,7 +250,7 @@ export class Filter {
case "topic":
break;
case "sender":
case "pm-with":
case "dm":
operand = operand.toString().toLowerCase();
if (operand === "me") {
operand = people.my_current_email();
@ -294,7 +299,7 @@ export class Filter {
static decodeOperand(encoded, operator) {
encoded = encoded.replace(/"/g, "");
if (["group-pm-with", "pm-with", "sender", "from"].includes(operator) === false) {
if (["group-pm-with", "dm", "sender", "from", "pm-with"].includes(operator) === false) {
encoded = encoded.replace(/\+/g, " ");
}
return util.robust_url_decode(encoded).trim();
@ -342,7 +347,7 @@ export class Filter {
}
operand = Filter.decodeOperand(parts.join(":"), operator);
// We use Filter.operator_to_prefix() checks if the
// We use Filter.operator_to_prefix() to check if the
// operator is known. If it is not known, then we treat
// it as a search for the given string (which may contain
// a `:`), not as a search operator.
@ -446,7 +451,7 @@ export class Filter {
}
is_non_huddle_pm() {
return this.has_operator("pm-with") && this.operands("pm-with")[0].split(",").length === 1;
return this.has_operator("dm") && this.operands("dm")[0].split(",").length === 1;
}
supports_collapsing_recipients() {
@ -464,7 +469,7 @@ export class Filter {
"not-stream",
"topic",
"not-topic",
"pm-with",
"dm",
"group-pm-with",
"not-group-pm-with",
"is-dm",
@ -498,7 +503,7 @@ export class Filter {
return true;
}
if (_.isEqual(term_types, ["pm-with"])) {
if (_.isEqual(term_types, ["dm"])) {
return true;
}
@ -555,7 +560,7 @@ export class Filter {
is_common_narrow() {
// can_mark_messages_read tests the following filters:
// stream, stream + topic,
// is:dm, pm-with:,
// is:dm, dm,
// is:mentioned, is:resolved
if (this.can_mark_messages_read()) {
return true;
@ -621,11 +626,8 @@ export class Filter {
return "/#narrow/is/mentioned";
case "streams-public":
return "/#narrow/streams/public";
case "pm-with":
return (
"/#narrow/pm-with/" +
people.emails_to_slug(this.operands("pm-with").join(","))
);
case "dm":
return "/#narrow/dm/" + people.emails_to_slug(this.operands("dm").join(","));
case "is-resolved":
return "/#narrow/topics/is/resolved";
// TODO: It is ambiguous how we want to handle the 'sender' case,
@ -670,7 +672,7 @@ export class Filter {
case "is-mentioned":
context.icon = "at";
break;
case "pm-with":
case "dm":
context.icon = "envelope";
break;
case "is-resolved":
@ -697,10 +699,10 @@ export class Filter {
return this._sub.name;
}
if (
(term_types.length === 2 && _.isEqual(term_types, ["pm-with", "near"])) ||
(term_types.length === 1 && _.isEqual(term_types, ["pm-with"]))
(term_types.length === 2 && _.isEqual(term_types, ["dm", "near"])) ||
(term_types.length === 1 && _.isEqual(term_types, ["dm"]))
) {
const emails = this.operands("pm-with")[0].split(",");
const emails = this.operands("dm")[0].split(",");
const names = emails.map((email) => {
if (!people.get_by_email(email)) {
return email;
@ -749,7 +751,7 @@ export class Filter {
contains_only_private_messages() {
return (
(this.has_operator("is") && this.operands("is")[0] === "dm") ||
this.has_operator("pm-with") ||
this.has_operator("dm") ||
this.has_operator("group-pm-with")
);
}
@ -804,7 +806,7 @@ export class Filter {
}
_fix_redundant_is_private(terms) {
if (!terms.some((term) => Filter.term_type(term) === "pm-with")) {
if (!terms.some((term) => Filter.term_type(term) === "dm")) {
return terms;
}
@ -881,6 +883,7 @@ export class Filter {
for (const term of this._operators) {
switch (term.operator) {
case "group-pm-with":
case "dm":
case "pm-with":
case "sender":
case "from":
@ -937,7 +940,7 @@ export class Filter {
"streams-public",
"stream",
"topic",
"pm-with",
"dm",
"group-pm-with",
"sender",
"near",
@ -1003,7 +1006,7 @@ export class Filter {
case "sender":
return verb + "sent by";
case "pm-with":
case "dm":
return verb + "direct messages with";
case "in":
@ -1111,7 +1114,7 @@ export class Filter {
is_conversation_view() {
const term_type = this.sorted_term_types();
if (_.isEqual(term_type, ["stream", "topic"]) || _.isEqual(term_type, ["pm-with"])) {
if (_.isEqual(term_type, ["stream", "topic"]) || _.isEqual(term_type, ["dm"])) {
return true;
}
return false;

View File

@ -38,7 +38,12 @@ export function build_reload_url() {
}
export function encode_operand(operator, operand) {
if (operator === "group-pm-with" || operator === "pm-with" || operator === "sender") {
if (
operator === "group-pm-with" ||
operator === "dm" ||
operator === "sender" ||
operator === "pm-with"
) {
const slug = people.emails_to_slug(operand);
if (slug) {
return slug;
@ -61,7 +66,12 @@ export function encode_stream_name(operand) {
}
export function decode_operand(operator, operand) {
if (operator === "group-pm-with" || operator === "pm-with" || operator === "sender") {
if (
operator === "group-pm-with" ||
operator === "dm" ||
operator === "sender" ||
operator === "pm-with"
) {
const emails = people.slug_to_emails(operand);
if (emails) {
return emails;
@ -120,7 +130,7 @@ export function by_sender_url(reply_to) {
export function pm_with_url(reply_to) {
const slug = people.emails_to_slug(reply_to);
return "#narrow/pm-with/" + slug;
return "#narrow/dm/" + slug;
}
export function huddle_with_url(user_ids_string) {
@ -128,7 +138,7 @@ export function huddle_with_url(user_ids_string) {
// that have already converted emails to a comma-delimited
// list of user_ids. We should be careful to keep this
// consistent with hash_util.decode_operand.
return "#narrow/pm-with/" + user_ids_string + "-group";
return "#narrow/dm/" + user_ids_string + "-group";
}
export function by_conversation_and_time_url(message) {

View File

@ -1031,7 +1031,7 @@ export function process_hotkey(e, hotkey) {
case "private":
narrow.activate(
[
{operator: "pm-with", operand: msg.reply_to},
{operator: "dm", operand: msg.reply_to},
{operator: "near", operand: msg.id},
],
{trigger: "hotkey"},

View File

@ -132,7 +132,7 @@ function get_messages_success(data, opts) {
// or convert the emails string to user IDs directly into the Filter code
// because doing so breaks the app in various modules that expect emails string.
function handle_operators_supporting_id_based_api(data) {
const operators_supporting_ids = new Set(["pm-with"]);
const operators_supporting_ids = new Set(["dm", "pm-with"]);
const operators_supporting_id = new Set(["sender", "group-pm-with", "stream"]);
if (data.narrow === undefined) {

View File

@ -151,8 +151,8 @@ export function compute_narrow_title(filter) {
return "#" + filter_title;
}
if (filter.has_operator("pm-with")) {
const emails = filter.operands("pm-with")[0];
if (filter.has_operator("dm")) {
const emails = filter.operands("dm")[0];
const user_ids = people.emails_strings_to_user_ids_string(emails);
if (user_ids !== undefined) {
@ -887,19 +887,19 @@ export function narrow_to_next_topic() {
}
export function narrow_to_next_pm_string() {
const curr_pm = narrow_state.pm_ids_string();
const current_direct_message = narrow_state.pm_ids_string();
const next_pm = topic_generator.get_next_unread_pm_string(curr_pm);
const next_direct_message = topic_generator.get_next_unread_pm_string(current_direct_message);
if (!next_pm) {
if (!next_direct_message) {
return;
}
// Hopefully someday we can narrow by user_ids_string instead of
// mapping back to emails.
const pm_with = people.user_ids_string_to_emails_string(next_pm);
const direct_message = people.user_ids_string_to_emails_string(next_direct_message);
const filter_expr = [{operator: "pm-with", operand: pm_with}];
const filter_expr = [{operator: "dm", operand: direct_message}];
// force_close parameter is true to not auto open compose_box
const opts = {
@ -951,7 +951,7 @@ export function by_recipient(target_id, opts) {
switch (message.type) {
case "private":
by("pm-with", message.reply_to, opts);
by("dm", message.reply_to, opts);
break;
case "stream":
@ -992,12 +992,12 @@ export function to_compose_target() {
const emails = util.extract_pm_recipients(recipient_string);
const invalid = emails.filter((email) => !people.is_valid_email_for_compose(email));
// If there are no recipients or any recipient is
// invalid, narrow to all PMs.
// invalid, narrow to all direct messages.
if (emails.length === 0 || invalid.length > 0) {
by("is", "dm", opts);
return;
}
by("pm-with", util.normalize_recipients(recipient_string), opts);
by("dm", util.normalize_recipients(recipient_string), opts);
}
}

View File

@ -283,7 +283,7 @@ function pick_empty_narrow_banner() {
search_data: retrieve_search_query_data(),
};
}
case "pm-with": {
case "dm": {
if (!people.is_valid_bulk_emails_for_compose(first_operand.split(","))) {
if (!first_operand.includes(",")) {
return {

View File

@ -84,8 +84,8 @@ export function set_compose_defaults() {
const opts = {};
const single = collect_single(operators());
// Set the stream, topic, and/or PM recipient if they are
// uniquely specified in the narrow view.
// Set the stream, topic, and/or direct message recipient
// if they are uniquely specified in the narrow view.
if (single.has("stream")) {
opts.stream = stream_data.get_name(single.get("stream"));
@ -95,8 +95,8 @@ export function set_compose_defaults() {
opts.topic = single.get("topic");
}
if (single.has("pm-with")) {
const private_message_recipient = single.get("pm-with");
if (single.has("dm")) {
const private_message_recipient = single.get("dm");
if (people.is_valid_bulk_emails_for_compose(private_message_recipient.split(","))) {
opts.private_message_recipient = private_message_recipient;
}
@ -146,8 +146,8 @@ export function topic() {
}
export function pm_ids_string() {
// If you are narrowed to a PM conversation
// with users 4, 5, and 99, this will return "4,5,99"
// If you are narrowed to a group direct message with
// users 4, 5, and 99, this will return "4,5,99"
const emails_string = pm_emails_string();
if (!emails_string) {
@ -164,7 +164,7 @@ export function pm_emails_string() {
return undefined;
}
const operands = current_filter.operands("pm-with");
const operands = current_filter.operands("dm");
if (operands.length !== 1) {
return undefined;
}
@ -247,7 +247,7 @@ export function _possible_unread_message_ids() {
return unread.get_msg_ids_for_stream(sub.stream_id);
}
if (current_filter.can_bucket_by("pm-with")) {
if (current_filter.can_bucket_by("dm")) {
current_filter_pm_string = pm_ids_string();
if (current_filter_pm_string === undefined) {
return [];
@ -285,7 +285,7 @@ export function narrowed_to_pms() {
if (current_filter === undefined) {
return false;
}
return current_filter.has_operator("pm-with") || current_filter.has_operand("is", "dm");
return current_filter.has_operator("dm") || current_filter.has_operand("is", "dm");
}
export function narrowed_by_pm_reply() {
@ -293,7 +293,7 @@ export function narrowed_by_pm_reply() {
return false;
}
const operators = current_filter.operators();
return operators.length === 1 && current_filter.has_operator("pm-with");
return operators.length === 1 && current_filter.has_operator("dm");
}
export function narrowed_by_topic_reply() {

View File

@ -530,11 +530,11 @@ export function pm_perma_link(message) {
if (user_ids.length >= 3) {
suffix = "group";
} else {
suffix = "pm";
suffix = "dm";
}
const slug = user_ids.join(",") + "-" + suffix;
const url = "#narrow/pm-with/" + slug;
const url = "#narrow/dm/" + slug;
return url;
}
@ -560,7 +560,7 @@ export function pm_with_url(message) {
}
const slug = user_ids.join(",") + "-" + suffix;
const url = "#narrow/pm-with/" + slug;
const url = "#narrow/dm/" + slug;
return url;
}

View File

@ -147,7 +147,7 @@ function scroll_all_private_into_view() {
export function handle_narrow_activated(filter) {
const active_filter = filter;
const is_all_private_message_view = _.isEqual(active_filter.sorted_term_types(), ["is-dm"]);
const narrow_to_private_messages_section = active_filter.operands("pm-with").length !== 0;
const narrow_to_private_messages_section = active_filter.operands("dm").length !== 0;
if (is_all_private_message_view) {
// In theory, this should get expanded when we scroll to the

View File

@ -19,7 +19,7 @@ export function get_active_user_ids_string() {
return undefined;
}
const emails = filter.operands("pm-with")[0];
const emails = filter.operands("dm")[0];
if (!emails) {
return undefined;

View File

@ -814,7 +814,7 @@ export function register_click_handlers() {
if (overlays.is_active()) {
overlays.close_active();
}
narrow.by("pm-with", email, {trigger: "user sidebar popover"});
narrow.by("dm", email, {trigger: "user sidebar popover"});
e.stopPropagation();
e.preventDefault();
});

View File

@ -101,7 +101,7 @@ function get_stream_suggestions(last, operators) {
{operator: "stream"},
{operator: "streams"},
{operator: "is", operand: "dm"},
{operator: "pm-with"},
{operator: "dm"},
{operator: "group-pm-with"},
];
if (!check_validity(last, operators, valid, invalid)) {
@ -136,7 +136,9 @@ function get_stream_suggestions(last, operators) {
}
function get_group_suggestions(last, operators) {
if (!check_validity(last, operators, ["pm-with"], [{operator: "stream"}])) {
// For users with "pm-with" in their muscle memory, still
// have group direct message suggestions with "dm:" operator.
if (!check_validity(last, operators, ["dm", "pm-with"], [{operator: "stream"}])) {
return [];
}
@ -175,13 +177,13 @@ function get_group_suggestions(last, operators) {
// Take top 15 persons, since they're ordered by pm_recipient_count.
persons = persons.slice(0, 15);
const prefix = Filter.operator_to_prefix("pm-with", negated);
const prefix = Filter.operator_to_prefix("dm", negated);
const person_highlighter = make_person_highlighter(last_part);
const suggestions = persons.map((person) => {
const term = {
operator: "pm-with",
operator: "dm",
operand: all_but_last_part + "," + person.email,
negated,
};
@ -236,11 +238,11 @@ function make_people_getter(last) {
};
}
// Possible args for autocomplete_operator: pm-with, sender, from, group-pm-with
// Possible args for autocomplete_operator: dm, pm-with, sender, from, group-pm-with
function get_person_suggestions(people_getter, last, operators, autocomplete_operator) {
if (last.operator === "is" && last.operand === "dm") {
// Interpret "is:dm" as equivalent to "pm-with:".
last = {operator: "pm-with", operand: "", negated: false};
if ((last.operator === "is" && last.operand === "dm") || last.operator === "pm-with") {
// Interpret "is:dm" or "pm-with:" operator as equivalent to "dm:".
last = {operator: "dm", operand: "", negated: false};
}
const query = last.operand;
@ -257,8 +259,10 @@ function get_person_suggestions(people_getter, last, operators, autocomplete_ope
case "group-pm-with":
invalid = [{operator: "stream"}, {operator: "is", operand: "resolved"}];
break;
case "dm":
case "pm-with":
invalid = [
{operator: "dm"},
{operator: "pm-with"},
{operator: "stream"},
{operator: "is", operand: "resolved"},
@ -288,9 +292,13 @@ function get_person_suggestions(people_getter, last, operators, autocomplete_ope
negated: last.negated,
},
];
if (autocomplete_operator === "pm-with" && last.negated) {
// In the special case of "-pm-with", add "is:dm" before it
// because we assume the user still wants to narrow to direct
if (
last.negated &&
(autocomplete_operator === "dm" || autocomplete_operator === "pm-with")
) {
// In the special case of "-dm" or "-pm-with", add "is:dm" before
// it because we assume the user still wants to narrow to direct
// messages.
terms.unshift({operator: "is", operand: "dm"});
}
@ -349,7 +357,7 @@ export function get_topic_suggestions_from_candidates({candidate_topics, guess})
function get_topic_suggestions(last, operators) {
const invalid = [
{operator: "pm-with"},
{operator: "dm"},
{operator: "is", operand: "dm"},
{operator: "group-pm-with"},
{operator: "topic"},
@ -508,7 +516,7 @@ function get_streams_filter_suggestions(last, operators) {
{operator: "is", operand: "dm"},
{operator: "stream"},
{operator: "group-pm-with"},
{operator: "pm-with"},
{operator: "dm"},
{operator: "in"},
{operator: "streams"},
],
@ -525,7 +533,7 @@ function get_is_filter_suggestions(last, operators) {
{operator: "is", operand: "dm"},
{operator: "is", operand: "resolved"},
{operator: "stream"},
{operator: "pm-with"},
{operator: "dm"},
{operator: "in"},
],
},
@ -555,7 +563,7 @@ function get_is_filter_suggestions(last, operators) {
invalid: [
{operator: "is", operand: "resolved"},
{operator: "is", operand: "dm"},
{operator: "pm-with"},
{operator: "dm"},
{operator: "group-pm-with"},
],
},
@ -646,10 +654,15 @@ function get_operator_suggestions(last) {
last_operand = last_operand.slice(1);
}
let choices = ["stream", "topic", "pm-with", "sender", "near", "from", "group-pm-with"];
let choices = ["stream", "topic", "dm", "sender", "near", "from", "group-pm-with", "pm-with"];
choices = choices.filter((choice) => common.phrase_match(last_operand, choice));
return choices.map((choice) => {
// Map results for "dm:" operator for users
// who have "pm-with" in their muscle memory.
if (choice === "pm-with") {
choice = "dm";
}
const op = [{operator: choice, operand: "", negated}];
return format_as_suggestion(op);
});
@ -718,7 +731,7 @@ export function get_search_result(base_query, query) {
search_operators.push(last);
}
const person_suggestion_ops = ["sender", "pm-with", "from", "group-pm"];
const person_suggestion_ops = ["sender", "dm", "from", "group-pm-with", "pm-with"];
// Handle spaces in person name in new suggestions only. Checks if the last operator is 'search'
// and the second last operator in search_operators is one out of person_suggestion_ops.
@ -775,7 +788,7 @@ export function get_search_result(base_query, query) {
get_sent_by_me_suggestions,
get_stream_suggestions,
get_people("sender"),
get_people("pm-with"),
get_people("dm"),
get_people("from"),
get_people("group-pm-with"),
get_group_suggestions,

View File

@ -28,12 +28,12 @@ const MAX_USERS_TO_DISPLAY_NAME = 3;
function get_users_typing_for_narrow() {
if (!narrow_state.narrowed_to_pms()) {
// Narrow is neither pm-with nor is: private
// Narrow is neither "dm:" nor "is:dm".
return [];
}
const first_term = narrow_state.operators()[0];
if (first_term.operator === "pm-with") {
if (first_term.operator === "dm") {
// Get list of users typing in this conversation
const narrow_emails_string = first_term.operand;
// TODO: Create people.emails_strings_to_user_ids.

View File

@ -383,7 +383,7 @@ test("first/prev/next", ({override, mock_template}) => {
rendered_alice = true;
assert.deepEqual(data, {
faded: true,
href: "#narrow/pm-with/1-Alice-Smith",
href: "#narrow/dm/1-Alice-Smith",
is_current_user: false,
name: "Alice Smith",
num_unread: 0,
@ -401,7 +401,7 @@ test("first/prev/next", ({override, mock_template}) => {
case fred.user_id:
rendered_fred = true;
assert.deepEqual(data, {
href: "#narrow/pm-with/2-Fred-Flintstone",
href: "#narrow/dm/2-Fred-Flintstone",
name: "Fred Flintstone",
user_id: fred.user_id,
is_current_user: false,
@ -449,7 +449,7 @@ test("insert_one_user_into_empty_list", ({override, mock_template}) => {
user_settings.user_list_style = 2;
mock_template("presence_row.hbs", true, (data, html) => {
assert.deepEqual(data, {
href: "#narrow/pm-with/1-Alice-Smith",
href: "#narrow/dm/1-Alice-Smith",
name: "Alice Smith",
user_id: 1,
is_current_user: false,

View File

@ -510,7 +510,7 @@ test("get_items_for_users", () => {
assert.deepEqual(buddy_data.get_items_for_users(user_ids), [
{
faded: false,
href: "#narrow/pm-with/1001-Human-Myself",
href: "#narrow/dm/1001-Human-Myself",
is_current_user: true,
name: "Human Myself",
num_unread: 0,
@ -522,7 +522,7 @@ test("get_items_for_users", () => {
},
{
faded: false,
href: "#narrow/pm-with/1002-Alice-Smith",
href: "#narrow/dm/1002-Alice-Smith",
is_current_user: false,
name: "Alice Smith",
num_unread: 0,
@ -534,7 +534,7 @@ test("get_items_for_users", () => {
},
{
faded: false,
href: "#narrow/pm-with/1003-Fred-Flintstone",
href: "#narrow/dm/1003-Fred-Flintstone",
is_current_user: false,
name: "Fred Flintstone",
num_unread: 0,

View File

@ -77,7 +77,7 @@ run_test("typing_events.render_notifications_for_narrow", ({override, mock_templ
override(page_params, "user_id", anna.user_id);
const group = [anna.user_id, vronsky.user_id, levin.user_id, kitty.user_id];
const group_emails = `${anna.email},${vronsky.email},${levin.email},${kitty.email}`;
narrow_state.set_current_filter(new Filter([{operator: "pm-with", operand: group_emails}]));
narrow_state.set_current_filter(new Filter([{operator: "dm", operand: group_emails}]));
// Based on typing_events.MAX_USERS_TO_DISPLAY_NAME (which is currently 3),
// we display either the list of all users typing (if they do not exceed

View File

@ -230,7 +230,7 @@ test("basics", () => {
assert.ok(filter.is_personal_filter());
assert.ok(!filter.is_conversation_view());
operators = [{operator: "pm-with", operand: "joe@example.com"}];
operators = [{operator: "dm", operand: "joe@example.com"}];
filter = new Filter(operators);
assert.ok(filter.is_non_huddle_pm());
assert.ok(filter.contains_only_private_messages());
@ -241,7 +241,7 @@ test("basics", () => {
assert.ok(!filter.is_personal_filter());
assert.ok(filter.is_conversation_view());
operators = [{operator: "pm-with", operand: "joe@example.com,jack@example.com"}];
operators = [{operator: "dm", operand: "joe@example.com,jack@example.com"}];
filter = new Filter(operators);
assert.ok(!filter.is_non_huddle_pm());
assert.ok(filter.contains_only_private_messages());
@ -251,6 +251,12 @@ test("basics", () => {
assert.ok(!filter.is_personal_filter());
assert.ok(filter.is_conversation_view());
// "pm-with" was renamed to "dm"
operators = [{operator: "pm-with", operand: "joe@example.com"}];
filter = new Filter(operators);
assert.ok(filter.has_operator("dm"));
assert.ok(!filter.has_operator(" pm-with"));
operators = [{operator: "group-pm-with", operand: "joe@example.com"}];
filter = new Filter(operators);
assert.ok(!filter.is_non_huddle_pm());
@ -432,23 +438,23 @@ test("can_mark_messages_read", () => {
filter = new Filter(stream_negated_topic_operators);
assert.ok(!filter.can_mark_messages_read());
const pm_with = [{operator: "pm-with", operand: "joe@example.com,"}];
const dm = [{operator: "dm", operand: "joe@example.com,"}];
const pm_with_negated = [{operator: "pm-with", operand: "joe@example.com,", negated: true}];
const dm_negated = [{operator: "dm", operand: "joe@example.com,", negated: true}];
const group_pm = [{operator: "pm-with", operand: "joe@example.com,STEVE@foo.com"}];
filter = new Filter(pm_with);
const dm_group = [{operator: "dm", operand: "joe@example.com,STEVE@foo.com"}];
filter = new Filter(dm);
assert.ok(filter.can_mark_messages_read());
filter = new Filter(pm_with_negated);
filter = new Filter(dm_negated);
assert.ok(!filter.can_mark_messages_read());
filter = new Filter(group_pm);
filter = new Filter(dm_group);
assert.ok(filter.can_mark_messages_read());
assert_not_mark_read_with_is_operands(group_pm);
assert_not_mark_read_with_is_operands(pm_with);
assert_not_mark_read_with_has_operands(group_pm);
assert_not_mark_read_with_has_operands(pm_with);
assert_not_mark_read_when_searching(group_pm);
assert_not_mark_read_when_searching(pm_with);
assert_not_mark_read_with_is_operands(dm_group);
assert_not_mark_read_with_is_operands(dm);
assert_not_mark_read_with_has_operands(dm_group);
assert_not_mark_read_with_has_operands(dm);
assert_not_mark_read_when_searching(dm_group);
assert_not_mark_read_when_searching(dm);
const is_dm = [{operator: "is", operand: "dm"}];
filter = new Filter(is_dm);
@ -484,7 +490,7 @@ test("can_mark_messages_read", () => {
// test caching of term types
// init and stub
filter = new Filter(pm_with);
filter = new Filter(dm);
filter.stub = filter.calc_can_mark_messages_read;
filter.calc_can_mark_messages_read = function () {
this.calc_can_mark_messages_read_called = true;
@ -598,18 +604,18 @@ test("redundancies", () => {
let filter;
terms = [
{operator: "pm-with", operand: "joe@example.com,"},
{operator: "dm", operand: "joe@example.com,"},
{operator: "is", operand: "dm"},
];
filter = new Filter(terms);
assert.ok(filter.can_bucket_by("pm-with"));
assert.ok(filter.can_bucket_by("dm"));
terms = [
{operator: "pm-with", operand: "joe@example.com,", negated: true},
{operator: "dm", operand: "joe@example.com,", negated: true},
{operator: "is", operand: "dm"},
];
filter = new Filter(terms);
assert.ok(filter.can_bucket_by("is-dm", "not-pm-with"));
assert.ok(filter.can_bucket_by("is-dm", "not-dm"));
});
test("canonicalization", () => {
@ -627,8 +633,9 @@ test("canonicalization", () => {
assert.equal(term.operator, "sender");
assert.equal(term.operand, "me@example.com");
// "pm-with" was renamed to "dm"
term = Filter.canonicalize_term({operator: "pm-with", operand: "me"});
assert.equal(term.operator, "pm-with");
assert.equal(term.operator, "dm");
assert.equal(term.operand, "me@example.com");
term = Filter.canonicalize_term({operator: "search", operand: "foo"});
@ -757,7 +764,7 @@ test("predicate_basics", () => {
assert.ok(predicate({sender_id: joe.user_id}));
assert.ok(!predicate({sender_email: steve.user_id}));
predicate = get_predicate([["pm-with", "Joe@example.com"]]);
predicate = get_predicate([["dm", "Joe@example.com"]]);
assert.ok(
predicate({
type: "private",
@ -778,7 +785,7 @@ test("predicate_basics", () => {
);
assert.ok(!predicate({type: "stream"}));
predicate = get_predicate([["pm-with", "Joe@example.com,steve@foo.com"]]);
predicate = get_predicate([["dm", "Joe@example.com,steve@foo.com"]]);
assert.ok(
predicate({
type: "private",
@ -787,7 +794,7 @@ test("predicate_basics", () => {
);
// Make sure your own email is ignored
predicate = get_predicate([["pm-with", "Joe@example.com,steve@foo.com,me@example.com"]]);
predicate = get_predicate([["dm", "Joe@example.com,steve@foo.com,me@example.com"]]);
assert.ok(
predicate({
type: "private",
@ -795,7 +802,7 @@ test("predicate_basics", () => {
}),
);
predicate = get_predicate([["pm-with", "nobody@example.com"]]);
predicate = get_predicate([["dm", "nobody@example.com"]]);
assert.ok(
!predicate({
type: "private",
@ -1000,8 +1007,8 @@ test("parse", () => {
];
_test();
string = "pm-with:leo+test@zulip.com";
operators = [{operator: "pm-with", operand: "leo+test@zulip.com"}];
string = "dm:leo+test@zulip.com";
operators = [{operator: "dm", operand: "leo+test@zulip.com"}];
_test();
string = "sender:leo+test@zulip.com";
@ -1260,7 +1267,7 @@ test("can_bucket_by", () => {
let filter = new Filter(terms);
assert.equal(filter.can_bucket_by("stream"), true);
assert.equal(filter.can_bucket_by("stream", "topic"), false);
assert.equal(filter.can_bucket_by("pm-with"), false);
assert.equal(filter.can_bucket_by("dm"), false);
terms = [
// try a non-orthodox ordering
@ -1270,7 +1277,7 @@ test("can_bucket_by", () => {
filter = new Filter(terms);
assert.equal(filter.can_bucket_by("stream"), true);
assert.equal(filter.can_bucket_by("stream", "topic"), true);
assert.equal(filter.can_bucket_by("pm-with"), false);
assert.equal(filter.can_bucket_by("dm"), false);
terms = [
{operator: "stream", operand: "My stream", negated: true},
@ -1279,19 +1286,19 @@ test("can_bucket_by", () => {
filter = new Filter(terms);
assert.equal(filter.can_bucket_by("stream"), false);
assert.equal(filter.can_bucket_by("stream", "topic"), false);
assert.equal(filter.can_bucket_by("pm-with"), false);
assert.equal(filter.can_bucket_by("dm"), false);
terms = [{operator: "pm-with", operand: "foo@example.com", negated: true}];
terms = [{operator: "dm", operand: "foo@example.com", negated: true}];
filter = new Filter(terms);
assert.equal(filter.can_bucket_by("stream"), false);
assert.equal(filter.can_bucket_by("stream", "topic"), false);
assert.equal(filter.can_bucket_by("pm-with"), false);
assert.equal(filter.can_bucket_by("dm"), false);
terms = [{operator: "pm-with", operand: "foo@example.com,bar@example.com"}];
terms = [{operator: "dm", operand: "foo@example.com,bar@example.com"}];
filter = new Filter(terms);
assert.equal(filter.can_bucket_by("stream"), false);
assert.equal(filter.can_bucket_by("stream", "topic"), false);
assert.equal(filter.can_bucket_by("pm-with"), true);
assert.equal(filter.can_bucket_by("dm"), true);
assert.equal(filter.can_bucket_by("is-mentioned"), false);
assert.equal(filter.can_bucket_by("is-dm"), false);
@ -1327,7 +1334,7 @@ test("can_bucket_by", () => {
filter = new Filter(terms);
assert.equal(filter.can_bucket_by("stream", "topic"), false);
assert.equal(filter.can_bucket_by("stream"), false);
assert.equal(filter.can_bucket_by("pm-with"), false);
assert.equal(filter.can_bucket_by("dm"), false);
assert.equal(filter.can_bucket_by("is-mentioned"), false);
assert.equal(filter.can_bucket_by("is-dm"), false);
});
@ -1347,8 +1354,8 @@ test("term_type", () => {
assert_term_type(term("streams", "public"), "streams-public");
assert_term_type(term("stream", "whatever"), "stream");
assert_term_type(term("pm-with", "whomever"), "pm-with");
assert_term_type(term("pm-with", "whomever", true), "not-pm-with");
assert_term_type(term("dm", "whomever"), "dm");
assert_term_type(term("dm", "whomever", true), "not-dm");
assert_term_type(term("is", "dm"), "is-dm");
assert_term_type(term("is", "private"), "is-private");
assert_term_type(term("has", "link"), "has-link");
@ -1362,8 +1369,8 @@ test("term_type", () => {
assert_term_sort(["topic", "stream", "sender"], ["stream", "topic", "sender"]);
assert_term_sort(
["has-link", "near", "is-unread", "pm-with"],
["pm-with", "near", "is-unread", "has-link"],
["has-link", "near", "is-unread", "dm"],
["dm", "near", "is-unread", "has-link"],
);
assert_term_sort(["bogus", "stream", "topic"], ["stream", "topic", "bogus"]);
@ -1427,13 +1434,13 @@ test("first_valid_id_from", ({override}) => {
test("update_email", () => {
const terms = [
{operator: "pm-with", operand: "steve@foo.com"},
{operator: "dm", operand: "steve@foo.com"},
{operator: "sender", operand: "steve@foo.com"},
{operator: "stream", operand: "steve@foo.com"}, // try to be tricky
];
const filter = new Filter(terms);
filter.update_email(steve.user_id, "showell@foo.com");
assert.deepEqual(filter.operands("pm-with"), ["showell@foo.com"]);
assert.deepEqual(filter.operands("dm"), ["showell@foo.com"]);
assert.deepEqual(filter.operands("sender"), ["showell@foo.com"]);
assert.deepEqual(filter.operands("stream"), ["steve@foo.com"]);
});
@ -1519,10 +1526,10 @@ test("navbar_helpers", () => {
{operator: "stream", operand: "Elephant"},
{operator: "topic", operand: "pink"},
];
const pm_with = [{operator: "pm-with", operand: "joe@example.com"}];
const group_pm = [{operator: "pm-with", operand: "joe@example.com,STEVE@foo.com"}];
const group_pm_including_missing_person = [
{operator: "pm-with", operand: "joe@example.com,STEVE@foo.com,sally@doesnotexist.com"},
const dm = [{operator: "dm", operand: "joe@example.com"}];
const dm_group = [{operator: "dm", operand: "joe@example.com,STEVE@foo.com"}];
const dm_group_including_missing_person = [
{operator: "dm", operand: "joe@example.com,STEVE@foo.com,sally@doesnotexist.com"},
];
// not common narrows, but used for browser title updates
const is_alerted = [{operator: "is", operand: "alerted"}];
@ -1532,8 +1539,8 @@ test("navbar_helpers", () => {
{operator: "topic", operand: "bar"},
{operator: "near", operand: "12"},
];
const pm_with_near = [
{operator: "pm-with", operand: "joe@example.com"},
const dm_near = [
{operator: "dm", operand: "joe@example.com"},
{operator: "near", operand: "12"},
];
@ -1630,23 +1637,22 @@ test("navbar_helpers", () => {
redirect_url_with_search: "/#narrow/stream/12-webPublicSub",
},
{
operator: pm_with,
operator: dm,
is_common_narrow: true,
icon: "envelope",
title: properly_separated_names([joe.full_name]),
redirect_url_with_search:
"/#narrow/pm-with/" + joe.user_id + "-" + parseOneAddress(joe.email).local,
"/#narrow/dm/" + joe.user_id + "-" + parseOneAddress(joe.email).local,
},
{
operator: group_pm,
operator: dm_group,
is_common_narrow: true,
icon: "envelope",
title: properly_separated_names([joe.full_name, steve.full_name]),
redirect_url_with_search:
"/#narrow/pm-with/" + joe.user_id + "," + steve.user_id + "-group",
redirect_url_with_search: "/#narrow/dm/" + joe.user_id + "," + steve.user_id + "-group",
},
{
operator: group_pm_including_missing_person,
operator: dm_group_including_missing_person,
is_common_narrow: true,
icon: "envelope",
title: properly_separated_names([
@ -1654,7 +1660,7 @@ test("navbar_helpers", () => {
steve.full_name,
"sally@doesnotexist.com",
]),
redirect_url_with_search: "/#narrow/pm-with/undefined",
redirect_url_with_search: "/#narrow/dm/undefined",
},
{
operator: is_alerted,
@ -1678,7 +1684,7 @@ test("navbar_helpers", () => {
redirect_url_with_search: "#",
},
{
operator: pm_with_near,
operator: dm_near,
is_common_narrow: false,
icon: "envelope",
title: properly_separated_names([joe.full_name]),
@ -1757,7 +1763,7 @@ test("error_cases", () => {
// This test just gives us 100% line coverage on defensive code that
// should not be reached unless we break other code.
const predicate = get_predicate([["pm-with", "Joe@example.com"]]);
const predicate = get_predicate([["dm", "Joe@example.com"]]);
blueslip.expect("error", "Empty recipient list in message");
assert.ok(!predicate({type: "private", display_recipient: []}));
});
@ -1776,9 +1782,7 @@ run_test("is_spectator_compatible", () => {
]),
);
assert.ok(Filter.is_spectator_compatible([{operator: "sender", operand: "hamlet@zulip.com"}]));
assert.ok(
!Filter.is_spectator_compatible([{operator: "pm-with", operand: "hamlet@zulip.com"}]),
);
assert.ok(!Filter.is_spectator_compatible([{operator: "dm", operand: "hamlet@zulip.com"}]));
assert.ok(
!Filter.is_spectator_compatible([{operator: "group-pm-with", operand: "hamlet@zulip.com"}]),
);
@ -1798,4 +1802,8 @@ run_test("is_spectator_compatible", () => {
// "is:private" was renamed to "is:dm"
assert.ok(!Filter.is_spectator_compatible([{operator: "is", operand: "private"}]));
// "pm-with" was renamed to "dm"
assert.ok(
!Filter.is_spectator_compatible([{operator: "pm-with", operand: "hamlet@zulip.com"}]),
);
});

View File

@ -162,7 +162,7 @@ run_test("test_by_conversation_and_time_url", () => {
assert.equal(
hash_util.by_conversation_and_time_url(message),
"http://zulip.zulipdev.com/#narrow/pm-with/15-pm/near/43",
"http://zulip.zulipdev.com/#narrow/dm/15-dm/near/43",
);
});

View File

@ -95,6 +95,7 @@ run_test("operators_trailing_slash", () => {
run_test("people_slugs", () => {
let operators;
let hash;
let narrow;
const alice = {
email: "alice@example.com",
@ -106,12 +107,22 @@ run_test("people_slugs", () => {
operators = [{operator: "sender", operand: "alice@example.com"}];
hash = hash_util.operators_to_hash(operators);
assert.equal(hash, "#narrow/sender/42-Alice-Smith");
const narrow = hash_util.parse_narrow(hash.split("/"));
narrow = hash_util.parse_narrow(hash.split("/"));
assert.deepEqual(narrow, [{operator: "sender", operand: "alice@example.com", negated: false}]);
operators = [{operator: "dm", operand: "alice@example.com"}];
hash = hash_util.operators_to_hash(operators);
assert.equal(hash, "#narrow/dm/42-Alice-Smith");
narrow = hash_util.parse_narrow(hash.split("/"));
assert.deepEqual(narrow, [{operator: "dm", operand: "alice@example.com", negated: false}]);
// Even though we renamed "pm-with" to "dm", preexisting
// links/URLs with "pm-with" operator are handled correctly.
operators = [{operator: "pm-with", operand: "alice@example.com"}];
hash = hash_util.operators_to_hash(operators);
assert.equal(hash, "#narrow/pm-with/42-Alice-Smith");
narrow = hash_util.parse_narrow(hash.split("/"));
assert.deepEqual(narrow, [{operator: "pm-with", operand: "alice@example.com", negated: false}]);
});
function test_helper({override, change_tab}) {

View File

@ -293,7 +293,7 @@ run_test("initialize", () => {
});
function simulate_narrow() {
const filter = new Filter([{operator: "pm-with", operand: alice.email}]);
const filter = new Filter([{operator: "dm", operand: alice.email}]);
const msg_list = new message_list.MessageList({
table_name: "zfilt",
@ -364,7 +364,7 @@ run_test("loading_newer", () => {
anchor: "444",
num_before: 0,
num_after: 100,
narrow: `[{"negated":false,"operator":"pm-with","operand":[${alice.user_id}]}]`,
narrow: `[{"negated":false,"operator":"dm","operand":[${alice.user_id}]}]`,
client_gravatar: true,
},
resp: {

View File

@ -126,7 +126,7 @@ run_test("basics", () => {
run_test("muting", () => {
let mld = new MessageListData({
excludes_muted_topics: false,
filter: new Filter([{operator: "pm-with", operand: "alice@example.com"}]),
filter: new Filter([{operator: "dm", operand: "alice@example.com"}]),
});
const msgs = [

View File

@ -175,15 +175,26 @@ run_test("urls", () => {
people.initialize_current_user(me.user_id);
let url = hash_util.pm_with_url(ray.email);
assert.equal(url, "#narrow/pm-with/22-Raymond");
assert.equal(url, "#narrow/dm/22-Raymond");
url = hash_util.huddle_with_url("22,23");
assert.equal(url, "#narrow/pm-with/22,23-group");
assert.equal(url, "#narrow/dm/22,23-group");
url = hash_util.by_sender_url(ray.email);
assert.equal(url, "#narrow/sender/22-Raymond");
let emails = hash_util.decode_operand("pm-with", "22,23-group");
let emails = hash_util.decode_operand("dm", "22,23-group");
assert.equal(emails, "alice@example.com,ray@example.com");
emails = hash_util.decode_operand("dm", "5,22,23-group");
assert.equal(emails, "alice@example.com,ray@example.com");
emails = hash_util.decode_operand("dm", "5-group");
assert.equal(emails, "me@example.com");
// Even though we renamed "pm-with" to "dm", preexisting
// links/URLs with "pm-with" operator are decoded correctly.
emails = hash_util.decode_operand("pm-with", "22,23-group");
assert.equal(emails, "alice@example.com,ray@example.com");
emails = hash_util.decode_operand("pm-with", "5,22,23-group");
@ -330,7 +341,7 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
settings_config.private_message_policy_values.disabled.code;
// prioritize information about invalid user(s) in narrow/search
set_filter([["pm-with", ["Yo"]]]);
set_filter([["dm", ["Yo"]]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -338,14 +349,14 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
);
people.add_active_user(alice);
set_filter([["pm-with", ["alice@example.com", "Yo"]]]);
set_filter([["dm", ["alice@example.com", "Yo"]]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
empty_narrow_html("translated: One or more of these users do not exist!"),
);
set_filter([["pm-with", "alice@example.com"]]);
set_filter([["dm", "alice@example.com"]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -357,7 +368,7 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
// direct messages with a bot are possible even though
// the organization has disabled sending direct messages
people.add_active_user(bot);
set_filter([["pm-with", "bot@example.com"]]);
set_filter([["dm", "bot@example.com"]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -369,7 +380,7 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
// group direct messages with bots are not possible when
// sending direct messages is disabled
set_filter([["pm-with", bot.email + "," + alice.email]]);
set_filter([["dm", bot.email + "," + alice.email]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -381,7 +392,7 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
// sending direct messages enabled
page_params.realm_private_message_policy =
settings_config.private_message_policy_values.by_anyone.code;
set_filter([["pm-with", "alice@example.com"]]);
set_filter([["dm", "alice@example.com"]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -393,7 +404,7 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
people.add_active_user(me);
people.initialize_current_user(me.user_id);
set_filter([["pm-with", me.email]]);
set_filter([["dm", me.email]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -403,7 +414,7 @@ run_test("show_empty_narrow_message", ({mock_template}) => {
),
);
set_filter([["pm-with", me.email + "," + alice.email]]);
set_filter([["dm", me.email + "," + alice.email]]);
narrow_banner.show_empty_narrow_message();
assert.equal(
$(".empty_feed_notice_main").html(),
@ -711,7 +722,7 @@ run_test("narrow_to_compose_target streams", ({override_rewire}) => {
assert.deepEqual(args.operators, [{operator: "stream", operand: "ROME"}]);
});
run_test("narrow_to_compose_target PMs", ({override, override_rewire}) => {
run_test("narrow_to_compose_target direct messages", ({override, override_rewire}) => {
const args = {called: false};
override_rewire(narrow, "activate", (operators, opts) => {
args.operators = operators;
@ -732,7 +743,7 @@ run_test("narrow_to_compose_target PMs", ({override, override_rewire}) => {
args.called = false;
narrow.to_compose_target();
assert.equal(args.called, true);
assert.deepEqual(args.operators, [{operator: "pm-with", operand: "alice@example.com"}]);
assert.deepEqual(args.operators, [{operator: "dm", operand: "alice@example.com"}]);
// Test with valid persons
emails = "alice@example.com,ray@example.com";
@ -740,7 +751,7 @@ run_test("narrow_to_compose_target PMs", ({override, override_rewire}) => {
narrow.to_compose_target();
assert.equal(args.called, true);
assert.deepEqual(args.operators, [
{operator: "pm-with", operand: "alice@example.com,ray@example.com"},
{operator: "dm", operand: "alice@example.com,ray@example.com"},
]);
// Test with some invalid persons
@ -803,7 +814,7 @@ run_test("narrow_compute_title", ({override}) => {
filter = new Filter([{operator: "stream", operand: "Elephant"}]);
assert.equal(narrow.compute_narrow_title(filter), "translated: Unknown stream #Elephant");
// Private messages with narrows
// Direct messages with narrows
const joe = {
email: "joe@example.com",
user_id: 31,
@ -811,14 +822,14 @@ run_test("narrow_compute_title", ({override}) => {
};
people.add_active_user(joe);
filter = new Filter([{operator: "pm-with", operand: "joe@example.com"}]);
filter = new Filter([{operator: "dm", operand: "joe@example.com"}]);
assert.equal(narrow.compute_narrow_title(filter), "joe");
filter = new Filter([{operator: "pm-with", operand: "joe@example.com,sally@doesnotexist.com"}]);
filter = new Filter([{operator: "dm", operand: "joe@example.com,sally@doesnotexist.com"}]);
blueslip.expect("warn", "Unknown emails: joe@example.com,sally@doesnotexist.com");
assert.equal(narrow.compute_narrow_title(filter), "translated: Invalid users");
filter = new Filter([{operator: "pm-with", operand: "sally@doesnotexist.com"}]);
filter = new Filter([{operator: "dm", operand: "sally@doesnotexist.com"}]);
blueslip.expect("warn", "Unknown emails: sally@doesnotexist.com");
assert.equal(narrow.compute_narrow_title(filter), "translated: Invalid user");
});

View File

@ -195,9 +195,9 @@ run_test("is private with no target", () => {
test_with(fixture);
});
run_test("pm-with with target outside of range", () => {
run_test("dm with target outside of range", () => {
const fixture = {
filter_terms: [{operator: "pm-with", operand: "alice@example.com"}],
filter_terms: [{operator: "dm", operand: "alice@example.com"}],
target_id: 5,
unread_info: {
flavor: "not_found",

View File

@ -79,7 +79,7 @@ test("narrowed", () => {
assert.ok(narrow_state.narrowed_by_stream_reply());
assert.ok(!narrow_state.narrowed_to_starred());
set_filter([["pm-with", "steve@zulip.com"]]);
set_filter([["dm", "steve@zulip.com"]]);
assert.ok(narrow_state.narrowed_to_pms());
assert.ok(narrow_state.narrowed_by_reply());
assert.ok(narrow_state.narrowed_by_pm_reply());
@ -178,9 +178,9 @@ test("set_compose_defaults", () => {
assert.equal(stream_and_topic.stream, "Foo");
assert.equal(stream_and_topic.topic, "Bar");
set_filter([["pm-with", "foo@bar.com"]]);
let pm_test = narrow_state.set_compose_defaults();
assert.equal(pm_test.private_message_recipient, undefined);
set_filter([["dm", "foo@bar.com"]]);
let dm_test = narrow_state.set_compose_defaults();
assert.equal(dm_test.private_message_recipient, undefined);
const john = {
email: "john@doe.com",
@ -190,9 +190,15 @@ test("set_compose_defaults", () => {
people.add_active_user(john);
people.add_active_user(john);
set_filter([["dm", "john@doe.com"]]);
dm_test = narrow_state.set_compose_defaults();
assert.equal(dm_test.private_message_recipient, "john@doe.com");
// Even though we renamed "pm-with" to "dm",
// compose defaults are set correctly.
set_filter([["pm-with", "john@doe.com"]]);
pm_test = narrow_state.set_compose_defaults();
assert.equal(pm_test.private_message_recipient, "john@doe.com");
dm_test = narrow_state.set_compose_defaults();
assert.equal(dm_test.private_message_recipient, "john@doe.com");
set_filter([
["topic", "duplicate"],
@ -216,13 +222,13 @@ test("update_email", () => {
people.add_active_user(steve);
set_filter([
["pm-with", "steve@foo.com"],
["dm", "steve@foo.com"],
["sender", "steve@foo.com"],
["stream", "steve@foo.com"], // try to be tricky
]);
narrow_state.update_email(steve.user_id, "showell@foo.com");
const filter = narrow_state.filter();
assert.deepEqual(filter.operands("pm-with"), ["showell@foo.com"]);
assert.deepEqual(filter.operands("dm"), ["showell@foo.com"]);
assert.deepEqual(filter.operands("sender"), ["showell@foo.com"]);
assert.deepEqual(filter.operands("stream"), ["steve@foo.com"]);
});
@ -245,7 +251,7 @@ test("topic", () => {
set_filter([
["sender", "test@foo.com"],
["pm-with", "test@foo.com"],
["dm", "test@foo.com"],
]);
assert.equal(narrow_state.topic(), undefined);
@ -278,8 +284,8 @@ test("stream_sub", () => {
test("pm_ids_string", () => {
// This function will return undefined unless we're clearly
// narrowed to a specific PM (including huddles) with real
// users.
// narrowed to a specific direct message (including group
// direct messages) with real users.
narrow_state.set_current_filter(undefined);
assert.equal(narrow_state.pm_ids_string(), undefined);
@ -289,10 +295,10 @@ test("pm_ids_string", () => {
]);
assert.equal(narrow_state.pm_ids_string(), undefined);
set_filter([["pm-with", ""]]);
set_filter([["dm", ""]]);
assert.equal(narrow_state.pm_ids_string(), undefined);
set_filter([["pm-with", "bogus@foo.com"]]);
set_filter([["dm", "bogus@foo.com"]]);
assert.equal(narrow_state.pm_ids_string(), undefined);
const alice = {
@ -310,6 +316,6 @@ test("pm_ids_string", () => {
people.add_active_user(alice);
people.add_active_user(bob);
set_filter([["pm-with", "bob@foo.com,alice@foo.com"]]);
set_filter([["dm", "bob@foo.com,alice@foo.com"]]);
assert.equal(narrow_state.pm_ids_string(), "444,555");
});

View File

@ -143,7 +143,7 @@ run_test("get_unread_ids", () => {
// this actually does filtering
assert_unread_info({flavor: "not_found"});
terms = [{operator: "pm-with", operand: "alice@example.com"}];
terms = [{operator: "dm", operand: "alice@example.com"}];
set_filter(terms);
unread_ids = candidate_ids();
assert.deepEqual(unread_ids, []);
@ -176,7 +176,7 @@ run_test("get_unread_ids", () => {
unread_ids = candidate_ids();
assert.deepEqual(unread_ids, [stream_msg.id, private_msg.id]);
terms = [{operator: "pm-with", operand: "bob@example.com"}];
terms = [{operator: "dm", operand: "bob@example.com"}];
set_filter(terms);
unread_ids = candidate_ids();

View File

@ -771,8 +771,8 @@ test_people("message_methods", () => {
display_recipient: [{id: maria.user_id}, {id: me.user_id}, {id: charles.user_id}],
sender_id: charles.user_id,
};
assert.equal(people.pm_with_url(message), "#narrow/pm-with/301,302-group");
assert.equal(people.pm_perma_link(message), "#narrow/pm-with/30,301,302-group");
assert.equal(people.pm_with_url(message), "#narrow/dm/301,302-group");
assert.equal(people.pm_perma_link(message), "#narrow/dm/30,301,302-group");
assert.equal(people.pm_reply_to(message), "Athens@example.com,charles@example.com");
assert.equal(people.small_avatar_url(message), "http://charles.com/foo.png?s=50");
@ -781,8 +781,8 @@ test_people("message_methods", () => {
display_recipient: [{id: maria.user_id}, {id: me.user_id}],
avatar_url: "legacy.png",
};
assert.equal(people.pm_with_url(message), "#narrow/pm-with/302-Maria-Athens");
assert.equal(people.pm_perma_link(message), "#narrow/pm-with/30,302-pm");
assert.equal(people.pm_with_url(message), "#narrow/dm/302-Maria-Athens");
assert.equal(people.pm_perma_link(message), "#narrow/dm/30,302-dm");
assert.equal(people.pm_reply_to(message), "Athens@example.com");
assert.equal(people.small_avatar_url(message), "http://zulip.zulipdev.com/legacy.png?s=50");
@ -818,8 +818,8 @@ test_people("message_methods", () => {
type: "private",
display_recipient: [{id: me.user_id}],
};
assert.equal(people.pm_with_url(message), "#narrow/pm-with/30-Me-Myself");
assert.equal(people.pm_perma_link(message), "#narrow/pm-with/30-pm");
assert.equal(people.pm_with_url(message), "#narrow/dm/30-Me-Myself");
assert.equal(people.pm_perma_link(message), "#narrow/dm/30-dm");
message = {type: "stream"};
assert.equal(people.pm_with_user_ids(message), undefined);

View File

@ -74,7 +74,7 @@ function test(label, f) {
}
function set_pm_with_filter(emails) {
const active_filter = new Filter([{operator: "pm-with", operand: emails}]);
const active_filter = new Filter([{operator: "dm", operand: emails}]);
narrow_state.set_current_filter(active_filter);
}
@ -102,7 +102,7 @@ test("get_conversations", ({override}) => {
is_zero: false,
recipients: "Me Myself",
unread: 1,
url: "#narrow/pm-with/103-Me-Myself",
url: "#narrow/dm/103-Me-Myself",
user_circle_class: "user_circle_empty",
user_ids_string: "103",
status_emoji_info: {
@ -115,7 +115,7 @@ test("get_conversations", ({override}) => {
unread: 1,
is_zero: false,
is_active: false,
url: "#narrow/pm-with/101,102-group",
url: "#narrow/dm/101,102-group",
user_circle_class: undefined,
is_group: true,
status_emoji_info: undefined,
@ -153,7 +153,7 @@ test("get_conversations bot", ({override}) => {
unread: 1,
is_zero: false,
is_active: false,
url: "#narrow/pm-with/314-Outgoing-webhook",
url: "#narrow/dm/314-Outgoing-webhook",
status_emoji_info: undefined,
user_circle_class: "user_circle_green",
is_group: false,
@ -164,7 +164,7 @@ test("get_conversations bot", ({override}) => {
unread: 1,
is_zero: false,
is_active: false,
url: "#narrow/pm-with/101,102-group",
url: "#narrow/dm/101,102-group",
user_circle_class: undefined,
status_emoji_info: undefined,
is_group: true,

View File

@ -176,7 +176,7 @@ test_ui("sender_hover", ({override, mock_template}) => {
user_type: $t({defaultMessage: "Member"}),
user_circle_class: "user_circle_empty",
user_last_seen_time_status: "translated: Active more than 2 weeks ago",
pm_with_url: "#narrow/pm-with/42-Alice-Smith",
pm_with_url: "#narrow/dm/42-Alice-Smith",
sent_by_url: "#narrow/sender/42-Alice-Smith",
private_message_class: "respond_personal_button",
show_manage_menu: true,

View File

@ -166,11 +166,11 @@ test("initialize", ({mock_template}) => {
},
],
[
"pm-with:zo",
"dm:zo",
{
description_html: "direct messages with",
is_person: true,
search_string: "pm-with:user7@zulipdev.com",
search_string: "dm:user7@zulipdev.com",
user_pill_context: {
display_value: "<strong>Zo</strong>e",
has_image: true,
@ -203,7 +203,7 @@ test("initialize", ({mock_template}) => {
},
],
]),
strings: ["zo", "sender:zo", "pm-with:zo", "group-pm-with:zo"],
strings: ["zo", "sender:zo", "dm:zo", "group-pm-with:zo"],
};
/* Test source */

View File

@ -148,11 +148,11 @@ run_test("initialize", ({mock_template}) => {
},
],
[
"pm-with:zo",
"dm:zo",
{
description_html: "direct messages with",
is_person: true,
search_string: "pm-with:user7@zulipdev.com",
search_string: "dm:user7@zulipdev.com",
user_pill_context: {
display_value: "<strong>Zo</strong>e",
has_image: true,
@ -185,7 +185,7 @@ run_test("initialize", ({mock_template}) => {
},
],
]),
strings: ["zo", "sender:zo", "pm-with:zo", "group-pm-with:zo"],
strings: ["zo", "sender:zo", "dm:zo", "group-pm-with:zo"],
};
/* Test source */

View File

@ -112,16 +112,16 @@ test("subset_suggestions", () => {
assert.deepEqual(suggestions.strings, expected);
});
test("dm_suggestions", () => {
test("dm_suggestions", ({override}) => {
let query = "is:dm";
let suggestions = get_suggestions("", query);
let expected = [
"is:dm",
"pm-with:alice@zulip.com",
"pm-with:bob@zulip.com",
"pm-with:jeff@zulip.com",
"pm-with:myself@zulip.com",
"pm-with:ted@zulip.com",
"dm:alice@zulip.com",
"dm:bob@zulip.com",
"dm:jeff@zulip.com",
"dm:myself@zulip.com",
"dm:ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
@ -132,7 +132,7 @@ test("dm_suggestions", () => {
"al",
"is:alerted",
"sender:alice@zulip.com",
"pm-with:alice@zulip.com",
"dm:alice@zulip.com",
"group-pm-with:alice@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
@ -150,19 +150,19 @@ test("dm_suggestions", () => {
expected = ["is:dm"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:t";
query = "dm:t";
suggestions = get_suggestions("", query);
expected = ["pm-with:t", "pm-with:ted@zulip.com"];
expected = ["dm:t", "dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:t";
query = "-dm:t";
suggestions = get_suggestions("", query);
expected = ["-pm-with:t", "is:dm -pm-with:ted@zulip.com"];
expected = ["-dm:t", "is:dm -dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:ted@zulip.com";
query = "dm:ted@zulip.com";
suggestions = get_suggestions("", query);
expected = ["pm-with:ted@zulip.com"];
expected = ["dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:ted";
@ -200,7 +200,7 @@ test("dm_suggestions", () => {
assert.deepEqual(suggestions.strings, expected);
query = "near:3";
base_query = "pm-with:ted@zulip.com";
base_query = "dm:ted@zulip.com";
suggestions = get_suggestions(base_query, query);
expected = ["near:3"];
assert.deepEqual(suggestions.strings, expected);
@ -219,16 +219,16 @@ test("dm_suggestions", () => {
"al",
"is:alerted",
"sender:alice@zulip.com",
"pm-with:alice@zulip.com",
"dm:alice@zulip.com",
"group-pm-with:alice@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// Make sure it handles past context correctly
query = "pm-with:";
query = "dm:";
base_query = "stream:Denmark";
suggestions = get_suggestions(base_query, query);
expected = ["pm-with:"];
expected = ["dm:"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:";
@ -236,85 +236,111 @@ test("dm_suggestions", () => {
suggestions = get_suggestions(base_query, query);
expected = ["sender:"];
assert.deepEqual(suggestions.strings, expected);
// "pm-with" operator returns search result
// and "dm" operator as a suggestions
override(narrow_state, "stream", () => undefined);
query = "pm-with";
suggestions = get_suggestions("", query);
expected = ["pm-with", "dm:"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:t";
suggestions = get_suggestions("", query);
expected = ["pm-with:t", "dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
});
test("group_suggestions", () => {
// Entering a comma in a pm-with query should immediately generate
// Entering a comma in a dm query should immediately generate
// suggestions for the next person.
let query = "pm-with:bob@zulip.com,";
let query = "dm:bob@zulip.com,";
let suggestions = get_suggestions("", query);
let expected = [
"pm-with:bob@zulip.com,",
"pm-with:bob@zulip.com,alice@zulip.com",
"pm-with:bob@zulip.com,jeff@zulip.com",
"pm-with:bob@zulip.com,ted@zulip.com",
"dm:bob@zulip.com,",
"dm:bob@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// Only the last part of a comma-separated pm-with query should be used to
// Only the last part of a comma-separated dm query should be used to
// generate suggestions.
query = "pm-with:bob@zulip.com,t";
query = "dm:bob@zulip.com,t";
suggestions = get_suggestions("", query);
expected = ["pm-with:bob@zulip.com,t", "pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["dm:bob@zulip.com,t", "dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
// Smit should also generate ted@zulip.com (Ted Smith) as a suggestion.
query = "pm-with:bob@zulip.com,Smit";
query = "dm:bob@zulip.com,Smit";
suggestions = get_suggestions("", query);
expected = ["pm-with:bob@zulip.com,Smit", "pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["dm:bob@zulip.com,Smit", "dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
// Do not suggest "myself@zulip.com" (the name of the current user)
query = "pm-with:ted@zulip.com,mys";
query = "dm:ted@zulip.com,mys";
suggestions = get_suggestions("", query);
expected = ["pm-with:ted@zulip.com,mys"];
expected = ["dm:ted@zulip.com,mys"];
assert.deepEqual(suggestions.strings, expected);
// No superfluous suggestions should be generated.
query = "pm-with:bob@zulip.com,red";
query = "dm:bob@zulip.com,red";
suggestions = get_suggestions("", query);
expected = ["pm-with:bob@zulip.com,red"];
expected = ["dm:bob@zulip.com,red"];
assert.deepEqual(suggestions.strings, expected);
// is:dm should be properly prepended to each suggestion if the pm-with
// operator is negated.
// "is:dm" should be properly prepended to each suggestion
// if the "dm" operator is negated.
query = "-pm-with:bob@zulip.com,";
query = "-dm:bob@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"-pm-with:bob@zulip.com,",
"is:dm -pm-with:bob@zulip.com,alice@zulip.com",
"is:dm -pm-with:bob@zulip.com,jeff@zulip.com",
"is:dm -pm-with:bob@zulip.com,ted@zulip.com",
"-dm:bob@zulip.com,",
"is:dm -dm:bob@zulip.com,alice@zulip.com",
"is:dm -dm:bob@zulip.com,jeff@zulip.com",
"is:dm -dm:bob@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:bob@zulip.com,t";
query = "-dm:bob@zulip.com,t";
suggestions = get_suggestions("", query);
expected = ["-pm-with:bob@zulip.com,t", "is:dm -pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["-dm:bob@zulip.com,t", "is:dm -dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:bob@zulip.com,Smit";
query = "-dm:bob@zulip.com,Smit";
suggestions = get_suggestions("", query);
expected = ["-pm-with:bob@zulip.com,Smit", "is:dm -pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["-dm:bob@zulip.com,Smit", "is:dm -dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:bob@zulip.com,red";
query = "-dm:bob@zulip.com,red";
suggestions = get_suggestions("", query);
expected = ["-pm-with:bob@zulip.com,red"];
expected = ["-dm:bob@zulip.com,red"];
assert.deepEqual(suggestions.strings, expected);
// If user types "pm-with" operator, an email and a comma,
// show suggestions for group direct messages with the "dm"
// operator.
query = "pm-with:bob@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:bob@zulip.com,",
"dm:bob@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// Test multiple operators
query = "pm-with:bob@zulip.com,Smit";
query = "dm:bob@zulip.com,Smit";
let base_query = "is:starred has:link";
suggestions = get_suggestions(base_query, query);
expected = ["pm-with:bob@zulip.com,Smit", "pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["dm:bob@zulip.com,Smit", "dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:bob@zulip.com,Smit";
query = "dm:bob@zulip.com,Smit";
base_query = "stream:Denmark has:link";
suggestions = get_suggestions(base_query, query);
expected = ["pm-with:bob@zulip.com,Smit"];
expected = ["dm:bob@zulip.com,Smit"];
assert.deepEqual(suggestions.strings, expected);
function message(user_ids, timestamp) {
@ -332,42 +358,45 @@ test("group_suggestions", () => {
message([bob.user_id, ted.user_id, jeff.user_id], 98),
]);
// Simulate a past huddle which should now prioritize ted over alice
query = "pm-with:bob@zulip.com,";
// Simulate a past group direct message which should now
// prioritize ted over alice
query = "dm:bob@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:bob@zulip.com,",
"pm-with:bob@zulip.com,ted@zulip.com",
"pm-with:bob@zulip.com,alice@zulip.com",
"pm-with:bob@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,",
"dm:bob@zulip.com,ted@zulip.com",
"dm:bob@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,jeff@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// bob,ted,jeff is already an existing huddle, so prioritize this one
query = "pm-with:bob@zulip.com,ted@zulip.com,";
// bob, ted, and jeff are already an existing group direct message,
// so prioritize this one
query = "dm:bob@zulip.com,ted@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:bob@zulip.com,ted@zulip.com,",
"pm-with:bob@zulip.com,ted@zulip.com,jeff@zulip.com",
"pm-with:bob@zulip.com,ted@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,ted@zulip.com,",
"dm:bob@zulip.com,ted@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,ted@zulip.com,alice@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// bob,ted,jeff is already an existing huddle, but if we start with just jeff,
// then don't prioritize ted over alice because it doesn't complete the full huddle.
query = "pm-with:jeff@zulip.com,";
// bob, ted, and jeff are already an existing group direct message,
// but if we start with just jeff, then don't prioritize ted over
// alice because it doesn't complete the full group direct message.
query = "dm:jeff@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:jeff@zulip.com,",
"pm-with:jeff@zulip.com,alice@zulip.com",
"pm-with:jeff@zulip.com,bob@zulip.com",
"pm-with:jeff@zulip.com,ted@zulip.com",
"dm:jeff@zulip.com,",
"dm:jeff@zulip.com,alice@zulip.com",
"dm:jeff@zulip.com,bob@zulip.com",
"dm:jeff@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:jeff@zulip.com,ted@zulip.com hi";
query = "dm:jeff@zulip.com,ted@zulip.com hi";
suggestions = get_suggestions("", query);
expected = ["pm-with:jeff@zulip.com,ted@zulip.com hi"];
expected = ["dm:jeff@zulip.com,ted@zulip.com hi"];
assert.deepEqual(suggestions.strings, expected);
});
@ -486,7 +515,7 @@ test("check_is_suggestions", ({override}) => {
"is:unread",
"is:resolved",
"sender:alice@zulip.com",
"pm-with:alice@zulip.com",
"dm:alice@zulip.com",
"group-pm-with:alice@zulip.com",
"has:image",
];
@ -678,12 +707,7 @@ test("topic_suggestions", ({override}) => {
stream_data.add_sub({stream_id: office_id, name: "office", subscribed: true});
suggestions = get_suggestions("", "te");
expected = [
"te",
"sender:ted@zulip.com",
"pm-with:ted@zulip.com",
"group-pm-with:ted@zulip.com",
];
expected = ["te", "sender:ted@zulip.com", "dm:ted@zulip.com", "group-pm-with:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
stream_topic_history.add_message({
@ -702,7 +726,7 @@ test("topic_suggestions", ({override}) => {
expected = [
"te",
"sender:ted@zulip.com",
"pm-with:ted@zulip.com",
"dm:ted@zulip.com",
"group-pm-with:ted@zulip.com",
"stream:office topic:team",
"stream:office topic:test",
@ -856,8 +880,8 @@ test("people_suggestions", ({override}) => {
"te",
"sender:bob@zulip.com",
"sender:ted@zulip.com",
"pm-with:bob@zulip.com", // bob térry
"pm-with:ted@zulip.com",
"dm:bob@zulip.com", // bob térry
"dm:ted@zulip.com",
"group-pm-with:bob@zulip.com",
"group-pm-with:ted@zulip.com",
];
@ -865,17 +889,17 @@ test("people_suggestions", ({override}) => {
assert.deepEqual(suggestions.strings, expected);
const is_person = (q) => suggestions.lookup_table.get(q).is_person;
assert.equal(is_person("pm-with:ted@zulip.com"), true);
assert.equal(is_person("dm:ted@zulip.com"), true);
assert.equal(is_person("sender:ted@zulip.com"), true);
assert.equal(is_person("group-pm-with:ted@zulip.com"), true);
const has_image = (q) => suggestions.lookup_table.get(q).user_pill_context.has_image;
assert.equal(has_image("pm-with:bob@zulip.com"), true);
assert.equal(has_image("dm:bob@zulip.com"), true);
assert.equal(has_image("sender:bob@zulip.com"), true);
assert.equal(has_image("group-pm-with:bob@zulip.com"), true);
const describe = (q) => suggestions.lookup_table.get(q).description_html;
assert.equal(describe("pm-with:ted@zulip.com"), "Direct messages with");
assert.equal(describe("dm:ted@zulip.com"), "Direct messages with");
assert.equal(describe("sender:ted@zulip.com"), "Sent by");
assert.equal(describe("group-pm-with:ted@zulip.com"), "Group direct messages including");
@ -884,23 +908,18 @@ test("people_suggestions", ({override}) => {
const get_full_name = (q) =>
suggestions.lookup_table.get(q).user_pill_context.display_value.string;
assert.equal(get_full_name("sender:ted@zulip.com"), expectedString);
assert.equal(get_full_name("pm-with:ted@zulip.com"), expectedString);
assert.equal(get_full_name("dm:ted@zulip.com"), expectedString);
assert.equal(get_full_name("group-pm-with:ted@zulip.com"), expectedString);
expectedString = `${example_avatar_url}?s=50`;
const get_avatar_url = (q) => suggestions.lookup_table.get(q).user_pill_context.img_src;
assert.equal(get_avatar_url("pm-with:bob@zulip.com"), expectedString);
assert.equal(get_avatar_url("dm:bob@zulip.com"), expectedString);
assert.equal(get_avatar_url("sender:bob@zulip.com"), expectedString);
assert.equal(get_avatar_url("group-pm-with:bob@zulip.com"), expectedString);
suggestions = get_suggestions("", "Ted "); // note space
expected = [
"Ted",
"sender:ted@zulip.com",
"pm-with:ted@zulip.com",
"group-pm-with:ted@zulip.com",
];
expected = ["Ted", "sender:ted@zulip.com", "dm:ted@zulip.com", "group-pm-with:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
@ -993,7 +1012,7 @@ test("multiple_operators_without_pills", () => {
"is:dm al",
"is:dm is:alerted",
"is:dm sender:alice@zulip.com",
"is:dm pm-with:alice@zulip.com",
"is:dm dm:alice@zulip.com",
"is:dm group-pm-with:alice@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);

View File

@ -114,16 +114,16 @@ test("subset_suggestions", () => {
assert.deepEqual(suggestions.strings, expected);
});
test("dm_suggestions", () => {
test("dm_suggestions", ({override}) => {
let query = "is:dm";
let suggestions = get_suggestions("", query);
let expected = [
"is:dm",
"pm-with:alice@zulip.com",
"pm-with:bob@zulip.com",
"pm-with:jeff@zulip.com",
"pm-with:myself@zulip.com",
"pm-with:ted@zulip.com",
"dm:alice@zulip.com",
"dm:bob@zulip.com",
"dm:jeff@zulip.com",
"dm:myself@zulip.com",
"dm:ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
@ -133,7 +133,7 @@ test("dm_suggestions", () => {
"is:dm al",
"is:dm is:alerted",
"is:dm sender:alice@zulip.com",
"is:dm pm-with:alice@zulip.com",
"is:dm dm:alice@zulip.com",
"is:dm group-pm-with:alice@zulip.com",
"is:dm",
];
@ -152,19 +152,19 @@ test("dm_suggestions", () => {
expected = ["is:dm"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:t";
query = "dm:t";
suggestions = get_suggestions("", query);
expected = ["pm-with:t", "pm-with:ted@zulip.com"];
expected = ["dm:t", "dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:t";
query = "-dm:t";
suggestions = get_suggestions("", query);
expected = ["-pm-with:t", "is:dm -pm-with:ted@zulip.com"];
expected = ["-dm:t", "is:dm -dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:ted@zulip.com";
query = "dm:ted@zulip.com";
suggestions = get_suggestions("", query);
expected = ["pm-with:ted@zulip.com"];
expected = ["dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:ted";
@ -199,9 +199,9 @@ test("dm_suggestions", () => {
expected = ["is:dm near:3", "is:dm"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:ted@zulip.com near:3";
query = "dm:ted@zulip.com near:3";
suggestions = get_suggestions("", query);
expected = ["pm-with:ted@zulip.com near:3", "pm-with:ted@zulip.com"];
expected = ["dm:ted@zulip.com near:3", "dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
// Make sure suggestions still work if preceding tokens
@ -216,7 +216,7 @@ test("dm_suggestions", () => {
"is:starred has:link is:dm al",
"is:starred has:link is:dm is:alerted",
"is:starred has:link is:dm sender:alice@zulip.com",
"is:starred has:link is:dm pm-with:alice@zulip.com",
"is:starred has:link is:dm dm:alice@zulip.com",
"is:starred has:link is:dm group-pm-with:alice@zulip.com",
"is:starred has:link is:dm",
"is:starred has:link",
@ -225,98 +225,124 @@ test("dm_suggestions", () => {
assert.deepEqual(suggestions.strings, expected);
// Make sure it handles past context correctly
query = "stream:Denmark pm-with:";
query = "stream:Denmark dm:";
suggestions = get_suggestions("", query);
expected = ["stream:Denmark pm-with:", "stream:Denmark"];
expected = ["stream:Denmark dm:", "stream:Denmark"];
assert.deepEqual(suggestions.strings, expected);
query = "sender:ted@zulip.com sender:";
suggestions = get_suggestions("", query);
expected = ["sender:ted@zulip.com sender:", "sender:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
// "pm-with" operator returns search result
// and "dm" operator as a suggestions
override(narrow_state, "stream", () => undefined);
query = "pm-with";
suggestions = get_suggestions("", query);
expected = ["pm-with", "dm:"];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:t";
suggestions = get_suggestions("", query);
expected = ["pm-with:t", "dm:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
});
test("group_suggestions", () => {
// Entering a comma in a pm-with query should immediately generate
// suggestions for the next person.
let query = "pm-with:bob@zulip.com,";
// Entering a comma in a "dm:" query should immediately
// generate suggestions for the next person.
let query = "dm:bob@zulip.com,";
let suggestions = get_suggestions("", query);
let expected = [
"pm-with:bob@zulip.com,",
"pm-with:bob@zulip.com,alice@zulip.com",
"pm-with:bob@zulip.com,jeff@zulip.com",
"pm-with:bob@zulip.com,ted@zulip.com",
"dm:bob@zulip.com,",
"dm:bob@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// Only the last part of a comma-separated pm-with query should be used to
// generate suggestions.
query = "pm-with:bob@zulip.com,t";
// Only the last part of a comma-separated "dm" query
// should be used to generate suggestions.
query = "dm:bob@zulip.com,t";
suggestions = get_suggestions("", query);
expected = ["pm-with:bob@zulip.com,t", "pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["dm:bob@zulip.com,t", "dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
// Smit should also generate ted@zulip.com (Ted Smith) as a suggestion.
query = "pm-with:bob@zulip.com,Smit";
query = "dm:bob@zulip.com,Smit";
suggestions = get_suggestions("", query);
expected = ["pm-with:bob@zulip.com,Smit", "pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["dm:bob@zulip.com,Smit", "dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
// Do not suggest "myself@zulip.com" (the name of the current user)
query = "pm-with:ted@zulip.com,my";
query = "dm:ted@zulip.com,my";
suggestions = get_suggestions("", query);
expected = ["pm-with:ted@zulip.com,my"];
expected = ["dm:ted@zulip.com,my"];
assert.deepEqual(suggestions.strings, expected);
// No superfluous suggestions should be generated.
query = "pm-with:bob@zulip.com,red";
query = "dm:bob@zulip.com,red";
suggestions = get_suggestions("", query);
expected = ["pm-with:bob@zulip.com,red"];
expected = ["dm:bob@zulip.com,red"];
assert.deepEqual(suggestions.strings, expected);
// is:dm should be properly prepended to each suggestion if the pm-with
// operator is negated.
// "is:dm" should be properly prepended to each suggestion
// if the "dm" operator is negated.
query = "-pm-with:bob@zulip.com,";
query = "-dm:bob@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"-pm-with:bob@zulip.com,",
"is:dm -pm-with:bob@zulip.com,alice@zulip.com",
"is:dm -pm-with:bob@zulip.com,jeff@zulip.com",
"is:dm -pm-with:bob@zulip.com,ted@zulip.com",
"-dm:bob@zulip.com,",
"is:dm -dm:bob@zulip.com,alice@zulip.com",
"is:dm -dm:bob@zulip.com,jeff@zulip.com",
"is:dm -dm:bob@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:bob@zulip.com,t";
query = "-dm:bob@zulip.com,t";
suggestions = get_suggestions("", query);
expected = ["-pm-with:bob@zulip.com,t", "is:dm -pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["-dm:bob@zulip.com,t", "is:dm -dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:bob@zulip.com,Smit";
query = "-dm:bob@zulip.com,Smit";
suggestions = get_suggestions("", query);
expected = ["-pm-with:bob@zulip.com,Smit", "is:dm -pm-with:bob@zulip.com,ted@zulip.com"];
expected = ["-dm:bob@zulip.com,Smit", "is:dm -dm:bob@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
query = "-pm-with:bob@zulip.com,red";
query = "-dm:bob@zulip.com,red";
suggestions = get_suggestions("", query);
expected = ["-pm-with:bob@zulip.com,red"];
expected = ["-dm:bob@zulip.com,red"];
assert.deepEqual(suggestions.strings, expected);
// If user types "pm-with" operator, an email and a comma,
// show suggestions for group direct messages with the "dm"
// operator.
query = "pm-with:bob@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:bob@zulip.com,",
"dm:bob@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// Test multiple operators
query = "is:starred has:link pm-with:bob@zulip.com,Smit";
query = "is:starred has:link dm:bob@zulip.com,Smit";
suggestions = get_suggestions("", query);
expected = [
"is:starred has:link pm-with:bob@zulip.com,Smit",
"is:starred has:link pm-with:bob@zulip.com,ted@zulip.com",
"is:starred has:link dm:bob@zulip.com,Smit",
"is:starred has:link dm:bob@zulip.com,ted@zulip.com",
"is:starred has:link",
"is:starred",
];
assert.deepEqual(suggestions.strings, expected);
query = "stream:Denmark has:link pm-with:bob@zulip.com,Smit";
query = "stream:Denmark has:link dm:bob@zulip.com,Smit";
suggestions = get_suggestions("", query);
expected = [
"stream:Denmark has:link pm-with:bob@zulip.com,Smit",
"stream:Denmark has:link dm:bob@zulip.com,Smit",
"stream:Denmark has:link",
"stream:Denmark",
];
@ -337,42 +363,45 @@ test("group_suggestions", () => {
message([bob.user_id, ted.user_id, jeff.user_id], 98),
]);
// Simulate a past huddle which should now prioritize ted over alice
query = "pm-with:bob@zulip.com,";
// Simulate a past group direct message which should now
// prioritize ted over alice
query = "dm:bob@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:bob@zulip.com,",
"pm-with:bob@zulip.com,ted@zulip.com",
"pm-with:bob@zulip.com,alice@zulip.com",
"pm-with:bob@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,",
"dm:bob@zulip.com,ted@zulip.com",
"dm:bob@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,jeff@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// bob,ted,jeff is already an existing huddle, so prioritize this one
query = "pm-with:bob@zulip.com,ted@zulip.com,";
// bob, ted, and jeff are already an existing group direct message,
// so prioritize this one
query = "dm:bob@zulip.com,ted@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:bob@zulip.com,ted@zulip.com,",
"pm-with:bob@zulip.com,ted@zulip.com,jeff@zulip.com",
"pm-with:bob@zulip.com,ted@zulip.com,alice@zulip.com",
"dm:bob@zulip.com,ted@zulip.com,",
"dm:bob@zulip.com,ted@zulip.com,jeff@zulip.com",
"dm:bob@zulip.com,ted@zulip.com,alice@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
// bob,ted,jeff is already an existing huddle, but if we start with just jeff,
// then don't prioritize ted over alice because it doesn't complete the full huddle.
query = "pm-with:jeff@zulip.com,";
// bob, ted, and jeff are already an existing group direct message,
// but if we start with just jeff, then don't prioritize ted over
// alice because it doesn't complete the full group direct message.
query = "dm:jeff@zulip.com,";
suggestions = get_suggestions("", query);
expected = [
"pm-with:jeff@zulip.com,",
"pm-with:jeff@zulip.com,alice@zulip.com",
"pm-with:jeff@zulip.com,bob@zulip.com",
"pm-with:jeff@zulip.com,ted@zulip.com",
"dm:jeff@zulip.com,",
"dm:jeff@zulip.com,alice@zulip.com",
"dm:jeff@zulip.com,bob@zulip.com",
"dm:jeff@zulip.com,ted@zulip.com",
];
assert.deepEqual(suggestions.strings, expected);
query = "pm-with:jeff@zulip.com,ted@zulip.com hi";
query = "dm:jeff@zulip.com,ted@zulip.com hi";
suggestions = get_suggestions("", query);
expected = ["pm-with:jeff@zulip.com,ted@zulip.com hi", "pm-with:jeff@zulip.com,ted@zulip.com"];
expected = ["dm:jeff@zulip.com,ted@zulip.com hi", "dm:jeff@zulip.com,ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
});
@ -494,7 +523,7 @@ test("check_is_suggestions", ({override}) => {
"is:unread",
"is:resolved",
"sender:alice@zulip.com",
"pm-with:alice@zulip.com",
"dm:alice@zulip.com",
"group-pm-with:alice@zulip.com",
"has:image",
];
@ -645,12 +674,7 @@ test("topic_suggestions", ({override}) => {
stream_data.add_sub({stream_id: office_id, name: "office", subscribed: true});
suggestions = get_suggestions("", "te");
expected = [
"te",
"sender:ted@zulip.com",
"pm-with:ted@zulip.com",
"group-pm-with:ted@zulip.com",
];
expected = ["te", "sender:ted@zulip.com", "dm:ted@zulip.com", "group-pm-with:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);
stream_topic_history.add_message({
@ -669,7 +693,7 @@ test("topic_suggestions", ({override}) => {
expected = [
"te",
"sender:ted@zulip.com",
"pm-with:ted@zulip.com",
"dm:ted@zulip.com",
"group-pm-with:ted@zulip.com",
"stream:office topic:team",
"stream:office topic:test",
@ -828,8 +852,8 @@ test("people_suggestions", ({override}) => {
"te",
"sender:bob@zulip.com",
"sender:ted@zulip.com",
"pm-with:bob@zulip.com", // bob térry
"pm-with:ted@zulip.com",
"dm:bob@zulip.com", // bob térry
"dm:ted@zulip.com",
"group-pm-with:bob@zulip.com",
"group-pm-with:ted@zulip.com",
];
@ -839,21 +863,21 @@ test("people_suggestions", ({override}) => {
function is_person(q) {
return suggestions.lookup_table.get(q).is_person;
}
assert.equal(is_person("pm-with:ted@zulip.com"), true);
assert.equal(is_person("dm:ted@zulip.com"), true);
assert.equal(is_person("sender:ted@zulip.com"), true);
assert.equal(is_person("group-pm-with:ted@zulip.com"), true);
function has_image(q) {
return suggestions.lookup_table.get(q).user_pill_context.has_image;
}
assert.equal(has_image("pm-with:bob@zulip.com"), true);
assert.equal(has_image("dm:bob@zulip.com"), true);
assert.equal(has_image("sender:bob@zulip.com"), true);
assert.equal(has_image("group-pm-with:bob@zulip.com"), true);
function describe(q) {
return suggestions.lookup_table.get(q).description_html;
}
assert.equal(describe("pm-with:ted@zulip.com"), "Direct messages with");
assert.equal(describe("dm:ted@zulip.com"), "Direct messages with");
assert.equal(describe("sender:ted@zulip.com"), "Sent by");
assert.equal(describe("group-pm-with:ted@zulip.com"), "Group direct messages including");
@ -863,7 +887,7 @@ test("people_suggestions", ({override}) => {
return suggestions.lookup_table.get(q).user_pill_context.display_value.string;
}
assert.equal(get_full_name("sender:ted@zulip.com"), expectedString);
assert.equal(get_full_name("pm-with:ted@zulip.com"), expectedString);
assert.equal(get_full_name("dm:ted@zulip.com"), expectedString);
assert.equal(get_full_name("group-pm-with:ted@zulip.com"), expectedString);
expectedString = example_avatar_url + "?s=50";
@ -871,18 +895,13 @@ test("people_suggestions", ({override}) => {
function get_avatar_url(q) {
return suggestions.lookup_table.get(q).user_pill_context.img_src;
}
assert.equal(get_avatar_url("pm-with:bob@zulip.com"), expectedString);
assert.equal(get_avatar_url("dm:bob@zulip.com"), expectedString);
assert.equal(get_avatar_url("sender:bob@zulip.com"), expectedString);
assert.equal(get_avatar_url("group-pm-with:bob@zulip.com"), expectedString);
suggestions = get_suggestions("", "Ted "); // note space
expected = [
"Ted",
"sender:ted@zulip.com",
"pm-with:ted@zulip.com",
"group-pm-with:ted@zulip.com",
];
expected = ["Ted", "sender:ted@zulip.com", "dm:ted@zulip.com", "group-pm-with:ted@zulip.com"];
assert.deepEqual(suggestions.strings, expected);

View File

@ -46,7 +46,7 @@ run_test("render_notifications_for_narrow", ({override, mock_template}) => {
override(page_params, "user_id", anna.user_id);
const group = [anna.user_id, vronsky.user_id, levin.user_id, kitty.user_id];
const group_emails = `${anna.email},${vronsky.email},${levin.email},${kitty.email}`;
narrow_state.set_current_filter(new Filter([{operator: "pm-with", operand: group_emails}]));
narrow_state.set_current_filter(new Filter([{operator: "dm", operand: group_emails}]));
const $typing_notifications = $("#typing_notifications");