markdown: Add @stream as an alias for @all.

Fixes: #8930.
This commit is contained in:
Shubham Dhama
2018-04-03 21:25:57 +05:30
committed by Tim Abbott
parent 771db7fb90
commit b650b6b38c
11 changed files with 84 additions and 37 deletions

View File

@@ -896,20 +896,14 @@ user_pill.get_user_ids = function () {
assert.deepEqual(returned, reference); assert.deepEqual(returned, reference);
} }
var all_items = [ var all_items = _.map(['all', 'everyone', 'stream'], function (mention) {
{ return {
special_item_text: 'translated: all (Notify stream)', special_item_text: 'translated: ' + mention +" (Notify stream)",
email: 'all', email: mention,
pm_recipient_count: Infinity, pm_recipient_count: Infinity,
full_name: 'all', full_name: mention,
}, };
{ });
special_item_text: 'translated: everyone (Notify stream)',
email: 'everyone',
pm_recipient_count: Infinity,
full_name: 'everyone',
},
];
var people_with_all = global.people.get_realm_persons().concat(all_items); var people_with_all = global.people.get_realm_persons().concat(all_items);
var all_mentions = people_with_all.concat(global.user_groups.get_realm_user_groups()); var all_mentions = people_with_all.concat(global.user_groups.get_realm_user_groups());
@@ -1094,20 +1088,14 @@ user_pill.get_user_ids = function () {
}()); }());
(function test_typeahead_results() { (function test_typeahead_results() {
var all_items = [ var all_items = _.map(['all', 'everyone', 'stream'], function (mention) {
{ return {
special_item_text: 'all (translated: Notify stream)', special_item_text: 'translated: ' + mention +" (Notify stream)",
email: 'all', email: mention,
pm_recipient_count: Infinity, pm_recipient_count: Infinity,
full_name: 'all', full_name: mention,
}, };
{ });
special_item_text: 'everyone (translated: Notify stream)',
email: 'everyone',
pm_recipient_count: Infinity,
full_name: 'everyone',
},
];
var people_with_all = global.people.get_realm_persons().concat(all_items); var people_with_all = global.people.get_realm_persons().concat(all_items);
var all_mentions = people_with_all.concat(global.user_groups.get_realm_user_groups()); var all_mentions = people_with_all.concat(global.user_groups.get_realm_user_groups());
var stream_list = [denmark_stream, sweden_stream, netherland_stream]; var stream_list = [denmark_stream, sweden_stream, netherland_stream];

View File

@@ -386,6 +386,20 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
assert.equal(message.mentioned, true); assert.equal(message.mentioned, true);
assert.equal(message.mentioned_me_directly, true); assert.equal(message.mentioned_me_directly, true);
input = "test @**everyone**";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.is_me_message, false);
assert.equal(message.mentioned, true);
assert.equal(message.mentioned_me_directly, false);
input = "test @**stream**";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.is_me_message, false);
assert.equal(message.mentioned, true);
assert.equal(message.mentioned_me_directly, false);
input = "test @all"; input = "test @all";
message = {subject: "No links here", raw_content: input}; message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message); markdown.apply_markdown(message);

View File

@@ -166,6 +166,13 @@ zrequire('util');
'some text before only @**everyone**', 'some text before only @**everyone**',
]; ];
var messages_with_stream_mentions = [
'@**stream**',
'some text before @**stream** some text after',
'@**stream** some text after only',
'some text before only @**stream**',
];
var messages_without_all_mentions = [ var messages_without_all_mentions = [
'@all', '@all',
'some text before @all some text after', 'some text before @all some text after',
@@ -183,6 +190,16 @@ zrequire('util');
'`@**everyone**`', '`@**everyone**`',
'some_email@**everyone**.com', 'some_email@**everyone**.com',
]; ];
var messages_without_stream_mentions = [
'some text before @stream some text after',
'@stream',
'`@stream`',
'some_email@stream.com',
'`@**stream**`',
'some_email@**stream**.com',
];
var i; var i;
for (i=0; i<messages_with_all_mentions.length; i += 1) { for (i=0; i<messages_with_all_mentions.length; i += 1) {
assert(util.is_all_or_everyone_mentioned(messages_with_all_mentions[i])); assert(util.is_all_or_everyone_mentioned(messages_with_all_mentions[i]));
@@ -192,6 +209,10 @@ zrequire('util');
assert(util.is_all_or_everyone_mentioned(messages_with_everyone_mentions[i])); assert(util.is_all_or_everyone_mentioned(messages_with_everyone_mentions[i]));
} }
for (i=0; i<messages_with_stream_mentions.length; i += 1) {
assert(util.is_all_or_everyone_mentioned(messages_with_stream_mentions[i]));
}
for (i=0; i<messages_without_all_mentions.length; i += 1) { for (i=0; i<messages_without_all_mentions.length; i += 1) {
assert(!util.is_all_or_everyone_mentioned(messages_without_everyone_mentions[i])); assert(!util.is_all_or_everyone_mentioned(messages_without_everyone_mentions[i]));
} }
@@ -199,6 +220,10 @@ zrequire('util');
for (i=0; i<messages_without_everyone_mentions.length; i += 1) { for (i=0; i<messages_without_everyone_mentions.length; i += 1) {
assert(!util.is_all_or_everyone_mentioned(messages_without_everyone_mentions[i])); assert(!util.is_all_or_everyone_mentioned(messages_without_everyone_mentions[i]));
} }
for (i=0; i<messages_without_stream_mentions.length; i += 1) {
assert(!util.is_all_or_everyone_mentioned(messages_without_stream_mentions[i]));
}
}()); }());
(function test_move_array_elements_to_front() { (function test_move_array_elements_to_front() {

View File

@@ -735,8 +735,8 @@ exports.initialize = function () {
if (data !== undefined && data.mentioned !== undefined) { if (data !== undefined && data.mentioned !== undefined) {
var email = data.mentioned.email; var email = data.mentioned.email;
// warn if @all or @everyone is mentioned // warn if @all, @everyone or @stream is mentioned
if (data.mentioned.full_name === 'all' || data.mentioned.full_name === 'everyone') { if (data.mentioned.full_name === 'all' || data.mentioned.full_name === 'everyone' || data.mentioned.full_name === 'stream') {
return; // don't check if @all or @everyone is subscribed to a stream return; // don't check if @all or @everyone is subscribed to a stream
} }

View File

@@ -374,7 +374,7 @@ exports.compose_content_begins_typeahead = function (query) {
this.completing = 'mention'; this.completing = 'mention';
this.token = current_token; this.token = current_token;
var all_items = _.map(['all', 'everyone'], function (mention) { var all_items = _.map(['all', 'everyone', 'stream'], function (mention) {
return { return {
special_item_text: i18n.t("__wildcard_mention_token__ (Notify stream)", special_item_text: i18n.t("__wildcard_mention_token__ (Notify stream)",
{wildcard_mention_token: mention}), {wildcard_mention_token: mention}),

View File

@@ -57,7 +57,7 @@ exports.apply_markdown = function (message) {
return '<span class="user-mention" data-user-id="' + person.user_id + '">' + return '<span class="user-mention" data-user-id="' + person.user_id + '">' +
'@' + person.full_name + '@' + person.full_name +
'</span>'; '</span>';
} else if (name === 'all' || name === 'everyone') { } else if (name === 'all' || name === 'everyone' || name === 'stream') {
message.mentioned = true; message.mentioned = true;
return '<span class="user-mention" data-user-id="*">' + return '<span class="user-mention" data-user-id="*">' +
'@' + name + '@' + name +

View File

@@ -185,10 +185,10 @@ exports.compare_by_pms = function (user_a, user_b) {
}; };
function compare_for_at_mentioning(person_a, person_b, tertiary_compare, current_stream) { function compare_for_at_mentioning(person_a, person_b, tertiary_compare, current_stream) {
// give preference to "all" or "everyone" // give preference to "all", "everyone" or "stream"
if (person_a.email === "all" || person_a.email === "everyone") { if (person_a.email === "all" || person_a.email === "everyone" || person_a.email === "stream") {
return -1; return -1;
} else if (person_b.email === "all" || person_b.email === "everyone") { } else if (person_b.email === "all" || person_b.email === "everyone" || person_b.email === "stream") {
return 1; return 1;
} }

View File

@@ -198,7 +198,7 @@ exports.CachedValue.prototype = {
}; };
exports.is_all_or_everyone_mentioned = function (message_content) { exports.is_all_or_everyone_mentioned = function (message_content) {
var all_everyone_re = /(^|\s)(@\*{2}(all|everyone)\*{2})($|\s)/; var all_everyone_re = /(^|\s)(@\*{2}(all|everyone|stream)\*{2})($|\s)/;
return all_everyone_re.test(message_content); return all_everyone_re.test(message_content);
}; };

View File

@@ -5,10 +5,10 @@ import re
# Match multi-word string between @** ** or match any one-word # Match multi-word string between @** ** or match any one-word
# sequences after @ # sequences after @
find_mentions = r'(?<![^\s\'\"\(,:<])@(\*\*[^\*]+\*\*|all|everyone)' find_mentions = r'(?<![^\s\'\"\(,:<])@(\*\*[^\*]+\*\*|all|everyone|stream)'
user_group_mentions = r'(?<![^\s\'\"\(,:<])@(\*[^\*]+\*)' user_group_mentions = r'(?<![^\s\'\"\(,:<])@(\*[^\*]+\*)'
wildcards = ['all', 'everyone'] wildcards = ['all', 'everyone', 'stream']
def user_mention_matches_wildcard(mention: Text) -> bool: def user_mention_matches_wildcard(mention: Text) -> bool:
return mention in wildcards return mention in wildcards
@@ -20,7 +20,7 @@ def extract_name(s: Text) -> Optional[Text]:
return None return None
return name return name
# We don't care about @all or @everyone # We don't care about @all, @everyone or @stream
return None return None
def possible_mentions(content: Text) -> Set[Text]: def possible_mentions(content: Text) -> Set[Text]:

View File

@@ -833,6 +833,17 @@ class BugdownTest(ZulipTestCase):
'</span> test</p>') '</span> test</p>')
self.assertTrue(msg.mentions_wildcard) self.assertTrue(msg.mentions_wildcard)
def test_mention_stream(self) -> None:
user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test"))
content = "@**stream** test"
self.assertEqual(render_markdown(msg, content),
'<p><span class="user-mention" data-user-id="*">'
'@stream'
'</span> test</p>')
self.assertTrue(msg.mentions_wildcard)
def test_mention_at_wildcard(self) -> None: def test_mention_at_wildcard(self) -> None:
user_profile = self.example_user('othello') user_profile = self.example_user('othello')
msg = Message(sender=user_profile, sending_client=get_client("test")) msg = Message(sender=user_profile, sending_client=get_client("test"))

View File

@@ -2929,6 +2929,15 @@ class SoftDeactivationMessageTest(ZulipTestCase):
assert_um_count(cordelia, general_user_msg_count + 1) assert_um_count(cordelia, general_user_msg_count + 1)
assert_last_um_content(cordelia, message) assert_last_um_content(cordelia, message)
general_user_msg_count = len(get_user_messages(cordelia))
soft_deactivated_user_msg_count = len(get_user_messages(long_term_idle_user))
message = 'Test @**stream** mention'
send_stream_message(message)
assert_last_um_content(long_term_idle_user, message)
assert_um_count(long_term_idle_user, soft_deactivated_user_msg_count + 1)
assert_um_count(cordelia, general_user_msg_count + 1)
assert_last_um_content(cordelia, message)
# Test UserMessage row is not created while user is deactivated if there # Test UserMessage row is not created while user is deactivated if there
# is a alert word in message. # is a alert word in message.
do_add_alert_words(long_term_idle_user, ['test_alert_word']) do_add_alert_words(long_term_idle_user, ['test_alert_word'])