-
-
Notifications
You must be signed in to change notification settings - Fork 259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling Empty Narrows #1543
base: main
Are you sure you want to change the base?
Handling Empty Narrows #1543
Changes from all commits
4992dbe
936cf2f
6cac57d
f8503f8
dcb213a
0fb5bf0
df2feb4
299a1c1
3444552
2a66297
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -518,8 +518,8 @@ def test_stream_muting_confirmation_popup( | |
"search_within_topic_narrow", | ||
], | ||
) | ||
@pytest.mark.parametrize("msg_ids", [({200, 300, 400}), (set()), ({100})]) | ||
def test_search_message( | ||
@pytest.mark.parametrize("msg_ids", [({200, 300, 400}), ({100})]) | ||
def test_search_message__hits( | ||
self, | ||
initial_narrow: List[Any], | ||
final_narrow: List[Any], | ||
|
@@ -550,6 +550,60 @@ def set_msg_ids(*args: Any, **kwargs: Any) -> None: | |
create_msg.assert_called_once_with(controller.model, msg_ids) | ||
assert controller.model.index == dict(index_search_messages, search=msg_ids) | ||
|
||
@pytest.mark.parametrize( | ||
"initial_narrow, final_narrow", | ||
[ | ||
([], [["search", "FOO"]]), | ||
([["search", "BOO"]], [["search", "FOO"]]), | ||
([["stream", "PTEST"]], [["stream", "PTEST"], ["search", "FOO"]]), | ||
( | ||
[["pm-with", "[email protected]"], ["search", "BOO"]], | ||
[["pm-with", "[email protected]"], ["search", "FOO"]], | ||
), | ||
( | ||
[["stream", "PTEST"], ["topic", "RDS"]], | ||
[["stream", "PTEST"], ["topic", "RDS"], ["search", "FOO"]], | ||
), | ||
], | ||
ids=[ | ||
"Default_all_msg_search", | ||
"redo_default_search", | ||
"search_within_stream", | ||
"pm_search_again", | ||
"search_within_topic_narrow", | ||
], | ||
) | ||
def test_search_message__no_hits( | ||
self, | ||
initial_narrow: List[Any], | ||
final_narrow: List[Any], | ||
controller: Controller, | ||
mocker: MockerFixture, | ||
index_search_messages: Index, | ||
msg_ids: Set[int] = set(), | ||
) -> None: | ||
get_message = mocker.patch(MODEL + ".get_messages") | ||
create_msg = mocker.patch(MODULE + ".create_msg_box_list") | ||
mocker.patch(MODEL + ".get_message_ids_in_current_narrow", return_value=msg_ids) | ||
controller.model.index = index_search_messages # Any initial search index | ||
controller.view.message_view = mocker.patch("urwid.ListBox") | ||
controller.model.narrow = initial_narrow | ||
|
||
def set_msg_ids(*args: Any, **kwargs: Any) -> None: | ||
controller.model.index["search"].update(msg_ids) | ||
|
||
get_message.side_effect = set_msg_ids | ||
assert controller.model.index["search"] == {500} | ||
|
||
controller.search_messages("FOO") | ||
|
||
assert controller.model.narrow == final_narrow | ||
get_message.assert_called_once_with( | ||
num_after=0, num_before=30, anchor=10000000000 | ||
) | ||
create_msg.assert_not_called() | ||
assert controller.model.index == dict(index_search_messages, search=msg_ids) | ||
|
||
@pytest.mark.parametrize( | ||
"screen_size, expected_popup_size", | ||
[ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ def test_init(self, mocker, message_type, set_fields): | |
display_recipient=[ | ||
{"id": 7, "email": "[email protected]", "full_name": "Boo is awesome"} | ||
], | ||
id=457823, | ||
stream_id=5, | ||
subject="hi", | ||
sender_email="[email protected]", | ||
|
@@ -65,18 +66,13 @@ def test_init(self, mocker, message_type, set_fields): | |
assert msg_box.message_links == OrderedDict() | ||
assert msg_box.time_mentions == list() | ||
|
||
def test_init_fails_with_bad_message_type(self): | ||
message = dict(type="BLAH") | ||
|
||
with pytest.raises(RuntimeError): | ||
MessageBox(message, self.model, None) | ||
|
||
def test_private_message_to_self(self, mocker): | ||
message = dict( | ||
type="private", | ||
display_recipient=[ | ||
{"full_name": "Foo Foo", "email": "[email protected]", "id": None} | ||
], | ||
id=457823, | ||
sender_id=9, | ||
content="<p> self message. </p>", | ||
sender_full_name="Foo Foo", | ||
|
@@ -88,6 +84,7 @@ def test_private_message_to_self(self, mocker): | |
MODULE + ".MessageBox._is_private_message_to_self", return_value=True | ||
) | ||
mocker.patch.object(MessageBox, "main_view") | ||
|
||
msg_box = MessageBox(message, self.model, None) | ||
|
||
assert msg_box.recipient_emails == ["[email protected]"] | ||
|
@@ -759,6 +756,7 @@ def test_main_view(self, mocker, message, last_message): | |
"color": "#bd6", | ||
}, | ||
} | ||
self.model.controller.is_in_empty_narrow = False | ||
MessageBox(message, self.model, last_message) | ||
|
||
@pytest.mark.parametrize( | ||
|
@@ -838,6 +836,7 @@ def test_main_view_generates_stream_header( | |
"color": "#bd6", | ||
}, | ||
} | ||
self.model.controller.is_in_empty_narrow = False | ||
last_message = dict(message, **to_vary_in_last_message) | ||
msg_box = MessageBox(message, self.model, last_message) | ||
view_components = msg_box.main_view() | ||
|
@@ -890,6 +889,7 @@ def test_main_view_generates_stream_header( | |
def test_main_view_generates_PM_header( | ||
self, mocker, message, to_vary_in_last_message | ||
): | ||
self.model.controller.is_in_empty_narrow = False | ||
last_message = dict(message, **to_vary_in_last_message) | ||
msg_box = MessageBox(message, self.model, last_message) | ||
view_components = msg_box.main_view() | ||
|
@@ -1032,9 +1032,11 @@ def test_msg_generates_search_and_header_bar( | |
}, | ||
} | ||
self.model.narrow = msg_narrow | ||
self.model.controller.is_in_empty_narrow = False | ||
messages = messages_successful_response["messages"] | ||
current_message = messages[msg_type] | ||
msg_box = MessageBox(current_message, self.model, messages[0]) | ||
|
||
search_bar = msg_box.top_search_bar() | ||
header_bar = msg_box.recipient_header() | ||
|
||
|
@@ -1151,8 +1153,11 @@ def test_main_view_compact_output( | |
): | ||
message_fixture.update({"id": 4}) | ||
varied_message = dict(message_fixture, **to_vary_in_each_message) | ||
self.model.controller.is_in_empty_narrow = False | ||
msg_box = MessageBox(varied_message, self.model, varied_message) | ||
|
||
view_components = msg_box.main_view() | ||
|
||
assert len(view_components) == 1 | ||
assert isinstance(view_components[0], Padding) | ||
|
||
|
@@ -1162,7 +1167,9 @@ def test_main_view_generates_EDITED_label( | |
messages = messages_successful_response["messages"] | ||
for message in messages: | ||
self.model.index["edited_messages"].add(message["id"]) | ||
self.model.controller.is_in_empty_narrow = False | ||
msg_box = MessageBox(message, self.model, message) | ||
|
||
view_components = msg_box.main_view() | ||
|
||
label = view_components[0].original_widget.contents[0] | ||
|
@@ -1188,6 +1195,7 @@ def test_update_message_author_status( | |
): | ||
message = message_fixture | ||
last_msg = dict(message, **to_vary_in_last_message) | ||
self.model.controller.is_in_empty_narrow = False | ||
|
||
msg_box = MessageBox(message, self.model, last_msg) | ||
|
||
|
@@ -1391,6 +1399,7 @@ def test_keypress_EDIT_MESSAGE( | |
to_vary_in_each_message["subject"] = "" | ||
varied_message = dict(message_fixture, **to_vary_in_each_message) | ||
message_type = varied_message["type"] | ||
self.model.controller.is_in_empty_narrow = False | ||
msg_box = MessageBox(varied_message, self.model, message_fixture) | ||
size = widget_size(msg_box) | ||
msg_box.model.user_id = 1 | ||
|
@@ -1405,6 +1414,7 @@ def test_keypress_EDIT_MESSAGE( | |
report_error = msg_box.model.controller.report_error | ||
report_warning = msg_box.model.controller.report_warning | ||
mocker.patch(MODULE + ".time", return_value=100) | ||
msg_box.model.controller.is_in_empty_narrow = False | ||
|
||
msg_box.keypress(size, key) | ||
|
||
|
@@ -1820,6 +1830,7 @@ def test_reactions_view( | |
varied_message = dict(message_fixture, **to_vary_in_each_message) | ||
msg_box = MessageBox(varied_message, self.model, None) | ||
reactions = to_vary_in_each_message["reactions"] | ||
msg_box.model.controller.is_in_empty_narrow = False | ||
|
||
reactions_view = msg_box.reactions_view(reactions) | ||
|
||
|
@@ -1976,6 +1987,7 @@ def test_mouse_event_left_click( | |
mocker.patch.object(msg_box, "keypress") | ||
msg_box.model = mocker.Mock() | ||
msg_box.model.controller.is_in_editor_mode.return_value = compose_box_is_open | ||
msg_box.model.controller.is_in_empty_narrow = False | ||
|
||
msg_box.mouse_event(size, "mouse press", 1, col, row, focus) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1742,6 +1742,9 @@ def _handle_message_event(self, event: Event) -> None: | |
msg_w = msg_w_list[0] | ||
|
||
if self.current_narrow_contains_message(message): | ||
if self.controller.is_in_empty_narrow: | ||
del msg_log[0] | ||
self.controller.is_in_empty_narrow = False | ||
Comment on lines
+1745
to
+1747
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this the part that is not working properly, in your 'Next steps'? It looks like this commit should come later in the sequencce, at or after where we add an empty message, or else the As per another comment, this isn't updated at all in Note that we will also want this to be triggered for star changes as it stands, and may be a lot simpler to test in that way, ie. to make a narrow empty using 0/1 starred messages - though of course is a different function under test in that case. |
||
msg_log.append(msg_w) | ||
|
||
self.controller.update_screen() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1014,7 +1014,7 @@ def main_view(self) -> Any: | |
self.text_box, | ||
] | ||
) | ||
self.msg_narrow = urwid.Text("DONT HIDE") | ||
self.msg_narrow = urwid.Text("") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said in the channel, it's great to remove this line, though I think this was associated with the comment some lines above, which we could also remove? (look through the git log via git blame?) In terms of this commit, it would be helpful to clarify under which conditions the application would display an empty recipient bar, since I very rarely actually see this odd text. This doesn't need to be via an exact analysis, but notes would be helpful, since looking back to this change in the future would help clarify what happens here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was going to suggest taking advantage of this small commit to eg. refactor the attribute naming to be private. However, this is one of those coupled classes/objects, so many of these names are actually public, so this likely would be best settled with a separate refactoring effort. In the absence of that, you could add comments to clarify each attribute for now; would that help you next time? If so, it'd help others who next read the code :) |
||
self.recipient_bar = urwid.LineBox( | ||
self.msg_narrow, | ||
title="Current message recipients", | ||
|
@@ -1032,9 +1032,11 @@ def keypress(self, size: urwid_Size, key: str) -> Optional[str]: | |
return key | ||
|
||
elif is_command_key("EXECUTE_SEARCH", key): | ||
self.controller.exit_editor_mode() | ||
self.controller.search_messages(self.text_box.edit_text) | ||
self.controller.view.middle_column.set_focus("body") | ||
if self.controller.search_messages(self.text_box.edit_text): | ||
self.controller.exit_editor_mode() | ||
self.controller.view.middle_column.set_focus("body") | ||
else: | ||
self.controller.report_error(["No results found."]) | ||
Comment on lines
-1035
to
+1039
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if we want to take this approach rather than just have the empty result like the rest of this branch is pursuing, but it's an interesting extra change - I assume this is extra to the original version? |
||
return key | ||
|
||
key = super().keypress(size, key) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this small commit factored out, so that it would cover Sumanth's original process here? Oh, I think you said that it was where the inspiration came from?
(I'm torn whether this belongs in the model or controller here, but that's probably a refactoring to consider how to structure the whole narrowing behavior)