174
120
return self.properties['visible']
177
class FakeOverlay(object):
179
"""A fake delay overlay."""
181
def __init__(self, *args, **kwargs):
183
self.show_counter = 0
184
self.hide_counter = 0
185
self.args = (args, kwargs)
189
self.show_counter += 1
193
self.hide_counter += 1
195
def resize(self, *args):
199
class FakeSignal(object):
201
"""A fake PyQt signal."""
203
def __init__(self, *args, **kwargs):
207
def connect(self, target):
211
def disconnect(self, *args):
212
"""Fake disconnect."""
215
def emit(self, *args):
221
class FakeOverlaySignal(FakeSignal):
223
"""Fake Signal for show and hide overlay."""
225
def __init__(self, target):
226
super(FakeOverlaySignal, self).__init__()
229
def connect(self, target):
230
"""We ignore the target and just call the function from the init."""
233
class FakeWizardPage(object):
235
"""A fake wizard page."""
237
def __init__(self, *args, **kwargs):
238
self.has_back_button = True
240
# pylint: disable=C0103
241
def initializePage(self):
242
"""Fake initializePage."""
245
class FakeMainWindow(object):
247
"""A fake MainWindow."""
249
currentIdChanged = FakeSignal()
250
loginSuccess = FakeSignal()
251
registrationIncomplete = FakeSignal()
252
registrationSuccess = FakeSignal()
253
userCancellation = FakeSignal()
255
SYNC_NOW_OR_LATER_PAGE = 4
256
CONGRATULATIONS_PAGE = 5
258
local_folders_page_id = 7
260
def __init__(self, close_callback=None):
261
self.button_texts = []
262
self.button_layout = None
264
self.overlay = FakeOverlay()
265
self.local_folders_page = FakeWizardPage()
266
self.folders_page = FakeWizardPage()
267
self.app_name = APP_NAME
273
# pylint: disable=C0103
274
def setButtonText(self, button, text):
275
"""Fake setButtonText."""
276
self.button_texts.append((button, text))
278
def setButtonLayout(self, layout):
279
"""Fake setButtonText."""
280
self.button_layout = layout
282
def button(self, button):
283
"""Fake button method to obtain the wizard buttons."""
284
return QtGui.QPushButton()
286
def setOption(self, *args):
287
"""Fake setOption."""
288
self.options.append(args)
297
class FakeController(object):
299
"""A fake controller for the tests."""
302
set_next_validation = lambda *a, **kw: None
304
def __init__(self, *args, **kwargs):
305
self.args = (args, kwargs)
307
# pylint: disable=C0103
308
def setupUi(self, view):
309
"""Fake the setup."""
310
# pylint: enable=C0103
313
class FakeWizard(object):
315
"""Replace wizard() function on wizard pages."""
317
customButtonClicked = QtCore.QObject()
321
email_verification_id = 4
325
reset_password_id = 8
328
self.overlay = FakeOverlay()
331
self.buttons_text = {}
333
self.sign_in_page = object()
334
self.setup_account = object()
335
self.current_user = object()
336
self.email_verification = object()
337
self.success = object()
338
self.error = object()
339
self.forgotten = object()
340
self.reset_password = object()
342
self.sign_in_page: self.sign_in_page_id,
343
self.setup_account: self.setup_account_id,
344
self.current_user: self.current_user_id,
345
self.email_verification: self.email_verification_id,
346
self.success: self.success_id,
347
self.error: self.error_id,
348
self.forgotten: self.forgotten_id,
349
self.reset_password: self.reset_password_id,
352
# Invalid name "setButtonLayout", "setOption"
353
# pylint: disable=C0103
355
def setButtonText(self, key, value):
356
"""Fake setButtonText."""
357
self.buttons_text[key] = value
359
def setButtonLayout(self, *args, **kwargs):
360
"""Fake the functionality of setButtonLayout on QWizard class."""
361
self.called.append(('setButtonLayout', (args, kwargs)))
363
def setOption(self, *args, **kwargs):
364
"""Fake the functionality of setOption on QWizard class."""
365
self.called.append(('setOption', (args, kwargs)))
367
# pylint: enable=C0103
369
def button(self, button_id):
370
"""Fake the functionality of button on QWizard class."""
371
return self.buttons.setdefault(button_id, QtGui.QPushButton())
375
self.called.append('next')
377
def page(self, p_id):
378
"""Fake page method."""
381
def set_titles(self, title):
382
"""Fake set_titles."""
383
self.called.append(('set_titles', title))
386
class FakeWizardButtonStyle(FakeWizard):
388
"""Fake Wizard with button style implementation."""
392
# pylint: disable=C0103
394
super(FakeWizardButtonStyle, self).__init__()
396
self.customButtonClicked = self
398
def setDefault(self, value):
399
"""Fake setDefault for button."""
400
self.data['default'] = value
403
"""Fake isDefault."""
404
return self.data['default']
405
# pylint: enable=C0103
407
def connect(self, func):
408
"""Fake customButtonClicked connect."""
409
self.data['connect'] = func
411
def disconnect(self, func):
412
"""Fake customButtonClicked disconnect."""
413
self.data['disconnect'] = func
415
def button(self, button_id):
416
"""Fake the functionality of button on QWizard class."""
420
"""Fake button style."""
424
"""Fake next for wizard."""
425
self.data['next'] = True
428
123
class BaseTestCase(TestCase):
429
124
"""The base test case."""
434
ui_backend_signals = ()
435
ui_wizard_class = FakeWizard
437
126
@defer.inlineCallbacks
439
128
yield super(BaseTestCase, self).setUp()
440
129
self._called = False
441
backend = FakedBackend()
442
self.sso_login_backend = backend.sso_login
443
self.patch(main, 'get_sso_client',
444
lambda *a: defer.succeed(backend))
446
self.app_name = APP_NAME
447
self.ping_url = PING_URL
448
self.signal_results = []
450
# self.ui_class is not callable
451
# pylint: disable=E1102, C0103, W0212
454
if self.ui_class is not None:
455
kwargs = dict(KWARGS) if self.kwargs is None else self.kwargs
456
self.ui = self.ui_class(**kwargs)
458
for signal in self.ui_signals:
459
self.patch(self.ui_class, signal, FakeSignal())
461
if self.ui_wizard_class is not None:
462
self.wizard = self.ui_wizard_class()
463
self.patch(self.ui, 'wizard', lambda: self.wizard)
466
self.addCleanup(self.ui.hide)
130
self.sso_login_backend = FakedBackend()
131
self.patch(main, 'get_sso_login_backend',
132
lambda *a: defer.succeed(self.sso_login_backend))
468
134
def _set_called(self, *args, **kwargs):
469
135
"""Store 'args' and 'kwargs' for test assertions."""
470
136
self._called = (args, kwargs)
472
def assert_backend_called(self, method, *args, **kwargs):
473
"""Check that 'method(*args, **kwargs)' was called in the backend."""
474
self.assertIn(method, self.ui.backend._called)
476
call = self.ui.backend._called[method]
477
self.assertEqual(call[0], args)
479
reply_handler = call[1].pop('reply_handler')
480
self.assertEqual(reply_handler, NO_OP)
482
error_handler = call[1].pop('error_handler')
483
self.assertEqual(error_handler.func, self.ui._handle_error)
485
self.assertEqual(call[1], kwargs)
487
def assert_signal_emitted(self, signal, signal_args,
488
trigger, *args, **kwargs):
489
"""Check that 'trigger(*signal_args)' emits 'signal(*signal_args)'."""
490
signal.connect(lambda *a: self.signal_results.append(a))
492
trigger(*args, **kwargs)
494
self.assertEqual(self.signal_results, [signal_args])
496
def assert_title_correct(self, title_label, expected, max_width):
497
"""Check that the label's text is equal to 'expected'."""
498
label = QtGui.QLabel()
499
maybe_elide_text(label, expected, max_width)
501
self.assertEqual(TITLE_STYLE % unicode(label.text()),
502
unicode(title_label.text()))
503
self.assertEqual(unicode(label.toolTip()),
504
unicode(title_label.toolTip()))
505
self.assertTrue(title_label.isVisible())
507
def assert_subtitle_correct(self, subtitle_label, expected, max_width):
508
"""Check that the subtitle is equal to 'expected'."""
509
label = QtGui.QLabel()
510
maybe_elide_text(label, expected, max_width)
512
self.assertEqual(unicode(label.text()), unicode(subtitle_label.text()))
513
self.assertEqual(unicode(label.toolTip()),
514
unicode(subtitle_label.toolTip()))
515
self.assertTrue(subtitle_label.isVisible())
517
def assert_error_correct(self, error_label, expected, max_width):
518
"""Check that the error 'error_label' displays 'expected' as text."""
519
label = QtGui.QLabel()
520
maybe_elide_text(label, expected, max_width)
522
self.assertEqual(ERROR_STYLE % unicode(label.text()),
523
unicode(error_label.text()))
524
self.assertEqual(unicode(label.toolTip()),
525
unicode(error_label.toolTip()))
526
self.assertTrue(error_label.isVisible())
528
def get_pixmap_data(self, pixmap):
529
"""Get the raw data of a QPixmap."""
530
byte_array = QtCore.QByteArray()
531
array_buffer = QtCore.QBuffer(byte_array)
532
pixmap.save(array_buffer, "PNG")
535
# Invalid name "assertEqualPixmap"
536
# pylint: disable=C0103
538
def assertEqualPixmaps(self, pixmap1, pixmap2):
539
"""Compare two Qt pixmaps."""
540
d1 = self.get_pixmap_data(pixmap1)
541
d2 = self.get_pixmap_data(pixmap2)
542
self.assertEqual(d1, d2)
544
# pylint: enable=C0103
546
@defer.inlineCallbacks
547
def test_setup_page(self):
548
"""Test the backend signal connection."""
549
if self.ui is None or getattr(self.ui, 'setup_page', None) is None:
553
self.patch(self.ui, '_setup_signals',
554
lambda *a: called.append('_setup_signals'))
555
self.patch(self.ui, '_connect_ui',
556
lambda *a: called.append('_connect_ui'))
557
self.patch(self.ui, '_set_translated_strings',
558
lambda *a: called.append('_set_translated_strings'))
560
yield self.ui.setup_page()
562
self.assertEqual(self.ui.backend, self.sso_login_backend)
564
for signal in self.ui_backend_signals:
565
self.assertIn(signal, self.ui._signals)
566
self.assertTrue(callable(self.ui._signals[signal]))
568
expected = ['_set_translated_strings', '_connect_ui', '_setup_signals']
569
self.assertEqual(expected, called)
572
class PageBaseTestCase(BaseTestCase):
574
"""BaseTestCase with some specialization for the Wizard Pages."""
576
@defer.inlineCallbacks
578
yield super(PageBaseTestCase, self).setUp()
579
self._overlay_show_counter = 0
580
self._overlay_hide_counter = 0
582
if self.ui is not None:
583
fake_show_overlay_signal = FakeOverlaySignal(
584
self._show_overlay_slot)
585
fake_hide_overlay_signal = FakeOverlaySignal(
586
self._hide_overlay_slot)
587
self.patch(self.ui, "processingStarted", fake_show_overlay_signal)
588
self.patch(self.ui, "processingFinished", fake_hide_overlay_signal)
590
def _show_overlay_slot(self):
591
"""Fake show overlay slot."""
592
self._overlay_show_counter += 1
594
def _hide_overlay_slot(self):
595
"""Fake hide overlay slot."""
596
self._overlay_hide_counter += 1
598
def assert_signal_emitted(self, signal, signal_args,
599
trigger, *args, **kwargs):
600
"""Check that 'trigger(*args, **kwargs)' emits 'signal(*signal_args)'.
602
Also check that the _overlay_hide_counter was increased by one, and
603
that the ui is enabled.
606
super(PageBaseTestCase, self).assert_signal_emitted(signal,
607
signal_args, trigger, *args, **kwargs)
608
self.assertEqual(self._overlay_hide_counter, 1)
609
self.assertTrue(self.ui.isEnabled())
611
# pylint: disable=W0221
613
def assert_title_correct(self, expected):
614
"""Check that the title is equal to 'expected'."""
615
check = super(PageBaseTestCase, self).assert_title_correct
616
check(self.ui.header.title_label, expected,
617
self.ui.header.max_title_width)
619
def assert_subtitle_correct(self, expected):
620
"""Check that the subtitle is equal to 'expected'."""
621
check = super(PageBaseTestCase, self).assert_subtitle_correct
622
check(self.ui.header.subtitle_label, expected,
623
self.ui.header.max_subtitle_width)
625
# pylint: enable=W0221