tornado: Move the /notify-tornado endpoint, and document it better.

This commit is contained in:
Alex Vandiver 2024-02-08 19:10:25 +00:00 committed by Tim Abbott
parent 3f8a0c968a
commit 84fa9be73a
5 changed files with 16 additions and 10 deletions

View File

@ -227,9 +227,10 @@ class EventsEndpointTest(ZulipTestCase):
self.assert_json_error(result, "User not authorized for this query")
def test_tornado_endpoint(self) -> None:
# This test is mostly intended to get minimal coverage on
# the /notify_tornado endpoint, so we can have 100% URL coverage,
# but it does exercise a little bit of the codepath.
# This test is mostly intended to get minimal coverage on the
# /api/internal/notify_tornado endpoint (only used in
# puppeteer tests), so we can have 100% URL coverage, but it
# does exercise a little bit of the codepath.
post_data = dict(
data=orjson.dumps(
dict(
@ -243,7 +244,7 @@ class EventsEndpointTest(ZulipTestCase):
req = HostRequestMock(post_data)
req.META["REMOTE_ADDR"] = "127.0.0.1"
with self.assertRaises(RequestVariableMissingError) as context:
result = self.client_post_request("/notify_tornado", req)
result = self.client_post_request("/api/internal/notify_tornado", req)
self.assertEqual(str(context.exception), "Missing 'secret' argument")
self.assertEqual(context.exception.http_status_code, 400)
@ -251,21 +252,21 @@ class EventsEndpointTest(ZulipTestCase):
req = HostRequestMock(post_data, user_profile=None)
req.META["REMOTE_ADDR"] = "127.0.0.1"
with self.assertRaises(AccessDeniedError) as access_denied_error:
result = self.client_post_request("/notify_tornado", req)
result = self.client_post_request("/api/internal/notify_tornado", req)
self.assertEqual(str(access_denied_error.exception), "Access denied")
self.assertEqual(access_denied_error.exception.http_status_code, 403)
post_data["secret"] = settings.SHARED_SECRET
req = HostRequestMock(post_data, tornado_handler=dummy_handler)
req.META["REMOTE_ADDR"] = "127.0.0.1"
result = self.client_post_request("/notify_tornado", req)
result = self.client_post_request("/api/internal/notify_tornado", req)
self.assert_json_success(result)
post_data = dict(secret=settings.SHARED_SECRET)
req = HostRequestMock(post_data, tornado_handler=dummy_handler)
req.META["REMOTE_ADDR"] = "127.0.0.1"
with self.assertRaises(RequestVariableMissingError) as context:
result = self.client_post_request("/notify_tornado", req)
result = self.client_post_request("/api/internal/notify_tornado", req)
self.assertEqual(str(context.exception), "Missing 'data' argument")
self.assertEqual(context.exception.http_status_code, 400)

View File

@ -17,10 +17,10 @@ def create_tornado_application(*, autoreload: bool = False) -> tornado.web.Appli
django_handler.load_middleware()
urls = (
r"/notify_tornado",
r"/json/events",
r"/api/v1/events",
r"/api/v1/events/internal",
r"/api/internal/notify_tornado",
)
return tornado.web.Application(

View File

@ -155,9 +155,12 @@ def send_notification_http(port: int, data: Mapping[str, Any]) -> None:
process_notification(data)
else:
# This codepath is only used when running full-stack puppeteer
# tests, which don't have RabbitMQ but do have a separate
# Tornado process.
tornado_url = get_tornado_url(port)
requests_client().post(
tornado_url + "/notify_tornado",
tornado_url + "/api/internal/notify_tornado",
data=dict(data=orjson.dumps(data), secret=settings.SHARED_SECRET),
)

View File

@ -43,6 +43,8 @@ def in_tornado_thread(f: Callable[P, T]) -> Callable[P, T]:
def notify(
request: HttpRequest, data: Mapping[str, Any] = REQ(json_validator=check_dict([]))
) -> HttpResponse:
# Only the puppeteer full-stack tests use this endpoint; it
# injects an event, as if read from RabbitMQ.
in_tornado_thread(process_notification)(data)
return json_success(request)

View File

@ -745,7 +745,7 @@ urls += [
#
# Since these views don't use rest_dispatch, they cannot have
# asynchronous Tornado behavior.
path("notify_tornado", notify),
path("api/internal/notify_tornado", notify),
path("api/v1/events/internal", get_events_internal),
]