Skip to content

Commit 5801358

Browse files
alex-ozdemirneiljp
authored andcommitted
bugfix: model/boxes/buttons: Fully handle both server color formats.
The zulip server used to store some colors in the format #xxx and others in the format #xxxxxx. The terminal client did not handle the #xxx format correctly in all cases until this commit. This commit: * removes an instance of on-the-fly color canonicalization in `ui_tools/boxes.py` (in `StreamButton.__init__`) * adds a color canonicalization step to `model.py` (in `Model._stream_info_from_subscriptions`) * removes integration tests that verify that `StreamButton` canonicalizes its colors. * modifies integration tests to verify that the model canonicalizes its colors.
1 parent a3166b3 commit 5801358

File tree

5 files changed

+20
-64
lines changed

5 files changed

+20
-64
lines changed

tests/conftest.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def logged_on_user():
104104
general_stream = {
105105
'name': 'Some general stream',
106106
'invite_only': False,
107-
'color': '#b0a5fd',
107+
'color': '#b0a5fd', # Color in '#xxxxxx' format
108108
'pin_to_top': False,
109109
'stream_id': 1000,
110110
'in_home_view': True,
@@ -126,7 +126,7 @@ def logged_on_user():
126126
'invite_only': True,
127127
'name': 'Secret stream',
128128
'email_address': '[email protected]',
129-
'color': '#c3c3c3',
129+
'color': '#ccc', # Color in '#xxx' format
130130
'in_home_view': True,
131131
'audible_notifications': False,
132132
'is_old_stream': True,
@@ -662,10 +662,10 @@ def streams():
662662
List of streams created corresponding to
663663
`initial_data` fixture.
664664
"""
665-
return [['Secret stream', 99, '#c3c3c3', True],
666-
['Some general stream', 1000, '#b0a5fd', False],
667-
['Stream 1', 1, '#b0a5fd', False],
668-
['Stream 2', 2, '#b0a5fd', False]]
665+
return [['Secret stream', 99, '#ccc', True],
666+
['Some general stream', 1000, '#baf', False],
667+
['Stream 1', 1, '#baf', False],
668+
['Stream 2', 2, '#baf', False]]
669669

670670

671671
@pytest.fixture

tests/ui/test_ui_tools.py

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ def test_soup2markup(self, content, markup):
12171217
timestamp=99, reactions=[])
12181218
self.model.stream_dict = {
12191219
5: { # matches stream_id above
1220-
'color': '#bfd56f',
1220+
'color': '#bd6',
12211221
},
12221222
}
12231223
self.model.server_url = "SOME_BASE_URL"
@@ -1288,7 +1288,7 @@ def test_soup2markup(self, content, markup):
12881288
def test_main_view(self, mocker, message, last_message):
12891289
self.model.stream_dict = {
12901290
5: {
1291-
'color': '#bfd56f',
1291+
'color': '#bd6',
12921292
},
12931293
}
12941294
msg_box = MessageBox(message, self.model, last_message)
@@ -1317,7 +1317,7 @@ def test_main_view_generates_stream_header(self, mocker, message,
13171317
mocker.patch(VIEWS + ".urwid.Text")
13181318
self.model.stream_dict = {
13191319
5: {
1320-
'color': '#bfd56f',
1320+
'color': '#bd6',
13211321
},
13221322
}
13231323
last_message = dict(message, **to_vary_in_last_message)
@@ -1406,7 +1406,7 @@ def test_msg_generates_search_and_header_bar(self, mocker,
14061406
assert_search_bar):
14071407
self.model.stream_dict = {
14081408
205: {
1409-
'color': '#bfd56f',
1409+
'color': '#bd6',
14101410
},
14111411
}
14121412
self.model.narrow = msg_narrow
@@ -1735,48 +1735,6 @@ def test_text_content(self, mocker,
17351735
assert len(text[0]) == len(expected_text) == (width - 1)
17361736
assert text[0] == expected_text
17371737

1738-
@pytest.mark.parametrize('color', [
1739-
'#ffffff', '#f0f0f0', '#f0f1f2', '#fff'
1740-
])
1741-
def test_color_formats(self, mocker, color):
1742-
mocker.patch(STREAMBUTTON + ".mark_muted")
1743-
controller = mocker.Mock()
1744-
controller.model.muted_streams = {}
1745-
properties = ["", 1, color, False] # only color is important
1746-
view_mock = mocker.Mock()
1747-
background = (None, 'white', 'black')
1748-
view_mock.palette = [background]
1749-
1750-
stream_button = StreamButton(properties,
1751-
controller=controller,
1752-
view=view_mock,
1753-
width=10,
1754-
count=5)
1755-
1756-
expected_palette = ([background] +
1757-
[('#fff', '', '', '', '#fff, bold', 'black')] +
1758-
[('s#fff', '', '', '', 'black', '#fff')])
1759-
assert view_mock.palette == expected_palette
1760-
1761-
@pytest.mark.parametrize('color', [
1762-
'#', '#f', '#ff', '#ffff', '#fffff', '#fffffff'
1763-
])
1764-
def test_invalid_color_format(self, mocker, color):
1765-
properties = ["", 1, color, False] # only color is important
1766-
view_mock = mocker.Mock()
1767-
controller = mocker.Mock()
1768-
controller.model.muted_streams = {}
1769-
background = (None, 'white', 'black')
1770-
view_mock.palette = [background]
1771-
1772-
with pytest.raises(RuntimeError) as e:
1773-
StreamButton(properties,
1774-
controller=controller,
1775-
view=view_mock,
1776-
width=10,
1777-
count=5)
1778-
assert str(e.value) == "Unknown color format: '{}'".format(color)
1779-
17801738
@pytest.mark.parametrize('stream_id, muted_streams, called_value,\
17811739
is_action_muting, updated_all_msgs', [
17821740
(86, {}, 204, False, 380),

zulipterminal/model.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from zulipterminal.helper import (
1717
asynch,
1818
classify_unread_counts,
19+
canonicalize_color,
1920
index_messages,
2021
set_count,
2122
initial_index,
@@ -523,6 +524,12 @@ def _stream_info_from_subscriptions(
523524
subscriptions: List[Dict[str, Any]]
524525
) -> Tuple[Dict[int, Any], Set[int], List[List[str]], List[List[str]]]:
525526
stream_keys = ('name', 'stream_id', 'color', 'invite_only')
527+
528+
# Canonicalize color formats, since zulip server versions may use
529+
# different formats
530+
for subscription in subscriptions:
531+
subscription['color'] = canonicalize_color(subscription['color'])
532+
526533
# Mapping of stream-id to all available stream info
527534
# Stream IDs for muted streams
528535
# Limited stream info sorted by name (used in display)

zulipterminal/ui_tools/boxes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def _is_private_message_to_self(self) -> bool:
218218

219219
def stream_header(self) -> Any:
220220
bar_color = self.model.stream_dict[self.stream_id]['color']
221-
bar_color = 's' + bar_color[:2] + bar_color[3] + bar_color[5]
221+
bar_color = 's' + bar_color
222222
stream_title_markup = ('bar', [
223223
(bar_color, '{} >'.format(self.stream_name)),
224224
('title', ' {} '.format(self.topic_name))
@@ -257,7 +257,7 @@ def top_search_bar(self) -> Any:
257257
text_to_fill = 'Starred messages'
258258
elif self.message['type'] == 'stream':
259259
bar_color = self.model.stream_dict[self.stream_id]['color']
260-
bar_color = 's' + bar_color[:2] + bar_color[3] + bar_color[5]
260+
bar_color = 's' + bar_color
261261
if len(curr_narrow) == 2 and curr_narrow[1][0] == 'topic':
262262
text_to_fill = ('bar', [ # type: ignore
263263
(bar_color, '{}'.format(self.stream_name)),

zulipterminal/ui_tools/buttons.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,11 @@ def __init__(self, properties: List[Any],
126126
count: int=0) -> None:
127127
# FIXME Is having self.stream_id the best way to do this?
128128
# (self.stream_id is used elsewhere)
129-
self.stream_name, self.stream_id, orig_color, is_private = properties
129+
self.stream_name, self.stream_id, color, is_private = properties
130130
self.model = controller.model
131131
self.count = count
132132
self.view = view
133133

134-
# Simplify the color from the original version & add to palette
135-
# TODO Should this occur elsewhere and more intelligently?
136-
if len(orig_color) == 7: # modern zulip server format
137-
color = ''.join(orig_color[i] for i in (0, 1, 3, 5))
138-
elif len(orig_color) == 4: # possible with zulip servers <=1.9.0 ?
139-
color = orig_color
140-
else:
141-
raise RuntimeError("Unknown color format: '{}'".format(orig_color))
142-
143134
for entry in view.palette:
144135
if entry[0] is None:
145136
background = entry[5] if len(entry) > 4 else entry[2]

0 commit comments

Comments
 (0)