test_events: Extract BaseAction.

This commit is contained in:
Steve Howell 2020-06-27 15:03:37 +00:00 committed by Tim Abbott
parent e8649ec047
commit 987408db68
4 changed files with 21 additions and 20 deletions

View File

@ -219,7 +219,7 @@ The design above achieves everything we desire, at the cost that we
need to write a correct `apply_events` function. This is a difficult
function to implement correctly, because the situations that it tests
for almost never happen (being race conditions). So we have a special
test class, `EventsRegisterTest`, that is specifically designed to
helper test class, `BaseAction`, that is specifically designed to
test this function by ensuring the possible race condition always
happens. In particular, it does the following:
@ -231,7 +231,7 @@ e.g. `do_change_full_name`, and capture any events that are generated.
`fetch_initial_state_data` again now.
The `apply_events` code is correct if those two results are identical.
The `EventsRegisterTest` tests in `test_events` will print a diff
The `BaseAction` tests in `test_events` will print a diff
between the "hybrid state" and the "normal state" obtained from
calling `fetch_initial_state_data` after the changes. Those tests
also inspect the events generated to ensure they have the expected
@ -242,9 +242,9 @@ to differ what what it was before (which help catch common classes of
bugs).
The final detail we need to ensure that `apply_events` always works
correctly is to make sure that we have `EventsRegisterTest` tests for
correctly is to make sure that we have relevant tests for
every event type that can be generated by Zulip. This can be tested
manually using `test-backend --coverage EventsRegisterTest` and then
manually using `test-backend --coverage BaseAction` and then
checking that all the calls to `send_event` are covered. Someday
we'll add automation that verifies this directly by inspecting the
coverage data.

View File

@ -398,7 +398,7 @@ below some threshold.
The Zulip back end has a mechanism where it will fetch initial data
for a client from the database, and then it will subsequently apply
some queued up events to that data to the data structure before notifying
the client. The `EventsRegisterTest.do_test()` helper helps tests
the client. The `BaseAction.do_test()` helper helps tests
verify that the application of those events via apply_events() produces
the same data structure as performing an action that generates said event.

View File

@ -84,7 +84,7 @@ def always_want(msg_type: str) -> bool:
# Fetch initial data. When event_types is not specified, clients want
# all event types. Whenever you add new code to this function, you
# should also add corresponding events for changes in the data
# structures and new code to apply_events (and add a test in EventsRegisterTest).
# structures and new code to apply_events (and add a test in test_events.py).
def fetch_initial_state_data(user_profile: UserProfile,
event_types: Optional[Iterable[str]],
queue_id: str, client_gravatar: bool,

View File

@ -164,24 +164,11 @@ basic_stream_fields = [
('stream_post_policy', check_int),
]
class EventsRegisterTest(ZulipTestCase):
class BaseAction(ZulipTestCase):
def setUp(self) -> None:
super().setUp()
self.user_profile = self.example_user('hamlet')
def create_bot(self, email: str, **extras: Any) -> Optional[UserProfile]:
return self.create_test_bot(email, self.user_profile, **extras)
def realm_bot_schema(self, field_name: str, check: Validator[object]) -> Validator[Dict[str, object]]:
return check_events_dict([
('type', equals('realm_bot')),
('op', equals('update')),
('bot', check_dict_only([
('user_id', check_int),
(field_name, check),
])),
])
def do_test(self, action: Callable[[], object], event_types: Optional[List[str]]=None,
include_subscribers: bool=True, state_change_expected: bool=True,
notification_settings_null: bool=False, client_gravatar: bool=True,
@ -310,6 +297,20 @@ class EventsRegisterTest(ZulipTestCase):
sys.stdout.flush()
raise AssertionError('Mismatching states')
class NormalActionsTest(BaseAction):
def create_bot(self, email: str, **extras: Any) -> Optional[UserProfile]:
return self.create_test_bot(email, self.user_profile, **extras)
def realm_bot_schema(self, field_name: str, check: Validator[object]) -> Validator[Dict[str, object]]:
return check_events_dict([
('type', equals('realm_bot')),
('op', equals('update')),
('bot', check_dict_only([
('user_id', check_int),
(field_name, check),
])),
])
def test_mentioned_send_message_events(self) -> None:
user = self.example_user('hamlet')