~mvo/ubuntu-sso-client/strawman-lp711413

« back to all changes in this revision

Viewing changes to ubuntu_sso/tests/test_credentials.py

- Made the service use the Qt UI if available, and if no UI is installed, propagate a decent error instead of AssertionError (LP: #994632).

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 
38
38
import ubuntu_sso.main
39
39
 
40
 
from ubuntu_sso import credentials, utils
 
40
from ubuntu_sso import credentials
41
41
from ubuntu_sso.credentials import (
42
42
    APP_NAME_KEY,
43
43
    HELP_TEXT_KEY,
111
111
class BasicTestCase(TestCase):
112
112
    """Test case with a helper tracker."""
113
113
 
 
114
    bin_dir = 'some/bin/dir'
 
115
 
114
116
    @defer.inlineCallbacks
115
117
    def setUp(self):
116
118
        """Init."""
121
123
        self.memento.setLevel(logging.DEBUG)
122
124
        credentials.logger.addHandler(self.memento)
123
125
 
 
126
        self.patch(credentials, 'get_bin_dir', lambda: self.bin_dir)
 
127
 
124
128
    def _set_called(self, *args, **kwargs):
125
129
        """Set _called to True."""
126
130
        self._called = (args, kwargs)
285
289
        yield super(RegisterTestCase, self).setUp()
286
290
        self.deferred = defer.Deferred()
287
291
        self.patch_inner(self.fake_inner)
288
 
        self.exe_path = os.path.join(utils.get_bin_dir(),
289
 
                                     KWARGS[UI_EXECUTABLE_KEY])
 
292
        self.exe_path = os.path.join(self.bin_dir, KWARGS[UI_EXECUTABLE_KEY])
290
293
        self.inner_args = [
291
294
            self.exe_path,
292
295
            '--app_name', APP_NAME,
347
350
                   lambda kr, app: defer.succeed(None))
348
351
        self._next_inner_result = credentials.USER_SUCCESS
349
352
 
350
 
        # patch os.path.exists so it also returns True when queried for the
351
 
        # faked exe_path
352
 
        really_exists = os.path.exists
 
353
        # patch os.path.exists so it returns True for the faked exe_path
353
354
        self.patch(credentials.os.path, 'exists',
354
 
                   lambda path: path == self.exe_path or really_exists(path))
 
355
                   lambda path: path == self.exe_path)
355
356
 
356
357
        result = yield self.method_call(**self.kwargs)
357
358
        self.assertEqual(result, TOKEN)
368
369
        self._next_inner_result = credentials.USER_SUCCESS
369
370
 
370
371
        assert not os.path.exists(self.exe_path)
 
372
        self.patch(credentials.os.path, 'exists',
 
373
                   lambda path: path.endswith(credentials.UI_EXECUTABLE_GTK))
371
374
 
372
375
        result = yield self.method_call(**self.kwargs)
373
376
        self.assertEqual(result, TOKEN)
374
377
 
375
378
        # the ui was opened and proper params were passed
376
379
        args = yield self.deferred
377
 
        self.inner_args[0] = os.path.join(utils.get_bin_dir(),
 
380
        self.inner_args[0] = os.path.join(self.bin_dir,
378
381
                                          credentials.UI_EXECUTABLE_GTK)
379
382
        self.assertEqual(self.inner_args, args)
380
383
 
381
384
    @defer.inlineCallbacks
 
385
    def test_ui_executable_uses_qt_ui_if_gtk_not_available(self):
 
386
        """The executable loads the QT UI if the GTK+ does not exist."""
 
387
        self.patch(credentials.Keyring, 'get_credentials',
 
388
                   lambda kr, app: defer.succeed(None))
 
389
        self._next_inner_result = credentials.USER_SUCCESS
 
390
 
 
391
        self.patch(credentials.os.path, 'exists',
 
392
                   lambda path: path.endswith(credentials.UI_EXECUTABLE_QT))
 
393
 
 
394
        result = yield self.method_call(**self.kwargs)
 
395
        self.assertEqual(result, TOKEN)
 
396
 
 
397
        # the ui was opened and proper params were passed
 
398
        args = yield self.deferred
 
399
        self.inner_args[0] = os.path.join(self.bin_dir,
 
400
                                          credentials.UI_EXECUTABLE_QT)
 
401
        self.assertEqual(self.inner_args, args)
 
402
 
 
403
    @defer.inlineCallbacks
 
404
    def test_raises_exception_if_no_ui_available(self):
 
405
        """If no GUI is available, raise GUINotAvailableError."""
 
406
        self.patch(credentials.Keyring, 'get_credentials',
 
407
                   lambda kr, app: defer.succeed(None))
 
408
        self.patch(credentials.os.path, 'exists', lambda path: False)
 
409
 
 
410
        f = self.method_call(**self.kwargs)
 
411
        yield self.assertFailure(f, credentials.GUINotAvailableError)
 
412
 
 
413
    @defer.inlineCallbacks
382
414
    def test_without_existent_token_and_return_code_cancel(self, exc=None):
383
415
        """The operation returns exc if defined, else UserCancellationError."""
384
416
        self.patch(credentials.Keyring, 'get_credentials',
385
417
                   lambda kr, app: defer.succeed(None))
386
418
        self._next_inner_result = credentials.USER_CANCELLATION
387
419
 
 
420
        self.patch(credentials.os.path, 'exists',
 
421
                   lambda path: path == self.exe_path)
 
422
 
388
423
        if exc is None:
389
424
            exc = credentials.UserCancellationError
390
425
        yield self.assertFailure(self.method_call(**self.kwargs), exc)
391
426
 
392
427
    @defer.inlineCallbacks
393
 
    def test_without_existent_token_and_return_other(self, result=None):
 
428
    def test_without_existent_token_and_return_other_code(self, result=None):
394
429
        """The operation returns CredentialsError with 'result'."""
395
430
        self.patch(credentials.Keyring, 'get_credentials',
396
431
                   lambda kr, app: defer.succeed(None))
397
432
        self._next_inner_result = credentials.USER_CANCELLATION * 2  # other
398
433
 
 
434
        self.patch(credentials.os.path, 'exists',
 
435
                   lambda path: path == self.exe_path)
 
436
 
399
437
        exc = yield self.assertFailure(self.method_call(**self.kwargs),
400
438
                                       credentials.CredentialsError)
401
439
        if result is None:
422
460
                   lambda kr, app: defer.succeed(None))
423
461
        self.patch_inner(self.fail_inner)
424
462
 
 
463
        self.patch(credentials.os.path, 'exists',
 
464
                   lambda path: path == self.exe_path)
 
465
 
425
466
        yield self.assertFailure(self.method_call(**self.kwargs),
426
467
                                 SampleMiscException)
427
468
 
478
519
    def test_ui_executable_falls_back_to_gtk(self):
479
520
        """This check does not apply for this test case."""
480
521
 
 
522
    def test_ui_executable_uses_qt_ui_if_gtk_not_available(self):
 
523
        """This check does not apply for this test case."""
 
524
 
 
525
    def test_raises_exception_if_no_ui_available(self):
 
526
        """This check does not apply for this test case."""
 
527
 
481
528
    def test_without_existent_token_and_return_code_cancel(self, exc=None):
482
529
        """The operation returns UserNotValidatedError."""
483
530
        exc = credentials.UserNotValidatedError
484
531
        return super(LoginEmailPasswordTestCase, self).\
485
532
               test_without_existent_token_and_return_code_cancel(exc=exc)
486
533
 
487
 
    def test_without_existent_token_and_return_other(self, result=None):
 
534
    def test_without_existent_token_and_return_other_code(self, result=None):
488
535
        """The operation returns CredentialsError with 'result'."""
489
536
        result = 'foo'
490
537
        return super(LoginEmailPasswordTestCase, self).\
491
 
               test_without_existent_token_and_return_other(result=result)
 
538
               test_without_existent_token_and_return_other_code(result=result)