mirror of https://github.com/zulip/zulip.git
typeahead: Nest User inside UserPillData, UserOrMention.
Commit33484e7ac3
(#29200) added a cache for remove_diacritics, but this caching was rendered ineffective by commit45e9c046d8
(#29650) because it relied on mutating a direct reference to the User object. Fix the cache by rearranging the types to preserve that direct reference. Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
2340855851
commit
aaf90a1da0
|
@ -206,10 +206,10 @@ export function warn_if_mentioning_unsubscribed_user(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mentioned.is_broadcast) {
|
if (mentioned.type === "broadcast") {
|
||||||
return; // don't check if @all/@everyone/@stream
|
return; // don't check if @all/@everyone/@stream
|
||||||
}
|
}
|
||||||
const user_id = mentioned.user_id;
|
const user_id = mentioned.user.user_id;
|
||||||
|
|
||||||
const stream_id = get_stream_id_for_textarea($textarea);
|
const stream_id = get_stream_id_for_textarea($textarea);
|
||||||
if (!stream_id) {
|
if (!stream_id) {
|
||||||
|
@ -237,7 +237,7 @@ export function warn_if_mentioning_unsubscribed_user(
|
||||||
? $t({defaultMessage: "Subscribe them"})
|
? $t({defaultMessage: "Subscribe them"})
|
||||||
: null,
|
: null,
|
||||||
can_subscribe_other_users,
|
can_subscribe_other_users,
|
||||||
name: mentioned.full_name,
|
name: mentioned.user.full_name,
|
||||||
classname: compose_banner.CLASSNAMES.recipient_not_subscribed,
|
classname: compose_banner.CLASSNAMES.recipient_not_subscribed,
|
||||||
should_add_guest_user_indicator: people.should_add_guest_user_indicator(user_id),
|
should_add_guest_user_indicator: people.should_add_guest_user_indicator(user_id),
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,7 @@ import * as stream_topic_history from "./stream_topic_history";
|
||||||
import * as stream_topic_history_util from "./stream_topic_history_util";
|
import * as stream_topic_history_util from "./stream_topic_history_util";
|
||||||
import * as timerender from "./timerender";
|
import * as timerender from "./timerender";
|
||||||
import * as typeahead_helper from "./typeahead_helper";
|
import * as typeahead_helper from "./typeahead_helper";
|
||||||
import type {UserOrMention, UserOrMentionPillData} from "./typeahead_helper";
|
import type {UserOrMentionPillData} from "./typeahead_helper";
|
||||||
import type {UserGroupPillData} from "./user_group_pill";
|
import type {UserGroupPillData} from "./user_group_pill";
|
||||||
import * as user_groups from "./user_groups";
|
import * as user_groups from "./user_groups";
|
||||||
import type {UserGroup} from "./user_groups";
|
import type {UserGroup} from "./user_groups";
|
||||||
|
@ -493,7 +493,6 @@ export function broadcast_mentions(): PseudoMentionUser[] {
|
||||||
pm_recipient_count: Number.POSITIVE_INFINITY,
|
pm_recipient_count: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
full_name: mention,
|
full_name: mention,
|
||||||
is_broadcast: true,
|
|
||||||
|
|
||||||
// used for sorting
|
// used for sorting
|
||||||
idx,
|
idx,
|
||||||
|
@ -596,16 +595,9 @@ export function get_pm_people(query: string): (UserGroupPillData | UserPillData)
|
||||||
// to do this.
|
// to do this.
|
||||||
const user_suggestions: (UserGroupPillData | UserPillData)[] = [];
|
const user_suggestions: (UserGroupPillData | UserPillData)[] = [];
|
||||||
for (const suggestion of suggestions) {
|
for (const suggestion of suggestions) {
|
||||||
if (suggestion.type === "user_or_mention") {
|
assert(suggestion.type !== "broadcast");
|
||||||
assert(suggestion.is_broadcast === undefined);
|
|
||||||
user_suggestions.push({
|
|
||||||
...suggestion,
|
|
||||||
type: "user",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
user_suggestions.push(suggestion);
|
user_suggestions.push(suggestion);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return user_suggestions;
|
return user_suggestions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,18 +626,20 @@ export function get_person_suggestions(
|
||||||
}
|
}
|
||||||
// Exclude muted users from typeaheads.
|
// Exclude muted users from typeaheads.
|
||||||
persons = muted_users.filter_muted_users(persons);
|
persons = muted_users.filter_muted_users(persons);
|
||||||
let user_or_mention_list: UserOrMention[] = persons.map((person) => ({
|
let person_items: UserOrMentionPillData[] = persons.map((person) => ({
|
||||||
...person,
|
type: "user",
|
||||||
is_broadcast: undefined,
|
user: person,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (opts.want_broadcast) {
|
if (opts.want_broadcast) {
|
||||||
user_or_mention_list = [...user_or_mention_list, ...broadcast_mentions()];
|
person_items = [
|
||||||
|
...person_items,
|
||||||
|
...broadcast_mentions().map((mention) => ({
|
||||||
|
type: "broadcast" as const,
|
||||||
|
user: mention,
|
||||||
|
})),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
const person_items: UserOrMentionPillData[] = user_or_mention_list.map((person) => ({
|
|
||||||
...person,
|
|
||||||
type: "user_or_mention",
|
|
||||||
}));
|
|
||||||
|
|
||||||
return person_items.filter((item) => typeahead_helper.query_matches_person(query, item));
|
return person_items.filter((item) => typeahead_helper.query_matches_person(query, item));
|
||||||
}
|
}
|
||||||
|
@ -975,7 +969,8 @@ export function content_highlighter_html(item: TypeaheadSuggestion): string | un
|
||||||
case "emoji":
|
case "emoji":
|
||||||
return typeahead_helper.render_emoji(item);
|
return typeahead_helper.render_emoji(item);
|
||||||
case "user_group":
|
case "user_group":
|
||||||
case "user_or_mention":
|
case "user":
|
||||||
|
case "broadcast":
|
||||||
return typeahead_helper.render_person_or_user_group(item);
|
return typeahead_helper.render_person_or_user_group(item);
|
||||||
case "slash":
|
case "slash":
|
||||||
return typeahead_helper.render_typeahead_item({
|
return typeahead_helper.render_typeahead_item({
|
||||||
|
@ -1041,7 +1036,8 @@ export function content_typeahead_selected(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "user_group":
|
case "user_group":
|
||||||
case "user_or_mention": {
|
case "user":
|
||||||
|
case "broadcast": {
|
||||||
const is_silent = item.is_silent;
|
const is_silent = item.is_silent;
|
||||||
beginning = beginning.slice(0, -token.length - 1);
|
beginning = beginning.slice(0, -token.length - 1);
|
||||||
if (beginning.endsWith("@_*")) {
|
if (beginning.endsWith("@_*")) {
|
||||||
|
@ -1061,14 +1057,18 @@ export function content_typeahead_selected(
|
||||||
// that functionality yet, and we haven't gotten much
|
// that functionality yet, and we haven't gotten much
|
||||||
// feedback on this being an actual pitfall.
|
// feedback on this being an actual pitfall.
|
||||||
} else {
|
} else {
|
||||||
const user_id = item.is_broadcast ? undefined : item.user_id;
|
const user_id = item.type === "broadcast" ? undefined : item.user.user_id;
|
||||||
let mention_text = people.get_mention_syntax(item.full_name, user_id, is_silent);
|
let mention_text = people.get_mention_syntax(
|
||||||
if (!is_silent && !item.is_broadcast) {
|
item.user.full_name,
|
||||||
|
user_id,
|
||||||
|
is_silent,
|
||||||
|
);
|
||||||
|
if (!is_silent && item.type !== "broadcast") {
|
||||||
compose_validate.warn_if_mentioning_unsubscribed_user(item, $textbox);
|
compose_validate.warn_if_mentioning_unsubscribed_user(item, $textbox);
|
||||||
mention_text = compose_validate.convert_mentions_to_silent_in_direct_messages(
|
mention_text = compose_validate.convert_mentions_to_silent_in_direct_messages(
|
||||||
mention_text,
|
mention_text,
|
||||||
item.full_name,
|
item.user.full_name,
|
||||||
item.user_id,
|
item.user.user_id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
beginning += mention_text + " ";
|
beginning += mention_text + " ";
|
||||||
|
@ -1358,7 +1358,7 @@ export function initialize({
|
||||||
pill_widget.clear_text();
|
pill_widget.clear_text();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
compose_pm_pill.set_from_typeahead(item);
|
compose_pm_pill.set_from_typeahead(item.user);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
stopAdvance: true, // Do not advance to the next field on a Tab or Enter
|
stopAdvance: true, // Do not advance to the next field on a Tab or Enter
|
||||||
|
|
|
@ -69,7 +69,6 @@ export type PseudoMentionUser = {
|
||||||
email: string;
|
email: string;
|
||||||
pm_recipient_count: number;
|
pm_recipient_count: number;
|
||||||
full_name: string;
|
full_name: string;
|
||||||
is_broadcast: true;
|
|
||||||
idx: number;
|
idx: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,8 @@ import type {UserPillData} from "./user_pill";
|
||||||
|
|
||||||
function person_matcher(query: string, item: UserPillData): boolean {
|
function person_matcher(query: string, item: UserPillData): boolean {
|
||||||
return (
|
return (
|
||||||
people.is_known_user_id(item.user_id) && typeahead_helper.query_matches_person(query, item)
|
people.is_known_user_id(item.user.user_id) &&
|
||||||
|
typeahead_helper.query_matches_person(query, item)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +74,9 @@ export function set_up(
|
||||||
// If user_source is specified in opts, it
|
// If user_source is specified in opts, it
|
||||||
// is given priority. Otherwise we use
|
// is given priority. Otherwise we use
|
||||||
// default user_pill.typeahead_source.
|
// default user_pill.typeahead_source.
|
||||||
const users: UserPillData[] = opts.user_source().map((user) => ({
|
const users: UserPillData[] = opts
|
||||||
...user,
|
.user_source()
|
||||||
type: "user",
|
.map((user) => ({type: "user", user}));
|
||||||
}));
|
|
||||||
source = [...source, ...users];
|
source = [...source, ...users];
|
||||||
} else {
|
} else {
|
||||||
source = [...source, ...user_pill.typeahead_source(pills, exclude_bots)];
|
source = [...source, ...user_pill.typeahead_source(pills, exclude_bots)];
|
||||||
|
@ -132,7 +132,7 @@ export function set_up(
|
||||||
const users: UserPillData[] = [];
|
const users: UserPillData[] = [];
|
||||||
if (include_users) {
|
if (include_users) {
|
||||||
for (const match of matches) {
|
for (const match of matches) {
|
||||||
if (match.type === "user" && people.is_known_user_id(match.user_id)) {
|
if (match.type === "user" && people.is_known_user_id(match.user.user_id)) {
|
||||||
users.push(match);
|
users.push(match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,9 +164,9 @@ export function set_up(
|
||||||
} else if (
|
} else if (
|
||||||
include_users &&
|
include_users &&
|
||||||
item.type === "user" &&
|
item.type === "user" &&
|
||||||
people.is_known_user_id(item.user_id)
|
people.is_known_user_id(item.user.user_id)
|
||||||
) {
|
) {
|
||||||
user_pill.append_user(item, pills);
|
user_pill.append_user(item.user, pills);
|
||||||
}
|
}
|
||||||
|
|
||||||
$input.trigger("focus");
|
$input.trigger("focus");
|
||||||
|
|
|
@ -26,9 +26,10 @@ import * as user_status from "./user_status";
|
||||||
import type {UserStatusEmojiInfo} from "./user_status";
|
import type {UserStatusEmojiInfo} from "./user_status";
|
||||||
import * as util from "./util";
|
import * as util from "./util";
|
||||||
|
|
||||||
export type UserOrMention = PseudoMentionUser | (User & {is_broadcast: undefined});
|
export type UserOrMention =
|
||||||
|
| {type: "broadcast"; user: PseudoMentionUser}
|
||||||
|
| {type: "user"; user: User};
|
||||||
export type UserOrMentionPillData = UserOrMention & {
|
export type UserOrMentionPillData = UserOrMention & {
|
||||||
type: "user_or_mention";
|
|
||||||
is_silent?: boolean;
|
is_silent?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,32 +117,34 @@ export function render_typeahead_item(args: {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function render_person(person: UserPillData | UserOrMentionPillData): string {
|
export function render_person(person: UserPillData | UserOrMentionPillData): string {
|
||||||
if (person.type === "user_or_mention" && person.is_broadcast) {
|
if (person.type === "broadcast") {
|
||||||
return render_typeahead_item({
|
return render_typeahead_item({
|
||||||
primary: person.special_item_text,
|
primary: person.user.special_item_text,
|
||||||
is_person: true,
|
is_person: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const user_circle_class = buddy_data.get_user_circle_class(person.user_id);
|
const user_circle_class = buddy_data.get_user_circle_class(person.user.user_id);
|
||||||
|
|
||||||
const avatar_url = people.small_avatar_url_for_person(person);
|
const avatar_url = people.small_avatar_url_for_person(person.user);
|
||||||
|
|
||||||
const status_emoji_info = user_status.get_status_emoji(person.user_id);
|
const status_emoji_info = user_status.get_status_emoji(person.user.user_id);
|
||||||
|
|
||||||
const PRONOUNS_ID = realm.custom_profile_field_types.PRONOUNS.id;
|
const PRONOUNS_ID = realm.custom_profile_field_types.PRONOUNS.id;
|
||||||
const pronouns_list = people.get_custom_fields_by_type(person.user_id, PRONOUNS_ID);
|
const pronouns_list = people.get_custom_fields_by_type(person.user.user_id, PRONOUNS_ID);
|
||||||
|
|
||||||
const pronouns = pronouns_list?.[0]?.value;
|
const pronouns = pronouns_list?.[0]?.value;
|
||||||
|
|
||||||
const typeahead_arguments = {
|
const typeahead_arguments = {
|
||||||
primary: person.full_name,
|
primary: person.user.full_name,
|
||||||
img_src: avatar_url,
|
img_src: avatar_url,
|
||||||
user_circle_class,
|
user_circle_class,
|
||||||
is_person: true,
|
is_person: true,
|
||||||
status_emoji_info,
|
status_emoji_info,
|
||||||
should_add_guest_user_indicator: people.should_add_guest_user_indicator(person.user_id),
|
should_add_guest_user_indicator: people.should_add_guest_user_indicator(
|
||||||
|
person.user.user_id,
|
||||||
|
),
|
||||||
pronouns,
|
pronouns,
|
||||||
secondary: person.delivery_email,
|
secondary: person.user.delivery_email,
|
||||||
};
|
};
|
||||||
|
|
||||||
return render_typeahead_item(typeahead_arguments);
|
return render_typeahead_item(typeahead_arguments);
|
||||||
|
@ -249,43 +252,31 @@ export function compare_people_for_relevance(
|
||||||
current_stream_id?: number,
|
current_stream_id?: number,
|
||||||
): number {
|
): number {
|
||||||
// give preference to "all", "everyone" or "stream"
|
// give preference to "all", "everyone" or "stream"
|
||||||
// We use is_broadcast for a quick check. It will
|
|
||||||
// true for all/everyone/stream and undefined (falsy)
|
|
||||||
// for actual people.
|
|
||||||
const person_a_is_broadcast = person_a.type === "user_or_mention" && person_a.is_broadcast;
|
|
||||||
const person_b_is_broadcast = person_b.type === "user_or_mention" && person_b.is_broadcast;
|
|
||||||
if (compose_state.get_message_type() !== "private") {
|
if (compose_state.get_message_type() !== "private") {
|
||||||
if (person_a_is_broadcast) {
|
if (person_a.type === "broadcast") {
|
||||||
if (person_b_is_broadcast) {
|
if (person_b.type === "broadcast") {
|
||||||
return person_a.idx - person_b.idx;
|
return person_a.user.idx - person_b.user.idx;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
} else if (person_b_is_broadcast) {
|
} else if (person_b.type === "broadcast") {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (person_a_is_broadcast) {
|
if (person_a.type === "broadcast") {
|
||||||
if (person_b_is_broadcast) {
|
if (person_b.type === "broadcast") {
|
||||||
return person_a.idx - person_b.idx;
|
return person_a.user.idx - person_b.user.idx;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
} else if (person_b_is_broadcast) {
|
} else if (person_b.type === "broadcast") {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now handle actual people users.
|
// Now handle actual people users.
|
||||||
assert(
|
|
||||||
(person_a.type === "user_or_mention" && !person_a.is_broadcast) || person_a.type === "user",
|
|
||||||
);
|
|
||||||
assert(
|
|
||||||
(person_b.type === "user_or_mention" && !person_b.is_broadcast) || person_b.type === "user",
|
|
||||||
);
|
|
||||||
|
|
||||||
// give preference to subscribed users first
|
// give preference to subscribed users first
|
||||||
if (current_stream_id !== undefined) {
|
if (current_stream_id !== undefined) {
|
||||||
const a_is_sub = stream_data.is_user_subscribed(current_stream_id, person_a.user_id);
|
const a_is_sub = stream_data.is_user_subscribed(current_stream_id, person_a.user.user_id);
|
||||||
const b_is_sub = stream_data.is_user_subscribed(current_stream_id, person_b.user_id);
|
const b_is_sub = stream_data.is_user_subscribed(current_stream_id, person_b.user.user_id);
|
||||||
|
|
||||||
if (a_is_sub && !b_is_sub) {
|
if (a_is_sub && !b_is_sub) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -295,13 +286,13 @@ export function compare_people_for_relevance(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compare_by_current_conversation !== undefined) {
|
if (compare_by_current_conversation !== undefined) {
|
||||||
const preference = compare_by_current_conversation(person_a, person_b);
|
const preference = compare_by_current_conversation(person_a.user, person_b.user);
|
||||||
if (preference !== 0) {
|
if (preference !== 0) {
|
||||||
return preference;
|
return preference;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return compare_by_pms(person_a, person_b);
|
return compare_by_pms(person_a.user, person_b.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sort_people_for_relevance<UserType extends UserOrMentionPillData | UserPillData>(
|
export function sort_people_for_relevance<UserType extends UserOrMentionPillData | UserPillData>(
|
||||||
|
@ -444,7 +435,7 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
||||||
return sort_people_for_relevance(items, current_stream_id, current_topic);
|
return sort_people_for_relevance(items, current_stream_id, current_topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
const users_name_results = typeahead.triage_raw(query, users, (p) => p.full_name);
|
const users_name_results = typeahead.triage_raw(query, users, (p) => p.user.full_name);
|
||||||
const users_name_good_matches = [
|
const users_name_good_matches = [
|
||||||
...users_name_results.exact_matches,
|
...users_name_results.exact_matches,
|
||||||
...users_name_results.begins_with_case_sensitive_matches,
|
...users_name_results.begins_with_case_sensitive_matches,
|
||||||
|
@ -455,7 +446,7 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
||||||
const email_results = typeahead.triage_raw(
|
const email_results = typeahead.triage_raw(
|
||||||
query,
|
query,
|
||||||
users_name_results.no_matches,
|
users_name_results.no_matches,
|
||||||
(p) => p.email,
|
(p) => p.user.email,
|
||||||
);
|
);
|
||||||
const email_good_matches = [
|
const email_good_matches = [
|
||||||
...email_results.exact_matches,
|
...email_results.exact_matches,
|
||||||
|
@ -523,11 +514,13 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
||||||
|
|
||||||
function add_user_recipients(items: UserType[]): void {
|
function add_user_recipients(items: UserType[]): void {
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const item_is_broadcast = item.type === "user_or_mention" && item.is_broadcast;
|
if (
|
||||||
const topic_wildcard_mention = item.email === "topic";
|
item.type !== "broadcast" ||
|
||||||
if (!item_is_broadcast || topic_wildcard_mention || !stream_wildcard_mention_included) {
|
item.user.email === "topic" ||
|
||||||
|
!stream_wildcard_mention_included
|
||||||
|
) {
|
||||||
recipients.push(item);
|
recipients.push(item);
|
||||||
if (item_is_broadcast && !topic_wildcard_mention) {
|
if (item.type === "broadcast" && item.user.email !== "topic") {
|
||||||
stream_wildcard_mention_included = true;
|
stream_wildcard_mention_included = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -654,16 +647,13 @@ export function query_matches_person(
|
||||||
query: string,
|
query: string,
|
||||||
person: UserPillData | UserOrMentionPillData,
|
person: UserPillData | UserOrMentionPillData,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (typeahead.query_matches_string_in_order(query, person.full_name, " ")) {
|
if (typeahead.query_matches_string_in_order(query, person.user.full_name, " ")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (
|
if (person.type === "user" && Boolean(person.user.delivery_email)) {
|
||||||
(person.type === "user" || person.is_broadcast === undefined) &&
|
|
||||||
Boolean(person.delivery_email)
|
|
||||||
) {
|
|
||||||
return typeahead.query_matches_string_in_order(
|
return typeahead.query_matches_string_in_order(
|
||||||
query,
|
query,
|
||||||
people.get_visible_email(person),
|
people.get_visible_email(person.user),
|
||||||
" ",
|
" ",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export type UserPill = {
|
||||||
|
|
||||||
export type UserPillWidget = InputPillContainer<UserPill>;
|
export type UserPillWidget = InputPillContainer<UserPill>;
|
||||||
|
|
||||||
export type UserPillData = User & {type: "user"};
|
export type UserPillData = {type: "user"; user: User};
|
||||||
|
|
||||||
export function create_item_from_email(
|
export function create_item_from_email(
|
||||||
email: string,
|
email: string,
|
||||||
|
@ -136,10 +136,7 @@ export function typeahead_source(
|
||||||
exclude_bots?: boolean,
|
exclude_bots?: boolean,
|
||||||
): UserPillData[] {
|
): UserPillData[] {
|
||||||
const users = exclude_bots ? people.get_realm_active_human_users() : people.get_realm_users();
|
const users = exclude_bots ? people.get_realm_active_human_users() : people.get_realm_users();
|
||||||
return filter_taken_users(users, pill_widget).map((user) => ({
|
return filter_taken_users(users, pill_widget).map((user) => ({type: "user", user}));
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filter_taken_users(
|
export function filter_taken_users(
|
||||||
|
|
|
@ -666,7 +666,9 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
||||||
override(settings_data, "user_can_subscribe_other_users", () => true);
|
override(settings_data, "user_can_subscribe_other_users", () => true);
|
||||||
|
|
||||||
let mentioned_details = {
|
let mentioned_details = {
|
||||||
|
user: {
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_banner_rendered = false;
|
let new_banner_rendered = false;
|
||||||
|
@ -679,19 +681,19 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
||||||
return "<banner-stub>";
|
return "<banner-stub>";
|
||||||
});
|
});
|
||||||
|
|
||||||
function test_noop_case(is_private, is_zephyr_mirror, is_broadcast) {
|
function test_noop_case(is_private, is_zephyr_mirror, type) {
|
||||||
new_banner_rendered = false;
|
new_banner_rendered = false;
|
||||||
const msg_type = is_private ? "private" : "stream";
|
const msg_type = is_private ? "private" : "stream";
|
||||||
compose_state.set_message_type(msg_type);
|
compose_state.set_message_type(msg_type);
|
||||||
realm.realm_is_zephyr_mirror_realm = is_zephyr_mirror;
|
realm.realm_is_zephyr_mirror_realm = is_zephyr_mirror;
|
||||||
mentioned_details.is_broadcast = is_broadcast;
|
mentioned_details.type = type;
|
||||||
compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details, $textarea);
|
compose_validate.warn_if_mentioning_unsubscribed_user(mentioned_details, $textarea);
|
||||||
assert.ok(!new_banner_rendered);
|
assert.ok(!new_banner_rendered);
|
||||||
}
|
}
|
||||||
|
|
||||||
test_noop_case(true, false, false);
|
test_noop_case(true, false, "user");
|
||||||
test_noop_case(false, true, false);
|
test_noop_case(false, true, "user");
|
||||||
test_noop_case(false, false, true);
|
test_noop_case(false, false, "broadcast");
|
||||||
|
|
||||||
$("#compose_invite_users").hide();
|
$("#compose_invite_users").hide();
|
||||||
compose_state.set_message_type("stream");
|
compose_state.set_message_type("stream");
|
||||||
|
@ -717,11 +719,14 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
||||||
|
|
||||||
// Test mentioning a user that should gets a warning.
|
// Test mentioning a user that should gets a warning.
|
||||||
mentioned_details = {
|
mentioned_details = {
|
||||||
|
type: "user",
|
||||||
|
user: {
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
user_id: 34,
|
user_id: 34,
|
||||||
full_name: "Foo Barson",
|
full_name: "Foo Barson",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
people.add_active_user(mentioned_details);
|
people.add_active_user(mentioned_details.user);
|
||||||
|
|
||||||
new_banner_rendered = false;
|
new_banner_rendered = false;
|
||||||
const $banner_container = $("#compose_banners");
|
const $banner_container = $("#compose_banners");
|
||||||
|
|
|
@ -61,20 +61,12 @@ const ct = composebox_typeahead;
|
||||||
// broadcast-mentions/persons/groups.
|
// broadcast-mentions/persons/groups.
|
||||||
ct.__Rewire__("max_num_items", 15);
|
ct.__Rewire__("max_num_items", 15);
|
||||||
|
|
||||||
function user_or_mention_item(item) {
|
function user_item(user) {
|
||||||
return {
|
return {type: "user", user};
|
||||||
is_broadcast: undefined, // default, overridden by `item`
|
|
||||||
...item,
|
|
||||||
type: "user_or_mention",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_item(item) {
|
function broadcast_item(user) {
|
||||||
return {
|
return {type: "broadcast", user};
|
||||||
...item,
|
|
||||||
is_broadcast: undefined,
|
|
||||||
type: "user",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function slash_item(slash) {
|
function slash_item(slash) {
|
||||||
|
@ -333,90 +325,102 @@ function emoji_objects(emoji_names) {
|
||||||
return emoji_names.map((emoji_name) => emoji_list_by_name.get(emoji_name));
|
return emoji_names.map((emoji_name) => emoji_list_by_name.get(emoji_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
const ali = user_or_mention_item({
|
const ali = {
|
||||||
email: "ali@zulip.com",
|
email: "ali@zulip.com",
|
||||||
user_id: 98,
|
user_id: 98,
|
||||||
full_name: "Ali",
|
full_name: "Ali",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
});
|
};
|
||||||
|
const ali_item = user_item(ali);
|
||||||
|
|
||||||
const alice = user_or_mention_item({
|
const alice = {
|
||||||
email: "alice@zulip.com",
|
email: "alice@zulip.com",
|
||||||
user_id: 99,
|
user_id: 99,
|
||||||
full_name: "Alice",
|
full_name: "Alice",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
});
|
};
|
||||||
|
const alice_item = user_item(alice);
|
||||||
|
|
||||||
const hamlet = user_or_mention_item({
|
const hamlet = {
|
||||||
email: "hamlet@zulip.com",
|
email: "hamlet@zulip.com",
|
||||||
user_id: 100,
|
user_id: 100,
|
||||||
full_name: "King Hamlet",
|
full_name: "King Hamlet",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
});
|
};
|
||||||
|
const hamlet_item = user_item(hamlet);
|
||||||
|
|
||||||
const othello = user_or_mention_item({
|
const othello = {
|
||||||
email: "othello@zulip.com",
|
email: "othello@zulip.com",
|
||||||
user_id: 101,
|
user_id: 101,
|
||||||
full_name: "Othello, the Moor of Venice",
|
full_name: "Othello, the Moor of Venice",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
delivery_email: null,
|
delivery_email: null,
|
||||||
});
|
};
|
||||||
|
const othello_item = user_item(othello);
|
||||||
|
|
||||||
const cordelia = user_or_mention_item({
|
const cordelia = {
|
||||||
email: "cordelia@zulip.com",
|
email: "cordelia@zulip.com",
|
||||||
user_id: 102,
|
user_id: 102,
|
||||||
full_name: "Cordelia, Lear's daughter",
|
full_name: "Cordelia, Lear's daughter",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
});
|
};
|
||||||
|
const cordelia_item = user_item(cordelia);
|
||||||
|
|
||||||
const deactivated_user = user_or_mention_item({
|
const deactivated_user = {
|
||||||
email: "other@zulip.com",
|
email: "other@zulip.com",
|
||||||
user_id: 103,
|
user_id: 103,
|
||||||
full_name: "Deactivated User",
|
full_name: "Deactivated User",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
});
|
};
|
||||||
|
const deactivated_user_item = user_item(deactivated_user);
|
||||||
|
|
||||||
const lear = user_or_mention_item({
|
const lear = {
|
||||||
email: "lear@zulip.com",
|
email: "lear@zulip.com",
|
||||||
user_id: 104,
|
user_id: 104,
|
||||||
full_name: "King Lear",
|
full_name: "King Lear",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
});
|
};
|
||||||
|
const lear_item = user_item(lear);
|
||||||
|
|
||||||
const twin1 = user_or_mention_item({
|
const twin1 = {
|
||||||
full_name: "Mark Twin",
|
full_name: "Mark Twin",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
user_id: 105,
|
user_id: 105,
|
||||||
email: "twin1@zulip.com",
|
email: "twin1@zulip.com",
|
||||||
});
|
};
|
||||||
|
const twin1_item = user_item(twin1);
|
||||||
|
|
||||||
const twin2 = user_or_mention_item({
|
const twin2 = {
|
||||||
full_name: "Mark Twin",
|
full_name: "Mark Twin",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
user_id: 106,
|
user_id: 106,
|
||||||
email: "twin2@zulip.com",
|
email: "twin2@zulip.com",
|
||||||
});
|
};
|
||||||
|
const twin2_item = user_item(twin2);
|
||||||
|
|
||||||
const gael = user_or_mention_item({
|
const gael = {
|
||||||
full_name: "Gaël Twin",
|
full_name: "Gaël Twin",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
user_id: 107,
|
user_id: 107,
|
||||||
email: "twin3@zulip.com",
|
email: "twin3@zulip.com",
|
||||||
});
|
};
|
||||||
|
const gael_item = user_item(gael);
|
||||||
|
|
||||||
const hal = user_or_mention_item({
|
const hal = {
|
||||||
full_name: "Earl Hal",
|
full_name: "Earl Hal",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
user_id: 108,
|
user_id: 108,
|
||||||
email: "hal@zulip.com",
|
email: "hal@zulip.com",
|
||||||
});
|
};
|
||||||
|
const hal_item = user_item(hal);
|
||||||
|
|
||||||
const harry = user_or_mention_item({
|
const harry = {
|
||||||
full_name: "Harry",
|
full_name: "Harry",
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
user_id: 109,
|
user_id: 109,
|
||||||
email: "harry@zulip.com",
|
email: "harry@zulip.com",
|
||||||
});
|
};
|
||||||
|
const harry_item = user_item(harry);
|
||||||
|
|
||||||
const hamletcharacters = user_group_item({
|
const hamletcharacters = user_group_item({
|
||||||
name: "hamletcharacters",
|
name: "hamletcharacters",
|
||||||
|
@ -457,17 +461,17 @@ const make_emoji = (emoji_dict) => ({
|
||||||
|
|
||||||
// Sorted by name
|
// Sorted by name
|
||||||
const sorted_user_list = [
|
const sorted_user_list = [
|
||||||
ali,
|
ali_item,
|
||||||
alice,
|
alice_item,
|
||||||
cordelia,
|
cordelia_item,
|
||||||
hal, // Early Hal
|
hal_item, // Early Hal
|
||||||
gael,
|
gael_item,
|
||||||
harry,
|
harry_item,
|
||||||
hamlet, // King Hamlet
|
hamlet_item, // King Hamlet
|
||||||
lear,
|
lear_item,
|
||||||
twin1, // Mark Twin
|
twin1_item, // Mark Twin
|
||||||
twin2,
|
twin2_item,
|
||||||
othello,
|
othello_item,
|
||||||
];
|
];
|
||||||
|
|
||||||
function test(label, f) {
|
function test(label, f) {
|
||||||
|
@ -585,38 +589,38 @@ test("content_typeahead_selected", ({override}) => {
|
||||||
|
|
||||||
query = "@**Mark Tw";
|
query = "@**Mark Tw";
|
||||||
ct.get_or_set_token_for_testing("Mark Tw");
|
ct.get_or_set_token_for_testing("Mark Tw");
|
||||||
actual_value = ct.content_typeahead_selected(twin1, query, input_element);
|
actual_value = ct.content_typeahead_selected(twin1_item, query, input_element);
|
||||||
expected_value = "@**Mark Twin|105** ";
|
expected_value = "@**Mark Twin|105** ";
|
||||||
assert.equal(actual_value, expected_value);
|
assert.equal(actual_value, expected_value);
|
||||||
|
|
||||||
let warned_for_mention = false;
|
let warned_for_mention = false;
|
||||||
override(compose_validate, "warn_if_mentioning_unsubscribed_user", (mentioned) => {
|
override(compose_validate, "warn_if_mentioning_unsubscribed_user", (mentioned) => {
|
||||||
assert.equal(mentioned, othello);
|
assert.equal(mentioned, othello_item);
|
||||||
warned_for_mention = true;
|
warned_for_mention = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
query = "@oth";
|
query = "@oth";
|
||||||
ct.get_or_set_token_for_testing("oth");
|
ct.get_or_set_token_for_testing("oth");
|
||||||
actual_value = ct.content_typeahead_selected(othello, query, input_element);
|
actual_value = ct.content_typeahead_selected(othello_item, query, input_element);
|
||||||
expected_value = "@**Othello, the Moor of Venice** ";
|
expected_value = "@**Othello, the Moor of Venice** ";
|
||||||
assert.equal(actual_value, expected_value);
|
assert.equal(actual_value, expected_value);
|
||||||
assert.ok(warned_for_mention);
|
assert.ok(warned_for_mention);
|
||||||
|
|
||||||
query = "Hello @oth";
|
query = "Hello @oth";
|
||||||
ct.get_or_set_token_for_testing("oth");
|
ct.get_or_set_token_for_testing("oth");
|
||||||
actual_value = ct.content_typeahead_selected(othello, query, input_element);
|
actual_value = ct.content_typeahead_selected(othello_item, query, input_element);
|
||||||
expected_value = "Hello @**Othello, the Moor of Venice** ";
|
expected_value = "Hello @**Othello, the Moor of Venice** ";
|
||||||
assert.equal(actual_value, expected_value);
|
assert.equal(actual_value, expected_value);
|
||||||
|
|
||||||
query = "@**oth";
|
query = "@**oth";
|
||||||
ct.get_or_set_token_for_testing("oth");
|
ct.get_or_set_token_for_testing("oth");
|
||||||
actual_value = ct.content_typeahead_selected(othello, query, input_element);
|
actual_value = ct.content_typeahead_selected(othello_item, query, input_element);
|
||||||
expected_value = "@**Othello, the Moor of Venice** ";
|
expected_value = "@**Othello, the Moor of Venice** ";
|
||||||
assert.equal(actual_value, expected_value);
|
assert.equal(actual_value, expected_value);
|
||||||
|
|
||||||
query = "@*oth";
|
query = "@*oth";
|
||||||
ct.get_or_set_token_for_testing("oth");
|
ct.get_or_set_token_for_testing("oth");
|
||||||
actual_value = ct.content_typeahead_selected(othello, query, input_element);
|
actual_value = ct.content_typeahead_selected(othello_item, query, input_element);
|
||||||
expected_value = "@**Othello, the Moor of Venice** ";
|
expected_value = "@**Othello, the Moor of Venice** ";
|
||||||
assert.equal(actual_value, expected_value);
|
assert.equal(actual_value, expected_value);
|
||||||
|
|
||||||
|
@ -638,7 +642,7 @@ test("content_typeahead_selected", ({override}) => {
|
||||||
// silent mention
|
// silent mention
|
||||||
ct.get_or_set_completing_for_tests("silent_mention");
|
ct.get_or_set_completing_for_tests("silent_mention");
|
||||||
const silent_hamlet = {
|
const silent_hamlet = {
|
||||||
...hamlet,
|
...hamlet_item,
|
||||||
is_silent: true,
|
is_silent: true,
|
||||||
};
|
};
|
||||||
query = "@_kin";
|
query = "@_kin";
|
||||||
|
@ -944,23 +948,21 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
// This should match the users added at the beginning of this test file.
|
// This should match the users added at the beginning of this test file.
|
||||||
let actual_value = options.source("");
|
let actual_value = options.source("");
|
||||||
let expected_value = [
|
let expected_value = [
|
||||||
user_item(ali),
|
ali_item,
|
||||||
user_item(alice),
|
alice_item,
|
||||||
user_item(cordelia),
|
cordelia_item,
|
||||||
user_item(hal),
|
hal_item,
|
||||||
user_item(gael),
|
gael_item,
|
||||||
user_item(harry),
|
harry_item,
|
||||||
user_item(hamlet),
|
hamlet_item,
|
||||||
user_item(lear),
|
lear_item,
|
||||||
user_item(twin1),
|
twin1_item,
|
||||||
user_item(twin2),
|
twin2_item,
|
||||||
user_item(othello),
|
othello_item,
|
||||||
hamletcharacters,
|
hamletcharacters,
|
||||||
backend,
|
backend,
|
||||||
call_center,
|
call_center,
|
||||||
];
|
];
|
||||||
actual_value.sort((a, b) => a.user_id - b.user_id);
|
|
||||||
expected_value.sort((a, b) => a.user_id - b.user_id);
|
|
||||||
assert.deepEqual(actual_value, expected_value);
|
assert.deepEqual(actual_value, expected_value);
|
||||||
|
|
||||||
function matcher(query, person) {
|
function matcher(query, person) {
|
||||||
|
@ -970,46 +972,46 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
|
|
||||||
let query;
|
let query;
|
||||||
query = "el"; // Matches both "othELlo" and "cordELia"
|
query = "el"; // Matches both "othELlo" and "cordELia"
|
||||||
assert.equal(matcher(query, othello), true);
|
assert.equal(matcher(query, othello_item), true);
|
||||||
assert.equal(matcher(query, cordelia), true);
|
assert.equal(matcher(query, cordelia_item), true);
|
||||||
|
|
||||||
query = "bender"; // Doesn't exist
|
query = "bender"; // Doesn't exist
|
||||||
assert.equal(matcher(query, othello), false);
|
assert.equal(matcher(query, othello_item), false);
|
||||||
assert.equal(matcher(query, cordelia), false);
|
assert.equal(matcher(query, cordelia_item), false);
|
||||||
|
|
||||||
query = "gael";
|
query = "gael";
|
||||||
assert.equal(matcher(query, gael), true);
|
assert.equal(matcher(query, gael_item), true);
|
||||||
|
|
||||||
query = "Gaël";
|
query = "Gaël";
|
||||||
assert.equal(matcher(query, gael), true);
|
assert.equal(matcher(query, gael_item), true);
|
||||||
|
|
||||||
query = "gaël";
|
query = "gaël";
|
||||||
assert.equal(matcher(query, gael), true);
|
assert.equal(matcher(query, gael_item), true);
|
||||||
|
|
||||||
// Don't make suggestions if the last name only has whitespaces
|
// Don't make suggestions if the last name only has whitespaces
|
||||||
// (we're between typing names).
|
// (we're between typing names).
|
||||||
query = "othello@zulip.com, ";
|
query = "othello@zulip.com, ";
|
||||||
assert.equal(matcher(query, othello), false);
|
assert.equal(matcher(query, othello_item), false);
|
||||||
assert.equal(matcher(query, cordelia), false);
|
assert.equal(matcher(query, cordelia_item), false);
|
||||||
|
|
||||||
// query = 'othello@zulip.com,, , cord';
|
// query = 'othello@zulip.com,, , cord';
|
||||||
query = "cord";
|
query = "cord";
|
||||||
assert.equal(matcher(query, othello), false);
|
assert.equal(matcher(query, othello_item), false);
|
||||||
assert.equal(matcher(query, cordelia), true);
|
assert.equal(matcher(query, cordelia_item), true);
|
||||||
|
|
||||||
// If the user is already in the list, typeahead doesn't include it
|
// If the user is already in the list, typeahead doesn't include it
|
||||||
// again.
|
// again.
|
||||||
query = "cordelia@zulip.com, cord";
|
query = "cordelia@zulip.com, cord";
|
||||||
assert.equal(matcher(query, othello), false);
|
assert.equal(matcher(query, othello_item), false);
|
||||||
assert.equal(matcher(query, cordelia), false);
|
assert.equal(matcher(query, cordelia_item), false);
|
||||||
|
|
||||||
// Matching by email
|
// Matching by email
|
||||||
query = "oth";
|
query = "oth";
|
||||||
deactivated_user.delivery_email = null;
|
deactivated_user.delivery_email = null;
|
||||||
assert.equal(matcher(query, deactivated_user), false);
|
assert.equal(matcher(query, deactivated_user_item), false);
|
||||||
|
|
||||||
deactivated_user.delivery_email = "other@zulip.com";
|
deactivated_user.delivery_email = "other@zulip.com";
|
||||||
assert.equal(matcher(query, deactivated_user), true);
|
assert.equal(matcher(query, deactivated_user_item), true);
|
||||||
|
|
||||||
function sorter(query, people) {
|
function sorter(query, people) {
|
||||||
return typeahead_helper.sort_recipients({
|
return typeahead_helper.sort_recipients({
|
||||||
|
@ -1024,21 +1026,21 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
// beginning first, and then the rest of them in REVERSE order of
|
// beginning first, and then the rest of them in REVERSE order of
|
||||||
// the input.
|
// the input.
|
||||||
query = "othello";
|
query = "othello";
|
||||||
actual_value = sorter(query, [othello]);
|
actual_value = sorter(query, [othello_item]);
|
||||||
expected_value = [othello];
|
expected_value = [othello_item];
|
||||||
assert.deepEqual(actual_value, expected_value);
|
assert.deepEqual(actual_value, expected_value);
|
||||||
|
|
||||||
query = "Ali";
|
query = "Ali";
|
||||||
actual_value = sorter(query, [alice, ali]);
|
actual_value = sorter(query, [alice_item, ali_item]);
|
||||||
expected_value = [ali, alice];
|
expected_value = [ali_item, alice_item];
|
||||||
assert.deepEqual(actual_value, expected_value);
|
assert.deepEqual(actual_value, expected_value);
|
||||||
|
|
||||||
// A literal match at the beginning of an element puts it at the top.
|
// A literal match at the beginning of an element puts it at the top.
|
||||||
query = "co"; // Matches everything ("x@zulip.COm")
|
query = "co"; // Matches everything ("x@zulip.COm")
|
||||||
actual_value = sorter(query, [othello, deactivated_user, cordelia]);
|
actual_value = sorter(query, [othello_item, deactivated_user_item, cordelia_item]);
|
||||||
expected_value = [cordelia, deactivated_user, othello];
|
expected_value = [cordelia_item, deactivated_user_item, othello_item];
|
||||||
actual_value.sort((a, b) => a.user_id - b.user_id);
|
actual_value.sort((a, b) => a.user.user_id - b.user.user_id);
|
||||||
expected_value.sort((a, b) => a.user_id - b.user_id);
|
expected_value.sort((a, b) => a.user.user_id - b.user.user_id);
|
||||||
assert.deepEqual(actual_value, expected_value);
|
assert.deepEqual(actual_value, expected_value);
|
||||||
|
|
||||||
query = "non-existing-user";
|
query = "non-existing-user";
|
||||||
|
@ -1050,8 +1052,8 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
// if there wasn't any logic replacing `no break-space`
|
// if there wasn't any logic replacing `no break-space`
|
||||||
// with normal space.
|
// with normal space.
|
||||||
query = "cordelia, lear's\u00A0";
|
query = "cordelia, lear's\u00A0";
|
||||||
assert.equal(matcher(query, cordelia), true);
|
assert.equal(matcher(query, cordelia_item), true);
|
||||||
assert.equal(matcher(query, othello), false);
|
assert.equal(matcher(query, othello_item), false);
|
||||||
|
|
||||||
const event = {
|
const event = {
|
||||||
target: "#doesnotmatter",
|
target: "#doesnotmatter",
|
||||||
|
@ -1060,12 +1062,12 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
// options.updater()
|
// options.updater()
|
||||||
options.query = "othello";
|
options.query = "othello";
|
||||||
appended_names = [];
|
appended_names = [];
|
||||||
options.updater(othello, event);
|
options.updater(othello_item, event);
|
||||||
assert.deepEqual(appended_names, ["Othello, the Moor of Venice"]);
|
assert.deepEqual(appended_names, ["Othello, the Moor of Venice"]);
|
||||||
|
|
||||||
options.query = "othello@zulip.com, cor";
|
options.query = "othello@zulip.com, cor";
|
||||||
appended_names = [];
|
appended_names = [];
|
||||||
actual_value = options.updater(cordelia, event);
|
actual_value = options.updater(cordelia_item, event);
|
||||||
assert.deepEqual(appended_names, ["Cordelia, Lear's daughter"]);
|
assert.deepEqual(appended_names, ["Cordelia, Lear's daughter"]);
|
||||||
|
|
||||||
const click_event = {type: "click", target: "#doesnotmatter"};
|
const click_event = {type: "click", target: "#doesnotmatter"};
|
||||||
|
@ -1073,7 +1075,7 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
// Focus lost (caused by the click event in the typeahead list)
|
// Focus lost (caused by the click event in the typeahead list)
|
||||||
$("#private_message_recipient").trigger("blur");
|
$("#private_message_recipient").trigger("blur");
|
||||||
appended_names = [];
|
appended_names = [];
|
||||||
actual_value = options.updater(othello, click_event);
|
actual_value = options.updater(othello_item, click_event);
|
||||||
assert.deepEqual(appended_names, ["Othello, the Moor of Venice"]);
|
assert.deepEqual(appended_names, ["Othello, the Moor of Venice"]);
|
||||||
|
|
||||||
cleared = false;
|
cleared = false;
|
||||||
|
@ -1120,7 +1122,7 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
||||||
// content_highlighter_html.
|
// content_highlighter_html.
|
||||||
ct.get_or_set_completing_for_tests("mention");
|
ct.get_or_set_completing_for_tests("mention");
|
||||||
ct.get_or_set_token_for_testing("othello");
|
ct.get_or_set_token_for_testing("othello");
|
||||||
actual_value = options.highlighter_html(othello);
|
actual_value = options.highlighter_html(othello_item);
|
||||||
expected_value =
|
expected_value =
|
||||||
` <span class="user_circle_empty user_circle"></span>\n` +
|
` <span class="user_circle_empty user_circle"></span>\n` +
|
||||||
` <img class="typeahead-image" src="http://zulip.zulipdev.com/avatar/${othello.user_id}?s=50" />\n` +
|
` <img class="typeahead-image" src="http://zulip.zulipdev.com/avatar/${othello.user_id}?s=50" />\n` +
|
||||||
|
@ -1486,7 +1488,7 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const mention_all = user_or_mention_item(ct.broadcast_mentions()[0]);
|
const mention_all = broadcast_item(ct.broadcast_mentions()[0]);
|
||||||
const users_and_all_mention = [...sorted_user_list, mention_all];
|
const users_and_all_mention = [...sorted_user_list, mention_all];
|
||||||
const users_and_user_groups = [
|
const users_and_user_groups = [
|
||||||
...sorted_user_list,
|
...sorted_user_list,
|
||||||
|
@ -1495,7 +1497,7 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
||||||
backend,
|
backend,
|
||||||
call_center, // "folks working in support"
|
call_center, // "folks working in support"
|
||||||
];
|
];
|
||||||
const mention_everyone = user_or_mention_item(ct.broadcast_mentions()[1]);
|
const mention_everyone = broadcast_item(ct.broadcast_mentions()[1]);
|
||||||
function mentions_with_silent_marker(mentions, is_silent) {
|
function mentions_with_silent_marker(mentions, is_silent) {
|
||||||
return mentions.map((item) => ({
|
return mentions.map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
|
@ -1515,25 +1517,34 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
||||||
assert_typeahead_equals("@_**", mentions_with_silent_marker(users_and_user_groups, true));
|
assert_typeahead_equals("@_**", mentions_with_silent_marker(users_and_user_groups, true));
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test @**o",
|
"test @**o",
|
||||||
mentions_with_silent_marker([othello, cordelia, mention_everyone], false),
|
mentions_with_silent_marker([othello_item, cordelia_item, mention_everyone], false),
|
||||||
|
);
|
||||||
|
assert_typeahead_equals(
|
||||||
|
"test @_**o",
|
||||||
|
mentions_with_silent_marker([othello_item, cordelia_item], true),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals("test @_**o", mentions_with_silent_marker([othello, cordelia], true));
|
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test @*o",
|
"test @*o",
|
||||||
mentions_with_silent_marker([othello, cordelia, mention_everyone], false),
|
mentions_with_silent_marker([othello_item, cordelia_item, mention_everyone], false),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test @_*k",
|
"test @_*k",
|
||||||
mentions_with_silent_marker([hamlet, lear, twin1, twin2, backend], true),
|
mentions_with_silent_marker(
|
||||||
|
[hamlet_item, lear_item, twin1_item, twin2_item, backend],
|
||||||
|
true,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test @*h",
|
"test @*h",
|
||||||
mentions_with_silent_marker([harry, hal, hamlet, cordelia, othello], false),
|
mentions_with_silent_marker(
|
||||||
|
[harry_item, hal_item, hamlet_item, cordelia_item, othello_item],
|
||||||
|
false,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test @_*h",
|
"test @_*h",
|
||||||
mentions_with_silent_marker(
|
mentions_with_silent_marker(
|
||||||
[harry, hal, hamlet, hamletcharacters, cordelia, othello],
|
[harry_item, hal_item, hamlet_item, hamletcharacters, cordelia_item, othello_item],
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1550,28 +1561,69 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test\n@i",
|
"test\n@i",
|
||||||
mentions_with_silent_marker(
|
mentions_with_silent_marker(
|
||||||
[ali, alice, cordelia, gael, hamlet, lear, twin1, twin2, othello],
|
[
|
||||||
|
ali_item,
|
||||||
|
alice_item,
|
||||||
|
cordelia_item,
|
||||||
|
gael_item,
|
||||||
|
hamlet_item,
|
||||||
|
lear_item,
|
||||||
|
twin1_item,
|
||||||
|
twin2_item,
|
||||||
|
othello_item,
|
||||||
|
],
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test\n@_i",
|
"test\n@_i",
|
||||||
mentions_with_silent_marker(
|
mentions_with_silent_marker(
|
||||||
[ali, alice, cordelia, gael, hamlet, lear, twin1, twin2, othello],
|
[
|
||||||
|
ali_item,
|
||||||
|
alice_item,
|
||||||
|
cordelia_item,
|
||||||
|
gael_item,
|
||||||
|
hamlet_item,
|
||||||
|
lear_item,
|
||||||
|
twin1_item,
|
||||||
|
twin2_item,
|
||||||
|
othello_item,
|
||||||
|
],
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test\n @l",
|
"test\n @l",
|
||||||
mentions_with_silent_marker(
|
mentions_with_silent_marker(
|
||||||
[cordelia, lear, ali, alice, hal, gael, hamlet, othello, mention_all],
|
[
|
||||||
|
cordelia_item,
|
||||||
|
lear_item,
|
||||||
|
ali_item,
|
||||||
|
alice_item,
|
||||||
|
hal_item,
|
||||||
|
gael_item,
|
||||||
|
hamlet_item,
|
||||||
|
othello_item,
|
||||||
|
mention_all,
|
||||||
|
],
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test\n @_l",
|
"test\n @_l",
|
||||||
mentions_with_silent_marker(
|
mentions_with_silent_marker(
|
||||||
[cordelia, lear, ali, alice, hal, gael, hamlet, othello, hamletcharacters, call_center],
|
[
|
||||||
|
cordelia_item,
|
||||||
|
lear_item,
|
||||||
|
ali_item,
|
||||||
|
alice_item,
|
||||||
|
hal_item,
|
||||||
|
gael_item,
|
||||||
|
hamlet_item,
|
||||||
|
othello_item,
|
||||||
|
hamletcharacters,
|
||||||
|
call_center,
|
||||||
|
],
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -1583,9 +1635,12 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
||||||
assert_typeahead_equals(" @_zuli", []);
|
assert_typeahead_equals(" @_zuli", []);
|
||||||
assert_typeahead_equals(
|
assert_typeahead_equals(
|
||||||
"test @o",
|
"test @o",
|
||||||
mentions_with_silent_marker([othello, cordelia, mention_everyone], false),
|
mentions_with_silent_marker([othello_item, cordelia_item, mention_everyone], false),
|
||||||
|
);
|
||||||
|
assert_typeahead_equals(
|
||||||
|
"test @_o",
|
||||||
|
mentions_with_silent_marker([othello_item, cordelia_item], true),
|
||||||
);
|
);
|
||||||
assert_typeahead_equals("test @_o", mentions_with_silent_marker([othello, cordelia], true));
|
|
||||||
assert_typeahead_equals("test @z", []);
|
assert_typeahead_equals("test @z", []);
|
||||||
assert_typeahead_equals("test @_z", []);
|
assert_typeahead_equals("test @_z", []);
|
||||||
|
|
||||||
|
@ -1760,7 +1815,11 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
||||||
assert_typeahead_equals("~~~test", "ing", []);
|
assert_typeahead_equals("~~~test", "ing", []);
|
||||||
const terminal_symbols = ",.;?!()[]> \"'\n\t";
|
const terminal_symbols = ",.;?!()[]> \"'\n\t";
|
||||||
for (const symbol of terminal_symbols.split()) {
|
for (const symbol of terminal_symbols.split()) {
|
||||||
assert_typeahead_equals("@othello", symbol, mentions_with_silent_marker([othello], false));
|
assert_typeahead_equals(
|
||||||
|
"@othello",
|
||||||
|
symbol,
|
||||||
|
mentions_with_silent_marker([othello_item], false),
|
||||||
|
);
|
||||||
assert_typeahead_equals(":tada", symbol, emoji_objects(["tada"]));
|
assert_typeahead_equals(":tada", symbol, emoji_objects(["tada"]));
|
||||||
assert_typeahead_starts_with("```p", symbol, p_langs);
|
assert_typeahead_starts_with("```p", symbol, p_langs);
|
||||||
assert_typeahead_starts_with("~~~p", symbol, p_langs);
|
assert_typeahead_starts_with("~~~p", symbol, p_langs);
|
||||||
|
@ -1808,10 +1867,10 @@ test("content_highlighter_html", ({override_rewire}) => {
|
||||||
ct.get_or_set_completing_for_tests("mention");
|
ct.get_or_set_completing_for_tests("mention");
|
||||||
let th_render_person_called = false;
|
let th_render_person_called = false;
|
||||||
override_rewire(typeahead_helper, "render_person", (person) => {
|
override_rewire(typeahead_helper, "render_person", (person) => {
|
||||||
assert.deepEqual(person, othello);
|
assert.deepEqual(person, othello_item);
|
||||||
th_render_person_called = true;
|
th_render_person_called = true;
|
||||||
});
|
});
|
||||||
ct.content_highlighter_html(othello);
|
ct.content_highlighter_html(othello_item);
|
||||||
|
|
||||||
let th_render_user_group_called = false;
|
let th_render_user_group_called = false;
|
||||||
override_rewire(typeahead_helper, "render_user_group", (user_group) => {
|
override_rewire(typeahead_helper, "render_user_group", (user_group) => {
|
||||||
|
@ -1873,10 +1932,10 @@ test("filter_and_sort_mentions (normal)", () => {
|
||||||
current_user.user_id = 101;
|
current_user.user_id = 101;
|
||||||
let suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
let suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
||||||
|
|
||||||
const mention_all = user_or_mention_item(ct.broadcast_mentions()[0]);
|
const mention_all = broadcast_item(ct.broadcast_mentions()[0]);
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
suggestions,
|
suggestions,
|
||||||
possibly_silent_list([mention_all, ali, alice, hal, call_center], is_silent),
|
possibly_silent_list([mention_all, ali_item, alice_item, hal_item, call_center], is_silent),
|
||||||
);
|
);
|
||||||
|
|
||||||
// call_center group is shown in typeahead even when user is member of
|
// call_center group is shown in typeahead even when user is member of
|
||||||
|
@ -1885,7 +1944,7 @@ test("filter_and_sort_mentions (normal)", () => {
|
||||||
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
suggestions,
|
suggestions,
|
||||||
possibly_silent_list([mention_all, ali, alice, hal, call_center], is_silent),
|
possibly_silent_list([mention_all, ali_item, alice_item, hal_item, call_center], is_silent),
|
||||||
);
|
);
|
||||||
|
|
||||||
// call_center group is not shown in typeahead when user is neither
|
// call_center group is not shown in typeahead when user is neither
|
||||||
|
@ -1893,7 +1952,10 @@ test("filter_and_sort_mentions (normal)", () => {
|
||||||
// recursive subgroups.
|
// recursive subgroups.
|
||||||
current_user.user_id = 102;
|
current_user.user_id = 102;
|
||||||
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
||||||
assert.deepEqual(suggestions, possibly_silent_list([mention_all, ali, alice, hal], is_silent));
|
assert.deepEqual(
|
||||||
|
suggestions,
|
||||||
|
possibly_silent_list([mention_all, ali_item, alice_item, hal_item], is_silent),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("filter_and_sort_mentions (silent)", () => {
|
test("filter_and_sort_mentions (silent)", () => {
|
||||||
|
@ -1901,14 +1963,20 @@ test("filter_and_sort_mentions (silent)", () => {
|
||||||
|
|
||||||
let suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
let suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
||||||
|
|
||||||
assert.deepEqual(suggestions, possibly_silent_list([ali, alice, hal, call_center], is_silent));
|
assert.deepEqual(
|
||||||
|
suggestions,
|
||||||
|
possibly_silent_list([ali_item, alice_item, hal_item, call_center], is_silent),
|
||||||
|
);
|
||||||
|
|
||||||
// call_center group is shown in typeahead irrespective of whether
|
// call_center group is shown in typeahead irrespective of whether
|
||||||
// user is member of can_mention_group or its subgroups for a
|
// user is member of can_mention_group or its subgroups for a
|
||||||
// silent mention.
|
// silent mention.
|
||||||
current_user.user_id = 102;
|
current_user.user_id = 102;
|
||||||
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
||||||
assert.deepEqual(suggestions, possibly_silent_list([ali, alice, hal, call_center], is_silent));
|
assert.deepEqual(
|
||||||
|
suggestions,
|
||||||
|
possibly_silent_list([ali_item, alice_item, hal_item, call_center], is_silent),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("typeahead_results", () => {
|
test("typeahead_results", () => {
|
||||||
|
@ -2005,22 +2073,22 @@ test("typeahead_results", () => {
|
||||||
is_silent: false,
|
is_silent: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
assert_mentions_matches("cordelia", [not_silent(cordelia)]);
|
assert_mentions_matches("cordelia", [not_silent(cordelia_item)]);
|
||||||
assert_mentions_matches("cordelia, le", [not_silent(cordelia)]);
|
assert_mentions_matches("cordelia, le", [not_silent(cordelia_item)]);
|
||||||
assert_mentions_matches("cordelia, le ", []);
|
assert_mentions_matches("cordelia, le ", []);
|
||||||
assert_mentions_matches("moor", [not_silent(othello)]);
|
assert_mentions_matches("moor", [not_silent(othello_item)]);
|
||||||
assert_mentions_matches("moor ", [not_silent(othello)]);
|
assert_mentions_matches("moor ", [not_silent(othello_item)]);
|
||||||
assert_mentions_matches("moor of", [not_silent(othello)]);
|
assert_mentions_matches("moor of", [not_silent(othello_item)]);
|
||||||
assert_mentions_matches("moor of ven", [not_silent(othello)]);
|
assert_mentions_matches("moor of ven", [not_silent(othello_item)]);
|
||||||
assert_mentions_matches("oor", [not_silent(othello)]);
|
assert_mentions_matches("oor", [not_silent(othello_item)]);
|
||||||
assert_mentions_matches("oor ", []);
|
assert_mentions_matches("oor ", []);
|
||||||
assert_mentions_matches("oor o", []);
|
assert_mentions_matches("oor o", []);
|
||||||
assert_mentions_matches("oor of venice", []);
|
assert_mentions_matches("oor of venice", []);
|
||||||
assert_mentions_matches("King ", [not_silent(hamlet), not_silent(lear)]);
|
assert_mentions_matches("King ", [not_silent(hamlet_item), not_silent(lear_item)]);
|
||||||
assert_mentions_matches("King H", [not_silent(hamlet)]);
|
assert_mentions_matches("King H", [not_silent(hamlet_item)]);
|
||||||
assert_mentions_matches("King L", [not_silent(lear)]);
|
assert_mentions_matches("King L", [not_silent(lear_item)]);
|
||||||
assert_mentions_matches("delia lear", []);
|
assert_mentions_matches("delia lear", []);
|
||||||
assert_mentions_matches("Mark Tw", [not_silent(twin1), not_silent(twin2)]);
|
assert_mentions_matches("Mark Tw", [not_silent(twin1_item), not_silent(twin2_item)]);
|
||||||
|
|
||||||
// Earlier user group and stream mentions were autocompleted by their
|
// Earlier user group and stream mentions were autocompleted by their
|
||||||
// description too. This is now removed as it often led to unexpected
|
// description too. This is now removed as it often led to unexpected
|
||||||
|
@ -2034,31 +2102,31 @@ test("typeahead_results", () => {
|
||||||
|
|
||||||
// Verify we suggest only the first matching stream wildcard mention,
|
// Verify we suggest only the first matching stream wildcard mention,
|
||||||
// irrespective of how many equivalent stream wildcard mentions match.
|
// irrespective of how many equivalent stream wildcard mentions match.
|
||||||
const mention_everyone = not_silent(user_or_mention_item(ct.broadcast_mentions()[1]));
|
const mention_everyone = not_silent(broadcast_item(ct.broadcast_mentions()[1]));
|
||||||
// Here, we suggest only "everyone" instead of both the matching
|
// Here, we suggest only "everyone" instead of both the matching
|
||||||
// "everyone" and "stream" wildcard mentions.
|
// "everyone" and "stream" wildcard mentions.
|
||||||
assert_mentions_matches("e", [
|
assert_mentions_matches("e", [
|
||||||
not_silent(mention_everyone),
|
not_silent(mention_everyone),
|
||||||
not_silent(hal),
|
not_silent(hal_item),
|
||||||
not_silent(alice),
|
not_silent(alice_item),
|
||||||
not_silent(cordelia),
|
not_silent(cordelia_item),
|
||||||
not_silent(gael),
|
not_silent(gael_item),
|
||||||
not_silent(hamlet),
|
not_silent(hamlet_item),
|
||||||
not_silent(lear),
|
not_silent(lear_item),
|
||||||
not_silent(othello),
|
not_silent(othello_item),
|
||||||
not_silent(hamletcharacters),
|
not_silent(hamletcharacters),
|
||||||
not_silent(call_center),
|
not_silent(call_center),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Verify we suggest both 'the first matching stream wildcard' and
|
// Verify we suggest both 'the first matching stream wildcard' and
|
||||||
// 'topic wildcard' mentions. Not only one matching wildcard mention.
|
// 'topic wildcard' mentions. Not only one matching wildcard mention.
|
||||||
const mention_topic = user_or_mention_item(ct.broadcast_mentions()[4]);
|
const mention_topic = broadcast_item(ct.broadcast_mentions()[4]);
|
||||||
// Here, we suggest both "everyone" and "topic".
|
// Here, we suggest both "everyone" and "topic".
|
||||||
assert_mentions_matches("o", [
|
assert_mentions_matches("o", [
|
||||||
not_silent(othello),
|
not_silent(othello_item),
|
||||||
not_silent(mention_everyone),
|
not_silent(mention_everyone),
|
||||||
not_silent(mention_topic),
|
not_silent(mention_topic),
|
||||||
not_silent(cordelia),
|
not_silent(cordelia_item),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Autocomplete by slash commands.
|
// Autocomplete by slash commands.
|
||||||
|
@ -2101,20 +2169,20 @@ test("message people", ({override, override_rewire}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
results = ct.get_person_suggestions("Ha", opts);
|
results = ct.get_person_suggestions("Ha", opts);
|
||||||
assert.deepEqual(results, [harry, hal]);
|
assert.deepEqual(results, [harry_item, hal_item]);
|
||||||
|
|
||||||
// Now let's exclude Hal and include King Hamlet.
|
// Now let's exclude Hal and include King Hamlet.
|
||||||
user_ids = [hamlet.user_id, harry.user_id];
|
user_ids = [hamlet.user_id, harry.user_id];
|
||||||
|
|
||||||
results = ct.get_person_suggestions("Ha", opts);
|
results = ct.get_person_suggestions("Ha", opts);
|
||||||
assert.deepEqual(results, [harry, hamlet]);
|
assert.deepEqual(results, [harry_item, hamlet_item]);
|
||||||
|
|
||||||
// Reincluding Hal and deactivating harry
|
// Reincluding Hal and deactivating harry
|
||||||
user_ids = [hamlet.user_id, harry.user_id, hal.user_id];
|
user_ids = [hamlet.user_id, harry.user_id, hal.user_id];
|
||||||
people.deactivate(harry);
|
people.deactivate(harry);
|
||||||
results = ct.get_person_suggestions("Ha", opts);
|
results = ct.get_person_suggestions("Ha", opts);
|
||||||
// harry is excluded since it has been deactivated.
|
// harry is excluded since it has been deactivated.
|
||||||
assert.deepEqual(results, [hal, hamlet]);
|
assert.deepEqual(results, [hal_item, hamlet_item]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("muted users excluded from results", () => {
|
test("muted users excluded from results", () => {
|
||||||
|
@ -2127,7 +2195,7 @@ test("muted users excluded from results", () => {
|
||||||
|
|
||||||
// Nobody is muted
|
// Nobody is muted
|
||||||
results = ct.get_person_suggestions("corde", opts);
|
results = ct.get_person_suggestions("corde", opts);
|
||||||
assert.deepEqual(results, [cordelia]);
|
assert.deepEqual(results, [cordelia_item]);
|
||||||
|
|
||||||
// Mute Cordelia, and test that she's excluded from results.
|
// Mute Cordelia, and test that she's excluded from results.
|
||||||
muted_users.add_muted_user(cordelia.user_id);
|
muted_users.add_muted_user(cordelia.user_id);
|
||||||
|
@ -2137,7 +2205,7 @@ test("muted users excluded from results", () => {
|
||||||
// Make sure our muting logic doesn't break wildcard mentions
|
// Make sure our muting logic doesn't break wildcard mentions
|
||||||
// or user group mentions.
|
// or user group mentions.
|
||||||
results = ct.get_person_suggestions("all", opts);
|
results = ct.get_person_suggestions("all", opts);
|
||||||
const mention_all = user_or_mention_item(ct.broadcast_mentions()[0]);
|
const mention_all = broadcast_item(ct.broadcast_mentions()[0]);
|
||||||
assert.deepEqual(results, [mention_all, call_center]);
|
assert.deepEqual(results, [mention_all, call_center]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2163,12 +2231,12 @@ test("direct message recipients sorted according to stream / topic being viewed"
|
||||||
compose_state.set_stream_id("");
|
compose_state.set_stream_id("");
|
||||||
results = ct.get_pm_people("li");
|
results = ct.get_pm_people("li");
|
||||||
// `get_pm_people` can't return mentions, so the items are all user items.
|
// `get_pm_people` can't return mentions, so the items are all user items.
|
||||||
assert.deepEqual(results, [user_item(ali), user_item(alice), user_item(cordelia)]);
|
assert.deepEqual(results, [ali_item, alice_item, cordelia_item]);
|
||||||
|
|
||||||
// When viewing denmark stream, subscriber cordelia is placed higher
|
// When viewing denmark stream, subscriber cordelia is placed higher
|
||||||
compose_state.set_stream_id(denmark_stream.stream_id);
|
compose_state.set_stream_id(denmark_stream.stream_id);
|
||||||
results = ct.get_pm_people("li");
|
results = ct.get_pm_people("li");
|
||||||
assert.deepEqual(results, [user_item(cordelia), user_item(ali), user_item(alice)]);
|
assert.deepEqual(results, [cordelia_item, ali_item, alice_item]);
|
||||||
|
|
||||||
// Simulating just alice being subscribed to denmark.
|
// Simulating just alice being subscribed to denmark.
|
||||||
override_rewire(
|
override_rewire(
|
||||||
|
@ -2180,5 +2248,5 @@ test("direct message recipients sorted according to stream / topic being viewed"
|
||||||
// When viewing denmark stream to which alice is subscribed, ali is not
|
// When viewing denmark stream to which alice is subscribed, ali is not
|
||||||
// 1st despite having an exact name match with the query.
|
// 1st despite having an exact name match with the query.
|
||||||
results = ct.get_pm_people("ali");
|
results = ct.get_pm_people("ali");
|
||||||
assert.deepEqual(results, [user_item(alice), user_item(ali)]);
|
assert.deepEqual(results, [alice_item, ali_item]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -39,10 +39,7 @@ function override_typeahead_helper(override_rewire) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_item(user) {
|
function user_item(user) {
|
||||||
return {
|
return {type: "user", user};
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const jill = {
|
const jill = {
|
||||||
|
|
|
@ -27,23 +27,17 @@ let next_id = 0;
|
||||||
|
|
||||||
function assertSameEmails(lst1, lst2) {
|
function assertSameEmails(lst1, lst2) {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
lst1.map((r) => r.email),
|
lst1.map((r) => r.user.email),
|
||||||
lst2.map((r) => r.email),
|
lst2.map((r) => r.user.email),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_item(user) {
|
function user_item(user) {
|
||||||
return {
|
return {type: "user", user};
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function user_or_mention_item(user_or_mention) {
|
function broadcast_item(user) {
|
||||||
return {
|
return {type: "broadcast", user};
|
||||||
...user_or_mention,
|
|
||||||
type: "user_or_mention",
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const a_bot = {
|
const a_bot = {
|
||||||
|
@ -53,6 +47,7 @@ const a_bot = {
|
||||||
is_bot: true,
|
is_bot: true,
|
||||||
user_id: 1,
|
user_id: 1,
|
||||||
};
|
};
|
||||||
|
const a_bot_item = user_item(a_bot);
|
||||||
|
|
||||||
const a_user = {
|
const a_user = {
|
||||||
email: "a_user@zulip.org",
|
email: "a_user@zulip.org",
|
||||||
|
@ -61,6 +56,7 @@ const a_user = {
|
||||||
is_bot: false,
|
is_bot: false,
|
||||||
user_id: 2,
|
user_id: 2,
|
||||||
};
|
};
|
||||||
|
const a_user_item = user_item(a_user);
|
||||||
|
|
||||||
const b_user_1 = {
|
const b_user_1 = {
|
||||||
email: "b_user_1@zulip.net",
|
email: "b_user_1@zulip.net",
|
||||||
|
@ -78,6 +74,7 @@ const b_user_2 = {
|
||||||
is_bot: false,
|
is_bot: false,
|
||||||
user_id: 4,
|
user_id: 4,
|
||||||
};
|
};
|
||||||
|
const b_user_2_item = user_item(b_user_2);
|
||||||
|
|
||||||
const b_user_3 = {
|
const b_user_3 = {
|
||||||
email: "b_user_3@zulip.net",
|
email: "b_user_3@zulip.net",
|
||||||
|
@ -95,6 +92,7 @@ const b_bot = {
|
||||||
is_bot: true,
|
is_bot: true,
|
||||||
user_id: 6,
|
user_id: 6,
|
||||||
};
|
};
|
||||||
|
const b_bot_item = user_item(b_bot);
|
||||||
|
|
||||||
const zman = {
|
const zman = {
|
||||||
email: "zman@test.net",
|
email: "zman@test.net",
|
||||||
|
@ -361,17 +359,14 @@ test("sort_languages on actual data", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function get_typeahead_result(query, current_stream_id, current_topic) {
|
function get_typeahead_result(query, current_stream_id, current_topic) {
|
||||||
const users = people.get_realm_users().map((user) => ({
|
const users = people.get_realm_users().map((user) => ({type: "user", user}));
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
}));
|
|
||||||
const result = th.sort_recipients({
|
const result = th.sort_recipients({
|
||||||
users,
|
users,
|
||||||
query,
|
query,
|
||||||
current_stream_id,
|
current_stream_id,
|
||||||
current_topic,
|
current_topic,
|
||||||
});
|
});
|
||||||
return result.map((person) => person.email);
|
return result.map((person) => person.user.email);
|
||||||
}
|
}
|
||||||
|
|
||||||
test("sort_recipients", () => {
|
test("sort_recipients", () => {
|
||||||
|
@ -470,14 +465,13 @@ test("sort_recipients all mention", () => {
|
||||||
compose_state.set_message_type("stream");
|
compose_state.set_message_type("stream");
|
||||||
const all_obj = ct.broadcast_mentions()[0];
|
const all_obj = ct.broadcast_mentions()[0];
|
||||||
assert.equal(all_obj.email, "all");
|
assert.equal(all_obj.email, "all");
|
||||||
assert.equal(all_obj.is_broadcast, true);
|
|
||||||
assert.equal(all_obj.idx, 0);
|
assert.equal(all_obj.idx, 0);
|
||||||
|
|
||||||
// Test person email is "all" or "everyone"
|
// Test person email is "all" or "everyone"
|
||||||
const test_objs = [...matches, all_obj];
|
const user_and_mention_items = [
|
||||||
const user_and_mention_items = test_objs.map((user_or_mention) =>
|
...matches.map((user) => user_item(user)),
|
||||||
user_or_mention_item(user_or_mention),
|
broadcast_item(all_obj),
|
||||||
);
|
];
|
||||||
const results = th.sort_recipients({
|
const results = th.sort_recipients({
|
||||||
users: user_and_mention_items,
|
users: user_and_mention_items,
|
||||||
query: "a",
|
query: "a",
|
||||||
|
@ -485,7 +479,16 @@ test("sort_recipients all mention", () => {
|
||||||
current_topic: "Linux topic",
|
current_topic: "Linux topic",
|
||||||
});
|
});
|
||||||
|
|
||||||
assertSameEmails(results, [all_obj, a_user, a_bot, b_user_1, b_user_2, b_user_3, zman, b_bot]);
|
assertSameEmails(results, [
|
||||||
|
broadcast_item(all_obj),
|
||||||
|
a_user_item,
|
||||||
|
a_bot_item,
|
||||||
|
b_user_1_item,
|
||||||
|
b_user_2_item,
|
||||||
|
b_user_3_item,
|
||||||
|
zman_item,
|
||||||
|
b_bot_item,
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sort_recipients pm counts", () => {
|
test("sort_recipients pm counts", () => {
|
||||||
|
@ -538,17 +541,14 @@ test("sort_recipients pm counts", () => {
|
||||||
|
|
||||||
test("sort_recipients dup bots", () => {
|
test("sort_recipients dup bots", () => {
|
||||||
const dup_objects = [...matches, a_bot];
|
const dup_objects = [...matches, a_bot];
|
||||||
const user_items = dup_objects.map((user) => ({
|
const user_items = dup_objects.map((user) => user_item(user));
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
}));
|
|
||||||
const recipients = th.sort_recipients({
|
const recipients = th.sort_recipients({
|
||||||
users: user_items,
|
users: user_items,
|
||||||
query: "b",
|
query: "b",
|
||||||
current_stream_id: undefined,
|
current_stream_id: undefined,
|
||||||
current_topic: "",
|
current_topic: "",
|
||||||
});
|
});
|
||||||
const recipients_email = recipients.map((person) => person.email);
|
const recipients_email = recipients.map((person) => person.user.email);
|
||||||
const expected = [
|
const expected = [
|
||||||
"b_user_1@zulip.net",
|
"b_user_1@zulip.net",
|
||||||
"b_user_2@zulip.net",
|
"b_user_2@zulip.net",
|
||||||
|
@ -564,13 +564,10 @@ test("sort_recipients dup bots", () => {
|
||||||
|
|
||||||
test("sort_recipients dup alls", () => {
|
test("sort_recipients dup alls", () => {
|
||||||
compose_state.set_message_type("stream");
|
compose_state.set_message_type("stream");
|
||||||
const all_obj = ct.broadcast_mentions()[0];
|
const all_obj_item = broadcast_item(ct.broadcast_mentions()[0]);
|
||||||
|
|
||||||
// full_name starts with same character but emails are 'all'
|
// full_name starts with same character but emails are 'all'
|
||||||
const test_objs = [all_obj, a_user, all_obj];
|
const user_and_mention_items = [all_obj_item, a_user_item, all_obj_item];
|
||||||
const user_and_mention_items = test_objs.map((user_or_mention) =>
|
|
||||||
user_or_mention_item(user_or_mention),
|
|
||||||
);
|
|
||||||
const recipients = th.sort_recipients({
|
const recipients = th.sort_recipients({
|
||||||
users: user_and_mention_items,
|
users: user_and_mention_items,
|
||||||
query: "a",
|
query: "a",
|
||||||
|
@ -578,43 +575,36 @@ test("sort_recipients dup alls", () => {
|
||||||
current_topic: "Linux topic",
|
current_topic: "Linux topic",
|
||||||
});
|
});
|
||||||
|
|
||||||
const expected = [all_obj, a_user];
|
const expected = [all_obj_item, a_user_item];
|
||||||
assertSameEmails(recipients, expected);
|
assertSameEmails(recipients, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sort_recipients dup alls direct message", () => {
|
test("sort_recipients dup alls direct message", () => {
|
||||||
compose_state.set_message_type("private");
|
compose_state.set_message_type("private");
|
||||||
const all_obj = ct.broadcast_mentions()[0];
|
const all_obj_item = broadcast_item(ct.broadcast_mentions()[0]);
|
||||||
|
|
||||||
// full_name starts with same character but emails are 'all'
|
// full_name starts with same character but emails are 'all'
|
||||||
const test_objs = [all_obj, a_user, all_obj];
|
const user_and_mention_items = [all_obj_item, a_user_item, all_obj_item];
|
||||||
const user_and_mention_items = test_objs.map((user_or_mention) =>
|
|
||||||
user_or_mention_item(user_or_mention),
|
|
||||||
);
|
|
||||||
const recipients = th.sort_recipients({
|
const recipients = th.sort_recipients({
|
||||||
users: user_and_mention_items,
|
users: user_and_mention_items,
|
||||||
query: "a",
|
query: "a",
|
||||||
});
|
});
|
||||||
|
|
||||||
const expected = [a_user, all_obj];
|
const expected = [a_user_item, all_obj_item];
|
||||||
assertSameEmails(recipients, expected);
|
assertSameEmails(recipients, expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sort_recipients subscribers", () => {
|
test("sort_recipients subscribers", () => {
|
||||||
// b_user_2 is a subscriber and b_user_1 is not.
|
// b_user_2 is a subscriber and b_user_1 is not.
|
||||||
peer_data.add_subscriber(dev_sub.stream_id, b_user_2.user_id);
|
peer_data.add_subscriber(dev_sub.stream_id, b_user_2.user_id);
|
||||||
const small_matches = [b_user_2, b_user_1];
|
const user_items = [b_user_2_item, b_user_1_item];
|
||||||
const user_items = small_matches.map((user) => ({
|
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
}));
|
|
||||||
const recipients = th.sort_recipients({
|
const recipients = th.sort_recipients({
|
||||||
users: user_items,
|
users: user_items,
|
||||||
query: "b",
|
query: "b",
|
||||||
current_stream_id: dev_sub.stream_id,
|
current_stream_id: dev_sub.stream_id,
|
||||||
current_topic: "Dev topic",
|
current_topic: "Dev topic",
|
||||||
});
|
});
|
||||||
const recipients_email = recipients.map((person) => person.email);
|
const recipients_email = recipients.map((person) => person.user.email);
|
||||||
const expected = ["b_user_2@zulip.net", "b_user_1@zulip.net"];
|
const expected = ["b_user_2@zulip.net", "b_user_1@zulip.net"];
|
||||||
assert.deepEqual(recipients_email, expected);
|
assert.deepEqual(recipients_email, expected);
|
||||||
});
|
});
|
||||||
|
@ -622,7 +612,6 @@ test("sort_recipients subscribers", () => {
|
||||||
test("sort_recipients recent senders", () => {
|
test("sort_recipients recent senders", () => {
|
||||||
// b_user_2 is the only recent sender, b_user_3 is the only pm partner
|
// b_user_2 is the only recent sender, b_user_3 is the only pm partner
|
||||||
// and all are subscribed to the stream Linux.
|
// and all are subscribed to the stream Linux.
|
||||||
const small_matches = [b_user_1, b_user_2, b_user_3];
|
|
||||||
peer_data.add_subscriber(linux_sub.stream_id, b_user_1.user_id);
|
peer_data.add_subscriber(linux_sub.stream_id, b_user_1.user_id);
|
||||||
peer_data.add_subscriber(linux_sub.stream_id, b_user_2.user_id);
|
peer_data.add_subscriber(linux_sub.stream_id, b_user_2.user_id);
|
||||||
peer_data.add_subscriber(linux_sub.stream_id, b_user_3.user_id);
|
peer_data.add_subscriber(linux_sub.stream_id, b_user_3.user_id);
|
||||||
|
@ -633,17 +622,14 @@ test("sort_recipients recent senders", () => {
|
||||||
id: (next_id += 1),
|
id: (next_id += 1),
|
||||||
});
|
});
|
||||||
pm_conversations.set_partner(b_user_3.user_id);
|
pm_conversations.set_partner(b_user_3.user_id);
|
||||||
const user_items = small_matches.map((user) => ({
|
const user_items = [b_user_1_item, b_user_2_item, b_user_3_item];
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
}));
|
|
||||||
const recipients = th.sort_recipients({
|
const recipients = th.sort_recipients({
|
||||||
users: user_items,
|
users: user_items,
|
||||||
query: "b",
|
query: "b",
|
||||||
current_stream_id: linux_sub.stream_id,
|
current_stream_id: linux_sub.stream_id,
|
||||||
current_topic: "Linux topic",
|
current_topic: "Linux topic",
|
||||||
});
|
});
|
||||||
const recipients_email = recipients.map((person) => person.email);
|
const recipients_email = recipients.map((person) => person.user.email);
|
||||||
// Prefer recent sender over pm partner
|
// Prefer recent sender over pm partner
|
||||||
const expected = ["b_user_2@zulip.net", "b_user_3@zulip.net", "b_user_1@zulip.net"];
|
const expected = ["b_user_2@zulip.net", "b_user_3@zulip.net", "b_user_1@zulip.net"];
|
||||||
assert.deepEqual(recipients_email, expected);
|
assert.deepEqual(recipients_email, expected);
|
||||||
|
@ -653,18 +639,14 @@ test("sort_recipients pm partners", () => {
|
||||||
// b_user_3 is a pm partner and b_user_2 is not and
|
// b_user_3 is a pm partner and b_user_2 is not and
|
||||||
// both are not subscribed to the stream Linux.
|
// both are not subscribed to the stream Linux.
|
||||||
pm_conversations.set_partner(b_user_3.user_id);
|
pm_conversations.set_partner(b_user_3.user_id);
|
||||||
const small_matches = [b_user_3, b_user_2];
|
const user_items = [b_user_3_item, b_user_2_item];
|
||||||
const user_items = small_matches.map((user) => ({
|
|
||||||
...user,
|
|
||||||
type: "user",
|
|
||||||
}));
|
|
||||||
const recipients = th.sort_recipients({
|
const recipients = th.sort_recipients({
|
||||||
users: user_items,
|
users: user_items,
|
||||||
query: "b",
|
query: "b",
|
||||||
current_stream_id: linux_sub.stream_id,
|
current_stream_id: linux_sub.stream_id,
|
||||||
current_topic: "Linux topic",
|
current_topic: "Linux topic",
|
||||||
});
|
});
|
||||||
const recipients_email = recipients.map((person) => person.email);
|
const recipients_email = recipients.map((person) => person.user.email);
|
||||||
const expected = ["b_user_3@zulip.net", "b_user_2@zulip.net"];
|
const expected = ["b_user_3@zulip.net", "b_user_2@zulip.net"];
|
||||||
assert.deepEqual(recipients_email, expected);
|
assert.deepEqual(recipients_email, expected);
|
||||||
});
|
});
|
||||||
|
@ -676,27 +658,29 @@ test("sort broadcast mentions for stream message type", () => {
|
||||||
// randomly rearrange them)
|
// randomly rearrange them)
|
||||||
compose_state.set_message_type("stream");
|
compose_state.set_message_type("stream");
|
||||||
const mentions = ct.broadcast_mentions().reverse();
|
const mentions = ct.broadcast_mentions().reverse();
|
||||||
const mention_items = mentions.map((mention) => user_or_mention_item(mention));
|
const broadcast_items = mentions.map((broadcast) => broadcast_item(broadcast));
|
||||||
const results = th.sort_people_for_relevance(mention_items, "", "");
|
const results = th.sort_people_for_relevance(broadcast_items, "", "");
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
results.map((r) => r.email),
|
results.map((r) => r.user.email),
|
||||||
["all", "everyone", "stream", "channel", "topic"],
|
["all", "everyone", "stream", "channel", "topic"],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Reverse the list to test actual sorting
|
// Reverse the list to test actual sorting
|
||||||
// and ensure test coverage for the defensive
|
// and ensure test coverage for the defensive
|
||||||
// code. Also, add in some people users.
|
// code. Also, add in some people users.
|
||||||
const test_objs = [...ct.broadcast_mentions()].reverse();
|
const user_or_mention_items = [
|
||||||
test_objs.unshift(zman);
|
zman_item,
|
||||||
test_objs.push(a_user);
|
...ct
|
||||||
const user_or_mention_items = test_objs.map((user_or_mention) =>
|
.broadcast_mentions()
|
||||||
user_or_mention_item(user_or_mention),
|
.map((broadcast) => broadcast_item(broadcast))
|
||||||
);
|
.reverse(),
|
||||||
|
a_user_item,
|
||||||
|
];
|
||||||
const results2 = th.sort_people_for_relevance(user_or_mention_items, "", "");
|
const results2 = th.sort_people_for_relevance(user_or_mention_items, "", "");
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
results2.map((r) => r.email),
|
results2.map((r) => r.user.email),
|
||||||
["all", "everyone", "stream", "channel", "topic", a_user.email, zman.email],
|
["all", "everyone", "stream", "channel", "topic", a_user.email, zman.email],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -704,24 +688,26 @@ test("sort broadcast mentions for stream message type", () => {
|
||||||
test("sort broadcast mentions for direct message type", () => {
|
test("sort broadcast mentions for direct message type", () => {
|
||||||
compose_state.set_message_type("private");
|
compose_state.set_message_type("private");
|
||||||
const mentions = ct.broadcast_mentions().reverse();
|
const mentions = ct.broadcast_mentions().reverse();
|
||||||
const mention_items = mentions.map((mention) => user_or_mention_item(mention));
|
const broadcast_items = mentions.map((broadcast) => broadcast_item(broadcast));
|
||||||
const results = th.sort_people_for_relevance(mention_items, "", "");
|
const results = th.sort_people_for_relevance(broadcast_items, "", "");
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
results.map((r) => r.email),
|
results.map((r) => r.user.email),
|
||||||
["all", "everyone"],
|
["all", "everyone"],
|
||||||
);
|
);
|
||||||
|
|
||||||
const test_objs = [...ct.broadcast_mentions()].reverse();
|
const user_or_mention_items = [
|
||||||
test_objs.unshift(zman);
|
zman_item,
|
||||||
test_objs.push(a_user);
|
...ct
|
||||||
const user_or_mention_items = test_objs.map((user_or_mention) =>
|
.broadcast_mentions()
|
||||||
user_or_mention_item(user_or_mention),
|
.map((broadcast) => broadcast_item(broadcast))
|
||||||
);
|
.reverse(),
|
||||||
|
a_user_item,
|
||||||
|
];
|
||||||
const results2 = th.sort_people_for_relevance(user_or_mention_items, "", "");
|
const results2 = th.sort_people_for_relevance(user_or_mention_items, "", "");
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
results2.map((r) => r.email),
|
results2.map((r) => r.user.email),
|
||||||
[a_user.email, zman.email, "all", "everyone"],
|
[a_user.email, zman.email, "all", "everyone"],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -732,7 +718,7 @@ test("test compare directly for stream message type", () => {
|
||||||
// coverage is subject to the whims of how JS sorts.
|
// coverage is subject to the whims of how JS sorts.
|
||||||
compose_state.set_message_type("stream");
|
compose_state.set_message_type("stream");
|
||||||
const all_obj = ct.broadcast_mentions()[0];
|
const all_obj = ct.broadcast_mentions()[0];
|
||||||
const all_obj_item = user_or_mention_item(all_obj);
|
const all_obj_item = broadcast_item(all_obj);
|
||||||
|
|
||||||
assert.equal(th.compare_people_for_relevance(all_obj_item, all_obj_item), 0);
|
assert.equal(th.compare_people_for_relevance(all_obj_item, all_obj_item), 0);
|
||||||
assert.equal(th.compare_people_for_relevance(all_obj_item, zman_item), -1);
|
assert.equal(th.compare_people_for_relevance(all_obj_item, zman_item), -1);
|
||||||
|
@ -742,7 +728,7 @@ test("test compare directly for stream message type", () => {
|
||||||
test("test compare directly for direct message", () => {
|
test("test compare directly for direct message", () => {
|
||||||
compose_state.set_message_type("private");
|
compose_state.set_message_type("private");
|
||||||
const all_obj = ct.broadcast_mentions()[0];
|
const all_obj = ct.broadcast_mentions()[0];
|
||||||
const all_obj_item = user_or_mention_item(all_obj);
|
const all_obj_item = broadcast_item(all_obj);
|
||||||
|
|
||||||
assert.equal(th.compare_people_for_relevance(all_obj_item, all_obj_item), 0);
|
assert.equal(th.compare_people_for_relevance(all_obj_item, all_obj_item), 0);
|
||||||
assert.equal(th.compare_people_for_relevance(all_obj_item, zman_item), 1);
|
assert.equal(th.compare_people_for_relevance(all_obj_item, zman_item), 1);
|
||||||
|
@ -791,7 +777,7 @@ test("render_person when emails hidden", ({mock_template}) => {
|
||||||
rendered = true;
|
rendered = true;
|
||||||
return "typeahead-item-stub";
|
return "typeahead-item-stub";
|
||||||
});
|
});
|
||||||
assert.equal(th.render_person(b_user_1), "typeahead-item-stub");
|
assert.equal(th.render_person(b_user_1_item), "typeahead-item-stub");
|
||||||
assert.ok(rendered);
|
assert.ok(rendered);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -808,7 +794,7 @@ test("render_person", ({mock_template}) => {
|
||||||
rendered = true;
|
rendered = true;
|
||||||
return "typeahead-item-stub";
|
return "typeahead-item-stub";
|
||||||
});
|
});
|
||||||
assert.equal(th.render_person(a_user), "typeahead-item-stub");
|
assert.equal(th.render_person(a_user_item), "typeahead-item-stub");
|
||||||
assert.ok(rendered);
|
assert.ok(rendered);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -823,8 +809,6 @@ test("render_person special_item_text", ({mock_template}) => {
|
||||||
is_bot: false,
|
is_bot: false,
|
||||||
user_id: 7,
|
user_id: 7,
|
||||||
special_item_text: "special_text",
|
special_item_text: "special_text",
|
||||||
is_broadcast: true,
|
|
||||||
type: "user_or_mention",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
rendered = false;
|
rendered = false;
|
||||||
|
@ -833,7 +817,7 @@ test("render_person special_item_text", ({mock_template}) => {
|
||||||
rendered = true;
|
rendered = true;
|
||||||
return "typeahead-item-stub";
|
return "typeahead-item-stub";
|
||||||
});
|
});
|
||||||
assert.equal(th.render_person(special_person), "typeahead-item-stub");
|
assert.equal(th.render_person(broadcast_item(special_person)), "typeahead-item-stub");
|
||||||
assert.ok(rendered);
|
assert.ok(rendered);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -147,10 +147,5 @@ test("typeahead", () => {
|
||||||
// excluded by virtue of already being one of the widget items.
|
// excluded by virtue of already being one of the widget items.
|
||||||
// And then bogus_item is just a red herring to test robustness.
|
// And then bogus_item is just a red herring to test robustness.
|
||||||
const result = user_pill.typeahead_source(pill_widget);
|
const result = user_pill.typeahead_source(pill_widget);
|
||||||
assert.deepEqual(result, [
|
assert.deepEqual(result, [{type: "user", user: alice}]);
|
||||||
{
|
|
||||||
...alice,
|
|
||||||
type: "user",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue