From 7bb7f2943f616c015bbc172fc81f11701c33534a Mon Sep 17 00:00:00 2001 From: Steve Howell Date: Tue, 18 Aug 2020 13:16:02 +0000 Subject: [PATCH] event_schema: Finish extraction with realm_emoji/update. We now no longer define any schemas in test_events--all of them are in event_schema, which helps our tooling cross-check schemas for openapi and node tests. --- zerver/lib/event_schema.py | 70 ++++++++++++++++++------------------- zerver/tests/test_events.py | 34 ++---------------- 2 files changed, 38 insertions(+), 66 deletions(-) diff --git a/zerver/lib/event_schema.py b/zerver/lib/event_schema.py index 4602844baf..91911e55af 100644 --- a/zerver/lib/event_schema.py +++ b/zerver/lib/event_schema.py @@ -1,10 +1,3 @@ -""" -This is new module that we intend to GROW from test_events.py. - -It will contain schemas (aka validators) for Zulip events. - -Right now it's only intended to be used by test code. -""" from typing import Dict, List, Sequence, Tuple, Union from zerver.lib.data_types import ( @@ -23,7 +16,6 @@ from zerver.lib.data_types import ( make_checker, ) from zerver.lib.topic import ORIG_TOPIC, TOPIC_LINKS, TOPIC_NAME -from zerver.lib.validator import Validator, check_dict_only, check_int from zerver.models import Realm, Stream, Subscription, UserProfile # These fields are used for "stream" events, and are included in the @@ -60,33 +52,6 @@ subscription_fields: Sequence[Tuple[str, object]] = [ ] -def check_events_dict( - required_keys: Sequence[Tuple[str, Validator[object]]], - optional_keys: Sequence[Tuple[str, Validator[object]]] = [], -) -> Validator[Dict[str, object]]: - """ - This is just a tiny wrapper on check_dict_only, but it provides - some minor benefits: - - - mark clearly that the schema is for a Zulip event - - make sure there's a type field - - add id field automatically - - sanity check that we have no duplicate keys (we - should just make check_dict_only do that, eventually) - - """ - rkeys = [key[0] for key in required_keys] - okeys = [key[0] for key in optional_keys] - keys = rkeys + okeys - assert len(keys) == len(set(keys)) - assert "type" in rkeys - assert "id" not in keys - return check_dict_only( - required_keys=[*required_keys, ("id", check_int)], - optional_keys=optional_keys, - ) - - equals_add_or_remove = UnionType( [ # force vertical @@ -640,6 +605,41 @@ realm_domains_remove_event = event_dict_type( ) check_realm_domains_remove = make_checker(realm_domains_remove_event) +realm_emoji_type = DictType( + required_keys=[ + ("id", str), + ("name", str), + ("source_url", str), + ("deactivated", bool), + ("author_id", int), + ] +) + +realm_emoji_update_event = event_dict_type( + required_keys=[ + ("type", Equals("realm_emoji")), + ("op", Equals("update")), + ("realm_emoji", StringDictType(realm_emoji_type)), + ] +) +_check_realm_emoji_update = make_checker(realm_emoji_update_event) + + +def check_realm_emoji_update(var_name: str, event: Dict[str, object]) -> None: + """ + The way we send realm emojis is kinda clumsy--we + send a dict mapping the emoji id to a sub_dict with + the fields (including the id). Ideally we can streamline + this and just send a list of dicts. The clients can make + a Map as needed. + """ + _check_realm_emoji_update(var_name, event) + + assert isinstance(event["realm_emoji"], dict) + for k, v in event["realm_emoji"].items(): + assert v["id"] == k + + export_type = DictType( required_keys=[ ("id", int), diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index 5f24a700ec..6e96cec09c 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -98,7 +98,6 @@ from zerver.lib.event_schema import ( check_default_stream_groups, check_default_streams, check_delete_message, - check_events_dict, check_has_zoom_token, check_hotspots, check_invites_changed, @@ -114,6 +113,7 @@ from zerver.lib.event_schema import ( check_realm_domains_add, check_realm_domains_change, check_realm_domains_remove, + check_realm_emoji_update, check_realm_export, check_realm_filters, check_realm_update, @@ -156,7 +156,6 @@ from zerver.lib.test_helpers import ( stdout_suppressed, ) from zerver.lib.topic import TOPIC_NAME -from zerver.lib.validator import check_bool, check_dict_only, check_int, check_string, equals from zerver.models import ( Attachment, Message, @@ -1231,33 +1230,6 @@ class NormalActionsTest(BaseAction): self.assertEqual(state_data['zulip_plan_is_not_limited'], False) def test_realm_emoji_events(self) -> None: - check_realm_emoji_fields = check_dict_only([ - ('id', check_string), - ('name', check_string), - ('source_url', check_string), - ('deactivated', check_bool), - ('author_id', check_int), - ]) - - def realm_emoji_checker(var_name: str, val: object) -> None: - ''' - The way we send realm emojis is kinda clumsy--we - send a dict mapping the emoji id to a sub_dict with - the fields (including the id). Ideally we can streamline - this and just send a list of dicts. The clients can make - a Map as needed. - ''' - assert isinstance(val, dict) - for k, v in val.items(): - assert isinstance(k, str) - assert v['id'] == k - check_realm_emoji_fields(f'{var_name}[{k}]', v) - - schema_checker = check_events_dict([ - ('type', equals('realm_emoji')), - ('op', equals('update')), - ('realm_emoji', realm_emoji_checker), - ]) author = self.example_user('iago') with get_test_image_file('img.png') as img_file: events = self.verify_action( @@ -1267,11 +1239,11 @@ class NormalActionsTest(BaseAction): author, img_file)) - schema_checker('events[0]', events[0]) + check_realm_emoji_update('events[0]', events[0]) events = self.verify_action( lambda: do_remove_realm_emoji(self.user_profile.realm, "my_emoji")) - schema_checker('events[0]', events[0]) + check_realm_emoji_update('events[0]', events[0]) def test_realm_filter_events(self) -> None: regex = "#(?P[123])"