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.
This commit is contained in:
Steve Howell
2020-08-18 13:16:02 +00:00
committed by Tim Abbott
parent ae4d083a5a
commit 7bb7f2943f
2 changed files with 38 additions and 66 deletions

View File

@@ -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),

View File

@@ -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<id>[123])"