Skip to content

Commit

Permalink
tests: boxes: Add tests for saving drafts.
Browse files Browse the repository at this point in the history
Added
- 1 fixture for saved drafts
- 2 fixtures for draft compositions - stream and private
- 2 setup fixtures - stream and private
- 2 test functions for stream compositions
  - when a draft previously exists, call the confirmation popup
  - when new draft matches saved draft, do not save again
- 3 test functions for private compositions - valid recipients,
invalid recipients, new draft matches already saved draft
Co-authored-by: Manu_K_Paul <[email protected]>
  • Loading branch information
Niloth-p committed Jun 14, 2024
1 parent e5e9010 commit 88584cd
Showing 1 changed file with 238 additions and 1 deletion.
239 changes: 238 additions & 1 deletion tests/ui_tools/test_boxes.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import datetime
from collections import OrderedDict
from typing import Any, Callable, Dict, List, Optional
from functools import reduce
from typing import Any, Callable, Dict, List, Optional, Tuple, Union

import pytest
from pytest import FixtureRequest
from pytest import param as case
from pytest_mock import MockerFixture
from urwid import Widget
Expand All @@ -11,6 +13,9 @@
TYPING_STARTED_EXPIRY_PERIOD,
TYPING_STARTED_WAIT_PERIOD,
TYPING_STOPPED_WAIT_PERIOD,
Composition,
PrivateComposition,
StreamComposition,
)
from zulipterminal.config.keys import (
keys_for_command,
Expand Down Expand Up @@ -103,6 +108,238 @@ def test_not_calling_typing_method_without_recipients(

assert not write_box.model.send_typing_status_by_user_ids.called

@pytest.fixture(
params=[
{
"draft_composition": None,
"expected_function": "model.save_draft",
},
{
"draft_composition": StreamComposition(
type="stream",
to="Random Stream",
content="Random stream draft",
subject="Topic name",
read_by_sender=True,
),
"expected_function": "view.controller.save_draft_confirmation_popup",
},
{
"draft_composition": PrivateComposition(
type="private",
to=[5140],
content="Random private draft",
read_by_sender=True,
),
"expected_function": "view.controller.save_draft_confirmation_popup",
},
{
"draft_composition": PrivateComposition(
type="private",
to=[5140, 5179],
content="Random group draft",
read_by_sender=True,
),
"expected_function": "view.controller.save_draft_confirmation_popup",
},
],
ids=[
"no_saved_draft_exists",
"saved_stream_draft_exists",
"saved_private_draft_exists",
"saved_private_group_draft_exists",
],
)
def saved_draft(
self, request: FixtureRequest
) -> Dict[str, Union[Optional[Composition], str]]:
return request.param

@pytest.fixture(
params=[
{
"type": "private",
"to": [5140],
"content": "Random message",
"read_by_sender": True,
},
{
"type": "private",
"to": [5140, 5179],
"content": "Random DM group message",
"read_by_sender": True,
},
],
ids=["dm", "dm_group"],
)
def private_draft_composition(self, request: FixtureRequest) -> PrivateComposition:
return request.param

@pytest.fixture(
params=[
{
"type": "stream",
"to": "Current Stream",
"content": "Random message",
"subject": "Topic",
"read_by_sender": True,
},
],
)
def stream_draft_composition(self, request: FixtureRequest) -> StreamComposition:
return request.param

@pytest.fixture
def private_draft_setup_fixture(self, mocker: MockerFixture, private_draft_composition: PrivateComposition, write_box: WriteBox) -> Tuple[MockerFixture, WriteBox]:
mocker.patch(MODULE + ".WriteBox.update_recipients")
write_box.msg_write_box = mocker.Mock(
edit_text=private_draft_composition["content"]
)
write_box.to_write_box = mocker.Mock()
write_box.compose_box_status = "open_with_private"
write_box.recipient_user_ids = private_draft_composition["to"]
return mocker, write_box

@pytest.fixture
def stream_draft_setup_fixture(self, mocker: MockerFixture, stream_draft_composition: StreamComposition, write_box: WriteBox) -> Tuple[MockerFixture, WriteBox]:
mocker.patch(MODULE + ".WriteBox.update_recipients")
write_box.msg_write_box = mocker.Mock(
edit_text=stream_draft_composition["content"]
)
write_box.stream_write_box = mocker.Mock(
edit_text=stream_draft_composition["to"]
)
write_box.title_write_box = mocker.Mock(
edit_text=stream_draft_composition["subject"]
)
write_box.compose_box_status = "open_with_stream"
write_box.stream_id = 1
return mocker, write_box

@pytest.mark.parametrize("key", keys_for_command("SAVE_AS_DRAFT"))
def test_keypress_SAVE_AS_DRAFT_stream(
self,
key: str,
saved_draft: Dict[str, Union[Optional[Composition], str]],
stream_draft_composition: StreamComposition,
stream_draft_setup_fixture: Tuple[MockerFixture, WriteBox],
write_box: WriteBox,
widget_size: Callable[[Widget], urwid_Size],
) -> None:
draft_saved_in_current_session = saved_draft["draft_composition"]
_, write_box = stream_draft_setup_fixture
assert isinstance(saved_draft["expected_function"], str)
expected_function = reduce(
getattr, saved_draft["expected_function"].split("."), write_box
)
write_box.model.session_draft_message.return_value = (
draft_saved_in_current_session
)

size = widget_size(write_box)
write_box.keypress(size, key)

write_box.model.session_draft_message.assert_called()
expected_function.assert_called_once_with(stream_draft_composition)

@pytest.mark.parametrize("key", keys_for_command("SAVE_AS_DRAFT"))
def test_keypress_SAVE_AS_DRAFT_private__valid_recipients(
self,
key: str,
mocker: MockerFixture,
private_draft_composition: PrivateComposition,
saved_draft: Dict[str, Union[Optional[Composition], str]],
private_draft_setup_fixture: Tuple[MockerFixture, WriteBox],
write_box: WriteBox,
widget_size: Callable[[Widget], urwid_Size],
) -> None:
draft_saved_in_current_session = saved_draft["draft_composition"]
mocker, write_box = private_draft_setup_fixture
assert isinstance(saved_draft["expected_function"], str)
expected_function = reduce(
getattr, saved_draft["expected_function"].split("."), write_box
)
mocker.patch(
MODULE + ".WriteBox._tidy_valid_recipients_and_notify_invalid_ones",
return_value=True,
)
write_box.model.session_draft_message.return_value = (
draft_saved_in_current_session
)

size = widget_size(write_box)
write_box.keypress(size, key)

write_box.model.session_draft_message.assert_called()
expected_function.assert_called_once_with(private_draft_composition)

@pytest.mark.parametrize("key", keys_for_command("SAVE_AS_DRAFT"))
def test_keypress_SAVE_AS_DRAFT_private__invalid_recipients(
self,
key: str,
mocker: MockerFixture,
saved_draft: Dict[str, Union[Optional[Composition], str]],
private_draft_setup_fixture: Tuple[MockerFixture, WriteBox],
write_box: WriteBox,
widget_size: Callable[[Widget], urwid_Size],
) -> None:
draft_saved_in_current_session = saved_draft["draft_composition"]
mocker, write_box = private_draft_setup_fixture
mocker.patch(
MODULE + ".WriteBox._tidy_valid_recipients_and_notify_invalid_ones",
return_value=False,
)
write_box.model.session_draft_message.return_value = (
draft_saved_in_current_session
)

size = widget_size(write_box)
write_box.keypress(size, key)

write_box.model.save_draft.assert_not_called()
write_box.view.controller.save_draft_confirmation_popup.assert_not_called()

@pytest.mark.parametrize("key", keys_for_command("SAVE_AS_DRAFT"))
def test_keypress_SAVE_AS_DRAFT_stream__already_saved(
self,
key: str,
stream_draft_composition: StreamComposition,
stream_draft_setup_fixture: Tuple[MockerFixture, WriteBox],
write_box: WriteBox,
widget_size: Callable[[Widget], urwid_Size],
) -> None:
write_box.model.session_draft_message.return_value = stream_draft_composition
_, write_box = stream_draft_setup_fixture

size = widget_size(write_box)
write_box.keypress(size, key)

write_box.model.session_draft_message.assert_called()
write_box.view.controller.save_draft_confirmation_popup.assert_not_called()

@pytest.mark.parametrize("key", keys_for_command("SAVE_AS_DRAFT"))
def test_keypress_SAVE_AS_DRAFT_private__same_as_saved_draft(
self,
key: str,
mocker: MockerFixture,
private_draft_composition: PrivateComposition,
private_draft_setup_fixture: Tuple[MockerFixture, WriteBox],
write_box: WriteBox,
widget_size: Callable[[Widget], urwid_Size],
) -> None:
mocker, write_box = private_draft_setup_fixture
mocker.patch(
MODULE + ".WriteBox._tidy_valid_recipients_and_notify_invalid_ones",
return_value=True,
)
write_box.model.session_draft_message.return_value = private_draft_composition

size = widget_size(write_box)
write_box.keypress(size, key)

write_box.model.session_draft_message.assert_called()
write_box.view.controller.save_draft_confirmation_popup.assert_not_called()

@pytest.mark.parametrize(
"text, state, is_valid_stream, required_typeahead",
[
Expand Down

0 comments on commit 88584cd

Please sign in to comment.