2016-09-14 15:39:41 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
from zerver.lib.alert_words import (
|
|
|
|
add_user_alert_words,
|
|
|
|
alert_words_in_realm,
|
|
|
|
remove_user_alert_words,
|
|
|
|
user_alert_words,
|
|
|
|
)
|
|
|
|
|
|
|
|
from zerver.lib.test_helpers import (
|
|
|
|
get_user_profile_by_email,
|
2016-09-14 18:25:44 +02:00
|
|
|
most_recent_message,
|
2016-09-14 15:39:41 +02:00
|
|
|
most_recent_usermessage,
|
2016-11-10 19:30:09 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
from zerver.lib.test_classes import (
|
2016-09-14 15:39:41 +02:00
|
|
|
ZulipTestCase,
|
|
|
|
)
|
|
|
|
|
|
|
|
from zerver.models import (
|
|
|
|
Recipient,
|
|
|
|
UserProfile,
|
|
|
|
)
|
|
|
|
|
2016-12-04 18:38:56 +01:00
|
|
|
from typing import Text
|
2016-09-14 15:39:41 +02:00
|
|
|
|
|
|
|
import ujson
|
|
|
|
|
|
|
|
class AlertWordTests(ZulipTestCase):
|
|
|
|
interesting_alert_word_list = ['alert', 'multi-word word', u'☃']
|
|
|
|
|
|
|
|
def test_internal_endpoint(self):
|
|
|
|
# type: () -> None
|
|
|
|
email = "cordelia@zulip.com"
|
|
|
|
self.login(email)
|
|
|
|
|
|
|
|
params = {
|
|
|
|
'alert_words': ujson.dumps(['milk', 'cookies'])
|
|
|
|
}
|
|
|
|
result = self.client_post('/json/users/me/alert_words', params)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
user = get_user_profile_by_email(email)
|
|
|
|
words = user_alert_words(user)
|
|
|
|
self.assertEqual(words, ['milk', 'cookies'])
|
|
|
|
|
|
|
|
def test_default_no_words(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
Users start out with no alert words.
|
|
|
|
"""
|
|
|
|
email = "cordelia@zulip.com"
|
|
|
|
user = get_user_profile_by_email(email)
|
|
|
|
|
|
|
|
words = user_alert_words(user)
|
|
|
|
|
|
|
|
self.assertEqual(words, [])
|
|
|
|
|
|
|
|
def test_add_word(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
add_user_alert_words can add multiple alert words at once.
|
|
|
|
"""
|
|
|
|
email = "cordelia@zulip.com"
|
|
|
|
user = get_user_profile_by_email(email)
|
|
|
|
|
|
|
|
# Add several words, including multi-word and non-ascii words.
|
|
|
|
add_user_alert_words(user, self.interesting_alert_word_list)
|
|
|
|
|
|
|
|
words = user_alert_words(user)
|
|
|
|
self.assertEqual(words, self.interesting_alert_word_list)
|
|
|
|
|
|
|
|
def test_remove_word(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
Removing alert words works via remove_user_alert_words, even
|
|
|
|
for multi-word and non-ascii words.
|
|
|
|
"""
|
|
|
|
email = "cordelia@zulip.com"
|
|
|
|
user = get_user_profile_by_email(email)
|
|
|
|
|
|
|
|
add_user_alert_words(user, self.interesting_alert_word_list)
|
|
|
|
|
|
|
|
theoretical_remaining_alerts = self.interesting_alert_word_list[:]
|
|
|
|
|
|
|
|
for alert_word in self.interesting_alert_word_list:
|
|
|
|
remove_user_alert_words(user, alert_word)
|
|
|
|
theoretical_remaining_alerts.remove(alert_word)
|
|
|
|
actual_remaining_alerts = user_alert_words(user)
|
|
|
|
self.assertEqual(actual_remaining_alerts,
|
|
|
|
theoretical_remaining_alerts)
|
|
|
|
|
|
|
|
def test_realm_words(self):
|
|
|
|
# type: () -> None
|
|
|
|
"""
|
|
|
|
We can gather alert words for an entire realm via
|
|
|
|
alert_words_in_realm. Alerts added for one user do not impact other
|
|
|
|
users.
|
|
|
|
"""
|
|
|
|
email = "cordelia@zulip.com"
|
|
|
|
user1 = get_user_profile_by_email(email)
|
|
|
|
|
|
|
|
add_user_alert_words(user1, self.interesting_alert_word_list)
|
|
|
|
|
|
|
|
email = "othello@zulip.com"
|
|
|
|
user2 = get_user_profile_by_email(email)
|
|
|
|
add_user_alert_words(user2, ['another'])
|
|
|
|
|
|
|
|
realm_words = alert_words_in_realm(user2.realm)
|
|
|
|
self.assertEqual(len(realm_words), 2)
|
|
|
|
self.assertEqual(list(realm_words.keys()), [user1.id, user2.id])
|
|
|
|
self.assertEqual(realm_words[user1.id],
|
|
|
|
self.interesting_alert_word_list)
|
|
|
|
self.assertEqual(realm_words[user2.id], ['another'])
|
|
|
|
|
|
|
|
def test_json_list_default(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login("hamlet@zulip.com")
|
|
|
|
|
|
|
|
result = self.client_get('/json/users/me/alert_words')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
data = ujson.loads(result.content)
|
|
|
|
self.assertEqual(data['alert_words'], [])
|
|
|
|
|
|
|
|
def test_json_list_add(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login("hamlet@zulip.com")
|
|
|
|
|
2017-02-17 06:00:02 +01:00
|
|
|
result = self.client_put('/json/users/me/alert_words', {'alert_words': ujson.dumps(['one ', '\n two', 'three'])})
|
2016-09-14 15:39:41 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_get('/json/users/me/alert_words')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
data = ujson.loads(result.content)
|
|
|
|
self.assertEqual(data['alert_words'], ['one', 'two', 'three'])
|
|
|
|
|
|
|
|
def test_json_list_remove(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login("hamlet@zulip.com")
|
|
|
|
|
|
|
|
result = self.client_put('/json/users/me/alert_words', {'alert_words': ujson.dumps(['one', 'two', 'three'])})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_delete('/json/users/me/alert_words', {'alert_words': ujson.dumps(['one'])})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_get('/json/users/me/alert_words')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
data = ujson.loads(result.content)
|
|
|
|
self.assertEqual(data['alert_words'], ['two', 'three'])
|
|
|
|
|
|
|
|
def test_json_list_set(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login("hamlet@zulip.com")
|
|
|
|
|
|
|
|
result = self.client_put('/json/users/me/alert_words', {'alert_words': ujson.dumps(['one', 'two', 'three'])})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_post('/json/users/me/alert_words', {'alert_words': ujson.dumps(['a', 'b', 'c'])})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_get('/json/users/me/alert_words')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
data = ujson.loads(result.content)
|
|
|
|
self.assertEqual(data['alert_words'], ['a', 'b', 'c'])
|
|
|
|
|
|
|
|
def message_does_alert(self, user_profile, message):
|
2016-12-04 18:38:56 +01:00
|
|
|
# type: (UserProfile, Text) -> bool
|
2016-09-14 15:39:41 +02:00
|
|
|
"""Send a bunch of messages as othello, so Hamlet is notified"""
|
|
|
|
self.send_message("othello@zulip.com", "Denmark", Recipient.STREAM, message)
|
|
|
|
user_message = most_recent_usermessage(user_profile)
|
|
|
|
return 'has_alert_word' in user_message.flags_list()
|
|
|
|
|
|
|
|
def test_alert_flags(self):
|
|
|
|
# type: () -> None
|
|
|
|
self.login("hamlet@zulip.com")
|
2017-05-07 17:21:26 +02:00
|
|
|
user_profile_hamlet = self.example_user('hamlet')
|
2016-09-14 15:39:41 +02:00
|
|
|
|
|
|
|
result = self.client_put('/json/users/me/alert_words', {'alert_words': ujson.dumps(['one', 'two', 'three'])})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_get('/json/users/me/alert_words')
|
|
|
|
self.assert_json_success(result)
|
|
|
|
data = ujson.loads(result.content)
|
|
|
|
self.assertEqual(data['alert_words'], ['one', 'two', 'three'])
|
|
|
|
|
|
|
|
# Alerts in the middle of messages work.
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "Normal alert one time"))
|
|
|
|
# Alerts at the end of messages work.
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "Normal alert one"))
|
|
|
|
# Alerts at the beginning of messages work.
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "two normal alerts"))
|
|
|
|
# Alerts with surrounding punctuation work.
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "This one? should alert"))
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "Definitely time for three."))
|
|
|
|
# Multiple alerts in a message work.
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "One two three o'clock"))
|
|
|
|
# Alerts are case-insensitive.
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "One o'clock"))
|
|
|
|
self.assertTrue(self.message_does_alert(user_profile_hamlet, "Case of ONE, won't stop me"))
|
|
|
|
|
|
|
|
# We don't cause alerts for matches in URLs.
|
|
|
|
self.assertFalse(self.message_does_alert(user_profile_hamlet, "Don't alert on http://t.co/one/ urls"))
|
|
|
|
self.assertFalse(self.message_does_alert(user_profile_hamlet, "Don't alert on http://t.co/one urls"))
|
|
|
|
|
2016-09-14 18:25:44 +02:00
|
|
|
def test_update_alert_words(self):
|
|
|
|
# type: () -> None
|
|
|
|
me_email = 'hamlet@zulip.com'
|
|
|
|
user_profile = get_user_profile_by_email(me_email)
|
|
|
|
|
|
|
|
self.login(me_email)
|
|
|
|
result = self.client_put('/json/users/me/alert_words', {'alert_words': ujson.dumps(['ALERT'])})
|
|
|
|
|
|
|
|
content = 'this is an ALERT for you'
|
|
|
|
self.send_message(me_email, "Denmark", Recipient.STREAM, content)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
original_message = most_recent_message(user_profile)
|
|
|
|
|
|
|
|
user_message = most_recent_usermessage(user_profile)
|
|
|
|
self.assertIn('has_alert_word', user_message.flags_list())
|
|
|
|
|
2016-12-22 10:17:49 +01:00
|
|
|
result = self.client_patch("/json/messages/" + str(original_message.id), {
|
2016-09-14 18:25:44 +02:00
|
|
|
'message_id': original_message.id,
|
|
|
|
'content': 'new ALERT for you',
|
|
|
|
})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
user_message = most_recent_usermessage(user_profile)
|
|
|
|
self.assertEqual(user_message.message.content, 'new ALERT for you')
|
|
|
|
self.assertIn('has_alert_word', user_message.flags_list())
|
|
|
|
|
2016-12-22 10:17:49 +01:00
|
|
|
result = self.client_patch("/json/messages/" + str(original_message.id), {
|
2016-09-14 18:25:44 +02:00
|
|
|
'message_id': original_message.id,
|
|
|
|
'content': 'sorry false alarm',
|
|
|
|
})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
user_message = most_recent_usermessage(user_profile)
|
|
|
|
self.assertEqual(user_message.message.content, 'sorry false alarm')
|
|
|
|
self.assertNotIn('has_alert_word', user_message.flags_list())
|