Skip to content

Commit

Permalink
slash commands: Add /mute_topic command (via zcommand).
Browse files Browse the repository at this point in the history
The muting occurs using muting_ui in the frontend,
where as the server side code checks if the stream
and topic to be muted exists.

Added tests for the server side code as well.
  • Loading branch information
rheaparekh committed Jun 27, 2018
1 parent 6a5dbe1 commit f5999a9
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 2 deletions.
16 changes: 16 additions & 0 deletions static/js/zcommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function update_setting(command) {
exports.process = function (message_content) {

var content = message_content.trim();
var tokens = content.split(' ');

if (content === '/ping') {
var start_time = new Date();
Expand All @@ -77,6 +78,21 @@ exports.process = function (message_content) {
return true;
}

if (tokens[0] === '/mute_topic') {

exports.send({
command: content,
on_success: function (data) {
if (data.subject && data.stream && data.type) {
muting_ui.toggle_mute(data);
} else {
exports.tell_user(data.msg);
}
},
});
return true;
}

if (content === '/day') {
update_setting(content);
return true;
Expand Down
37 changes: 35 additions & 2 deletions zerver/lib/zcommand.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
from typing import Any, Dict
from django.utils.translation import ugettext as _

from zerver.models import UserProfile
from zerver.models import UserProfile, get_realm_stream, \
get_stream_recipient, topic_exists, Stream
from zerver.lib.actions import do_set_user_display_setting
from zerver.lib.exceptions import JsonableError
from zerver.lib.bugdown import possible_linked_stream_names

def get_topic_from_mute_topic_content(content: str, stream_name: str) -> str:
"""
This functions helps to extract the topic name from the mute_topic command
"""
stream_link = ("#**%s**" % (stream_name))
topic_name = content.replace('mute_topic', '').replace(stream_link, '')
return topic_name.strip()

def process_zcommands(content: str, user_profile: UserProfile) -> Dict[str, Any]:
if not content.startswith('/'):
raise JsonableError(_('There should be a leading slash in the zcommand.'))
command = content[1:]
content = content[1:]

tokens = content.split(' ')
command = tokens[0]

if command == 'ping':
ret = dict() # type: Dict[str, Any]
Expand All @@ -32,4 +45,24 @@ def process_zcommands(content: str, user_profile: UserProfile) -> Dict[str, Any]
ret = dict(msg=msg)
return ret

if command == 'mute_topic':
linked_stream = possible_linked_stream_names(content)
if len(tokens) < 3 or len(linked_stream) != 1:
ret = dict(msg="Usage: /mute_topic #<stream_name> <topic_name>")
return ret

[stream_name] = linked_stream
topic = get_topic_from_mute_topic_content(content, stream_name)
try:
stream = get_realm_stream(stream_name=stream_name,
realm_id=user_profile.realm.id)
except Stream.DoesNotExist:
return dict(msg='A valid stream name is required.')

if topic_exists(topic, get_stream_recipient(stream.id)):
ret = dict(subject=topic, stream=stream_name, type='stream')
else:
ret = dict(msg="A valid topic name is required.")
return ret

raise JsonableError(_('No such command: %s') % (command,))
59 changes: 59 additions & 0 deletions zerver/tests/test_zcommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
from zerver.lib.test_classes import (
ZulipTestCase,
)
from zerver.lib.actions import (
create_stream_if_needed, get_realm,
)

class ZcommandTest(ZulipTestCase):

Expand Down Expand Up @@ -53,3 +56,59 @@ def test_day_zcommand(self) -> None:
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn('still in day mode', result.json()['msg'])

def test_mute_topic_zcommand(self) -> None:
self.login(self.example_email("hamlet"))
realm = get_realm("zulip")

# Test invalid usage of mute_topic command
payload = dict(command="/mute_topic invalid")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn('Usage: /mute_topic #<stream_name> <topic_name>', result.json()['msg'])

# Test invalid stream
payload = dict(command="/mute_topic #**test stream with spaces** topic")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn('A valid stream name is required.', result.json()['msg'])

# Test invalid topic
payload = dict(command="/mute_topic #**Denmark** invalid_topic")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn('A valid topic name is required.', result.json()['msg'])

create_stream_if_needed(realm, "test stream with spaces")

# Test stream with spaces in the name
payload = dict(command="/mute_topic #**test stream with spaces** invalid_topic")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn('A valid topic name is required.', result.json()['msg'])

self.send_stream_message(self.example_email('hamlet'), "test stream with spaces",
content="test", topic_name="my topic")

# Test muting of a topic
payload = dict(command="/mute_topic #**test stream with spaces** my topic")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn("my topic", result.json()['subject'])
self.assertIn("test stream with spaces", result.json()['stream'])
self.assertIn("stream", result.json()['type'])

payload = dict(command="/mute_topic #**Verona** Verona1")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn("Verona1", result.json()['subject'])
self.assertIn("Verona", result.json()['stream'])
self.assertIn("stream", result.json()['type'])

# Test muting an already muted topic
payload = dict(command="/mute_topic #**Verona** Verona1")
result = self.client_post("/json/zcommand", payload)
self.assert_json_success(result)
self.assertIn("Verona1", result.json()['subject'])
self.assertIn("Verona", result.json()['stream'])
self.assertIn("stream", result.json()['type'])

0 comments on commit f5999a9

Please sign in to comment.