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;
|
||||
}
|
||||
|
||||
if (mentioned.is_broadcast) {
|
||||
if (mentioned.type === "broadcast") {
|
||||
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);
|
||||
if (!stream_id) {
|
||||
|
@ -237,7 +237,7 @@ export function warn_if_mentioning_unsubscribed_user(
|
|||
? $t({defaultMessage: "Subscribe them"})
|
||||
: null,
|
||||
can_subscribe_other_users,
|
||||
name: mentioned.full_name,
|
||||
name: mentioned.user.full_name,
|
||||
classname: compose_banner.CLASSNAMES.recipient_not_subscribed,
|
||||
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 timerender from "./timerender";
|
||||
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 * as user_groups from "./user_groups";
|
||||
import type {UserGroup} from "./user_groups";
|
||||
|
@ -493,7 +493,6 @@ export function broadcast_mentions(): PseudoMentionUser[] {
|
|||
pm_recipient_count: Number.POSITIVE_INFINITY,
|
||||
|
||||
full_name: mention,
|
||||
is_broadcast: true,
|
||||
|
||||
// used for sorting
|
||||
idx,
|
||||
|
@ -596,16 +595,9 @@ export function get_pm_people(query: string): (UserGroupPillData | UserPillData)
|
|||
// to do this.
|
||||
const user_suggestions: (UserGroupPillData | UserPillData)[] = [];
|
||||
for (const suggestion of suggestions) {
|
||||
if (suggestion.type === "user_or_mention") {
|
||||
assert(suggestion.is_broadcast === undefined);
|
||||
user_suggestions.push({
|
||||
...suggestion,
|
||||
type: "user",
|
||||
});
|
||||
} else {
|
||||
assert(suggestion.type !== "broadcast");
|
||||
user_suggestions.push(suggestion);
|
||||
}
|
||||
}
|
||||
return user_suggestions;
|
||||
}
|
||||
|
||||
|
@ -634,18 +626,20 @@ export function get_person_suggestions(
|
|||
}
|
||||
// Exclude muted users from typeaheads.
|
||||
persons = muted_users.filter_muted_users(persons);
|
||||
let user_or_mention_list: UserOrMention[] = persons.map((person) => ({
|
||||
...person,
|
||||
is_broadcast: undefined,
|
||||
let person_items: UserOrMentionPillData[] = persons.map((person) => ({
|
||||
type: "user",
|
||||
user: person,
|
||||
}));
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -975,7 +969,8 @@ export function content_highlighter_html(item: TypeaheadSuggestion): string | un
|
|||
case "emoji":
|
||||
return typeahead_helper.render_emoji(item);
|
||||
case "user_group":
|
||||
case "user_or_mention":
|
||||
case "user":
|
||||
case "broadcast":
|
||||
return typeahead_helper.render_person_or_user_group(item);
|
||||
case "slash":
|
||||
return typeahead_helper.render_typeahead_item({
|
||||
|
@ -1041,7 +1036,8 @@ export function content_typeahead_selected(
|
|||
}
|
||||
break;
|
||||
case "user_group":
|
||||
case "user_or_mention": {
|
||||
case "user":
|
||||
case "broadcast": {
|
||||
const is_silent = item.is_silent;
|
||||
beginning = beginning.slice(0, -token.length - 1);
|
||||
if (beginning.endsWith("@_*")) {
|
||||
|
@ -1061,14 +1057,18 @@ export function content_typeahead_selected(
|
|||
// that functionality yet, and we haven't gotten much
|
||||
// feedback on this being an actual pitfall.
|
||||
} else {
|
||||
const user_id = item.is_broadcast ? undefined : item.user_id;
|
||||
let mention_text = people.get_mention_syntax(item.full_name, user_id, is_silent);
|
||||
if (!is_silent && !item.is_broadcast) {
|
||||
const user_id = item.type === "broadcast" ? undefined : item.user.user_id;
|
||||
let mention_text = people.get_mention_syntax(
|
||||
item.user.full_name,
|
||||
user_id,
|
||||
is_silent,
|
||||
);
|
||||
if (!is_silent && item.type !== "broadcast") {
|
||||
compose_validate.warn_if_mentioning_unsubscribed_user(item, $textbox);
|
||||
mention_text = compose_validate.convert_mentions_to_silent_in_direct_messages(
|
||||
mention_text,
|
||||
item.full_name,
|
||||
item.user_id,
|
||||
item.user.full_name,
|
||||
item.user.user_id,
|
||||
);
|
||||
}
|
||||
beginning += mention_text + " ";
|
||||
|
@ -1358,7 +1358,7 @@ export function initialize({
|
|||
pill_widget.clear_text();
|
||||
}
|
||||
} 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
|
||||
|
|
|
@ -69,7 +69,6 @@ export type PseudoMentionUser = {
|
|||
email: string;
|
||||
pm_recipient_count: number;
|
||||
full_name: string;
|
||||
is_broadcast: true;
|
||||
idx: number;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ import type {UserPillData} from "./user_pill";
|
|||
|
||||
function person_matcher(query: string, item: UserPillData): boolean {
|
||||
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
|
||||
// is given priority. Otherwise we use
|
||||
// default user_pill.typeahead_source.
|
||||
const users: UserPillData[] = opts.user_source().map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
const users: UserPillData[] = opts
|
||||
.user_source()
|
||||
.map((user) => ({type: "user", user}));
|
||||
source = [...source, ...users];
|
||||
} else {
|
||||
source = [...source, ...user_pill.typeahead_source(pills, exclude_bots)];
|
||||
|
@ -132,7 +132,7 @@ export function set_up(
|
|||
const users: UserPillData[] = [];
|
||||
if (include_users) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -164,9 +164,9 @@ export function set_up(
|
|||
} else if (
|
||||
include_users &&
|
||||
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");
|
||||
|
|
|
@ -26,9 +26,10 @@ import * as user_status from "./user_status";
|
|||
import type {UserStatusEmojiInfo} from "./user_status";
|
||||
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 & {
|
||||
type: "user_or_mention";
|
||||
is_silent?: boolean;
|
||||
};
|
||||
|
||||
|
@ -116,32 +117,34 @@ export function render_typeahead_item(args: {
|
|||
}
|
||||
|
||||
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({
|
||||
primary: person.special_item_text,
|
||||
primary: person.user.special_item_text,
|
||||
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_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 typeahead_arguments = {
|
||||
primary: person.full_name,
|
||||
primary: person.user.full_name,
|
||||
img_src: avatar_url,
|
||||
user_circle_class,
|
||||
is_person: true,
|
||||
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,
|
||||
secondary: person.delivery_email,
|
||||
secondary: person.user.delivery_email,
|
||||
};
|
||||
|
||||
return render_typeahead_item(typeahead_arguments);
|
||||
|
@ -249,43 +252,31 @@ export function compare_people_for_relevance(
|
|||
current_stream_id?: number,
|
||||
): number {
|
||||
// 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 (person_a_is_broadcast) {
|
||||
if (person_b_is_broadcast) {
|
||||
return person_a.idx - person_b.idx;
|
||||
if (person_a.type === "broadcast") {
|
||||
if (person_b.type === "broadcast") {
|
||||
return person_a.user.idx - person_b.user.idx;
|
||||
}
|
||||
return -1;
|
||||
} else if (person_b_is_broadcast) {
|
||||
} else if (person_b.type === "broadcast") {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (person_a_is_broadcast) {
|
||||
if (person_b_is_broadcast) {
|
||||
return person_a.idx - person_b.idx;
|
||||
if (person_a.type === "broadcast") {
|
||||
if (person_b.type === "broadcast") {
|
||||
return person_a.user.idx - person_b.user.idx;
|
||||
}
|
||||
return 1;
|
||||
} else if (person_b_is_broadcast) {
|
||||
} else if (person_b.type === "broadcast") {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
if (current_stream_id !== undefined) {
|
||||
const a_is_sub = stream_data.is_user_subscribed(current_stream_id, person_a.user_id);
|
||||
const b_is_sub = stream_data.is_user_subscribed(current_stream_id, person_b.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.user_id);
|
||||
|
||||
if (a_is_sub && !b_is_sub) {
|
||||
return -1;
|
||||
|
@ -295,13 +286,13 @@ export function compare_people_for_relevance(
|
|||
}
|
||||
|
||||
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) {
|
||||
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>(
|
||||
|
@ -444,7 +435,7 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
|||
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 = [
|
||||
...users_name_results.exact_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(
|
||||
query,
|
||||
users_name_results.no_matches,
|
||||
(p) => p.email,
|
||||
(p) => p.user.email,
|
||||
);
|
||||
const email_good_matches = [
|
||||
...email_results.exact_matches,
|
||||
|
@ -523,11 +514,13 @@ export function sort_recipients<UserType extends UserOrMentionPillData | UserPil
|
|||
|
||||
function add_user_recipients(items: UserType[]): void {
|
||||
for (const item of items) {
|
||||
const item_is_broadcast = item.type === "user_or_mention" && item.is_broadcast;
|
||||
const topic_wildcard_mention = item.email === "topic";
|
||||
if (!item_is_broadcast || topic_wildcard_mention || !stream_wildcard_mention_included) {
|
||||
if (
|
||||
item.type !== "broadcast" ||
|
||||
item.user.email === "topic" ||
|
||||
!stream_wildcard_mention_included
|
||||
) {
|
||||
recipients.push(item);
|
||||
if (item_is_broadcast && !topic_wildcard_mention) {
|
||||
if (item.type === "broadcast" && item.user.email !== "topic") {
|
||||
stream_wildcard_mention_included = true;
|
||||
}
|
||||
}
|
||||
|
@ -654,16 +647,13 @@ export function query_matches_person(
|
|||
query: string,
|
||||
person: UserPillData | UserOrMentionPillData,
|
||||
): 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;
|
||||
}
|
||||
if (
|
||||
(person.type === "user" || person.is_broadcast === undefined) &&
|
||||
Boolean(person.delivery_email)
|
||||
) {
|
||||
if (person.type === "user" && Boolean(person.user.delivery_email)) {
|
||||
return typeahead.query_matches_string_in_order(
|
||||
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 UserPillData = User & {type: "user"};
|
||||
export type UserPillData = {type: "user"; user: User};
|
||||
|
||||
export function create_item_from_email(
|
||||
email: string,
|
||||
|
@ -136,10 +136,7 @@ export function typeahead_source(
|
|||
exclude_bots?: boolean,
|
||||
): UserPillData[] {
|
||||
const users = exclude_bots ? people.get_realm_active_human_users() : people.get_realm_users();
|
||||
return filter_taken_users(users, pill_widget).map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
return filter_taken_users(users, pill_widget).map((user) => ({type: "user", user}));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
let mentioned_details = {
|
||||
user: {
|
||||
email: "foo@bar.com",
|
||||
},
|
||||
};
|
||||
|
||||
let new_banner_rendered = false;
|
||||
|
@ -679,19 +681,19 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, mock_template}) => {
|
|||
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;
|
||||
const msg_type = is_private ? "private" : "stream";
|
||||
compose_state.set_message_type(msg_type);
|
||||
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);
|
||||
assert.ok(!new_banner_rendered);
|
||||
}
|
||||
|
||||
test_noop_case(true, false, false);
|
||||
test_noop_case(false, true, false);
|
||||
test_noop_case(false, false, true);
|
||||
test_noop_case(true, false, "user");
|
||||
test_noop_case(false, true, "user");
|
||||
test_noop_case(false, false, "broadcast");
|
||||
|
||||
$("#compose_invite_users").hide();
|
||||
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.
|
||||
mentioned_details = {
|
||||
type: "user",
|
||||
user: {
|
||||
email: "foo@bar.com",
|
||||
user_id: 34,
|
||||
full_name: "Foo Barson",
|
||||
},
|
||||
};
|
||||
people.add_active_user(mentioned_details);
|
||||
people.add_active_user(mentioned_details.user);
|
||||
|
||||
new_banner_rendered = false;
|
||||
const $banner_container = $("#compose_banners");
|
||||
|
|
|
@ -61,20 +61,12 @@ const ct = composebox_typeahead;
|
|||
// broadcast-mentions/persons/groups.
|
||||
ct.__Rewire__("max_num_items", 15);
|
||||
|
||||
function user_or_mention_item(item) {
|
||||
return {
|
||||
is_broadcast: undefined, // default, overridden by `item`
|
||||
...item,
|
||||
type: "user_or_mention",
|
||||
};
|
||||
function user_item(user) {
|
||||
return {type: "user", user};
|
||||
}
|
||||
|
||||
function user_item(item) {
|
||||
return {
|
||||
...item,
|
||||
is_broadcast: undefined,
|
||||
type: "user",
|
||||
};
|
||||
function broadcast_item(user) {
|
||||
return {type: "broadcast", user};
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
const ali = user_or_mention_item({
|
||||
const ali = {
|
||||
email: "ali@zulip.com",
|
||||
user_id: 98,
|
||||
full_name: "Ali",
|
||||
is_moderator: false,
|
||||
});
|
||||
};
|
||||
const ali_item = user_item(ali);
|
||||
|
||||
const alice = user_or_mention_item({
|
||||
const alice = {
|
||||
email: "alice@zulip.com",
|
||||
user_id: 99,
|
||||
full_name: "Alice",
|
||||
is_moderator: false,
|
||||
});
|
||||
};
|
||||
const alice_item = user_item(alice);
|
||||
|
||||
const hamlet = user_or_mention_item({
|
||||
const hamlet = {
|
||||
email: "hamlet@zulip.com",
|
||||
user_id: 100,
|
||||
full_name: "King Hamlet",
|
||||
is_moderator: false,
|
||||
});
|
||||
};
|
||||
const hamlet_item = user_item(hamlet);
|
||||
|
||||
const othello = user_or_mention_item({
|
||||
const othello = {
|
||||
email: "othello@zulip.com",
|
||||
user_id: 101,
|
||||
full_name: "Othello, the Moor of Venice",
|
||||
is_moderator: false,
|
||||
delivery_email: null,
|
||||
});
|
||||
};
|
||||
const othello_item = user_item(othello);
|
||||
|
||||
const cordelia = user_or_mention_item({
|
||||
const cordelia = {
|
||||
email: "cordelia@zulip.com",
|
||||
user_id: 102,
|
||||
full_name: "Cordelia, Lear's daughter",
|
||||
is_moderator: false,
|
||||
});
|
||||
};
|
||||
const cordelia_item = user_item(cordelia);
|
||||
|
||||
const deactivated_user = user_or_mention_item({
|
||||
const deactivated_user = {
|
||||
email: "other@zulip.com",
|
||||
user_id: 103,
|
||||
full_name: "Deactivated User",
|
||||
is_moderator: false,
|
||||
});
|
||||
};
|
||||
const deactivated_user_item = user_item(deactivated_user);
|
||||
|
||||
const lear = user_or_mention_item({
|
||||
const lear = {
|
||||
email: "lear@zulip.com",
|
||||
user_id: 104,
|
||||
full_name: "King Lear",
|
||||
is_moderator: false,
|
||||
});
|
||||
};
|
||||
const lear_item = user_item(lear);
|
||||
|
||||
const twin1 = user_or_mention_item({
|
||||
const twin1 = {
|
||||
full_name: "Mark Twin",
|
||||
is_moderator: false,
|
||||
user_id: 105,
|
||||
email: "twin1@zulip.com",
|
||||
});
|
||||
};
|
||||
const twin1_item = user_item(twin1);
|
||||
|
||||
const twin2 = user_or_mention_item({
|
||||
const twin2 = {
|
||||
full_name: "Mark Twin",
|
||||
is_moderator: false,
|
||||
user_id: 106,
|
||||
email: "twin2@zulip.com",
|
||||
});
|
||||
};
|
||||
const twin2_item = user_item(twin2);
|
||||
|
||||
const gael = user_or_mention_item({
|
||||
const gael = {
|
||||
full_name: "Gaël Twin",
|
||||
is_moderator: false,
|
||||
user_id: 107,
|
||||
email: "twin3@zulip.com",
|
||||
});
|
||||
};
|
||||
const gael_item = user_item(gael);
|
||||
|
||||
const hal = user_or_mention_item({
|
||||
const hal = {
|
||||
full_name: "Earl Hal",
|
||||
is_moderator: false,
|
||||
user_id: 108,
|
||||
email: "hal@zulip.com",
|
||||
});
|
||||
};
|
||||
const hal_item = user_item(hal);
|
||||
|
||||
const harry = user_or_mention_item({
|
||||
const harry = {
|
||||
full_name: "Harry",
|
||||
is_moderator: false,
|
||||
user_id: 109,
|
||||
email: "harry@zulip.com",
|
||||
});
|
||||
};
|
||||
const harry_item = user_item(harry);
|
||||
|
||||
const hamletcharacters = user_group_item({
|
||||
name: "hamletcharacters",
|
||||
|
@ -457,17 +461,17 @@ const make_emoji = (emoji_dict) => ({
|
|||
|
||||
// Sorted by name
|
||||
const sorted_user_list = [
|
||||
ali,
|
||||
alice,
|
||||
cordelia,
|
||||
hal, // Early Hal
|
||||
gael,
|
||||
harry,
|
||||
hamlet, // King Hamlet
|
||||
lear,
|
||||
twin1, // Mark Twin
|
||||
twin2,
|
||||
othello,
|
||||
ali_item,
|
||||
alice_item,
|
||||
cordelia_item,
|
||||
hal_item, // Early Hal
|
||||
gael_item,
|
||||
harry_item,
|
||||
hamlet_item, // King Hamlet
|
||||
lear_item,
|
||||
twin1_item, // Mark Twin
|
||||
twin2_item,
|
||||
othello_item,
|
||||
];
|
||||
|
||||
function test(label, f) {
|
||||
|
@ -585,38 +589,38 @@ test("content_typeahead_selected", ({override}) => {
|
|||
|
||||
query = "@**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** ";
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
let warned_for_mention = false;
|
||||
override(compose_validate, "warn_if_mentioning_unsubscribed_user", (mentioned) => {
|
||||
assert.equal(mentioned, othello);
|
||||
assert.equal(mentioned, othello_item);
|
||||
warned_for_mention = true;
|
||||
});
|
||||
|
||||
query = "@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** ";
|
||||
assert.equal(actual_value, expected_value);
|
||||
assert.ok(warned_for_mention);
|
||||
|
||||
query = "Hello @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** ";
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
query = "@**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** ";
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
query = "@*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** ";
|
||||
assert.equal(actual_value, expected_value);
|
||||
|
||||
|
@ -638,7 +642,7 @@ test("content_typeahead_selected", ({override}) => {
|
|||
// silent mention
|
||||
ct.get_or_set_completing_for_tests("silent_mention");
|
||||
const silent_hamlet = {
|
||||
...hamlet,
|
||||
...hamlet_item,
|
||||
is_silent: true,
|
||||
};
|
||||
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.
|
||||
let actual_value = options.source("");
|
||||
let expected_value = [
|
||||
user_item(ali),
|
||||
user_item(alice),
|
||||
user_item(cordelia),
|
||||
user_item(hal),
|
||||
user_item(gael),
|
||||
user_item(harry),
|
||||
user_item(hamlet),
|
||||
user_item(lear),
|
||||
user_item(twin1),
|
||||
user_item(twin2),
|
||||
user_item(othello),
|
||||
ali_item,
|
||||
alice_item,
|
||||
cordelia_item,
|
||||
hal_item,
|
||||
gael_item,
|
||||
harry_item,
|
||||
hamlet_item,
|
||||
lear_item,
|
||||
twin1_item,
|
||||
twin2_item,
|
||||
othello_item,
|
||||
hamletcharacters,
|
||||
backend,
|
||||
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);
|
||||
|
||||
function matcher(query, person) {
|
||||
|
@ -970,46 +972,46 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
|||
|
||||
let query;
|
||||
query = "el"; // Matches both "othELlo" and "cordELia"
|
||||
assert.equal(matcher(query, othello), true);
|
||||
assert.equal(matcher(query, cordelia), true);
|
||||
assert.equal(matcher(query, othello_item), true);
|
||||
assert.equal(matcher(query, cordelia_item), true);
|
||||
|
||||
query = "bender"; // Doesn't exist
|
||||
assert.equal(matcher(query, othello), false);
|
||||
assert.equal(matcher(query, cordelia), false);
|
||||
assert.equal(matcher(query, othello_item), false);
|
||||
assert.equal(matcher(query, cordelia_item), false);
|
||||
|
||||
query = "gael";
|
||||
assert.equal(matcher(query, gael), true);
|
||||
assert.equal(matcher(query, gael_item), true);
|
||||
|
||||
query = "Gaël";
|
||||
assert.equal(matcher(query, gael), true);
|
||||
assert.equal(matcher(query, gael_item), true);
|
||||
|
||||
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
|
||||
// (we're between typing names).
|
||||
query = "othello@zulip.com, ";
|
||||
assert.equal(matcher(query, othello), false);
|
||||
assert.equal(matcher(query, cordelia), false);
|
||||
assert.equal(matcher(query, othello_item), false);
|
||||
assert.equal(matcher(query, cordelia_item), false);
|
||||
|
||||
// query = 'othello@zulip.com,, , cord';
|
||||
query = "cord";
|
||||
assert.equal(matcher(query, othello), false);
|
||||
assert.equal(matcher(query, cordelia), true);
|
||||
assert.equal(matcher(query, othello_item), false);
|
||||
assert.equal(matcher(query, cordelia_item), true);
|
||||
|
||||
// If the user is already in the list, typeahead doesn't include it
|
||||
// again.
|
||||
query = "cordelia@zulip.com, cord";
|
||||
assert.equal(matcher(query, othello), false);
|
||||
assert.equal(matcher(query, cordelia), false);
|
||||
assert.equal(matcher(query, othello_item), false);
|
||||
assert.equal(matcher(query, cordelia_item), false);
|
||||
|
||||
// Matching by email
|
||||
query = "oth";
|
||||
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";
|
||||
assert.equal(matcher(query, deactivated_user), true);
|
||||
assert.equal(matcher(query, deactivated_user_item), true);
|
||||
|
||||
function sorter(query, people) {
|
||||
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
|
||||
// the input.
|
||||
query = "othello";
|
||||
actual_value = sorter(query, [othello]);
|
||||
expected_value = [othello];
|
||||
actual_value = sorter(query, [othello_item]);
|
||||
expected_value = [othello_item];
|
||||
assert.deepEqual(actual_value, expected_value);
|
||||
|
||||
query = "Ali";
|
||||
actual_value = sorter(query, [alice, ali]);
|
||||
expected_value = [ali, alice];
|
||||
actual_value = sorter(query, [alice_item, ali_item]);
|
||||
expected_value = [ali_item, alice_item];
|
||||
assert.deepEqual(actual_value, expected_value);
|
||||
|
||||
// A literal match at the beginning of an element puts it at the top.
|
||||
query = "co"; // Matches everything ("x@zulip.COm")
|
||||
actual_value = sorter(query, [othello, deactivated_user, cordelia]);
|
||||
expected_value = [cordelia, deactivated_user, othello];
|
||||
actual_value.sort((a, b) => a.user_id - b.user_id);
|
||||
expected_value.sort((a, b) => a.user_id - b.user_id);
|
||||
actual_value = sorter(query, [othello_item, deactivated_user_item, cordelia_item]);
|
||||
expected_value = [cordelia_item, deactivated_user_item, othello_item];
|
||||
actual_value.sort((a, b) => a.user.user_id - b.user.user_id);
|
||||
expected_value.sort((a, b) => a.user.user_id - b.user.user_id);
|
||||
assert.deepEqual(actual_value, expected_value);
|
||||
|
||||
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`
|
||||
// with normal space.
|
||||
query = "cordelia, lear's\u00A0";
|
||||
assert.equal(matcher(query, cordelia), true);
|
||||
assert.equal(matcher(query, othello), false);
|
||||
assert.equal(matcher(query, cordelia_item), true);
|
||||
assert.equal(matcher(query, othello_item), false);
|
||||
|
||||
const event = {
|
||||
target: "#doesnotmatter",
|
||||
|
@ -1060,12 +1062,12 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
|||
// options.updater()
|
||||
options.query = "othello";
|
||||
appended_names = [];
|
||||
options.updater(othello, event);
|
||||
options.updater(othello_item, event);
|
||||
assert.deepEqual(appended_names, ["Othello, the Moor of Venice"]);
|
||||
|
||||
options.query = "othello@zulip.com, cor";
|
||||
appended_names = [];
|
||||
actual_value = options.updater(cordelia, event);
|
||||
actual_value = options.updater(cordelia_item, event);
|
||||
assert.deepEqual(appended_names, ["Cordelia, Lear's daughter"]);
|
||||
|
||||
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)
|
||||
$("#private_message_recipient").trigger("blur");
|
||||
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"]);
|
||||
|
||||
cleared = false;
|
||||
|
@ -1120,7 +1122,7 @@ test("initialize", ({override, override_rewire, mock_template}) => {
|
|||
// content_highlighter_html.
|
||||
ct.get_or_set_completing_for_tests("mention");
|
||||
ct.get_or_set_token_for_testing("othello");
|
||||
actual_value = options.highlighter_html(othello);
|
||||
actual_value = options.highlighter_html(othello_item);
|
||||
expected_value =
|
||||
` <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` +
|
||||
|
@ -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_user_groups = [
|
||||
...sorted_user_list,
|
||||
|
@ -1495,7 +1497,7 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
|||
backend,
|
||||
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) {
|
||||
return mentions.map((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(
|
||||
"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 @*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 @_*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(
|
||||
"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(
|
||||
"test @_*h",
|
||||
mentions_with_silent_marker(
|
||||
[harry, hal, hamlet, hamletcharacters, cordelia, othello],
|
||||
[harry_item, hal_item, hamlet_item, hamletcharacters, cordelia_item, othello_item],
|
||||
true,
|
||||
),
|
||||
);
|
||||
|
@ -1550,28 +1561,69 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
|||
assert_typeahead_equals(
|
||||
"test\n@i",
|
||||
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,
|
||||
),
|
||||
);
|
||||
assert_typeahead_equals(
|
||||
"test\n@_i",
|
||||
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,
|
||||
),
|
||||
);
|
||||
assert_typeahead_equals(
|
||||
"test\n @l",
|
||||
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,
|
||||
),
|
||||
);
|
||||
assert_typeahead_equals(
|
||||
"test\n @_l",
|
||||
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,
|
||||
),
|
||||
);
|
||||
|
@ -1583,9 +1635,12 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
|||
assert_typeahead_equals(" @_zuli", []);
|
||||
assert_typeahead_equals(
|
||||
"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", []);
|
||||
|
||||
|
@ -1760,7 +1815,11 @@ test("begins_typeahead", ({override, override_rewire}) => {
|
|||
assert_typeahead_equals("~~~test", "ing", []);
|
||||
const terminal_symbols = ",.;?!()[]> \"'\n\t";
|
||||
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_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");
|
||||
let th_render_person_called = false;
|
||||
override_rewire(typeahead_helper, "render_person", (person) => {
|
||||
assert.deepEqual(person, othello);
|
||||
assert.deepEqual(person, othello_item);
|
||||
th_render_person_called = true;
|
||||
});
|
||||
ct.content_highlighter_html(othello);
|
||||
ct.content_highlighter_html(othello_item);
|
||||
|
||||
let th_render_user_group_called = false;
|
||||
override_rewire(typeahead_helper, "render_user_group", (user_group) => {
|
||||
|
@ -1873,10 +1932,10 @@ test("filter_and_sort_mentions (normal)", () => {
|
|||
current_user.user_id = 101;
|
||||
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(
|
||||
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
|
||||
|
@ -1885,7 +1944,7 @@ test("filter_and_sort_mentions (normal)", () => {
|
|||
suggestions = ct.filter_and_sort_mentions(is_silent, "al");
|
||||
assert.deepEqual(
|
||||
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
|
||||
|
@ -1893,7 +1952,10 @@ test("filter_and_sort_mentions (normal)", () => {
|
|||
// recursive subgroups.
|
||||
current_user.user_id = 102;
|
||||
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)", () => {
|
||||
|
@ -1901,14 +1963,20 @@ test("filter_and_sort_mentions (silent)", () => {
|
|||
|
||||
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
|
||||
// user is member of can_mention_group or its subgroups for a
|
||||
// silent mention.
|
||||
current_user.user_id = 102;
|
||||
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", () => {
|
||||
|
@ -2005,22 +2073,22 @@ test("typeahead_results", () => {
|
|||
is_silent: false,
|
||||
};
|
||||
}
|
||||
assert_mentions_matches("cordelia", [not_silent(cordelia)]);
|
||||
assert_mentions_matches("cordelia, le", [not_silent(cordelia)]);
|
||||
assert_mentions_matches("cordelia", [not_silent(cordelia_item)]);
|
||||
assert_mentions_matches("cordelia, le", [not_silent(cordelia_item)]);
|
||||
assert_mentions_matches("cordelia, le ", []);
|
||||
assert_mentions_matches("moor", [not_silent(othello)]);
|
||||
assert_mentions_matches("moor ", [not_silent(othello)]);
|
||||
assert_mentions_matches("moor of", [not_silent(othello)]);
|
||||
assert_mentions_matches("moor of ven", [not_silent(othello)]);
|
||||
assert_mentions_matches("oor", [not_silent(othello)]);
|
||||
assert_mentions_matches("moor", [not_silent(othello_item)]);
|
||||
assert_mentions_matches("moor ", [not_silent(othello_item)]);
|
||||
assert_mentions_matches("moor of", [not_silent(othello_item)]);
|
||||
assert_mentions_matches("moor of ven", [not_silent(othello_item)]);
|
||||
assert_mentions_matches("oor", [not_silent(othello_item)]);
|
||||
assert_mentions_matches("oor ", []);
|
||||
assert_mentions_matches("oor o", []);
|
||||
assert_mentions_matches("oor of venice", []);
|
||||
assert_mentions_matches("King ", [not_silent(hamlet), not_silent(lear)]);
|
||||
assert_mentions_matches("King H", [not_silent(hamlet)]);
|
||||
assert_mentions_matches("King L", [not_silent(lear)]);
|
||||
assert_mentions_matches("King ", [not_silent(hamlet_item), not_silent(lear_item)]);
|
||||
assert_mentions_matches("King H", [not_silent(hamlet_item)]);
|
||||
assert_mentions_matches("King L", [not_silent(lear_item)]);
|
||||
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
|
||||
// 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,
|
||||
// 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
|
||||
// "everyone" and "stream" wildcard mentions.
|
||||
assert_mentions_matches("e", [
|
||||
not_silent(mention_everyone),
|
||||
not_silent(hal),
|
||||
not_silent(alice),
|
||||
not_silent(cordelia),
|
||||
not_silent(gael),
|
||||
not_silent(hamlet),
|
||||
not_silent(lear),
|
||||
not_silent(othello),
|
||||
not_silent(hal_item),
|
||||
not_silent(alice_item),
|
||||
not_silent(cordelia_item),
|
||||
not_silent(gael_item),
|
||||
not_silent(hamlet_item),
|
||||
not_silent(lear_item),
|
||||
not_silent(othello_item),
|
||||
not_silent(hamletcharacters),
|
||||
not_silent(call_center),
|
||||
]);
|
||||
|
||||
// Verify we suggest both 'the first matching stream wildcard' and
|
||||
// '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".
|
||||
assert_mentions_matches("o", [
|
||||
not_silent(othello),
|
||||
not_silent(othello_item),
|
||||
not_silent(mention_everyone),
|
||||
not_silent(mention_topic),
|
||||
not_silent(cordelia),
|
||||
not_silent(cordelia_item),
|
||||
]);
|
||||
|
||||
// Autocomplete by slash commands.
|
||||
|
@ -2101,20 +2169,20 @@ test("message people", ({override, override_rewire}) => {
|
|||
};
|
||||
|
||||
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.
|
||||
user_ids = [hamlet.user_id, harry.user_id];
|
||||
|
||||
results = ct.get_person_suggestions("Ha", opts);
|
||||
assert.deepEqual(results, [harry, hamlet]);
|
||||
assert.deepEqual(results, [harry_item, hamlet_item]);
|
||||
|
||||
// Reincluding Hal and deactivating harry
|
||||
user_ids = [hamlet.user_id, harry.user_id, hal.user_id];
|
||||
people.deactivate(harry);
|
||||
results = ct.get_person_suggestions("Ha", opts);
|
||||
// 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", () => {
|
||||
|
@ -2127,7 +2195,7 @@ test("muted users excluded from results", () => {
|
|||
|
||||
// Nobody is muted
|
||||
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.
|
||||
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
|
||||
// or user group mentions.
|
||||
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]);
|
||||
});
|
||||
|
||||
|
@ -2163,12 +2231,12 @@ test("direct message recipients sorted according to stream / topic being viewed"
|
|||
compose_state.set_stream_id("");
|
||||
results = ct.get_pm_people("li");
|
||||
// `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
|
||||
compose_state.set_stream_id(denmark_stream.stream_id);
|
||||
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.
|
||||
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
|
||||
// 1st despite having an exact name match with the query.
|
||||
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) {
|
||||
return {
|
||||
...user,
|
||||
type: "user",
|
||||
};
|
||||
return {type: "user", user};
|
||||
}
|
||||
|
||||
const jill = {
|
||||
|
|
|
@ -27,23 +27,17 @@ let next_id = 0;
|
|||
|
||||
function assertSameEmails(lst1, lst2) {
|
||||
assert.deepEqual(
|
||||
lst1.map((r) => r.email),
|
||||
lst2.map((r) => r.email),
|
||||
lst1.map((r) => r.user.email),
|
||||
lst2.map((r) => r.user.email),
|
||||
);
|
||||
}
|
||||
|
||||
function user_item(user) {
|
||||
return {
|
||||
...user,
|
||||
type: "user",
|
||||
};
|
||||
return {type: "user", user};
|
||||
}
|
||||
|
||||
function user_or_mention_item(user_or_mention) {
|
||||
return {
|
||||
...user_or_mention,
|
||||
type: "user_or_mention",
|
||||
};
|
||||
function broadcast_item(user) {
|
||||
return {type: "broadcast", user};
|
||||
}
|
||||
|
||||
const a_bot = {
|
||||
|
@ -53,6 +47,7 @@ const a_bot = {
|
|||
is_bot: true,
|
||||
user_id: 1,
|
||||
};
|
||||
const a_bot_item = user_item(a_bot);
|
||||
|
||||
const a_user = {
|
||||
email: "a_user@zulip.org",
|
||||
|
@ -61,6 +56,7 @@ const a_user = {
|
|||
is_bot: false,
|
||||
user_id: 2,
|
||||
};
|
||||
const a_user_item = user_item(a_user);
|
||||
|
||||
const b_user_1 = {
|
||||
email: "b_user_1@zulip.net",
|
||||
|
@ -78,6 +74,7 @@ const b_user_2 = {
|
|||
is_bot: false,
|
||||
user_id: 4,
|
||||
};
|
||||
const b_user_2_item = user_item(b_user_2);
|
||||
|
||||
const b_user_3 = {
|
||||
email: "b_user_3@zulip.net",
|
||||
|
@ -95,6 +92,7 @@ const b_bot = {
|
|||
is_bot: true,
|
||||
user_id: 6,
|
||||
};
|
||||
const b_bot_item = user_item(b_bot);
|
||||
|
||||
const zman = {
|
||||
email: "zman@test.net",
|
||||
|
@ -361,17 +359,14 @@ test("sort_languages on actual data", () => {
|
|||
});
|
||||
|
||||
function get_typeahead_result(query, current_stream_id, current_topic) {
|
||||
const users = people.get_realm_users().map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
const users = people.get_realm_users().map((user) => ({type: "user", user}));
|
||||
const result = th.sort_recipients({
|
||||
users,
|
||||
query,
|
||||
current_stream_id,
|
||||
current_topic,
|
||||
});
|
||||
return result.map((person) => person.email);
|
||||
return result.map((person) => person.user.email);
|
||||
}
|
||||
|
||||
test("sort_recipients", () => {
|
||||
|
@ -470,14 +465,13 @@ test("sort_recipients all mention", () => {
|
|||
compose_state.set_message_type("stream");
|
||||
const all_obj = ct.broadcast_mentions()[0];
|
||||
assert.equal(all_obj.email, "all");
|
||||
assert.equal(all_obj.is_broadcast, true);
|
||||
assert.equal(all_obj.idx, 0);
|
||||
|
||||
// Test person email is "all" or "everyone"
|
||||
const test_objs = [...matches, all_obj];
|
||||
const user_and_mention_items = test_objs.map((user_or_mention) =>
|
||||
user_or_mention_item(user_or_mention),
|
||||
);
|
||||
const user_and_mention_items = [
|
||||
...matches.map((user) => user_item(user)),
|
||||
broadcast_item(all_obj),
|
||||
];
|
||||
const results = th.sort_recipients({
|
||||
users: user_and_mention_items,
|
||||
query: "a",
|
||||
|
@ -485,7 +479,16 @@ test("sort_recipients all mention", () => {
|
|||
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", () => {
|
||||
|
@ -538,17 +541,14 @@ test("sort_recipients pm counts", () => {
|
|||
|
||||
test("sort_recipients dup bots", () => {
|
||||
const dup_objects = [...matches, a_bot];
|
||||
const user_items = dup_objects.map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
const user_items = dup_objects.map((user) => user_item(user));
|
||||
const recipients = th.sort_recipients({
|
||||
users: user_items,
|
||||
query: "b",
|
||||
current_stream_id: undefined,
|
||||
current_topic: "",
|
||||
});
|
||||
const recipients_email = recipients.map((person) => person.email);
|
||||
const recipients_email = recipients.map((person) => person.user.email);
|
||||
const expected = [
|
||||
"b_user_1@zulip.net",
|
||||
"b_user_2@zulip.net",
|
||||
|
@ -564,13 +564,10 @@ test("sort_recipients dup bots", () => {
|
|||
|
||||
test("sort_recipients dup alls", () => {
|
||||
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'
|
||||
const test_objs = [all_obj, a_user, all_obj];
|
||||
const user_and_mention_items = test_objs.map((user_or_mention) =>
|
||||
user_or_mention_item(user_or_mention),
|
||||
);
|
||||
const user_and_mention_items = [all_obj_item, a_user_item, all_obj_item];
|
||||
const recipients = th.sort_recipients({
|
||||
users: user_and_mention_items,
|
||||
query: "a",
|
||||
|
@ -578,43 +575,36 @@ test("sort_recipients dup alls", () => {
|
|||
current_topic: "Linux topic",
|
||||
});
|
||||
|
||||
const expected = [all_obj, a_user];
|
||||
const expected = [all_obj_item, a_user_item];
|
||||
assertSameEmails(recipients, expected);
|
||||
});
|
||||
|
||||
test("sort_recipients dup alls direct message", () => {
|
||||
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'
|
||||
const test_objs = [all_obj, a_user, all_obj];
|
||||
const user_and_mention_items = test_objs.map((user_or_mention) =>
|
||||
user_or_mention_item(user_or_mention),
|
||||
);
|
||||
const user_and_mention_items = [all_obj_item, a_user_item, all_obj_item];
|
||||
const recipients = th.sort_recipients({
|
||||
users: user_and_mention_items,
|
||||
query: "a",
|
||||
});
|
||||
|
||||
const expected = [a_user, all_obj];
|
||||
const expected = [a_user_item, all_obj_item];
|
||||
assertSameEmails(recipients, expected);
|
||||
});
|
||||
|
||||
test("sort_recipients subscribers", () => {
|
||||
// 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);
|
||||
const small_matches = [b_user_2, b_user_1];
|
||||
const user_items = small_matches.map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
const user_items = [b_user_2_item, b_user_1_item];
|
||||
const recipients = th.sort_recipients({
|
||||
users: user_items,
|
||||
query: "b",
|
||||
current_stream_id: dev_sub.stream_id,
|
||||
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"];
|
||||
assert.deepEqual(recipients_email, expected);
|
||||
});
|
||||
|
@ -622,7 +612,6 @@ test("sort_recipients subscribers", () => {
|
|||
test("sort_recipients recent senders", () => {
|
||||
// b_user_2 is the only recent sender, b_user_3 is the only pm partner
|
||||
// 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_2.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),
|
||||
});
|
||||
pm_conversations.set_partner(b_user_3.user_id);
|
||||
const user_items = small_matches.map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
const user_items = [b_user_1_item, b_user_2_item, b_user_3_item];
|
||||
const recipients = th.sort_recipients({
|
||||
users: user_items,
|
||||
query: "b",
|
||||
current_stream_id: linux_sub.stream_id,
|
||||
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
|
||||
const expected = ["b_user_2@zulip.net", "b_user_3@zulip.net", "b_user_1@zulip.net"];
|
||||
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
|
||||
// both are not subscribed to the stream Linux.
|
||||
pm_conversations.set_partner(b_user_3.user_id);
|
||||
const small_matches = [b_user_3, b_user_2];
|
||||
const user_items = small_matches.map((user) => ({
|
||||
...user,
|
||||
type: "user",
|
||||
}));
|
||||
const user_items = [b_user_3_item, b_user_2_item];
|
||||
const recipients = th.sort_recipients({
|
||||
users: user_items,
|
||||
query: "b",
|
||||
current_stream_id: linux_sub.stream_id,
|
||||
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"];
|
||||
assert.deepEqual(recipients_email, expected);
|
||||
});
|
||||
|
@ -676,27 +658,29 @@ test("sort broadcast mentions for stream message type", () => {
|
|||
// randomly rearrange them)
|
||||
compose_state.set_message_type("stream");
|
||||
const mentions = ct.broadcast_mentions().reverse();
|
||||
const mention_items = mentions.map((mention) => user_or_mention_item(mention));
|
||||
const results = th.sort_people_for_relevance(mention_items, "", "");
|
||||
const broadcast_items = mentions.map((broadcast) => broadcast_item(broadcast));
|
||||
const results = th.sort_people_for_relevance(broadcast_items, "", "");
|
||||
|
||||
assert.deepEqual(
|
||||
results.map((r) => r.email),
|
||||
results.map((r) => r.user.email),
|
||||
["all", "everyone", "stream", "channel", "topic"],
|
||||
);
|
||||
|
||||
// Reverse the list to test actual sorting
|
||||
// and ensure test coverage for the defensive
|
||||
// code. Also, add in some people users.
|
||||
const test_objs = [...ct.broadcast_mentions()].reverse();
|
||||
test_objs.unshift(zman);
|
||||
test_objs.push(a_user);
|
||||
const user_or_mention_items = test_objs.map((user_or_mention) =>
|
||||
user_or_mention_item(user_or_mention),
|
||||
);
|
||||
const user_or_mention_items = [
|
||||
zman_item,
|
||||
...ct
|
||||
.broadcast_mentions()
|
||||
.map((broadcast) => broadcast_item(broadcast))
|
||||
.reverse(),
|
||||
a_user_item,
|
||||
];
|
||||
const results2 = th.sort_people_for_relevance(user_or_mention_items, "", "");
|
||||
|
||||
assert.deepEqual(
|
||||
results2.map((r) => r.email),
|
||||
results2.map((r) => r.user.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", () => {
|
||||
compose_state.set_message_type("private");
|
||||
const mentions = ct.broadcast_mentions().reverse();
|
||||
const mention_items = mentions.map((mention) => user_or_mention_item(mention));
|
||||
const results = th.sort_people_for_relevance(mention_items, "", "");
|
||||
const broadcast_items = mentions.map((broadcast) => broadcast_item(broadcast));
|
||||
const results = th.sort_people_for_relevance(broadcast_items, "", "");
|
||||
|
||||
assert.deepEqual(
|
||||
results.map((r) => r.email),
|
||||
results.map((r) => r.user.email),
|
||||
["all", "everyone"],
|
||||
);
|
||||
|
||||
const test_objs = [...ct.broadcast_mentions()].reverse();
|
||||
test_objs.unshift(zman);
|
||||
test_objs.push(a_user);
|
||||
const user_or_mention_items = test_objs.map((user_or_mention) =>
|
||||
user_or_mention_item(user_or_mention),
|
||||
);
|
||||
const user_or_mention_items = [
|
||||
zman_item,
|
||||
...ct
|
||||
.broadcast_mentions()
|
||||
.map((broadcast) => broadcast_item(broadcast))
|
||||
.reverse(),
|
||||
a_user_item,
|
||||
];
|
||||
const results2 = th.sort_people_for_relevance(user_or_mention_items, "", "");
|
||||
|
||||
assert.deepEqual(
|
||||
results2.map((r) => r.email),
|
||||
results2.map((r) => r.user.email),
|
||||
[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.
|
||||
compose_state.set_message_type("stream");
|
||||
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, zman_item), -1);
|
||||
|
@ -742,7 +728,7 @@ test("test compare directly for stream message type", () => {
|
|||
test("test compare directly for direct message", () => {
|
||||
compose_state.set_message_type("private");
|
||||
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, zman_item), 1);
|
||||
|
@ -791,7 +777,7 @@ test("render_person when emails hidden", ({mock_template}) => {
|
|||
rendered = true;
|
||||
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);
|
||||
});
|
||||
|
||||
|
@ -808,7 +794,7 @@ test("render_person", ({mock_template}) => {
|
|||
rendered = true;
|
||||
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);
|
||||
});
|
||||
|
||||
|
@ -823,8 +809,6 @@ test("render_person special_item_text", ({mock_template}) => {
|
|||
is_bot: false,
|
||||
user_id: 7,
|
||||
special_item_text: "special_text",
|
||||
is_broadcast: true,
|
||||
type: "user_or_mention",
|
||||
};
|
||||
|
||||
rendered = false;
|
||||
|
@ -833,7 +817,7 @@ test("render_person special_item_text", ({mock_template}) => {
|
|||
rendered = true;
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
@ -147,10 +147,5 @@ test("typeahead", () => {
|
|||
// excluded by virtue of already being one of the widget items.
|
||||
// And then bogus_item is just a red herring to test robustness.
|
||||
const result = user_pill.typeahead_source(pill_widget);
|
||||
assert.deepEqual(result, [
|
||||
{
|
||||
...alice,
|
||||
type: "user",
|
||||
},
|
||||
]);
|
||||
assert.deepEqual(result, [{type: "user", user: alice}]);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue