Merge lp:~nataliabidart/ubuntuone-control-panel/folders-tweaks into lp:ubuntuone-control-panel
- folders-tweaks
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged |
---|---|
Approved by: | Natalia Bidart |
Approved revision: | 88 |
Merged at revision: | 86 |
Proposed branch: | lp:~nataliabidart/ubuntuone-control-panel/folders-tweaks |
Merge into: | lp:ubuntuone-control-panel |
Diff against target: |
1340 lines (+656/-575) 4 files modified
ubuntuone/controlpanel/gtk/gui.py (+16/-5) ubuntuone/controlpanel/gtk/tests/__init__.py (+17/-6) ubuntuone/controlpanel/gtk/tests/test_gui.py (+35/-564) ubuntuone/controlpanel/gtk/tests/test_gui_basic.py (+588/-0) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-control-panel/folders-tweaks |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Martin Albisetti (community) | ui | Approve | |
Review via email: mp+51765@code.launchpad.net |
Description of the change
To post a comment you must log in.
Revision history for this message
Martin Albisetti (beuno) : | # |
review:
Approve
(ui)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'ubuntuone/controlpanel/gtk/gui.py' |
2 | --- ubuntuone/controlpanel/gtk/gui.py 2011-02-28 23:24:53 +0000 |
3 | +++ ubuntuone/controlpanel/gtk/gui.py 2011-03-01 15:44:47 +0000 |
4 | @@ -397,12 +397,15 @@ |
5 | CONFIRM_MERGE = _('The contents of your cloud folder will be merged with ' |
6 | 'your local folder "%(folder_path)s" when subscribing.\n' |
7 | 'Do you want to subscribe to this cloud folder?') |
8 | + MUSIC_DISPLAY_NAME = _('Purchased Music') |
9 | + MUSIC_REAL_PATH = '~/.ubuntuone/Purchased from Ubuntu One' |
10 | |
11 | MAX_COLS = 8 |
12 | |
13 | - CONTACT_ICON_NAME = 'system-users' |
14 | + CONTACT_ICON_NAME = 'avatar-default' |
15 | FOLDER_ICON_NAME = 'folder' |
16 | SHARE_ICON_NAME = 'folder-remote' |
17 | + MUSIC_ICON_NAME = 'audio-x-generic' |
18 | ROW_HEADER = '<span font_size="large"><b>%s</b></span> ' \ |
19 | '<span foreground="grey">%s</span>' |
20 | ROOT = '%s - <span foreground="%s" font_size="small">%s</span>' |
21 | @@ -436,7 +439,14 @@ |
22 | def _process_path(self, path): |
23 | """Trim 'path' so the '~' is removed.""" |
24 | home = os.path.expanduser('~') |
25 | - return path.replace(os.path.join(home, ''), '') |
26 | + music_path = os.path.expanduser(self.MUSIC_REAL_PATH) |
27 | + |
28 | + if path == music_path: |
29 | + result = self.MUSIC_DISPLAY_NAME |
30 | + else: |
31 | + result = path.replace(os.path.join(home, ''), '') |
32 | + |
33 | + return result |
34 | |
35 | def on_volumes_info_ready(self, info): |
36 | """Backend notifies of volumes info.""" |
37 | @@ -454,13 +464,10 @@ |
38 | |
39 | if name: |
40 | name = name + "'s" |
41 | - icon_name = self.SHARE_ICON_NAME |
42 | - |
43 | # we already added user folders, let's add an empty row |
44 | treeiter = self.volumes_store.append(None, self._empty_row) |
45 | else: |
46 | name = self.MY_FOLDERS |
47 | - icon_name = self.FOLDER_ICON_NAME |
48 | |
49 | free_bytes_args = {'free_space': self.humanize(int(free_bytes))} |
50 | row = (self.ROW_HEADER % (name, self.FREE_SPACE % free_bytes_args), |
51 | @@ -472,6 +479,7 @@ |
52 | for volume in volumes: |
53 | sensitive = True |
54 | name = self._process_path(volume[u'path']) |
55 | + icon_name = self.FOLDER_ICON_NAME |
56 | |
57 | is_root = volume[u'type'] == backend.ControlBackend.ROOT_TYPE |
58 | is_share = volume[u'type'] == backend.ControlBackend.SHARE_TYPE |
59 | @@ -481,6 +489,9 @@ |
60 | name = self.ROOT % (name, ORANGE, self.ALWAYS_SUBSCRIBED) |
61 | elif is_share: |
62 | name = volume[u'name'] |
63 | + icon_name = self.SHARE_ICON_NAME |
64 | + elif name == self.MUSIC_DISPLAY_NAME: |
65 | + icon_name = self.MUSIC_ICON_NAME |
66 | |
67 | row = (name, bool(volume[u'subscribed']), icon_name, True, |
68 | sensitive, gtk.ICON_SIZE_MENU, volume['volume_id'], |
69 | |
70 | === modified file 'ubuntuone/controlpanel/gtk/tests/__init__.py' |
71 | --- ubuntuone/controlpanel/gtk/tests/__init__.py 2011-02-28 19:53:50 +0000 |
72 | +++ ubuntuone/controlpanel/gtk/tests/__init__.py 2011-03-01 15:44:47 +0000 |
73 | @@ -24,6 +24,7 @@ |
74 | |
75 | from ubuntuone.devtools.handlers import MementoHandler |
76 | |
77 | +from ubuntuone.controlpanel.backend import ControlBackend |
78 | from ubuntuone.controlpanel.gtk import gui |
79 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( |
80 | FakedTransaction) |
81 | @@ -41,26 +42,36 @@ |
82 | |
83 | ROOT = { |
84 | u'volume_id': '', u'path': '/home/tester/My Ubuntu', |
85 | - u'subscribed': 'True', u'type': u'ROOT', |
86 | + u'subscribed': 'True', u'type': ControlBackend.ROOT_TYPE, |
87 | +} |
88 | + |
89 | +MUSIC_FOLDER = { |
90 | + u'volume_id': u'58236', u'subscribed': u'True', |
91 | + u'type': ControlBackend.FOLDER_TYPE, |
92 | + u'path': u'/home/tester/.ubuntuone/Purchased from Ubuntu One', |
93 | + u'suggested_path': u'~/.ubuntuone/Purchased from Ubuntu One', |
94 | } |
95 | |
96 | FAKE_FOLDERS_INFO = [ |
97 | {u'volume_id': u'0', u'path': u'/home/tester/foo', |
98 | - u'suggested_path': u'~/foo', u'subscribed': u'', u'type': u'UDF'}, |
99 | + u'suggested_path': u'~/foo', u'subscribed': u'', |
100 | + u'type': ControlBackend.FOLDER_TYPE}, |
101 | {u'volume_id': u'1', u'path': u'/home/tester/bar', |
102 | - u'suggested_path': u'~/bar', u'subscribed': u'True', u'type': u'UDF'}, |
103 | + u'suggested_path': u'~/bar', u'subscribed': u'True', |
104 | + u'type': ControlBackend.FOLDER_TYPE}, |
105 | {u'volume_id': u'2', u'path': u'/home/tester/baz', |
106 | - u'suggested_path': u'~/baz', u'subscribed': u'True', u'type': u'UDF'}, |
107 | + u'suggested_path': u'~/baz', u'subscribed': u'True', |
108 | + u'type': ControlBackend.FOLDER_TYPE}, |
109 | ] |
110 | |
111 | FAKE_SHARES_INFO = [ |
112 | {u'volume_id': u'1234', u'name': u'do', |
113 | u'path': u'/home/tester/.local/share/ubuntuone/shares/do from Other User', |
114 | - u'subscribed': u'', u'type': u'SHARE'}, |
115 | + u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE}, |
116 | |
117 | {u'volume_id': u'5678', u'name': u're', |
118 | u'path': u'/home/tester/.local/share/ubuntuone/shares/re from Other User', |
119 | - u'subscribed': u'True', u'type': u'SHARE'}, |
120 | + u'subscribed': u'True', u'type': ControlBackend.SHARE_TYPE}, |
121 | ] |
122 | |
123 | FAKE_VOLUMES_INFO = [ |
124 | |
125 | === modified file 'ubuntuone/controlpanel/gtk/tests/test_gui.py' |
126 | --- ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-02-28 23:24:53 +0000 |
127 | +++ ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-03-01 15:44:47 +0000 |
128 | @@ -23,577 +23,19 @@ |
129 | from ubuntuone.controlpanel.gtk import gui |
130 | from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO, |
131 | FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, FAKE_FOLDERS_INFO, |
132 | - FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, ROOT, USER_HOME, |
133 | - BaseTestCase, FakedSSOBackend, FakedConfirmDialog, |
134 | + FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, |
135 | + MUSIC_FOLDER, ROOT, USER_HOME, |
136 | + FakedConfirmDialog, |
137 | +) |
138 | +from ubuntuone.controlpanel.gtk.tests.test_gui_basic import ( |
139 | + ControlPanelMixinTestCase, |
140 | ) |
141 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( |
142 | SUCCESS, FAILURE) |
143 | -from ubuntuone.controlpanel.tests import TOKEN |
144 | |
145 | |
146 | # Attribute 'yyy' defined outside __init__, access to a protected member |
147 | # pylint: disable=W0201, W0212 |
148 | -# Too many lines in module |
149 | -# pylint: disable=C0302 |
150 | - |
151 | - |
152 | -class ControlPanelMixinTestCase(BaseTestCase): |
153 | - """The test suite for the control panel widget.""" |
154 | - |
155 | - klass = gui.ControlPanelMixin |
156 | - ui_filename = None |
157 | - |
158 | - def test_is_a_control_panel_mixin(self): |
159 | - """Inherits from ControlPanelMixin.""" |
160 | - self.assertIsInstance(self.ui, gui.ControlPanelMixin) |
161 | - |
162 | - def test_ui_can_be_created(self): |
163 | - """UI main class exists and can be created.""" |
164 | - self.assertTrue(self.ui is not None) |
165 | - |
166 | - |
167 | -class ControlPanelWindowTestCase(BaseTestCase): |
168 | - """The test suite for the control panel window.""" |
169 | - |
170 | - klass = gui.ControlPanelWindow |
171 | - |
172 | - def test_is_a_window(self): |
173 | - """Inherits from gtk.Window.""" |
174 | - self.assertIsInstance(self.ui, gui.gtk.Window) |
175 | - |
176 | - def test_startup_visibility(self): |
177 | - """The widget is visible at startup.""" |
178 | - self.assertTrue(self.ui.get_visible(), 'must be visible at startup.') |
179 | - |
180 | - def test_main_start_gtk_main_loop(self): |
181 | - """The GTK main loop is started when calling main().""" |
182 | - self.patch(gui.gtk, 'main', self._set_called) |
183 | - self.ui.main() |
184 | - self.assertEqual(self._called, ((), {}), 'gtk.main was called.') |
185 | - |
186 | - def test_closing_stops_the_main_lopp(self): |
187 | - """The GTK main loop is stopped when closing the window.""" |
188 | - self.patch(gui.gtk, 'main_quit', self._set_called) |
189 | - self.ui.emit('delete-event', None) |
190 | - self.assertEqual(self._called, ((), {}), 'gtk.main_quit was called.') |
191 | - |
192 | - def test_title_is_correct(self): |
193 | - """The window title is correct.""" |
194 | - expected = self.ui.TITLE % {'app_name': gui.U1_APP_NAME} |
195 | - self.assertEqual(self.ui.get_title(), expected) |
196 | - |
197 | - def test_control_panel_is_the_only_child(self): |
198 | - """The control panel is the window's content.""" |
199 | - children = self.ui.get_children() |
200 | - self.assertEqual(1, len(children)) |
201 | - |
202 | - control_panel = self.ui.get_children()[0] |
203 | - self.assertTrue(control_panel is self.ui.control_panel) |
204 | - self.assertIsInstance(self.ui.control_panel, gui.ControlPanel) |
205 | - self.assertTrue(self.ui.control_panel.get_visible()) |
206 | - |
207 | - def test_main_window_is_passed_to_child(self): |
208 | - """The child gets the main_window.""" |
209 | - self.assertEqual(self.ui.control_panel.main_window, self.ui) |
210 | - |
211 | - def test_icon_name_is_correct(self): |
212 | - """The icon name is correct.""" |
213 | - self.assertEqual(self.ui.get_icon_name(), 'ubuntuone') |
214 | - |
215 | - def test_max_size(self): |
216 | - """Max size is not bigger than 736x525 (LP: #645526, LP: #683164).""" |
217 | - self.assertTrue(self.ui.get_size_request() <= (736, 525)) |
218 | - |
219 | - |
220 | -class ControlPanelWindowParamsTestCase(ControlPanelWindowTestCase): |
221 | - """The test suite for the control panel window when passing params.""" |
222 | - |
223 | - kwargs = {'switch_to': 'devices'} |
224 | - |
225 | - def test_switch_to(self): |
226 | - """Can pass a 'switch_to' parameter to start on a particular tab.""" |
227 | - actual = self.ui.control_panel.management.notebook.get_current_page() |
228 | - self.assertEqual(actual, self.ui.control_panel.management.DEVICES_PAGE) |
229 | - |
230 | - |
231 | -class ControlPanelWindowParamsNoneTestCase(ControlPanelWindowTestCase): |
232 | - """The suite for the control panel window when passing None params.""" |
233 | - |
234 | - kwargs = {'switch_to': None} |
235 | - |
236 | - def test_switch_to(self): |
237 | - """Can pass a 'switch_to' being None. Should default to dashboard.""" |
238 | - actual = self.ui.control_panel.management.notebook.get_current_page() |
239 | - expected = self.ui.control_panel.management.DASHBOARD_PAGE |
240 | - self.assertEqual(actual, expected) |
241 | - |
242 | - |
243 | -class ControlPanelWindowInvalidParamsTestCase(ControlPanelWindowTestCase): |
244 | - """The suite for the control panel window when passing invalid params.""" |
245 | - |
246 | - kwargs = {'switch_to': 'yadda-yadda'} |
247 | - |
248 | - def test_switch_to(self): |
249 | - """Can pass an invalid 'switch_to'. Should default to dashboard.""" |
250 | - actual = self.ui.control_panel.management.notebook.get_current_page() |
251 | - expected = self.ui.control_panel.management.DASHBOARD_PAGE |
252 | - self.assertEqual(actual, expected) |
253 | - |
254 | - |
255 | -class ControlPanelTestCase(BaseTestCase): |
256 | - """The test suite for the control panel itself.""" |
257 | - |
258 | - klass = gui.ControlPanel |
259 | - kwargs = {'main_window': object()} |
260 | - |
261 | - def assert_current_tab_correct(self, expected_tab): |
262 | - """Check that the wiget 'expected_tab' is the current page.""" |
263 | - actual = self.ui.get_nth_page(self.ui.get_current_page()) |
264 | - self.assertTrue(expected_tab is actual) |
265 | - |
266 | - def test_is_a_notebook(self): |
267 | - """Inherits from gtk.VBox.""" |
268 | - self.assertIsInstance(self.ui, gui.gtk.Notebook) |
269 | - |
270 | - def test_startup_visibility(self): |
271 | - """The widget is visible at startup.""" |
272 | - self.assertTrue(self.ui.get_visible(), |
273 | - 'must be visible at startup.') |
274 | - |
275 | - def test_startup_props(self): |
276 | - """The tabs and border are not shown.""" |
277 | - self.assertFalse(self.ui.get_show_border(), 'must not show border.') |
278 | - self.assertFalse(self.ui.get_show_tabs(), 'must not show tabs.') |
279 | - |
280 | - def test_overview_is_shown_at_startup(self): |
281 | - """The overview is shown at startup.""" |
282 | - self.assertIsInstance(self.ui.overview, gui.OverviewPanel) |
283 | - self.assert_current_tab_correct(self.ui.overview) |
284 | - |
285 | - def test_main_window_is_passed_to_child(self): |
286 | - """The child gets the main_window.""" |
287 | - self.assertEqual(self.ui.overview.main_window, |
288 | - self.kwargs['main_window']) |
289 | - |
290 | - def test_on_show_management_panel(self): |
291 | - """A ManagementPanel is shown when the callback is executed.""" |
292 | - self.ui.on_show_management_panel() |
293 | - self.assert_current_tab_correct(self.ui.management) |
294 | - |
295 | - def test_on_show_management_panel_is_idempotent(self): |
296 | - """Only one ManagementPanel is shown.""" |
297 | - self.ui.on_show_management_panel() |
298 | - self.ui.on_show_management_panel() |
299 | - |
300 | - self.assert_current_tab_correct(self.ui.management) |
301 | - |
302 | - def test_credentials_found_shows_dashboard_management_panel(self): |
303 | - """On 'credentials-found' signal, the management panel is shown. |
304 | - |
305 | - If first signal parameter is False, visible tab should be dashboard. |
306 | - |
307 | - """ |
308 | - self.patch(self.ui.management, 'load', self._set_called) |
309 | - self.ui.overview.emit('credentials-found', False, object()) |
310 | - |
311 | - self.assert_current_tab_correct(self.ui.management) |
312 | - self.assertEqual(self.ui.management.notebook.get_current_page(), |
313 | - self.ui.management.DASHBOARD_PAGE) |
314 | - self.assertEqual(self._called, ((), {})) |
315 | - |
316 | - def test_credentials_found_shows_volumes_management_panel(self): |
317 | - """On 'credentials-found' signal, the management panel is shown. |
318 | - |
319 | - If first signal parameter is True, visible tab should be volumes. |
320 | - |
321 | - """ |
322 | - a_token = object() |
323 | - self.ui.overview.emit('credentials-found', True, a_token) |
324 | - |
325 | - self.assert_current_tab_correct(self.ui.management) |
326 | - self.assertEqual(self.ui.management.notebook.get_current_page(), |
327 | - self.ui.management.VOLUMES_PAGE) |
328 | - |
329 | - def test_local_device_removed_shows_overview_panel(self): |
330 | - """On 'local-device-removed' signal, the overview panel is shown.""" |
331 | - self.ui.overview.emit('credentials-found', True, object()) |
332 | - self.ui.management.emit('local-device-removed') |
333 | - |
334 | - self.assert_current_tab_correct(self.ui.overview) |
335 | - |
336 | - |
337 | -class UbuntuOneBinTestCase(BaseTestCase): |
338 | - """The test suite for a Ubuntu One panel.""" |
339 | - |
340 | - klass = gui.UbuntuOneBin |
341 | - kwargs = {'title': 'Something old, something new and something blue.'} |
342 | - |
343 | - def test_is_a_vbox(self): |
344 | - """Inherits from proper gtk widget.""" |
345 | - self.assertIsInstance(self.ui, gui.gtk.VBox) |
346 | - |
347 | - def test_startup_visibility(self): |
348 | - """The widget is visible at startup.""" |
349 | - self.assertTrue(self.ui.get_visible(), |
350 | - 'must be visible at startup.') |
351 | - for child in self.ui.get_children(): |
352 | - self.assertTrue(child.get_visible()) |
353 | - |
354 | - def test_title_is_a_panel_title(self): |
355 | - """Title is the correct widget.""" |
356 | - self.assertIsInstance(self.ui.title, gui.PanelTitle) |
357 | - self.assertIn(self.ui.title, self.ui.get_children()) |
358 | - |
359 | - def test_title_markup_is_correct(self): |
360 | - """The title markup is correctly set when passed as argument.""" |
361 | - self.assertEqual(self.ui.title.label.get_text(), self.kwargs['title']) |
362 | - |
363 | - def test_title_is_correct(self): |
364 | - """The title markup is correctly set when defined at class level.""" |
365 | - ui = self.klass() # no title given |
366 | - self.assertEqual(ui.title.label.get_text(), '') |
367 | - |
368 | - def test_message_is_a_label_loading(self): |
369 | - """Message is the correct widget.""" |
370 | - self.assertIsInstance(self.ui.message, gui.LabelLoading) |
371 | - self.assertIn(self.ui.message, self.ui.get_children()) |
372 | - |
373 | - def test_on_success(self): |
374 | - """Callback to stop the Loading and clear messages.""" |
375 | - self.ui.on_success() |
376 | - self.assertEqual(self.ui.message.get_label(), '') |
377 | - self.assertFalse(self.ui.message.active) |
378 | - |
379 | - def test_on_success_with_message(self): |
380 | - """Callback to stop the Loading and show a info message.""" |
381 | - msg = 'WOW! <i>this rocks</i>' |
382 | - self.ui.on_success(message=msg) |
383 | - self.assertEqual(self.ui.message.get_label(), msg) |
384 | - self.assertFalse(self.ui.message.active) |
385 | - |
386 | - def test_on_error(self): |
387 | - """Callback to stop the Loading and clear messages.""" |
388 | - self.ui.on_error() |
389 | - self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
390 | - self.assertFalse(self.ui.message.active) |
391 | - |
392 | - def test_on_error_with_message(self): |
393 | - """Callback to stop the Loading and show a info message.""" |
394 | - msg = 'WOW! <i>this does not rock</i> :-/' |
395 | - self.ui.on_error(message=msg) |
396 | - self.assert_warning_correct(self.ui.message, msg) |
397 | - self.assertFalse(self.ui.message.active) |
398 | - |
399 | - def test_is_processing(self): |
400 | - """The flag 'is_processing' is False on start.""" |
401 | - self.assertFalse(self.ui.is_processing) |
402 | - self.assertTrue(self.ui.is_sensitive()) |
403 | - |
404 | - def test_set_is_processing(self): |
405 | - """When setting 'is_processing', the spinner is shown.""" |
406 | - self.ui.is_processing = False |
407 | - self.ui.is_processing = True |
408 | - |
409 | - self.assertTrue(self.ui.message.get_visible()) |
410 | - self.assertTrue(self.ui.message.active) |
411 | - self.assertFalse(self.ui.is_sensitive()) |
412 | - |
413 | - def test_unset_is_processing(self): |
414 | - """When unsetting 'is_processing', the spinner is not shown.""" |
415 | - self.ui.is_processing = True |
416 | - self.ui.is_processing = False |
417 | - |
418 | - self.assertTrue(self.ui.message.get_visible()) |
419 | - self.assertFalse(self.ui.message.active) |
420 | - self.assertTrue(self.ui.is_sensitive()) |
421 | - |
422 | - |
423 | -class OverwiewPanelTestCase(ControlPanelMixinTestCase): |
424 | - """The test suite for the overview panel.""" |
425 | - |
426 | - klass = gui.OverviewPanel |
427 | - kwargs = {'main_window': gui.gtk.Window()} |
428 | - ui_filename = 'overview.ui' |
429 | - |
430 | - def test_is_a_greyable_bin(self): |
431 | - """Inherits from GreyableBin.""" |
432 | - self.assertIsInstance(self.ui, gui.GreyableBin) |
433 | - |
434 | - def test_inner_widget_is_packed(self): |
435 | - """The 'itself' vbox is packed into the widget.""" |
436 | - self.assertIn(self.ui.itself, self.ui.get_children()) |
437 | - |
438 | - def test_join_now_is_default(self): |
439 | - """The 'join_now' button is the default widget.""" |
440 | - self.assertTrue(self.ui.join_now_button.get_property('can-default')) |
441 | - |
442 | - def test_sso_backend(self): |
443 | - """Has a correct SSO backend.""" |
444 | - self.assertIsInstance(self.ui.sso_backend, FakedSSOBackend) |
445 | - |
446 | - def test_sso_backend_signals(self): |
447 | - """The proper signals are connected to the backend.""" |
448 | - self.assertEqual(self.ui.sso_backend._signals['CredentialsFound'], |
449 | - [self.ui.on_credentials_found]) |
450 | - self.assertEqual(self.ui.sso_backend._signals['CredentialsNotFound'], |
451 | - [self.ui.on_credentials_not_found]) |
452 | - self.assertEqual(self.ui.sso_backend._signals['CredentialsError'], |
453 | - [self.ui.on_credentials_error]) |
454 | - self.assertEqual(self.ui.sso_backend._signals['AuthorizationDenied'], |
455 | - [self.ui.on_authorization_denied]) |
456 | - |
457 | - |
458 | -class OverwiewNetworkStatePanelTestCase(OverwiewPanelTestCase): |
459 | - """The test suite for the overview panel regarding network state.""" |
460 | - |
461 | - def test_network_state_is_created(self): |
462 | - """The network state is created.""" |
463 | - self.assertIsInstance(self.ui.network_manager_state, |
464 | - gui.networkstate.NetworkManagerState) |
465 | - self.assertEqual(self.ui.network_manager_state._kwargs['result_cb'], |
466 | - self.ui.on_network_state_changed) |
467 | - |
468 | - def test_network_state_is_queried_at_startup(self): |
469 | - """The network state is asked to the NetworkManagerState.""" |
470 | - self.assertTrue('find_online_state' in |
471 | - self.ui.network_manager_state._called) |
472 | - |
473 | - def test_state_online(self): |
474 | - """Network connection is online.""" |
475 | - self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
476 | - # all green, no warning |
477 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
478 | - self.assertTrue(self.ui.get_sensitive()) |
479 | - |
480 | - def test_state_offline(self): |
481 | - """Network connection is offline.""" |
482 | - self.ui.on_network_state_changed(gui.networkstate.OFFLINE) |
483 | - msg = self.ui.NETWORK_OFFLINE % {'app_name': gui.U1_APP_NAME} |
484 | - |
485 | - self.assert_warning_correct(self.ui.warning_label, msg) |
486 | - self.assertFalse(self.ui.get_sensitive()) |
487 | - |
488 | - def test_state_unknown(self): |
489 | - """Network connection is unknown.""" |
490 | - self.ui.on_network_state_changed(gui.networkstate.UNKNOWN) |
491 | - |
492 | - self.assert_warning_correct(self.ui.warning_label, |
493 | - self.ui.NETWORK_UNKNOWN) |
494 | - self.assertFalse(self.ui.get_sensitive()) |
495 | - |
496 | - |
497 | -class OverwiewPanelOnlineTestCase(OverwiewPanelTestCase): |
498 | - """The test suite for the overview panel.""" |
499 | - |
500 | - def setUp(self): |
501 | - super(OverwiewPanelOnlineTestCase, self).setUp() |
502 | - self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
503 | - |
504 | - def test_find_credentials_is_called(self): |
505 | - """Credentials are asked to SSO backend.""" |
506 | - self.assertFalse(self.ui._credentials_are_new) |
507 | - self.assert_backend_called('find_credentials', (gui.U1_APP_NAME, {}), |
508 | - backend=self.ui.sso_backend) |
509 | - |
510 | - def test_on_credentials_found(self): |
511 | - """Callback 'on_credentials_found' is correct.""" |
512 | - self.ui.connect('credentials-found', self._set_called) |
513 | - |
514 | - self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
515 | - |
516 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
517 | - # assume credentials were in local keyring |
518 | - self.assertEqual(self._called, ((self.ui, False, TOKEN), {})) |
519 | - |
520 | - def test_on_credentials_found_when_creds_are_not_new(self): |
521 | - """Callback 'on_credentials_found' distinguish if creds are new.""" |
522 | - self.ui.connect('credentials-found', self._set_called) |
523 | - |
524 | - # credentials weren't in the system |
525 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
526 | - # now they are! |
527 | - self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
528 | - |
529 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
530 | - # assume credentials were not in local keyring |
531 | - self.assertEqual(self._called, ((self.ui, True, TOKEN), {})) |
532 | - |
533 | - def test_on_credentials_not_found(self): |
534 | - """Callback 'on_credentials_not_found' is correct.""" |
535 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
536 | - self.assertTrue(self.ui.get_visible()) |
537 | - self.assertTrue(self.ui._credentials_are_new) |
538 | - |
539 | - def test_on_credentials_error(self): |
540 | - """Callback 'on_credentials_error' is correct.""" |
541 | - self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
542 | - self.assertTrue(self.ui.get_visible()) |
543 | - self.assert_warning_correct(self.ui.warning_label, |
544 | - self.ui.CREDENTIALS_ERROR) |
545 | - |
546 | - def test_on_authorization_denied(self): |
547 | - """Callback 'on_authorization_denied' is correct.""" |
548 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) |
549 | - self.assertTrue(self.ui.get_visible()) |
550 | - self.assert_warning_correct(self.ui.warning_label, |
551 | - self.ui.AUTHORIZATION_DENIED) |
552 | - |
553 | - |
554 | -class OverwiewPanelAppNameMismatchTestCase(OverwiewPanelTestCase): |
555 | - """The test suite for the overview panel when the app_name won't match.""" |
556 | - |
557 | - NOT_U1_APP = 'Not ' + gui.U1_APP_NAME |
558 | - |
559 | - def test_filter_by_app_name(self): |
560 | - """The filter_by_app_name decorator is correct.""" |
561 | - f = gui.filter_by_app_name(self._set_called) |
562 | - f(self.ui, self.NOT_U1_APP) |
563 | - self.assertFalse(self._called) |
564 | - self.assertTrue(self.memento.check_info('ignoring', self.NOT_U1_APP)) |
565 | - |
566 | - args = ('test', object()) |
567 | - kwargs = {'really': 'AWESOME'} |
568 | - f(self.ui, gui.U1_APP_NAME, *args, **kwargs) |
569 | - self.assertEqual(self._called, |
570 | - ((self.ui, gui.U1_APP_NAME,) + args, kwargs)) |
571 | - |
572 | - def test_on_credentials_found(self): |
573 | - """Callback 'on_credentials_found' is not executed.""" |
574 | - self.assert_function_decorated(gui.filter_by_app_name, |
575 | - self.ui.on_credentials_found) |
576 | - |
577 | - def test_on_credentials_not_found(self): |
578 | - """Callback 'on_credentials_not_found' is not executed.""" |
579 | - self.assert_function_decorated(gui.filter_by_app_name, |
580 | - self.ui.on_credentials_not_found) |
581 | - |
582 | - def test_on_credentials_error(self): |
583 | - """Callback 'on_credentials_error' is not executed.""" |
584 | - self.assert_function_decorated(gui.filter_by_app_name, |
585 | - self.ui.on_credentials_error) |
586 | - |
587 | - def test_on_authorization_denied(self): |
588 | - """Callback 'on_authorization_denied' is not executed.""" |
589 | - self.assert_function_decorated(gui.filter_by_app_name, |
590 | - self.ui.on_authorization_denied) |
591 | - |
592 | - |
593 | -class OverwiewPanelNoCredsTestCase(OverwiewPanelTestCase): |
594 | - """The test suite for the overview panel when no credentials are found.""" |
595 | - |
596 | - def setUp(self): |
597 | - super(OverwiewPanelNoCredsTestCase, self).setUp() |
598 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
599 | - |
600 | - def test_startup_visibility(self): |
601 | - """The widget is visible at startup.""" |
602 | - self.assertTrue(self.ui.get_visible(), |
603 | - 'must be visible at startup if credentials not found.') |
604 | - |
605 | - def test_warning_label_is_hidden(self): |
606 | - """The warning label is not shown by default.""" |
607 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
608 | - |
609 | - def test_image_is_correct(self): |
610 | - """There is an image attribute and is correct.""" |
611 | - self.assert_image_equal(self.ui.image, 'overview.png') |
612 | - |
613 | - def test_join_now_is_default_widget(self): |
614 | - """The join now button is the default widget.""" |
615 | - self.assertTrue(self.ui.join_now_button.get_property('can_default')) |
616 | - |
617 | - def test_join_now_button_clicked(self): |
618 | - """Test the 'join now' button callback.""" |
619 | - self.kwargs['main_window'].show() # ensure parent window is realized |
620 | - self.addCleanup(self.kwargs['main_window'].hide) |
621 | - |
622 | - self.ui.join_now_button.clicked() |
623 | - |
624 | - window_id = self.kwargs['main_window'].window.xid |
625 | - args = (gui.U1_APP_NAME, |
626 | - {gui.TC_URL_KEY: gui.U1_TC_URL, |
627 | - gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
628 | - gui.WINDOW_ID_KEY: str(window_id), |
629 | - gui.PING_URL_KEY: gui.U1_PING_URL}) |
630 | - self.assert_backend_called('register', args, |
631 | - backend=self.ui.sso_backend) |
632 | - |
633 | - def test_connect_button_clicked(self): |
634 | - """Test the 'join now' button callback.""" |
635 | - self.kwargs['main_window'].show() # ensure parent window is realized |
636 | - self.addCleanup(self.kwargs['main_window'].hide) |
637 | - |
638 | - self.ui.connect_button.clicked() |
639 | - |
640 | - window_id = self.kwargs['main_window'].window.xid |
641 | - args = (gui.U1_APP_NAME, |
642 | - {gui.TC_URL_KEY: gui.U1_TC_URL, |
643 | - gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
644 | - gui.WINDOW_ID_KEY: str(window_id), |
645 | - gui.PING_URL_KEY: gui.U1_PING_URL}) |
646 | - self.assert_backend_called('login', args, |
647 | - backend=self.ui.sso_backend) |
648 | - |
649 | - def test_join_now_button_clicked_set_greyed(self): |
650 | - """Clicking on 'join_now' self is greyed.""" |
651 | - self.ui.join_now_button.clicked() |
652 | - self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
653 | - |
654 | - def test_join_now_button_clicked_removes_warning(self): |
655 | - """Clicking on 'join_now' the warnings are removed.""" |
656 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
657 | - self.ui.join_now_button.clicked() |
658 | - |
659 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
660 | - |
661 | - def test_connect_button_clicked_set_greyed(self): |
662 | - """Clicking on 'connect' self is greyed.""" |
663 | - self.ui.connect_button.clicked() |
664 | - self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
665 | - |
666 | - def test_connect_button_clicked_removes_warning(self): |
667 | - """Clicking on 'connect' the warnings are removed.""" |
668 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
669 | - self.ui.connect_button.clicked() |
670 | - |
671 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
672 | - |
673 | - def test_on_credentials_not_found_unset_greyed(self): |
674 | - """Callback 'on_credentials_not_found' unsets the 'greyed' prop.""" |
675 | - self.ui.connect_button.clicked() |
676 | - self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
677 | - |
678 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
679 | - |
680 | - def test_on_credentials_error_unset_greyed(self): |
681 | - """Callback 'on_credentials_error' unsets the 'greyed' prop.""" |
682 | - self.ui.connect_button.clicked() |
683 | - self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
684 | - |
685 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
686 | - |
687 | - def test_on_authorization_denied_unset_greyed(self): |
688 | - """Callback 'on_authorization_denied' unsets the 'greyed' prop.""" |
689 | - self.ui.connect_button.clicked() |
690 | - self.ui.on_authorization_denied(gui.U1_APP_NAME) |
691 | - |
692 | - self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
693 | - |
694 | - def test_buttons_disabled_when_greyed(self): |
695 | - """Buttons should be disabled when widget is greyed.""" |
696 | - self.ui.set_sensitive(True) |
697 | - self.ui.set_property('greyed', True) |
698 | - |
699 | - self.assertFalse(self.ui.join_now_button.is_sensitive()) |
700 | - self.assertFalse(self.ui.connect_button.is_sensitive()) |
701 | - |
702 | - def test_buttons_enabled_when_not_greyed(self): |
703 | - """Buttons should be enabled when widget is not greyed.""" |
704 | - self.ui.set_sensitive(False) |
705 | - self.ui.set_property('greyed', False) |
706 | - |
707 | - self.assertTrue(self.ui.join_now_button.is_sensitive()) |
708 | - self.assertTrue(self.ui.connect_button.is_sensitive()) |
709 | |
710 | |
711 | class DashboardTestCase(ControlPanelMixinTestCase): |
712 | @@ -842,6 +284,35 @@ |
713 | self.assertEqual(self._called, |
714 | ((None, gui.FILE_URI_PREFIX + ROOT['path']), {})) |
715 | |
716 | + def test_on_volumes_info_ready_with_music_folder(self): |
717 | + """The volumes info is processed when ready.""" |
718 | + info = [(u'', u'147852369', [ROOT] + [MUSIC_FOLDER])] |
719 | + |
720 | + self.ui.on_volumes_info_ready(info) |
721 | + |
722 | + treeiter = self.ui.volumes_store.get_iter_root() |
723 | + row = self.ui.volumes_store.get(treeiter, *xrange(self.ui.MAX_COLS)) |
724 | + |
725 | + # walk 'Mine' folders children |
726 | + treeiter = self.ui.volumes_store.iter_children(treeiter) |
727 | + |
728 | + # grab next row since first one is root |
729 | + treeiter = self.ui.volumes_store.iter_next(treeiter) |
730 | + row = self.ui.volumes_store.get(treeiter, *xrange(self.ui.MAX_COLS)) |
731 | + |
732 | + volume = MUSIC_FOLDER |
733 | + expected_path = volume['path'].replace(USER_HOME, '~') |
734 | + expected_path = expected_path.replace(self.ui.MUSIC_REAL_PATH, |
735 | + self.ui.MUSIC_DISPLAY_NAME) |
736 | + self.assertEqual(row[0], expected_path) |
737 | + self.assertEqual(row[1], bool(volume['subscribed'])) |
738 | + self.assertEqual(row[2], self.ui.MUSIC_ICON_NAME) |
739 | + self.assertTrue(row[3], 'toggle should be shown on child!') |
740 | + self.assertTrue(row[4], 'toggle should be sensitive') |
741 | + self.assertEqual(row[5], gui.gtk.ICON_SIZE_MENU) |
742 | + self.assertEqual(row[6], volume['volume_id']) |
743 | + self.assertEqual(row[7], volume['path']) |
744 | + |
745 | |
746 | class VolumesSubscriptionTestCase(VolumesTestCase): |
747 | """The test suite for the volumes panel.""" |
748 | |
749 | === added file 'ubuntuone/controlpanel/gtk/tests/test_gui_basic.py' |
750 | --- ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 1970-01-01 00:00:00 +0000 |
751 | +++ ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-03-01 15:44:47 +0000 |
752 | @@ -0,0 +1,588 @@ |
753 | +# -*- coding: utf-8 -*- |
754 | + |
755 | +# Authors: Natalia B Bidart <natalia.bidart@canonical.com> |
756 | +# |
757 | +# Copyright 2010 Canonical Ltd. |
758 | +# |
759 | +# This program is free software: you can redistribute it and/or modify it |
760 | +# under the terms of the GNU General Public License version 3, as published |
761 | +# by the Free Software Foundation. |
762 | +# |
763 | +# This program is distributed in the hope that it will be useful, but |
764 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
765 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
766 | +# PURPOSE. See the GNU General Public License for more details. |
767 | +# |
768 | +# You should have received a copy of the GNU General Public License along |
769 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
770 | + |
771 | +"""The test suite for the control panel user interface (basics).""" |
772 | + |
773 | +from __future__ import division |
774 | + |
775 | +from ubuntuone.controlpanel.gtk import gui |
776 | +from ubuntuone.controlpanel.gtk.tests import BaseTestCase, FakedSSOBackend |
777 | +from ubuntuone.controlpanel.tests import TOKEN |
778 | + |
779 | + |
780 | +# Attribute 'yyy' defined outside __init__, access to a protected member |
781 | +# pylint: disable=W0201, W0212 |
782 | + |
783 | + |
784 | +class ControlPanelMixinTestCase(BaseTestCase): |
785 | + """The test suite for the control panel widget.""" |
786 | + |
787 | + klass = gui.ControlPanelMixin |
788 | + ui_filename = None |
789 | + |
790 | + def test_is_a_control_panel_mixin(self): |
791 | + """Inherits from ControlPanelMixin.""" |
792 | + self.assertIsInstance(self.ui, gui.ControlPanelMixin) |
793 | + |
794 | + def test_ui_can_be_created(self): |
795 | + """UI main class exists and can be created.""" |
796 | + self.assertTrue(self.ui is not None) |
797 | + |
798 | + |
799 | +class ControlPanelWindowTestCase(BaseTestCase): |
800 | + """The test suite for the control panel window.""" |
801 | + |
802 | + klass = gui.ControlPanelWindow |
803 | + |
804 | + def test_is_a_window(self): |
805 | + """Inherits from gtk.Window.""" |
806 | + self.assertIsInstance(self.ui, gui.gtk.Window) |
807 | + |
808 | + def test_startup_visibility(self): |
809 | + """The widget is visible at startup.""" |
810 | + self.assertTrue(self.ui.get_visible(), 'must be visible at startup.') |
811 | + |
812 | + def test_main_start_gtk_main_loop(self): |
813 | + """The GTK main loop is started when calling main().""" |
814 | + self.patch(gui.gtk, 'main', self._set_called) |
815 | + self.ui.main() |
816 | + self.assertEqual(self._called, ((), {}), 'gtk.main was called.') |
817 | + |
818 | + def test_closing_stops_the_main_lopp(self): |
819 | + """The GTK main loop is stopped when closing the window.""" |
820 | + self.patch(gui.gtk, 'main_quit', self._set_called) |
821 | + self.ui.emit('delete-event', None) |
822 | + self.assertEqual(self._called, ((), {}), 'gtk.main_quit was called.') |
823 | + |
824 | + def test_title_is_correct(self): |
825 | + """The window title is correct.""" |
826 | + expected = self.ui.TITLE % {'app_name': gui.U1_APP_NAME} |
827 | + self.assertEqual(self.ui.get_title(), expected) |
828 | + |
829 | + def test_control_panel_is_the_only_child(self): |
830 | + """The control panel is the window's content.""" |
831 | + children = self.ui.get_children() |
832 | + self.assertEqual(1, len(children)) |
833 | + |
834 | + control_panel = self.ui.get_children()[0] |
835 | + self.assertTrue(control_panel is self.ui.control_panel) |
836 | + self.assertIsInstance(self.ui.control_panel, gui.ControlPanel) |
837 | + self.assertTrue(self.ui.control_panel.get_visible()) |
838 | + |
839 | + def test_main_window_is_passed_to_child(self): |
840 | + """The child gets the main_window.""" |
841 | + self.assertEqual(self.ui.control_panel.main_window, self.ui) |
842 | + |
843 | + def test_icon_name_is_correct(self): |
844 | + """The icon name is correct.""" |
845 | + self.assertEqual(self.ui.get_icon_name(), 'ubuntuone') |
846 | + |
847 | + def test_max_size(self): |
848 | + """Max size is not bigger than 736x525 (LP: #645526, LP: #683164).""" |
849 | + self.assertTrue(self.ui.get_size_request() <= (736, 525)) |
850 | + |
851 | + |
852 | +class ControlPanelWindowParamsTestCase(ControlPanelWindowTestCase): |
853 | + """The test suite for the control panel window when passing params.""" |
854 | + |
855 | + kwargs = {'switch_to': 'devices'} |
856 | + |
857 | + def test_switch_to(self): |
858 | + """Can pass a 'switch_to' parameter to start on a particular tab.""" |
859 | + actual = self.ui.control_panel.management.notebook.get_current_page() |
860 | + self.assertEqual(actual, self.ui.control_panel.management.DEVICES_PAGE) |
861 | + |
862 | + |
863 | +class ControlPanelWindowParamsNoneTestCase(ControlPanelWindowTestCase): |
864 | + """The suite for the control panel window when passing None params.""" |
865 | + |
866 | + kwargs = {'switch_to': None} |
867 | + |
868 | + def test_switch_to(self): |
869 | + """Can pass a 'switch_to' being None. Should default to dashboard.""" |
870 | + actual = self.ui.control_panel.management.notebook.get_current_page() |
871 | + expected = self.ui.control_panel.management.DASHBOARD_PAGE |
872 | + self.assertEqual(actual, expected) |
873 | + |
874 | + |
875 | +class ControlPanelWindowInvalidParamsTestCase(ControlPanelWindowTestCase): |
876 | + """The suite for the control panel window when passing invalid params.""" |
877 | + |
878 | + kwargs = {'switch_to': 'yadda-yadda'} |
879 | + |
880 | + def test_switch_to(self): |
881 | + """Can pass an invalid 'switch_to'. Should default to dashboard.""" |
882 | + actual = self.ui.control_panel.management.notebook.get_current_page() |
883 | + expected = self.ui.control_panel.management.DASHBOARD_PAGE |
884 | + self.assertEqual(actual, expected) |
885 | + |
886 | + |
887 | +class ControlPanelTestCase(BaseTestCase): |
888 | + """The test suite for the control panel itself.""" |
889 | + |
890 | + klass = gui.ControlPanel |
891 | + kwargs = {'main_window': object()} |
892 | + |
893 | + def assert_current_tab_correct(self, expected_tab): |
894 | + """Check that the wiget 'expected_tab' is the current page.""" |
895 | + actual = self.ui.get_nth_page(self.ui.get_current_page()) |
896 | + self.assertTrue(expected_tab is actual) |
897 | + |
898 | + def test_is_a_notebook(self): |
899 | + """Inherits from gtk.VBox.""" |
900 | + self.assertIsInstance(self.ui, gui.gtk.Notebook) |
901 | + |
902 | + def test_startup_visibility(self): |
903 | + """The widget is visible at startup.""" |
904 | + self.assertTrue(self.ui.get_visible(), |
905 | + 'must be visible at startup.') |
906 | + |
907 | + def test_startup_props(self): |
908 | + """The tabs and border are not shown.""" |
909 | + self.assertFalse(self.ui.get_show_border(), 'must not show border.') |
910 | + self.assertFalse(self.ui.get_show_tabs(), 'must not show tabs.') |
911 | + |
912 | + def test_overview_is_shown_at_startup(self): |
913 | + """The overview is shown at startup.""" |
914 | + self.assertIsInstance(self.ui.overview, gui.OverviewPanel) |
915 | + self.assert_current_tab_correct(self.ui.overview) |
916 | + |
917 | + def test_main_window_is_passed_to_child(self): |
918 | + """The child gets the main_window.""" |
919 | + self.assertEqual(self.ui.overview.main_window, |
920 | + self.kwargs['main_window']) |
921 | + |
922 | + def test_on_show_management_panel(self): |
923 | + """A ManagementPanel is shown when the callback is executed.""" |
924 | + self.ui.on_show_management_panel() |
925 | + self.assert_current_tab_correct(self.ui.management) |
926 | + |
927 | + def test_on_show_management_panel_is_idempotent(self): |
928 | + """Only one ManagementPanel is shown.""" |
929 | + self.ui.on_show_management_panel() |
930 | + self.ui.on_show_management_panel() |
931 | + |
932 | + self.assert_current_tab_correct(self.ui.management) |
933 | + |
934 | + def test_credentials_found_shows_dashboard_management_panel(self): |
935 | + """On 'credentials-found' signal, the management panel is shown. |
936 | + |
937 | + If first signal parameter is False, visible tab should be dashboard. |
938 | + |
939 | + """ |
940 | + self.patch(self.ui.management, 'load', self._set_called) |
941 | + self.ui.overview.emit('credentials-found', False, object()) |
942 | + |
943 | + self.assert_current_tab_correct(self.ui.management) |
944 | + self.assertEqual(self.ui.management.notebook.get_current_page(), |
945 | + self.ui.management.DASHBOARD_PAGE) |
946 | + self.assertEqual(self._called, ((), {})) |
947 | + |
948 | + def test_credentials_found_shows_volumes_management_panel(self): |
949 | + """On 'credentials-found' signal, the management panel is shown. |
950 | + |
951 | + If first signal parameter is True, visible tab should be volumes. |
952 | + |
953 | + """ |
954 | + a_token = object() |
955 | + self.ui.overview.emit('credentials-found', True, a_token) |
956 | + |
957 | + self.assert_current_tab_correct(self.ui.management) |
958 | + self.assertEqual(self.ui.management.notebook.get_current_page(), |
959 | + self.ui.management.VOLUMES_PAGE) |
960 | + |
961 | + def test_local_device_removed_shows_overview_panel(self): |
962 | + """On 'local-device-removed' signal, the overview panel is shown.""" |
963 | + self.ui.overview.emit('credentials-found', True, object()) |
964 | + self.ui.management.emit('local-device-removed') |
965 | + |
966 | + self.assert_current_tab_correct(self.ui.overview) |
967 | + |
968 | + |
969 | +class UbuntuOneBinTestCase(BaseTestCase): |
970 | + """The test suite for a Ubuntu One panel.""" |
971 | + |
972 | + klass = gui.UbuntuOneBin |
973 | + kwargs = {'title': 'Something old, something new and something blue.'} |
974 | + |
975 | + def test_is_a_vbox(self): |
976 | + """Inherits from proper gtk widget.""" |
977 | + self.assertIsInstance(self.ui, gui.gtk.VBox) |
978 | + |
979 | + def test_startup_visibility(self): |
980 | + """The widget is visible at startup.""" |
981 | + self.assertTrue(self.ui.get_visible(), |
982 | + 'must be visible at startup.') |
983 | + for child in self.ui.get_children(): |
984 | + self.assertTrue(child.get_visible()) |
985 | + |
986 | + def test_title_is_a_panel_title(self): |
987 | + """Title is the correct widget.""" |
988 | + self.assertIsInstance(self.ui.title, gui.PanelTitle) |
989 | + self.assertIn(self.ui.title, self.ui.get_children()) |
990 | + |
991 | + def test_title_markup_is_correct(self): |
992 | + """The title markup is correctly set when passed as argument.""" |
993 | + self.assertEqual(self.ui.title.label.get_text(), self.kwargs['title']) |
994 | + |
995 | + def test_title_is_correct(self): |
996 | + """The title markup is correctly set when defined at class level.""" |
997 | + ui = self.klass() # no title given |
998 | + self.assertEqual(ui.title.label.get_text(), '') |
999 | + |
1000 | + def test_message_is_a_label_loading(self): |
1001 | + """Message is the correct widget.""" |
1002 | + self.assertIsInstance(self.ui.message, gui.LabelLoading) |
1003 | + self.assertIn(self.ui.message, self.ui.get_children()) |
1004 | + |
1005 | + def test_on_success(self): |
1006 | + """Callback to stop the Loading and clear messages.""" |
1007 | + self.ui.on_success() |
1008 | + self.assertEqual(self.ui.message.get_label(), '') |
1009 | + self.assertFalse(self.ui.message.active) |
1010 | + |
1011 | + def test_on_success_with_message(self): |
1012 | + """Callback to stop the Loading and show a info message.""" |
1013 | + msg = 'WOW! <i>this rocks</i>' |
1014 | + self.ui.on_success(message=msg) |
1015 | + self.assertEqual(self.ui.message.get_label(), msg) |
1016 | + self.assertFalse(self.ui.message.active) |
1017 | + |
1018 | + def test_on_error(self): |
1019 | + """Callback to stop the Loading and clear messages.""" |
1020 | + self.ui.on_error() |
1021 | + self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
1022 | + self.assertFalse(self.ui.message.active) |
1023 | + |
1024 | + def test_on_error_with_message(self): |
1025 | + """Callback to stop the Loading and show a info message.""" |
1026 | + msg = 'WOW! <i>this does not rock</i> :-/' |
1027 | + self.ui.on_error(message=msg) |
1028 | + self.assert_warning_correct(self.ui.message, msg) |
1029 | + self.assertFalse(self.ui.message.active) |
1030 | + |
1031 | + def test_is_processing(self): |
1032 | + """The flag 'is_processing' is False on start.""" |
1033 | + self.assertFalse(self.ui.is_processing) |
1034 | + self.assertTrue(self.ui.is_sensitive()) |
1035 | + |
1036 | + def test_set_is_processing(self): |
1037 | + """When setting 'is_processing', the spinner is shown.""" |
1038 | + self.ui.is_processing = False |
1039 | + self.ui.is_processing = True |
1040 | + |
1041 | + self.assertTrue(self.ui.message.get_visible()) |
1042 | + self.assertTrue(self.ui.message.active) |
1043 | + self.assertFalse(self.ui.is_sensitive()) |
1044 | + |
1045 | + def test_unset_is_processing(self): |
1046 | + """When unsetting 'is_processing', the spinner is not shown.""" |
1047 | + self.ui.is_processing = True |
1048 | + self.ui.is_processing = False |
1049 | + |
1050 | + self.assertTrue(self.ui.message.get_visible()) |
1051 | + self.assertFalse(self.ui.message.active) |
1052 | + self.assertTrue(self.ui.is_sensitive()) |
1053 | + |
1054 | + |
1055 | +class OverwiewPanelTestCase(ControlPanelMixinTestCase): |
1056 | + """The test suite for the overview panel.""" |
1057 | + |
1058 | + klass = gui.OverviewPanel |
1059 | + kwargs = {'main_window': gui.gtk.Window()} |
1060 | + ui_filename = 'overview.ui' |
1061 | + |
1062 | + def test_is_a_greyable_bin(self): |
1063 | + """Inherits from GreyableBin.""" |
1064 | + self.assertIsInstance(self.ui, gui.GreyableBin) |
1065 | + |
1066 | + def test_inner_widget_is_packed(self): |
1067 | + """The 'itself' vbox is packed into the widget.""" |
1068 | + self.assertIn(self.ui.itself, self.ui.get_children()) |
1069 | + |
1070 | + def test_join_now_is_default(self): |
1071 | + """The 'join_now' button is the default widget.""" |
1072 | + self.assertTrue(self.ui.join_now_button.get_property('can-default')) |
1073 | + |
1074 | + def test_sso_backend(self): |
1075 | + """Has a correct SSO backend.""" |
1076 | + self.assertIsInstance(self.ui.sso_backend, FakedSSOBackend) |
1077 | + |
1078 | + def test_sso_backend_signals(self): |
1079 | + """The proper signals are connected to the backend.""" |
1080 | + self.assertEqual(self.ui.sso_backend._signals['CredentialsFound'], |
1081 | + [self.ui.on_credentials_found]) |
1082 | + self.assertEqual(self.ui.sso_backend._signals['CredentialsNotFound'], |
1083 | + [self.ui.on_credentials_not_found]) |
1084 | + self.assertEqual(self.ui.sso_backend._signals['CredentialsError'], |
1085 | + [self.ui.on_credentials_error]) |
1086 | + self.assertEqual(self.ui.sso_backend._signals['AuthorizationDenied'], |
1087 | + [self.ui.on_authorization_denied]) |
1088 | + |
1089 | + |
1090 | +class OverwiewNetworkStatePanelTestCase(OverwiewPanelTestCase): |
1091 | + """The test suite for the overview panel regarding network state.""" |
1092 | + |
1093 | + def test_network_state_is_created(self): |
1094 | + """The network state is created.""" |
1095 | + self.assertIsInstance(self.ui.network_manager_state, |
1096 | + gui.networkstate.NetworkManagerState) |
1097 | + self.assertEqual(self.ui.network_manager_state._kwargs['result_cb'], |
1098 | + self.ui.on_network_state_changed) |
1099 | + |
1100 | + def test_network_state_is_queried_at_startup(self): |
1101 | + """The network state is asked to the NetworkManagerState.""" |
1102 | + self.assertTrue('find_online_state' in |
1103 | + self.ui.network_manager_state._called) |
1104 | + |
1105 | + def test_state_online(self): |
1106 | + """Network connection is online.""" |
1107 | + self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
1108 | + # all green, no warning |
1109 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
1110 | + self.assertTrue(self.ui.get_sensitive()) |
1111 | + |
1112 | + def test_state_offline(self): |
1113 | + """Network connection is offline.""" |
1114 | + self.ui.on_network_state_changed(gui.networkstate.OFFLINE) |
1115 | + msg = self.ui.NETWORK_OFFLINE % {'app_name': gui.U1_APP_NAME} |
1116 | + |
1117 | + self.assert_warning_correct(self.ui.warning_label, msg) |
1118 | + self.assertFalse(self.ui.get_sensitive()) |
1119 | + |
1120 | + def test_state_unknown(self): |
1121 | + """Network connection is unknown.""" |
1122 | + self.ui.on_network_state_changed(gui.networkstate.UNKNOWN) |
1123 | + |
1124 | + self.assert_warning_correct(self.ui.warning_label, |
1125 | + self.ui.NETWORK_UNKNOWN) |
1126 | + self.assertFalse(self.ui.get_sensitive()) |
1127 | + |
1128 | + |
1129 | +class OverwiewPanelOnlineTestCase(OverwiewPanelTestCase): |
1130 | + """The test suite for the overview panel.""" |
1131 | + |
1132 | + def setUp(self): |
1133 | + super(OverwiewPanelOnlineTestCase, self).setUp() |
1134 | + self.ui.on_network_state_changed(gui.networkstate.ONLINE) |
1135 | + |
1136 | + def test_find_credentials_is_called(self): |
1137 | + """Credentials are asked to SSO backend.""" |
1138 | + self.assertFalse(self.ui._credentials_are_new) |
1139 | + self.assert_backend_called('find_credentials', (gui.U1_APP_NAME, {}), |
1140 | + backend=self.ui.sso_backend) |
1141 | + |
1142 | + def test_on_credentials_found(self): |
1143 | + """Callback 'on_credentials_found' is correct.""" |
1144 | + self.ui.connect('credentials-found', self._set_called) |
1145 | + |
1146 | + self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
1147 | + |
1148 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
1149 | + # assume credentials were in local keyring |
1150 | + self.assertEqual(self._called, ((self.ui, False, TOKEN), {})) |
1151 | + |
1152 | + def test_on_credentials_found_when_creds_are_not_new(self): |
1153 | + """Callback 'on_credentials_found' distinguish if creds are new.""" |
1154 | + self.ui.connect('credentials-found', self._set_called) |
1155 | + |
1156 | + # credentials weren't in the system |
1157 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
1158 | + # now they are! |
1159 | + self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN) |
1160 | + |
1161 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
1162 | + # assume credentials were not in local keyring |
1163 | + self.assertEqual(self._called, ((self.ui, True, TOKEN), {})) |
1164 | + |
1165 | + def test_on_credentials_not_found(self): |
1166 | + """Callback 'on_credentials_not_found' is correct.""" |
1167 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
1168 | + self.assertTrue(self.ui.get_visible()) |
1169 | + self.assertTrue(self.ui._credentials_are_new) |
1170 | + |
1171 | + def test_on_credentials_error(self): |
1172 | + """Callback 'on_credentials_error' is correct.""" |
1173 | + self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
1174 | + self.assertTrue(self.ui.get_visible()) |
1175 | + self.assert_warning_correct(self.ui.warning_label, |
1176 | + self.ui.CREDENTIALS_ERROR) |
1177 | + |
1178 | + def test_on_authorization_denied(self): |
1179 | + """Callback 'on_authorization_denied' is correct.""" |
1180 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) |
1181 | + self.assertTrue(self.ui.get_visible()) |
1182 | + self.assert_warning_correct(self.ui.warning_label, |
1183 | + self.ui.AUTHORIZATION_DENIED) |
1184 | + |
1185 | + |
1186 | +class OverwiewPanelAppNameMismatchTestCase(OverwiewPanelTestCase): |
1187 | + """The test suite for the overview panel when the app_name won't match.""" |
1188 | + |
1189 | + NOT_U1_APP = 'Not ' + gui.U1_APP_NAME |
1190 | + |
1191 | + def test_filter_by_app_name(self): |
1192 | + """The filter_by_app_name decorator is correct.""" |
1193 | + f = gui.filter_by_app_name(self._set_called) |
1194 | + f(self.ui, self.NOT_U1_APP) |
1195 | + self.assertFalse(self._called) |
1196 | + self.assertTrue(self.memento.check_info('ignoring', self.NOT_U1_APP)) |
1197 | + |
1198 | + args = ('test', object()) |
1199 | + kwargs = {'really': 'AWESOME'} |
1200 | + f(self.ui, gui.U1_APP_NAME, *args, **kwargs) |
1201 | + self.assertEqual(self._called, |
1202 | + ((self.ui, gui.U1_APP_NAME,) + args, kwargs)) |
1203 | + |
1204 | + def test_on_credentials_found(self): |
1205 | + """Callback 'on_credentials_found' is not executed.""" |
1206 | + self.assert_function_decorated(gui.filter_by_app_name, |
1207 | + self.ui.on_credentials_found) |
1208 | + |
1209 | + def test_on_credentials_not_found(self): |
1210 | + """Callback 'on_credentials_not_found' is not executed.""" |
1211 | + self.assert_function_decorated(gui.filter_by_app_name, |
1212 | + self.ui.on_credentials_not_found) |
1213 | + |
1214 | + def test_on_credentials_error(self): |
1215 | + """Callback 'on_credentials_error' is not executed.""" |
1216 | + self.assert_function_decorated(gui.filter_by_app_name, |
1217 | + self.ui.on_credentials_error) |
1218 | + |
1219 | + def test_on_authorization_denied(self): |
1220 | + """Callback 'on_authorization_denied' is not executed.""" |
1221 | + self.assert_function_decorated(gui.filter_by_app_name, |
1222 | + self.ui.on_authorization_denied) |
1223 | + |
1224 | + |
1225 | +class OverwiewPanelNoCredsTestCase(OverwiewPanelTestCase): |
1226 | + """The test suite for the overview panel when no credentials are found.""" |
1227 | + |
1228 | + def setUp(self): |
1229 | + super(OverwiewPanelNoCredsTestCase, self).setUp() |
1230 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
1231 | + |
1232 | + def test_startup_visibility(self): |
1233 | + """The widget is visible at startup.""" |
1234 | + self.assertTrue(self.ui.get_visible(), |
1235 | + 'must be visible at startup if credentials not found.') |
1236 | + |
1237 | + def test_warning_label_is_hidden(self): |
1238 | + """The warning label is not shown by default.""" |
1239 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
1240 | + |
1241 | + def test_image_is_correct(self): |
1242 | + """There is an image attribute and is correct.""" |
1243 | + self.assert_image_equal(self.ui.image, 'overview.png') |
1244 | + |
1245 | + def test_join_now_is_default_widget(self): |
1246 | + """The join now button is the default widget.""" |
1247 | + self.assertTrue(self.ui.join_now_button.get_property('can_default')) |
1248 | + |
1249 | + def test_join_now_button_clicked(self): |
1250 | + """Test the 'join now' button callback.""" |
1251 | + self.kwargs['main_window'].show() # ensure parent window is realized |
1252 | + self.addCleanup(self.kwargs['main_window'].hide) |
1253 | + |
1254 | + self.ui.join_now_button.clicked() |
1255 | + |
1256 | + window_id = self.kwargs['main_window'].window.xid |
1257 | + args = (gui.U1_APP_NAME, |
1258 | + {gui.TC_URL_KEY: gui.U1_TC_URL, |
1259 | + gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
1260 | + gui.WINDOW_ID_KEY: str(window_id), |
1261 | + gui.PING_URL_KEY: gui.U1_PING_URL}) |
1262 | + self.assert_backend_called('register', args, |
1263 | + backend=self.ui.sso_backend) |
1264 | + |
1265 | + def test_connect_button_clicked(self): |
1266 | + """Test the 'join now' button callback.""" |
1267 | + self.kwargs['main_window'].show() # ensure parent window is realized |
1268 | + self.addCleanup(self.kwargs['main_window'].hide) |
1269 | + |
1270 | + self.ui.connect_button.clicked() |
1271 | + |
1272 | + window_id = self.kwargs['main_window'].window.xid |
1273 | + args = (gui.U1_APP_NAME, |
1274 | + {gui.TC_URL_KEY: gui.U1_TC_URL, |
1275 | + gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
1276 | + gui.WINDOW_ID_KEY: str(window_id), |
1277 | + gui.PING_URL_KEY: gui.U1_PING_URL}) |
1278 | + self.assert_backend_called('login', args, |
1279 | + backend=self.ui.sso_backend) |
1280 | + |
1281 | + def test_join_now_button_clicked_set_greyed(self): |
1282 | + """Clicking on 'join_now' self is greyed.""" |
1283 | + self.ui.join_now_button.clicked() |
1284 | + self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
1285 | + |
1286 | + def test_join_now_button_clicked_removes_warning(self): |
1287 | + """Clicking on 'join_now' the warnings are removed.""" |
1288 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
1289 | + self.ui.join_now_button.clicked() |
1290 | + |
1291 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
1292 | + |
1293 | + def test_connect_button_clicked_set_greyed(self): |
1294 | + """Clicking on 'connect' self is greyed.""" |
1295 | + self.ui.connect_button.clicked() |
1296 | + self.assertTrue(self.ui.get_property('greyed'), 'Must be greyed.') |
1297 | + |
1298 | + def test_connect_button_clicked_removes_warning(self): |
1299 | + """Clicking on 'connect' the warnings are removed.""" |
1300 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning |
1301 | + self.ui.connect_button.clicked() |
1302 | + |
1303 | + self.assertEqual(self.ui.warning_label.get_text(), '') |
1304 | + |
1305 | + def test_on_credentials_not_found_unset_greyed(self): |
1306 | + """Callback 'on_credentials_not_found' unsets the 'greyed' prop.""" |
1307 | + self.ui.connect_button.clicked() |
1308 | + self.ui.on_credentials_not_found(gui.U1_APP_NAME) |
1309 | + |
1310 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
1311 | + |
1312 | + def test_on_credentials_error_unset_greyed(self): |
1313 | + """Callback 'on_credentials_error' unsets the 'greyed' prop.""" |
1314 | + self.ui.connect_button.clicked() |
1315 | + self.ui.on_credentials_error(gui.U1_APP_NAME, {}) |
1316 | + |
1317 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
1318 | + |
1319 | + def test_on_authorization_denied_unset_greyed(self): |
1320 | + """Callback 'on_authorization_denied' unsets the 'greyed' prop.""" |
1321 | + self.ui.connect_button.clicked() |
1322 | + self.ui.on_authorization_denied(gui.U1_APP_NAME) |
1323 | + |
1324 | + self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.') |
1325 | + |
1326 | + def test_buttons_disabled_when_greyed(self): |
1327 | + """Buttons should be disabled when widget is greyed.""" |
1328 | + self.ui.set_sensitive(True) |
1329 | + self.ui.set_property('greyed', True) |
1330 | + |
1331 | + self.assertFalse(self.ui.join_now_button.is_sensitive()) |
1332 | + self.assertFalse(self.ui.connect_button.is_sensitive()) |
1333 | + |
1334 | + def test_buttons_enabled_when_not_greyed(self): |
1335 | + """Buttons should be enabled when widget is not greyed.""" |
1336 | + self.ui.set_sensitive(False) |
1337 | + self.ui.set_property('greyed', False) |
1338 | + |
1339 | + self.assertTrue(self.ui.join_now_button.is_sensitive()) |
1340 | + self.assertTrue(self.ui.connect_button.is_sensitive()) |
+1