Skip to content

Commit 21fc3c2

Browse files
preetmishraneiljp
authored andcommitted
refactor: views: Introduce PopUpView class to extract keypress method.
Added PopUpView, a base class for popups, that extracts the common keypress method and inherited it in HelpView. This class can be leveraged to introduce the keypress method and reduce potential code duplication in other popup views. Test added for PopUpView.
1 parent ad8fc87 commit 21fc3c2

File tree

2 files changed

+79
-24
lines changed

2 files changed

+79
-24
lines changed

tests/ui/test_ui_tools.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
from bs4 import BeautifulSoup
66
from urwid import AttrWrap, Columns, Padding, Text
77

8-
from zulipterminal.config.keys import keys_for_command
8+
from zulipterminal.config.keys import is_command_key, keys_for_command
99
from zulipterminal.helper import powerset
1010
from zulipterminal.ui_tools.boxes import MessageBox
1111
from zulipterminal.ui_tools.buttons import (
1212
StreamButton, TopButton, TopicButton, UserButton,
1313
)
1414
from zulipterminal.ui_tools.views import (
1515
HelpView, LeftColumnView, MessageView, MiddleColumnView, ModListWalker,
16-
MsgInfoView, PopUpConfirmationView, RightColumnView, StreamsView,
17-
TopicsView, UsersView,
16+
MsgInfoView, PopUpConfirmationView, PopUpView, RightColumnView,
17+
StreamsView, TopicsView, UsersView,
1818
)
1919

2020

@@ -1093,6 +1093,56 @@ def test_topics_view(self, mocker, stream_button, width=40):
10931093
])
10941094

10951095

1096+
class TestPopUpView:
1097+
@pytest.fixture(autouse=True)
1098+
def pop_up_view(self, mocker):
1099+
self.controller = mocker.Mock()
1100+
self.command = 'COMMAND'
1101+
self.widget = mocker.Mock()
1102+
self.widgets = [self.widget, ]
1103+
self.list_walker = mocker.patch(VIEWS + '.urwid.SimpleFocusListWalker',
1104+
return_value=[])
1105+
self.super_init = mocker.patch(VIEWS + '.urwid.ListBox.__init__')
1106+
self.super_keypress = mocker.patch(VIEWS + '.urwid.ListBox.keypress')
1107+
self.pop_up_view = PopUpView(self.controller, self.widgets,
1108+
self.command)
1109+
1110+
def test_init(self):
1111+
assert self.pop_up_view.controller == self.controller
1112+
assert self.pop_up_view.command == self.command
1113+
self.list_walker.assert_called_once_with(self.widgets)
1114+
self.super_init.assert_called_once_with(self.pop_up_view.log)
1115+
1116+
@pytest.mark.parametrize('key', keys_for_command('GO_BACK'))
1117+
def test_keypress_GO_BACK(self, key):
1118+
size = (200, 20)
1119+
self.pop_up_view.keypress(size, key)
1120+
assert self.controller.exit_popup.called
1121+
1122+
def test_keypress_command_key(self, mocker):
1123+
size = (200, 20)
1124+
mocker.patch(VIEWS + '.is_command_key', side_effect=(
1125+
lambda command, key: command == self.command
1126+
))
1127+
self.pop_up_view.keypress(size, 'cmd_key')
1128+
assert self.controller.exit_popup.called
1129+
1130+
def test_keypress_navigation(self, mocker,
1131+
navigation_key_expected_key_pair):
1132+
key, expected_key = navigation_key_expected_key_pair
1133+
size = (200, 20)
1134+
# Patch `is_command_key` to not raise an 'Invalid Command' exception
1135+
# when its parameters are (self.command, key) as there is no
1136+
# self.command='COMMAND' command in keys.py.
1137+
mocker.patch(VIEWS + '.is_command_key', side_effect=(
1138+
lambda command, key:
1139+
False if command == self.command
1140+
else is_command_key(command, key)
1141+
))
1142+
self.pop_up_view.keypress(size, key)
1143+
self.super_keypress.assert_called_once_with(size, expected_key)
1144+
1145+
10961146
class TestHelpMenu:
10971147
@pytest.fixture(autouse=True)
10981148
def mock_external_classes(self, mocker, monkeypatch):

zulipterminal/ui_tools/views.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -754,10 +754,32 @@ def keypress(self, size: urwid_Size, key: str) -> Optional[str]:
754754
return super().keypress(size, key)
755755

756756

757-
class HelpView(urwid.ListBox):
758-
def __init__(self, controller: Any) -> None:
757+
class PopUpView(urwid.ListBox):
758+
def __init__(self, controller: Any, widgets: List[Any],
759+
command: str) -> None:
759760
self.controller = controller
761+
self.command = command
762+
self.log = urwid.SimpleFocusListWalker(widgets)
763+
super().__init__(self.log)
764+
765+
def keypress(self, size: urwid_Size, key: str) -> str:
766+
if is_command_key('GO_BACK', key) or is_command_key(self.command, key):
767+
self.controller.exit_popup()
768+
elif is_command_key('GO_UP', key):
769+
key = 'up'
770+
elif is_command_key('GO_DOWN', key):
771+
key = 'down'
772+
elif is_command_key('SCROLL_UP', key):
773+
key = 'page up'
774+
elif is_command_key('SCROLL_DOWN', key):
775+
key = 'page down'
776+
elif is_command_key('GO_TO_BOTTOM', key):
777+
key = 'end'
778+
return super().keypress(size, key)
779+
760780

781+
class HelpView(PopUpView):
782+
def __init__(self, controller: Any) -> None:
761783
widths = [(len(binding['help_text'])+4,
762784
len(", ".join(binding['keys'])))
763785
for binding in KEY_BINDINGS.values()]
@@ -786,26 +808,9 @@ def __init__(self, controller: Any) -> None:
786808
)
787809
)
788810

789-
self.log = urwid.SimpleFocusListWalker(help_menu_content)
790-
791-
self.height = len(self.log)
811+
self.height = len(help_menu_content)
792812

793-
super().__init__(self.log)
794-
795-
def keypress(self, size: urwid_Size, key: str) -> str:
796-
if is_command_key('GO_BACK', key) or is_command_key('HELP', key):
797-
self.controller.exit_popup()
798-
elif is_command_key('GO_UP', key):
799-
key = 'up'
800-
elif is_command_key('GO_DOWN', key):
801-
key = 'down'
802-
elif is_command_key('SCROLL_UP', key):
803-
key = 'page up'
804-
elif is_command_key('SCROLL_DOWN', key):
805-
key = 'page down'
806-
elif is_command_key('GO_TO_BOTTOM', key):
807-
key = 'end'
808-
return super().keypress(size, key)
813+
super().__init__(controller, help_menu_content, 'HELP')
809814

810815

811816
class PopUpConfirmationView(urwid.Overlay):

0 commit comments

Comments
 (0)