Files
zulip/tools/check-schemas
opmkumar 2a15da47d9 message_edit: Show typing indicator for message editing.
This commit adds typing indicators for message editing in stream
as well as in dm, if the send typing notification
for corresponding is enabled.

Based on earlier work in #28585.

Co-authored-by: Rohan Gudimetla <rohan.gudimetla07@gmail.com>

Fixes #25719.
2025-02-12 15:08:56 -08:00

130 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python3
#
# Validates that 3 data sources agree about the structure of Zulip's events API:
#
# * Node fixtures for the server_events_dispatch.js tests.
# * OpenAPI definitions in zerver/openapi/zulip.yaml
# * The schemas defined in zerver/lib/events_schema.py used for the
# Zulip server's test suite.
#
# We compare the Python and OpenAPI schemas by converting the OpenAPI data
# into the event_schema style of types and the diffing the schemas.
import argparse
import os
import subprocess
import sys
from collections.abc import Callable
from typing import Any
import orjson
TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(TOOLS_DIR))
ROOT_DIR = os.path.dirname(TOOLS_DIR)
EVENTS_JS = "web/tests/lib/events.cjs"
# check for the venv
from tools.lib import sanity_check
sanity_check.check_venv(__file__)
USAGE = """
This program reads in fixture data for our
node tests, and then it validates the fixture
data with checkers from event_schema.py (which
are the same Python functions we use to validate
events in test_events.py).
It currently takes no arguments.
"""
parser = argparse.ArgumentParser(usage=USAGE)
parser.parse_args()
# We can eliminate the django dependency in event_schema,
# but unfortunately it"s coupled to modules like validate.py
# and topic.py.
import django
os.environ["DJANGO_SETTINGS_MODULE"] = "zproject.test_settings"
django.setup()
from zerver.lib import event_schema
make_checker = event_schema.__dict__["make_checker"]
def get_event_checker(event: dict[str, Any]) -> Callable[[str, dict[str, Any]], None]:
# Follow the naming convention to find the event checker.
# Start by grabbing the event type.
name = event["type"]
# This is a temporary workaround until a proper fix is implemented.
if name == "typing_edit_message":
if event["recipient"]["type"] == "channel":
name = "typing_edit_channel_message"
else:
name = "typing_edit_direct_message"
# Handle things like AttachmentRemoveEvent
if "op" in event:
name += "_" + event["op"].title()
# Change to CamelCase
name = name.replace("_", " ").title().replace(" ", "")
# And add the prefix.
name = "Event" + name
if not hasattr(event_schema, name):
raise ValueError(f"We could not find {name} in event_schemas.py")
return make_checker(getattr(event_schema, name))
def check_event(name: str, event: dict[str, Any]) -> None:
event["id"] = 1
checker = get_event_checker(event)
try:
checker(name, event)
except AssertionError:
print(f"\n{EVENTS_JS} has bad data for {name}:\n\n")
raise
def read_fixtures() -> dict[str, Any]:
cmd = [
"node",
os.path.join(TOOLS_DIR, "node_lib/dump_fixtures.js"),
]
schema = subprocess.check_output(cmd)
return orjson.loads(schema)
def verify_fixtures_are_sorted(names: list[str]) -> None:
for i in range(1, len(names)):
if names[i] < names[i - 1]:
raise Exception(
f"""
Please keep your fixtures in order within
your events.js file. The following
key is out of order
{names[i]}
"""
)
def run() -> None:
fixtures = read_fixtures()
verify_fixtures_are_sorted(list(fixtures.keys()))
for name, event in fixtures.items():
check_event(name, event)
print(f"Successfully checked {len(fixtures)} fixtures. All tests passed.")
if __name__ == "__main__":
run()