mirror of
https://github.com/zulip/zulip.git
synced 2025-11-04 22:13:26 +00:00
This is somewhat hacky, in that in order to do what we're doing, we need to parse the HTML of the rendered page to extract the first paragraph to include in the open graph description field. But BeautifulSoup does a good job of it. This carries a nontrivial performance penalty for loading these pages, but overall /help/ is a low-traffic site compared to the main app, so it doesn't matter much. (As a sidenote, it wouldn't be a bad idea to cache this stuff). There's lots of things we can improve in this, largely through editing the articles, but we can deal with that over time. Thanks to Rishi for writing all the tests.
115 lines
5.6 KiB
Python
115 lines
5.6 KiB
Python
import time
|
|
|
|
from django.http import HttpResponse
|
|
from django.test import override_settings
|
|
from unittest.mock import Mock, patch
|
|
from zerver.lib.test_classes import ZulipTestCase
|
|
from zerver.middleware import is_slow_query
|
|
from zerver.middleware import write_log_line
|
|
|
|
class SlowQueryTest(ZulipTestCase):
|
|
SLOW_QUERY_TIME = 10
|
|
log_data = {'extra': '[transport=websocket]',
|
|
'time_started': 0,
|
|
'bugdown_requests_start': 0,
|
|
'bugdown_time_start': 0,
|
|
'remote_cache_time_start': 0,
|
|
'remote_cache_requests_start': 0}
|
|
|
|
def test_is_slow_query(self) -> None:
|
|
self.assertFalse(is_slow_query(1.1, '/some/random/url'))
|
|
self.assertTrue(is_slow_query(2, '/some/random/url'))
|
|
self.assertTrue(is_slow_query(5.1, '/activity'))
|
|
self.assertFalse(is_slow_query(2, '/activity'))
|
|
self.assertFalse(is_slow_query(2, '/json/report/error'))
|
|
self.assertFalse(is_slow_query(2, '/api/v1/deployments/report_error'))
|
|
self.assertFalse(is_slow_query(2, '/realm_activity/whatever'))
|
|
self.assertFalse(is_slow_query(2, '/user_activity/whatever'))
|
|
self.assertFalse(is_slow_query(9, '/accounts/webathena_kerberos_login/'))
|
|
self.assertTrue(is_slow_query(11, '/accounts/webathena_kerberos_login/'))
|
|
|
|
@override_settings(SLOW_QUERY_LOGS_STREAM="logs")
|
|
@patch('logging.info')
|
|
def test_slow_query_log(self, mock_logging_info: Mock) -> None:
|
|
self.log_data['time_started'] = time.time() - self.SLOW_QUERY_TIME
|
|
write_log_line(self.log_data, path='/socket/open', method='SOCKET',
|
|
remote_ip='123.456.789.012', email='unknown', client_name='?')
|
|
last_message = self.get_last_message()
|
|
self.assertEqual(last_message.sender.email, "error-bot@zulip.com")
|
|
self.assertIn("logs", str(last_message.recipient))
|
|
self.assertEqual(last_message.topic_name(), "testserver: slow queries")
|
|
self.assertRegexpMatches(last_message.content,
|
|
r"123\.456\.789\.012 SOCKET 200 10\.\ds .*")
|
|
|
|
@override_settings(ERROR_BOT=None)
|
|
@patch('logging.info')
|
|
@patch('zerver.lib.actions.internal_send_message')
|
|
def test_slow_query_log_without_error_bot(self, mock_internal_send_message: Mock,
|
|
mock_logging_info: Mock) -> None:
|
|
self.log_data['time_started'] = time.time() - self.SLOW_QUERY_TIME
|
|
write_log_line(self.log_data, path='/socket/open', method='SOCKET',
|
|
remote_ip='123.456.789.012', email='unknown', client_name='?')
|
|
mock_internal_send_message.assert_not_called()
|
|
|
|
class OpenGraphTest(ZulipTestCase):
|
|
def check_title_and_description(self, path: str, title: str, description: str) -> None:
|
|
response = self.client_get(path)
|
|
self.assert_in_success_response([
|
|
# Open graph
|
|
'<meta property="og:title" content="{}">'.format(title),
|
|
'<meta property="og:description" content="{}">'.format(description),
|
|
# Twitter
|
|
'<meta property="twitter:title" content="{}">'.format(title),
|
|
'<meta name="twitter:description" content="{}">'.format(description),
|
|
], response)
|
|
|
|
def test_admonition_and_link(self) -> None:
|
|
# disable-message-edit-history starts with an {!admin-only.md!}, and has a link
|
|
# in the first paragraph.
|
|
self.check_title_and_description(
|
|
'/help/disable-message-edit-history',
|
|
"Disable message edit history (Zulip Help Center)",
|
|
"By default, Zulip displays messages that have been edited with an EDITED tag, " +
|
|
"and users can view the edit history of a message.")
|
|
|
|
def test_settings_tab(self) -> None:
|
|
# deactivate-your-account starts with {settings_tab|your-account}
|
|
self.check_title_and_description(
|
|
'/help/deactivate-your-account',
|
|
"Deactivate your account (Zulip Help Center)",
|
|
# Ideally, we'd grab the second and third paragraphs as well, if
|
|
# the first paragraph is this short
|
|
"Go to Your account.")
|
|
|
|
def test_tabs(self) -> None:
|
|
# logging-out starts with {start_tabs}
|
|
self.check_title_and_description(
|
|
'/help/logging-out',
|
|
"Logging out (Zulip Help Center)",
|
|
# Ideally we'd do something better here
|
|
"")
|
|
|
|
def test_index_pages(self) -> None:
|
|
self.check_title_and_description(
|
|
'/help/',
|
|
"Zulip Help Center",
|
|
("Zulip is a group chat app. Its most distinctive characteristic is that "
|
|
"conversation within an organization is divided into “streams” and further "
|
|
"subdivided into “topics”, so that much finer-grained conversations are possible "
|
|
"than with IRC or other chat tools."))
|
|
|
|
self.check_title_and_description(
|
|
'/api/',
|
|
"Zulip API Documentation",
|
|
("Zulip's APIs allow you to integrate other services with Zulip. This "
|
|
"guide should help you find the API you need:"))
|
|
|
|
def test_nonexistent_page(self) -> None:
|
|
response = self.client_get('/help/not-a-real-page')
|
|
# Test that our open graph logic doesn't throw a 500
|
|
self.assertEqual(response.status_code, 404)
|
|
self.assert_in_response(
|
|
# Probably we should make this "Zulip Help Center"
|
|
'<meta property="og:title" content="No such article. (Zulip Help Center)">', response)
|
|
self.assert_in_response('<meta property="og:description" content="No such article.">', response)
|