diff --git a/tests/ui_tools/test_boxes.py b/tests/ui_tools/test_boxes.py index 869cc981b9..1ef5947092 100644 --- a/tests/ui_tools/test_boxes.py +++ b/tests/ui_tools/test_boxes.py @@ -235,15 +235,39 @@ def test__compose_attributes_reset_for_private_compose( mocker.patch("urwid.connect_signal") write_box.model.user_id_email_dict = user_id_email_dict write_box.private_box_view(recipient_user_ids=[11]) + + # Testing input less than 15 characters; >15 prompts confirmation popup write_box.msg_write_box.edit_text = "random text" size = widget_size(write_box) write_box.keypress(size, key) + write_box.view.controller.exit_compose_confirmation_popup.assert_not_called() assert write_box.to_write_box is None assert write_box.msg_write_box.edit_text == "" assert write_box.compose_box_status == "closed" + @pytest.mark.parametrize("key", keys_for_command("GO_BACK")) + def test__compose_attributes_reset_for_private_compose_popup( + self, + key: str, + mocker: MockerFixture, + write_box: WriteBox, + widget_size: Callable[[Widget], urwid_Size], + user_id_email_dict: Dict[int, str], + ) -> None: + mocker.patch("urwid.connect_signal") + write_box.model.user_id_email_dict = user_id_email_dict + write_box.private_box_view(recipient_user_ids=[11]) + + # Testing input more than 15 characters; >15 prompts confirmation popup + write_box.msg_write_box.edit_text = "random text (>15 characters)" + + size = widget_size(write_box) + write_box.keypress(size, key) + + write_box.view.controller.exit_compose_confirmation_popup.assert_called_once() + @pytest.mark.parametrize("key", keys_for_command("GO_BACK")) def test__compose_attributes_reset_for_stream_compose( self, @@ -254,15 +278,37 @@ def test__compose_attributes_reset_for_stream_compose( ) -> None: mocker.patch(WRITEBOX + "._set_stream_write_box_style") write_box.stream_box_view(stream_id=1) + + # Testing input less than 15 characters; >15 prompts confirmation popup write_box.msg_write_box.edit_text = "random text" size = widget_size(write_box) write_box.keypress(size, key) + write_box.view.controller.exit_compose_confirmation_popup.assert_not_called() assert write_box.stream_id is None assert write_box.msg_write_box.edit_text == "" assert write_box.compose_box_status == "closed" + @pytest.mark.parametrize("key", keys_for_command("GO_BACK")) + def test__compose_attributes_reset_for_stream_compose_popup( + self, + key: str, + mocker: MockerFixture, + write_box: WriteBox, + widget_size: Callable[[Widget], urwid_Size], + ) -> None: + mocker.patch(WRITEBOX + "._set_stream_write_box_style") + write_box.stream_box_view(stream_id=1) + + # Testing input more than 15 characters; >15 prompts confirmation popup + write_box.msg_write_box.edit_text = "random text (>15 characters)" + + size = widget_size(write_box) + write_box.keypress(size, key) + + write_box.view.controller.exit_compose_confirmation_popup.assert_called_once_with() + @pytest.mark.parametrize( ["raw_recipients", "tidied_recipients"], [ @@ -1508,6 +1554,7 @@ def test_keypress_SEND_MESSAGE_no_topic( ) def test_keypress_typeahead_mode_autocomplete_key( self, + mocker: MockerFixture, write_box: WriteBox, widget_size: Callable[[Widget], urwid_Size], current_typeahead_mode: bool, @@ -1515,6 +1562,7 @@ def test_keypress_typeahead_mode_autocomplete_key( expect_footer_was_reset: bool, key: str, ) -> None: + write_box.msg_write_box = mocker.Mock(edit_text="") write_box.is_in_typeahead_mode = current_typeahead_mode size = widget_size(write_box) diff --git a/zulipterminal/core.py b/zulipterminal/core.py index 2799210ab9..5fefb4cc45 100644 --- a/zulipterminal/core.py +++ b/zulipterminal/core.py @@ -523,6 +523,21 @@ def stream_muting_confirmation_popup( mute_this_stream = partial(self.model.toggle_stream_muted_status, stream_id) self.loop.widget = PopUpConfirmationView(self, question, mute_this_stream) + def exit_compose_confirmation_popup(self) -> None: + question = urwid.Text( + ( + "bold", + "Please confirm that you wish to exit the compose box.\n" + "(You can save the message as a draft upon returning to compose)", + ), + "center", + ) + write_box = self.view.write_box + popup_view = PopUpConfirmationView( + self, question, write_box.exit_compose_box, location="center" + ) + self.loop.widget = popup_view + def copy_to_clipboard(self, text: str, text_category: str) -> None: try: pyperclip.copy(text) diff --git a/zulipterminal/ui_tools/boxes.py b/zulipterminal/ui_tools/boxes.py index 36128f444a..a52a62fb8a 100644 --- a/zulipterminal/ui_tools/boxes.py +++ b/zulipterminal/ui_tools/boxes.py @@ -710,6 +710,12 @@ def autocomplete_emojis( return emoji_typeahead, emojis + def exit_compose_box(self) -> None: + self._set_compose_attributes_to_defaults() + self.view.controller.exit_editor_mode() + self.main_view(False) + self.view.middle_column.set_focus("body") + def keypress(self, size: urwid_Size, key: str) -> Optional[str]: if self.is_in_typeahead_mode and not ( is_command_key("AUTOCOMPLETE", key) @@ -801,10 +807,11 @@ def keypress(self, size: urwid_Size, key: str) -> Optional[str]: ) elif is_command_key("GO_BACK", key): self.send_stop_typing_status() - self._set_compose_attributes_to_defaults() - self.view.controller.exit_editor_mode() - self.main_view(False) - self.view.middle_column.set_focus("body") + confirmation_msg_length = 15 + if len(self.msg_write_box.edit_text) > confirmation_msg_length: + self.view.controller.exit_compose_confirmation_popup() + else: + self.exit_compose_box() elif is_command_key("MARKDOWN_HELP", key): self.view.controller.show_markdown_help() return key