46
59
super(FakeMainWindow, self).__init__()
49
class SystrayTestCase(TestCase):
62
class FakeDesktopService(object):
64
"""Fake QDesktopService."""
69
def openUrl(cls, url):
71
FakeDesktopService.data['cls'] = cls
72
FakeDesktopService.data['url'] = url
75
class SystrayTestCase(BaseTestCase):
51
77
"""Test the notification area icon."""
79
class_ui = systray.TrayIcon
83
# We need to patch the startTimer first, to avoid the timer
84
# to get started on initialization.
85
self.patch(systray.TrayIcon, "startTimer", lambda s, x: None)
86
self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
87
yield super(SystrayTestCase, self).setUp()
88
self.patch(QtGui, "QDesktopServices", FakeDesktopService)
90
def assert_status_correct(self, status_bd, status_ui, action,
92
"""The shown status is correct."""
93
expected_text = status_ui
95
status = {backend.STATUS_KEY: status_bd}
96
self.ui._process_status(status)
98
actual_text = unicode(self.ui.status.text())
99
self.assertEqual(expected_text, actual_text)
101
self.assertFalse(self.ui.status.isEnabled())
102
self.assertEqual(unicode(self.ui.status_action.text()), action)
104
self.ui.status_action.trigger()
105
self.assertFalse(self.ui.status_action.isEnabled())
106
self.assert_backend_called(callback)
108
def test_process_info_invalid_status(self):
109
"""File sync status invalid, ignore event."""
110
status = {backend.STATUS_KEY: backend.FILE_SYNC_STARTING,
111
backend.MSG_KEY: qt.FILE_SYNC_STARTING,
112
'icon': backend.FILE_SYNC_STARTING}
113
self.ui._process_status(status)
114
self.ui._process_status(3)
116
actual_text = unicode(self.ui.status.text())
117
self.assertEqual(qt.FILE_SYNC_STARTING, actual_text)
119
def test_process_info_changed(self):
120
"""Backend's file sync status changed callback is connected."""
121
self.ui.refresh_status()
122
self.assertEqual(self.ui.backend.status_changed_handler,
123
self.ui._process_status)
125
def test_process_info_disabled(self):
126
"""File sync status disabled update the label."""
127
self.ui.refresh_status()
128
self.assert_status_correct(status_bd=backend.FILE_SYNC_DISABLED,
129
status_ui=qt.FILE_SYNC_DISABLED,
130
action=qt.FILE_SYNC_ENABLE,
131
callback='enable_files')
133
def test_process_info_disconnected(self):
134
"""File sync status disconnected update the label."""
135
self.assert_status_correct(status_bd=backend.FILE_SYNC_DISCONNECTED,
136
status_ui=qt.FILE_SYNC_DISCONNECTED,
137
action=qt.FILE_SYNC_CONNECT,
138
callback='connect_files')
140
def test_process_info_error(self):
141
"""File sync status error update the label."""
142
msg = qt.WARNING_MARKUP % qt.FILE_SYNC_ERROR
143
self.assert_status_correct(status_bd=backend.FILE_SYNC_ERROR,
145
action=qt.FILE_SYNC_RESTART,
146
callback='restart_files')
148
def test_process_info_idle(self):
149
"""File sync status idle update the label."""
150
self.assert_status_correct(status_bd=backend.FILE_SYNC_IDLE,
151
status_ui=qt.FILE_SYNC_IDLE,
152
action=qt.FILE_SYNC_DISCONNECT,
153
callback='disconnect_files')
155
def test_process_info_starting(self):
156
"""File sync status starting update the label."""
157
self.assert_status_correct(status_bd=backend.FILE_SYNC_STARTING,
158
status_ui=qt.FILE_SYNC_STARTING,
159
action=qt.FILE_SYNC_STOP,
160
callback='stop_files')
162
def test_process_info_stopped(self):
163
"""File sync status stopped update the label."""
164
self.assert_status_correct(status_bd=backend.FILE_SYNC_STOPPED,
165
status_ui=qt.FILE_SYNC_STOPPED,
166
action=qt.FILE_SYNC_START,
167
callback='start_files')
169
def test_process_info_syncing(self):
170
"""File sync status syncing update the label."""
171
self.assert_status_correct(status_bd=backend.FILE_SYNC_SYNCING,
172
status_ui=qt.FILE_SYNC_SYNCING,
173
action=qt.FILE_SYNC_DISCONNECT,
174
callback='disconnect_files')
176
def test_process_info_unknown(self):
177
"""File sync status unknown update the label."""
178
msg = qt.WARNING_MARKUP % qt.FILE_SYNC_ERROR
179
self.assert_status_correct(status_bd=backend.FILE_SYNC_UNKNOWN,
181
action=qt.FILE_SYNC_RESTART,
182
callback='restart_files')
184
def test_backend(self):
185
"""Backend is created."""
186
self.assertIsInstance(self.ui.backend,
187
backend.ControlBackend)
189
def test_refresh_status_requested(self):
190
"""test refresh_status was requested on initialized."""
193
def callback(status):
194
"""Fake _process_status callback."""
195
data['called'] = True
196
data['status'] = status
198
self.patch(self.ui, "_process_status", callback)
199
self.ui.refresh_status()
200
self.assert_backend_called('file_sync_status')
201
self.assertTrue(data['called'])
202
self.assertEqual(data['status'], [])
53
204
def test_quit(self):
54
205
"""Test the quit option in the menu."""
55
206
# Not done on setup, because if I patch stop
56
207
# after instantiation, it doesn't get called.
208
self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
57
209
self.patch(systray.TrayIcon, "stop", self._set_called)
58
210
tray = systray.TrayIcon()
59
211
tray.quit.trigger()
124
271
def test_delete_no_window(self):
125
272
"""Test deleting without an existing window."""
273
self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
126
274
tray = systray.TrayIcon()
127
275
tray.delete_window()
128
276
self.assertEqual(tray.window, None)
278
def test_open_u1_folder_action(self):
279
"""Test open_u1_folder_action."""
280
self.ui.open_u1_folder.trigger()
281
self.assertEqual(FakeDesktopService.data['cls'], FakeDesktopService)
282
expected_url = QtCore.QUrl(u'file://%s' % ROOT_PATH)
283
self.assertEqual(FakeDesktopService.data['url'], expected_url)
285
def test_get_more_storage_action(self):
286
"""Test get_more_storage."""
287
self.ui.get_more_storage.trigger()
288
self.assertEqual(FakeDesktopService.data['cls'], FakeDesktopService)
289
expected_url = QtCore.QUrl(systray.GET_STORAGE_LINK)
290
self.assertEqual(FakeDesktopService.data['url'], expected_url)
292
def test_go_to_web_action(self):
293
"""Test go_to_web."""
294
self.ui.go_to_web.trigger()
295
self.assertEqual(FakeDesktopService.data['cls'], FakeDesktopService)
296
expected_url = QtCore.QUrl(systray.DASHBOARD)
297
self.assertEqual(FakeDesktopService.data['url'], expected_url)
299
def test_get_help_action(self):
300
"""Test get_help_online."""
301
self.ui.get_help_online.trigger()
302
self.assertEqual(FakeDesktopService.data['cls'], FakeDesktopService)
303
expected_url = QtCore.QUrl(systray.GET_SUPPORT_LINK)
304
self.assertEqual(FakeDesktopService.data['url'], expected_url)
130
306
def test_initialization(self):
131
307
"""Test that everything initializes correctly."""
308
self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
132
309
tray = systray.TrayIcon()
133
310
self.assertTrue(tray.isVisible())
134
311
self.assertEqual(tray.window, None)
312
self.assertNotEqual(tray.icon(), None)
313
self.assertEqual(tray.uploading, {})
314
self.assertEqual(tray.recent_transfers, {})
135
315
self.assertIsInstance(tray.context_menu, QtGui.QMenu)
136
self.assertNotEqual(tray.icon(), None)
316
self.assertIsInstance(tray.status, QtGui.QAction)
317
self.assertIsInstance(tray.status_action, QtGui.QAction)
318
self.assertIsInstance(tray.open_u1, QtGui.QAction)
319
self.assertIsInstance(tray.open_u1_folder, QtGui.QAction)
320
self.assertIsInstance(tray.go_to_web, QtGui.QAction)
321
self.assertIsInstance(tray.get_more_storage, QtGui.QAction)
322
self.assertIsInstance(tray.get_help_online, QtGui.QAction)
323
self.assertIsInstance(tray.transfers, QtGui.QMenu)
324
# This checks that _get_volumes_info and _process_volumes_info
325
# is being called correctly on initialization.
326
expected_home = u'file://%s' % ROOT_PATH
327
self.assertEqual(tray.root_path, expected_home)
329
def test_get_transfers_data(self):
330
"""Check that _get_transfers_data return the proper data."""
334
def fake_callback(data):
335
"""Fake callback to process data."""
338
self.patch(self.ui.transfers, "_update_transfers", fake_callback)
339
self.ui.transfers.get_transfers_data()
340
self.assertEqual(result, [{RECENTTRANSFERS: [], UPLOADING: []}])
343
class TransfersMenuTestCase(BaseTestCase):
345
"""Test the info to be display in the transfers menu."""
347
class_ui = systray.TrayIcon
351
# We need to patch the startTimer first, to avoid the timer
352
# to get started on initialization.
353
self.patch(systray.TrayIcon, "startTimer", lambda s, x: None)
354
self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
355
yield super(TransfersMenuTestCase, self).setUp()
356
self.patch(QtGui, "QDesktopServices", FakeDesktopService)
357
self.patch(self.ui.transfers._parent.backend, "sync_menu",
359
self.recent_transfers = []
362
def fake_sync_menu(self):
363
"""Fake backend sync_menu."""
364
return {RECENTTRANSFERS: self.recent_transfers,
365
UPLOADING: self.uploading}
367
def test_load_menu(self):
368
"""Show the menu with just the labels."""
369
self.ui.transfers.get_transfers_data()
370
actions = self.ui.transfers.actions()
371
self.assertEqual(actions[0].text(), RECENT_TRANSFERS)
372
self.assertTrue(actions[1].isSeparator())
373
self.assertEqual(actions[2].text(), IN_PROGRESS)
375
def test_load_recent_transfers(self):
376
"""Show the menu with the recent transfers."""
377
self.recent_transfers = ['file1', 'file2']
378
self.ui.transfers.get_transfers_data()
379
actions = self.ui.transfers.actions()
380
self.assertEqual(actions[0].text(), RECENT_TRANSFERS)
381
self.assertEqual(actions[1].text(), 'file1')
382
self.assertEqual(actions[2].text(), 'file2')
383
self.assertTrue(actions[3].isSeparator())
384
self.assertEqual(actions[4].text(), IN_PROGRESS)
386
def test_load_in_progress(self):
387
"""Show the menu with the current progress."""
394
# Return copy of in_progress
395
self.uploading = in_progress[:]
396
self.ui.transfers.get_transfers_data()
397
actions = self.ui.transfers.actions()
398
self.assertEqual(actions[0].text(), RECENT_TRANSFERS)
399
self.assertTrue(actions[1].isSeparator())
400
self.assertEqual(actions[2].text(), IN_PROGRESS)
402
# This also check that the files are ordered based on written
403
percentage = in_progress[2][2] * 100 / in_progress[2][1]
404
text = IN_PROGRESS_FILE % (in_progress[2][0], percentage)
405
self.assertEqual(actions[3].label.text(), text)
406
self.assertEqual(actions[3].progress.value(), percentage)
408
percentage = in_progress[0][2] * 100 / in_progress[0][1]
409
text = IN_PROGRESS_FILE % (in_progress[0][0], percentage)
410
self.assertEqual(actions[4].label.text(), text)
411
self.assertEqual(actions[4].progress.value(), percentage)
413
percentage = in_progress[1][2] * 100 / in_progress[1][1]
414
text = IN_PROGRESS_FILE % (in_progress[1][0], percentage)
415
self.assertEqual(actions[5].label.text(), text)
416
self.assertEqual(actions[5].progress.value(), percentage)
418
def test_load_in_progress_refresh(self):
419
"""Show the menu with the current progress and refresh it."""
425
# Return copy of in_progress
426
self.uploading = in_progress[:]
427
self.ui.transfers.get_transfers_data()
428
actions = self.ui.transfers.actions()
429
self.assertEqual(actions[0].text(), RECENT_TRANSFERS)
430
self.assertTrue(actions[1].isSeparator())
431
self.assertEqual(actions[2].text(), IN_PROGRESS)
433
# This also check that the files are ordered based on written
434
previous_actions = []
435
percentage = in_progress[2][2] * 100 / in_progress[2][1]
436
text = IN_PROGRESS_FILE % (in_progress[2][0], percentage)
437
self.assertEqual(actions[3].text(), text)
438
previous_actions.append(actions[3])
440
percentage = in_progress[0][2] * 100 / in_progress[0][1]
441
text = IN_PROGRESS_FILE % (in_progress[0][0], percentage)
442
self.assertEqual(actions[4].text(), text)
443
previous_actions.append(actions[4])
445
percentage = in_progress[1][2] * 100 / in_progress[1][1]
446
text = IN_PROGRESS_FILE % (in_progress[1][0], percentage)
447
self.assertEqual(actions[5].text(), text)
448
previous_actions.append(actions[5])
455
self.uploading = in_progress[:]
457
self.ui.transfers.get_transfers_data()
458
actions = self.ui.transfers.actions()
460
self.assertEqual(actions[0].text(), RECENT_TRANSFERS)
461
self.assertTrue(actions[1].isSeparator())
462
self.assertEqual(actions[2].text(), IN_PROGRESS)
464
# This also check that the files are ordered based on written
465
percentage = in_progress[2][2] * 100 / in_progress[2][1]
466
text = IN_PROGRESS_FILE % (in_progress[2][0], percentage)
467
self.assertEqual(actions[3].text(), text)
468
current_actions.append(actions[3])
470
percentage = in_progress[0][2] * 100 / in_progress[0][1]
471
text = IN_PROGRESS_FILE % (in_progress[0][0], percentage)
472
self.assertEqual(actions[4].text(), text)
473
current_actions.append(actions[4])
475
percentage = in_progress[1][2] * 100 / in_progress[1][1]
476
text = IN_PROGRESS_FILE % (in_progress[1][0], percentage)
477
self.assertEqual(actions[5].text(), text)
478
current_actions.append(actions[5])
480
self.assertEqual(previous_actions, current_actions)
482
def test_menu_not_reload(self):
483
"""Show the menu and test that is not reload it on refresh."""
484
self.recent_transfers = ['file1', 'file2']
485
self.ui.transfers.get_transfers_data()
486
previous_actions = self.ui.transfers.actions()
487
self.ui.transfers.get_transfers_data()
488
current_actions = self.ui.transfers.actions()
489
self.assertEqual(previous_actions, current_actions)
491
def test_menu_reload(self):
492
"""Show the menu and test that is reload it on refresh."""
493
self.recent_transfers = ['file1', 'file2']
494
self.ui.transfers.get_transfers_data()
495
previous_actions = self.ui.transfers.actions()
496
self.recent_transfers = ['file1', 'file2', 'file3']
498
self.ui.transfers.get_transfers_data()
499
current_actions = self.ui.transfers.actions()
500
self.assertNotEqual(previous_actions, current_actions)
502
def test_progress_not_reload(self):
503
"""Show the menu and test that is not reload it on refresh."""
509
# Return copy of in_progress
510
self.uploading = in_progress[:]
511
self.ui.transfers.get_transfers_data()
512
previous_actions = self.ui.transfers.actions()
518
self.uploading = in_progress[:]
519
self.ui.transfers.get_transfers_data()
520
current_actions = self.ui.transfers.actions()
522
self.assertEqual(previous_actions, current_actions)
524
def test_progress_reload(self):
525
"""Show the menu and test that is reload it on refresh."""
531
# Return copy of in_progress
532
self.uploading = in_progress[:]
533
self.ui.transfers.get_transfers_data()
534
previous_actions = self.ui.transfers.actions()
539
('file4', 1000, 410),
541
self.uploading = in_progress[:]
542
self.ui.transfers.get_transfers_data()
543
current_actions = self.ui.transfers.actions()
545
self.assertNotEqual(previous_actions, current_actions)
548
class SharesTestCase(BaseTestCase):
550
"""Test the info to be displayed in the shares section."""
552
class_ui = systray.TrayIcon
556
# We need to patch the startTimer first, to avoid the timer
557
# to get started on initialization.
558
self.patch(systray.TrayIcon, "startTimer", lambda s, x: None)
559
self.patch(systray.TransfersMenu, "startTimer", lambda s, x: None)
560
yield super(SharesTestCase, self).setUp()
561
self.patch(QtGui, "QDesktopServices", FakeDesktopService)
562
self.patch(self.ui.backend, "get_shares", self.fake_get_backend)
563
self._shares_info = []
565
def fake_get_backend(self):
566
"""Fake get_backend."""
567
return self._shares_info
569
def test_shares_refresh_not_reload(self):
570
"""Check that we get the new info of shares but not reload the menu."""
571
actions = self.ui.context_menu.actions()
573
post_actions = self.ui.context_menu.actions()
574
self.assertEqual(actions, post_actions)
576
def test_shares_refresh_reload(self):
577
"""Check that we get the new info of shares but not reload the menu."""
578
actions = self.ui.context_menu.actions()
579
self._shares_info = [
580
{'accepted': False, 'other_visible_name': 'name',
581
'volume_id': 'asd123-asd123-asd123-asd123'}
584
post_actions = self.ui.context_menu.actions()
585
self.assertNotEqual(actions, post_actions)
587
def test_share_triggered(self):
588
"""Check that we get the new info of shares but not reload the menu."""
589
volume_id = 'asd123-asd123-asd123-asd123'
590
self._shares_info = [
591
{'accepted': False, 'other_visible_name': 'name',
592
'volume_id': volume_id}
595
actions = self.ui.context_menu.actions()
596
share_action = actions[7]
597
share_action.trigger()
598
expected = QtCore.QUrl(systray.ACCEPT_SHARES % volume_id)
599
self.assertEqual(FakeDesktopService.data['url'], expected)