2020-07-04 16:00:43 +02:00
|
|
|
from django.utils.timezone import now as timezone_now
|
|
|
|
|
2021-07-16 22:11:10 +02:00
|
|
|
from zerver.lib.actions import do_change_stream_invite_only
|
2020-07-04 16:00:43 +02:00
|
|
|
from zerver.lib.test_classes import ZulipTestCase
|
2021-07-16 22:11:10 +02:00
|
|
|
from zerver.models import Message, UserMessage, get_client, get_realm, get_stream
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
class TopicHistoryTest(ZulipTestCase):
|
|
|
|
def test_topics_history_zephyr_mirror(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.mit_user("sipbtest")
|
|
|
|
stream_name = "new_stream"
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# Send a message to this new stream from another user
|
|
|
|
self.subscribe(self.mit_user("starnine"), stream_name)
|
|
|
|
stream = get_stream(stream_name, user_profile.realm)
|
2021-02-12 08:19:30 +01:00
|
|
|
self.send_stream_message(self.mit_user("starnine"), stream_name, topic_name="secret topic")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# Now subscribe this MIT user to the new stream and verify
|
|
|
|
# that the new topic is not accessible
|
|
|
|
self.login_user(user_profile)
|
|
|
|
self.subscribe(user_profile, stream_name)
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = f"/json/users/me/{stream.id}/topics"
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {}, subdomain="zephyr")
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
history = result.json()["topics"]
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assertEqual(history, [])
|
|
|
|
|
|
|
|
def test_topics_history(self) -> None:
|
|
|
|
# verified: int(UserMessage.flags.read) == 1
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.example_user("iago")
|
2020-07-04 16:00:43 +02:00
|
|
|
self.login_user(user_profile)
|
2021-02-12 08:20:45 +01:00
|
|
|
stream_name = "Verona"
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
stream = get_stream(stream_name, user_profile.realm)
|
|
|
|
recipient = stream.recipient
|
|
|
|
|
|
|
|
def create_test_message(topic: str) -> int:
|
|
|
|
# TODO: Clean this up to send messages the normal way.
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
hamlet = self.example_user("hamlet")
|
2020-07-04 16:00:43 +02:00
|
|
|
message = Message(
|
|
|
|
sender=hamlet,
|
|
|
|
recipient=recipient,
|
2021-02-12 08:20:45 +01:00
|
|
|
content="whatever",
|
2020-07-04 16:00:43 +02:00
|
|
|
date_sent=timezone_now(),
|
2021-02-12 08:20:45 +01:00
|
|
|
sending_client=get_client("whatever"),
|
2020-07-04 16:00:43 +02:00
|
|
|
)
|
|
|
|
message.set_topic_name(topic)
|
|
|
|
message.save()
|
|
|
|
|
|
|
|
UserMessage.objects.create(
|
|
|
|
user_profile=user_profile,
|
|
|
|
message=message,
|
|
|
|
flags=0,
|
|
|
|
)
|
|
|
|
|
|
|
|
return message.id
|
|
|
|
|
|
|
|
# our most recent topics are topic0, topic1, topic2
|
|
|
|
|
|
|
|
# Create old messages with strange spellings.
|
2021-02-12 08:20:45 +01:00
|
|
|
create_test_message("topic2")
|
|
|
|
create_test_message("toPIc1")
|
|
|
|
create_test_message("toPIc0")
|
|
|
|
create_test_message("topic2")
|
|
|
|
create_test_message("topic2")
|
|
|
|
create_test_message("Topic2")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# Create new messages
|
2021-02-12 08:20:45 +01:00
|
|
|
topic2_msg_id = create_test_message("topic2")
|
|
|
|
create_test_message("topic1")
|
|
|
|
create_test_message("topic1")
|
|
|
|
topic1_msg_id = create_test_message("topic1")
|
|
|
|
topic0_msg_id = create_test_message("topic0")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = f"/json/users/me/{stream.id}/topics"
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {})
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
history = result.json()["topics"]
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# We only look at the most recent three topics, because
|
|
|
|
# the prior fixture data may be unreliable.
|
|
|
|
history = history[:3]
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
[topic["name"] for topic in history],
|
2021-02-12 08:19:30 +01:00
|
|
|
[
|
2021-02-12 08:20:45 +01:00
|
|
|
"topic0",
|
|
|
|
"topic1",
|
|
|
|
"topic2",
|
2021-02-12 08:19:30 +01:00
|
|
|
],
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
[topic["max_id"] for topic in history],
|
2021-02-12 08:19:30 +01:00
|
|
|
[
|
|
|
|
topic0_msg_id,
|
|
|
|
topic1_msg_id,
|
|
|
|
topic2_msg_id,
|
|
|
|
],
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# Now try as cordelia, who we imagine as a totally new user in
|
|
|
|
# that she doesn't have UserMessage rows. We should see the
|
|
|
|
# same results for a public stream.
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("cordelia")
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {})
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
history = result.json()["topics"]
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# We only look at the most recent three topics, because
|
|
|
|
# the prior fixture data may be unreliable.
|
|
|
|
history = history[:3]
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
[topic["name"] for topic in history],
|
2021-02-12 08:19:30 +01:00
|
|
|
[
|
2021-02-12 08:20:45 +01:00
|
|
|
"topic0",
|
|
|
|
"topic1",
|
|
|
|
"topic2",
|
2021-02-12 08:19:30 +01:00
|
|
|
],
|
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertIn("topic0", [topic["name"] for topic in history])
|
2020-07-04 16:00:43 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
[topic["max_id"] for topic in history],
|
2021-02-12 08:19:30 +01:00
|
|
|
[
|
|
|
|
topic0_msg_id,
|
|
|
|
topic1_msg_id,
|
|
|
|
topic2_msg_id,
|
|
|
|
],
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# Now make stream private, but subscribe cordelia
|
|
|
|
do_change_stream_invite_only(stream, True)
|
|
|
|
self.subscribe(self.example_user("cordelia"), stream.name)
|
|
|
|
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {})
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
history = result.json()["topics"]
|
2020-07-04 16:00:43 +02:00
|
|
|
history = history[:3]
|
|
|
|
|
|
|
|
# Cordelia doesn't have these recent history items when we
|
|
|
|
# wasn't subscribed in her results.
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertNotIn("topic0", [topic["name"] for topic in history])
|
|
|
|
self.assertNotIn("topic1", [topic["name"] for topic in history])
|
|
|
|
self.assertNotIn("topic2", [topic["name"] for topic in history])
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
def test_bad_stream_id(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# non-sensible stream id
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = "/json/users/me/9999999999/topics"
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {})
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Invalid stream id")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# out of realm
|
|
|
|
bad_stream = self.make_stream(
|
2021-02-12 08:20:45 +01:00
|
|
|
"mit_stream",
|
|
|
|
realm=get_realm("zephyr"),
|
2020-07-04 16:00:43 +02:00
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = f"/json/users/me/{bad_stream.id}/topics"
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {})
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Invalid stream id")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# private stream to which I am not subscribed
|
|
|
|
private_stream = self.make_stream(
|
2021-02-12 08:20:45 +01:00
|
|
|
"private_stream",
|
2020-07-04 16:00:43 +02:00
|
|
|
invite_only=True,
|
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = f"/json/users/me/{private_stream.id}/topics"
|
2020-09-02 08:14:51 +02:00
|
|
|
result = self.client_get(endpoint, {})
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Invalid stream id")
|
2020-07-04 16:00:43 +02:00
|
|
|
|
2020-08-21 17:12:05 +02:00
|
|
|
def test_get_topics_web_public_stream_web_public_request(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
stream = self.make_stream("web-public-steram", is_web_public=True)
|
2020-08-21 17:12:05 +02:00
|
|
|
for i in range(3):
|
2021-02-12 08:19:30 +01:00
|
|
|
self.send_stream_message(
|
2021-02-12 08:20:45 +01:00
|
|
|
self.example_user("iago"), stream.name, topic_name="topic" + str(i)
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2020-08-21 17:12:05 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = f"/json/users/me/{stream.id}/topics"
|
2020-08-21 17:12:05 +02:00
|
|
|
result = self.client_get(endpoint)
|
|
|
|
self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
history = result.json()["topics"]
|
2021-02-12 08:19:30 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
[topic["name"] for topic in history],
|
2021-02-12 08:19:30 +01:00
|
|
|
[
|
2021-02-12 08:20:45 +01:00
|
|
|
"topic2",
|
|
|
|
"topic1",
|
|
|
|
"topic0",
|
2021-02-12 08:19:30 +01:00
|
|
|
],
|
|
|
|
)
|
2020-08-21 17:12:05 +02:00
|
|
|
|
|
|
|
def test_get_topics_non_web_public_stream_web_public_request(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
stream = get_stream("Verona", self.example_user("iago").realm)
|
|
|
|
endpoint = f"/json/users/me/{stream.id}/topics"
|
2020-08-21 17:12:05 +02:00
|
|
|
result = self.client_get(endpoint)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Invalid stream id", 400)
|
2020-08-21 17:12:05 +02:00
|
|
|
|
|
|
|
def test_get_topics_non_existant_stream_web_public_request(self) -> None:
|
|
|
|
non_existant_stream_id = 10000000000000000000000
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = f"/json/users/me/{non_existant_stream_id}/topics"
|
2020-08-21 17:12:05 +02:00
|
|
|
result = self.client_get(endpoint)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Invalid stream id", 400)
|
2020-08-21 17:12:05 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2020-07-04 16:00:43 +02:00
|
|
|
class TopicDeleteTest(ZulipTestCase):
|
|
|
|
def test_topic_delete(self) -> None:
|
|
|
|
initial_last_msg_id = self.get_last_message().id
|
2021-02-12 08:20:45 +01:00
|
|
|
stream_name = "new_stream"
|
|
|
|
topic_name = "new topic 2"
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# NON-ADMIN USER
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.example_user("hamlet")
|
2020-07-04 16:00:43 +02:00
|
|
|
self.subscribe(user_profile, stream_name)
|
|
|
|
|
|
|
|
# Send message
|
|
|
|
stream = get_stream(stream_name, user_profile.realm)
|
|
|
|
self.send_stream_message(user_profile, stream_name, topic_name=topic_name)
|
|
|
|
last_msg_id = self.send_stream_message(user_profile, stream_name, topic_name=topic_name)
|
|
|
|
|
|
|
|
# Deleting the topic
|
|
|
|
self.login_user(user_profile)
|
2021-02-12 08:20:45 +01:00
|
|
|
endpoint = "/json/streams/" + str(stream.id) + "/delete_topic"
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
|
|
|
endpoint,
|
|
|
|
{
|
|
|
|
"topic_name": topic_name,
|
|
|
|
},
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_error(result, "Must be an organization administrator")
|
|
|
|
self.assertEqual(self.get_last_message().id, last_msg_id)
|
|
|
|
|
|
|
|
# Make stream private with limited history
|
2021-02-12 08:19:30 +01:00
|
|
|
do_change_stream_invite_only(stream, invite_only=True, history_public_to_subscribers=False)
|
2020-07-04 16:00:43 +02:00
|
|
|
|
|
|
|
# ADMIN USER subscribed now
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.example_user("iago")
|
2020-07-04 16:00:43 +02:00
|
|
|
self.subscribe(user_profile, stream_name)
|
|
|
|
self.login_user(user_profile)
|
|
|
|
new_last_msg_id = self.send_stream_message(user_profile, stream_name, topic_name=topic_name)
|
|
|
|
|
|
|
|
# Now admin deletes all messages in topic -- which should only
|
|
|
|
# delete new_last_msg_id, i.e. the one sent since they joined.
|
|
|
|
self.assertEqual(self.get_last_message().id, new_last_msg_id)
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
|
|
|
endpoint,
|
|
|
|
{
|
|
|
|
"topic_name": topic_name,
|
|
|
|
},
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(self.get_last_message().id, last_msg_id)
|
|
|
|
|
|
|
|
# Try to delete all messages in the topic again. There are no messages accessible
|
|
|
|
# to the administrator, so this should do nothing.
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
|
|
|
endpoint,
|
|
|
|
{
|
|
|
|
"topic_name": topic_name,
|
|
|
|
},
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(self.get_last_message().id, last_msg_id)
|
|
|
|
|
|
|
|
# Make the stream's history public to subscribers
|
2021-02-12 08:19:30 +01:00
|
|
|
do_change_stream_invite_only(stream, invite_only=True, history_public_to_subscribers=True)
|
2020-07-04 16:00:43 +02:00
|
|
|
# Delete the topic should now remove all messages
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
|
|
|
endpoint,
|
|
|
|
{
|
|
|
|
"topic_name": topic_name,
|
|
|
|
},
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(self.get_last_message().id, initial_last_msg_id)
|
|
|
|
|
|
|
|
# Delete again, to test the edge case of deleting an empty topic.
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
|
|
|
endpoint,
|
|
|
|
{
|
|
|
|
"topic_name": topic_name,
|
|
|
|
},
|
|
|
|
)
|
2020-07-04 16:00:43 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(self.get_last_message().id, initial_last_msg_id)
|