~ubuntu-branches/ubuntu/oneiric/ubuntuone-control-panel/oneiric

« back to all changes in this revision

Viewing changes to ubuntuone/controlpanel/gui/qt/tests/test_common.py

* New upstream release:
  [ Alejandro J. Cura <alecu@canonical.com>]
    - Do not throw a webclient error when closing
      (LP: #845105).
  [ Natalia B. Bidart <natalia.bidart@canonical.com> ]
    - Removed all code related to Bookmarks (LP: #850142).
    - Replaces references to "Evolution" by "Thunderbird" (LP: #849494).
  [ Rodney Dawes <rodney.dawes@canonical.com> ]
    - Don't install a .desktop file for control panel
      (part of LP: #838778).
    - Point the indicator/Unity API at the installer .desktop file
      (part of LP: #838778).
    - Set the WMCLASS so Unity will fall back properly
      (part of LP: #838778).
    - Fix a few grammar mistakes (LP: #835093).
    - Don't show the "Get NGB free!" label on "Join now" button at all
      (LP: #819955).
* debian/control:
  - ubuntuone-control-panel-gtk depends now on ubuntuone-installer >= 2.0.0.
  - require ubuntuone-client >= 2.0.0.
  - require ubuntu-sso-client >= 1.4.0.
  - no longer install a .desktop file (will be installed by ubuntuone-installer).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
 
 
3
# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
 
4
#
 
5
# Copyright 2011 Canonical Ltd.
 
6
#
 
7
# This program is free software: you can redistribute it and/or modify it
 
8
# under the terms of the GNU General Public License version 3, as published
 
9
# by the Free Software Foundation.
 
10
#
 
11
# This program is distributed in the hope that it will be useful, but
 
12
# WITHOUT ANY WARRANTY; without even the implied warranties of
 
13
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
14
# PURPOSE.  See the GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License along
 
17
# with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
 
 
19
"""Tests for the uri_hook helper."""
 
20
 
 
21
import logging
 
22
 
 
23
from PyQt4 import QtGui, QtCore
 
24
from twisted.internet import defer
 
25
 
 
26
from ubuntuone.controlpanel.logger import setup_logging
 
27
from ubuntuone.controlpanel.gui.qt import uri_hook, handle_errors
 
28
from ubuntuone.controlpanel.gui.qt.tests import (
 
29
    BaseTestCase,
 
30
    FakedDialog,
 
31
)
 
32
 
 
33
 
 
34
class UriHookTestCase(BaseTestCase):
 
35
    """The test suite for the uri_hook."""
 
36
 
 
37
    @defer.inlineCallbacks
 
38
    def setUp(self):
 
39
        yield super(UriHookTestCase, self).setUp()
 
40
        self.patch(QtGui.QDesktopServices, 'openUrl', self._set_called)
 
41
 
 
42
    def test_opens_url(self):
 
43
        """The url is opened properly."""
 
44
        expected = 'foo bar'
 
45
        uri_hook(expected)
 
46
        self.assertEqual(self._called, ((QtCore.QUrl(expected),), {}))
 
47
 
 
48
    def test_opens_url_encoded(self):
 
49
        """The encoded url is opened properly."""
 
50
        expected = 'http://foo.bar/?next=https://one.ubuntu.com/'
 
51
        uri_hook(expected)
 
52
        self.assertEqual(self._called, ((QtCore.QUrl(expected),), {}))
 
53
 
 
54
 
 
55
class HandleErrorTestCase(BaseTestCase):
 
56
    """Test suite for the generic error handler."""
 
57
 
 
58
    error_handler = None
 
59
    use_logger = False
 
60
    logger = logging.getLogger()  # root logger
 
61
 
 
62
    @defer.inlineCallbacks
 
63
    def setUp(self):
 
64
        yield super(HandleErrorTestCase, self).setUp()
 
65
        self.called = None
 
66
        self.result = None
 
67
        self.failure = None
 
68
        self.error_handler_called = None
 
69
 
 
70
        if self.use_logger:
 
71
            logger = self.logger
 
72
        else:
 
73
            logger = None
 
74
 
 
75
        self.decorate_me = handle_errors(error_handler=self.error_handler,
 
76
                                         logger=logger)(self._decorate_me)
 
77
 
 
78
    @defer.inlineCallbacks
 
79
    def _decorate_me(self, *args, **kwargs):
 
80
        """Helper to test thye decorator."""
 
81
        if self.failure:
 
82
            # Raising only classes, instances or string are allowed
 
83
            # pylint: disable=E0702
 
84
            raise self.failure
 
85
 
 
86
        yield
 
87
        self.called = (args, kwargs)
 
88
        defer.returnValue(self.result)
 
89
 
 
90
    @defer.inlineCallbacks
 
91
    def test_is_decorator(self):
 
92
        """Is a decorator."""
 
93
        yield self.decorate_me()
 
94
 
 
95
    @defer.inlineCallbacks
 
96
    def test_params_are_passed(self):
 
97
        """Named and unnamed arguments are passed."""
 
98
        args = ({}, object(), 'foo')
 
99
        kwargs = {'1': 1, 'test': None, '0': ['a']}
 
100
        yield self.decorate_me(*args, **kwargs)
 
101
 
 
102
        self.assertTrue(self.called, (args, kwargs))
 
103
 
 
104
    @defer.inlineCallbacks
 
105
    def test_result_is_returned(self):
 
106
        """Result is returned."""
 
107
        self.result = object()
 
108
        result = yield self.decorate_me()
 
109
 
 
110
        self.assertEqual(self.result, result)
 
111
 
 
112
    def test_name_is_preserved(self):
 
113
        """The method name is not masqueraded."""
 
114
        self.assertEqual(self.decorate_me.__name__, self._decorate_me.__name__)
 
115
 
 
116
    @defer.inlineCallbacks
 
117
    def test_exeptions_are_handled(self):
 
118
        """Any exception is handled and logged in the root logger."""
 
119
        msg = 'This is me failing badly.'
 
120
        self.failure = Exception(msg)
 
121
 
 
122
        yield self.decorate_me()
 
123
 
 
124
        logged = self.memento.check_exception(self.failure.__class__, msg)
 
125
        recs = '\n'.join(rec.exc_text for rec in self.memento.records)
 
126
        self.assertTrue(logged, 'Exception must be logged, got:\n%s' % recs)
 
127
 
 
128
    @defer.inlineCallbacks
 
129
    def test_show_error_message(self):
 
130
        """On error, show an error message."""
 
131
        self.failure = Exception()
 
132
 
 
133
        yield self.decorate_me()
 
134
 
 
135
        msg = self.failure.__class__.__name__
 
136
        self.assertEqual(FakedDialog.args,
 
137
                         (None, '', msg, QtGui.QMessageBox.Close))
 
138
        self.assertEqual(FakedDialog.kwargs, {})
 
139
 
 
140
    @defer.inlineCallbacks
 
141
    def test_show_error_message_if_args(self):
 
142
        """On error, show an error message."""
 
143
        msg1 = 'This is me failing badly.'
 
144
        msg2 = 'More details about what went wrong.'
 
145
        obj = object()
 
146
        self.failure = Exception(msg1, msg2, obj)
 
147
 
 
148
        yield self.decorate_me()
 
149
 
 
150
        msg = '\n'.join(map(repr, (msg1, msg2, obj)))
 
151
        msg = self.failure.__class__.__name__ + '\n' + msg
 
152
        self.assertEqual(FakedDialog.args,
 
153
                         (None, '', msg, QtGui.QMessageBox.Close))
 
154
        self.assertEqual(FakedDialog.kwargs, {})
 
155
 
 
156
    @defer.inlineCallbacks
 
157
    def test_show_error_message_if_mapping(self):
 
158
        """On error, show an error message."""
 
159
        msg1 = 'This is me failing badly.'
 
160
        msg2 = 'More details about what went wrong.'
 
161
        errdict = {'foo': msg1, 'bar': msg2}
 
162
        self.failure = Exception(errdict)
 
163
 
 
164
        yield self.decorate_me()
 
165
 
 
166
        msg = '\n'.join((msg1, msg2))
 
167
        self.assertEqual(FakedDialog.args,
 
168
                         (None, '', msg, QtGui.QMessageBox.Close))
 
169
        self.assertEqual(FakedDialog.kwargs, {})
 
170
 
 
171
    @defer.inlineCallbacks
 
172
    def test_no_error_message_if_no_exception(self):
 
173
        """On success, do not show an error message."""
 
174
        yield self.decorate_me()
 
175
 
 
176
        self.assertEqual(FakedDialog.args, None)
 
177
        self.assertEqual(FakedDialog.kwargs, None)
 
178
 
 
179
    @defer.inlineCallbacks
 
180
    def test_call_error_handler(self):
 
181
        """On success, do not execute error_handler."""
 
182
        yield self.decorate_me()
 
183
        self.assertFalse(self.error_handler_called)
 
184
 
 
185
 
 
186
class HandleErrorWithCustomLoggerTestCase(HandleErrorTestCase):
 
187
    """Test suite for the generic error handler."""
 
188
 
 
189
    use_logger = True
 
190
    logger = setup_logging('HandleErrorWithoutLoggerTestCase')  # custom logger
 
191
 
 
192
 
 
193
class HandleErrorWithHandlerTestCase(HandleErrorTestCase):
 
194
    """Test suite for the generic error handler when using a custom handler."""
 
195
 
 
196
    @defer.inlineCallbacks
 
197
    def error_handler(self, *a, **kw):
 
198
        """Implement an error handler."""
 
199
        self.error_handler_called = (a, kw)
 
200
        yield
 
201
 
 
202
    @defer.inlineCallbacks
 
203
    def test_call_error_handler(self):
 
204
        """On error, execute error_handler."""
 
205
        msg = 'This is me failing badly.'
 
206
        self.failure = Exception(msg)
 
207
 
 
208
        yield self.decorate_me()
 
209
 
 
210
        self.assertEqual(self.error_handler_called, ((), {}))