~dobey/ubuntu/oneiric/ubuntuone-control-panel/release-113

« back to all changes in this revision

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

  • Committer: Sebastien Bacher
  • Date: 2011-07-25 13:17:38 UTC
  • mfrom: (25.1.2 ubuntuone-control-panel)
  • Revision ID: seb128@ubuntu.com-20110725131738-yuevatnd859d1phs
Tags: 1.1.1-0ubuntu1
releasing version 1.1.1-0ubuntu1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
 
 
3
# Authors: Alejandro J. Cura <alecu@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
"""The test suite for the Qt UI for the control panel for Ubuntu One."""
 
20
 
 
21
import os
 
22
 
 
23
from PyQt4 import QtCore
 
24
 
 
25
from ubuntuone.controlpanel import backend
 
26
from ubuntuone.controlpanel.tests import TestCase, EXPECTED_ACCOUNT_INFO
 
27
from ubuntuone.controlpanel.gui.tests import FakedObject, USER_HOME
 
28
 
 
29
# Attribute 'yyy' defined outside __init__, access to a protected member
 
30
# pylint: disable=W0201, W0212
 
31
 
 
32
 
 
33
SAMPLE_ACCOUNT_INFO = EXPECTED_ACCOUNT_INFO
 
34
SAMPLE_NAME = EXPECTED_ACCOUNT_INFO["name"]
 
35
SAMPLE_EMAIL = EXPECTED_ACCOUNT_INFO["email"]
 
36
SAMPLE_PLAN = EXPECTED_ACCOUNT_INFO["type"]
 
37
 
 
38
SAMPLE_COMPUTER_INFO = {
 
39
    "type": "Computer",
 
40
    "name": "desktop i5",
 
41
    "is_local": False,
 
42
    "configurable": False,
 
43
    "device_id": '1258-6854',
 
44
}
 
45
 
 
46
SAMPLE_PHONE_INFO = {
 
47
    "type": "Phone",
 
48
    "name": "nokia 1100",
 
49
    "is_local": False,
 
50
    "configurable": False,
 
51
    "device_id": '987456-2321',
 
52
}
 
53
 
 
54
SAMPLE_DEVICES_INFO = [
 
55
    {
 
56
        "type": "Computer",
 
57
        "name": "toshiba laptop",
 
58
        "is_local": True,
 
59
        "configurable": False,
 
60
        "device_id": '0000',
 
61
    },
 
62
    SAMPLE_COMPUTER_INFO,
 
63
    SAMPLE_PHONE_INFO,
 
64
]
 
65
NO_OP = lambda *args: None
 
66
 
 
67
 
 
68
def set_path_on_file_dialog(folder_name=None, file_dialog=None):
 
69
    """Set a valid path in the file dialog to create a folder."""
 
70
    if folder_name is None:
 
71
        folder_name = 'Documents'
 
72
    folder = os.path.join(USER_HOME, folder_name)
 
73
    if file_dialog is None:
 
74
        file_dialog = FakedFileDialog
 
75
    file_dialog.response = QtCore.QString(folder)
 
76
    return folder
 
77
 
 
78
 
 
79
def skip_if_abstract_class(test):
 
80
    """Decorator to skip a test if is an abstract class."""
 
81
 
 
82
    def inner(instance):
 
83
        """Skip a test if is an abstract class."""
 
84
        abstract = instance.class_ui is None
 
85
        result = None
 
86
        if not abstract:
 
87
            result = test(instance)
 
88
 
 
89
        return result
 
90
 
 
91
    return inner
 
92
 
 
93
 
 
94
class FakeUi(FakedObject):
 
95
    """A fake Ui object."""
 
96
 
 
97
    exposed_methods = ['setupUi']
 
98
 
 
99
 
 
100
class FakedControlPanelBackend(FakedObject):
 
101
    """Fake a Control Panel Backend."""
 
102
 
 
103
    ROOT_TYPE = u'ROOT'
 
104
    FOLDER_TYPE = u'UDF'
 
105
    SHARE_TYPE = u'SHARE'
 
106
    NAME_NOT_SET = u'ENAMENOTSET'
 
107
    FREE_BYTES_NOT_AVAILABLE = u'EFREEBYTESNOTAVAILABLE'
 
108
    DEFAULT_FILE_SYNC_SETTINGS = {
 
109
        backend.AUTOCONNECT_KEY: True,
 
110
        backend.SHOW_ALL_NOTIFICATIONS_KEY: True,
 
111
        backend.SHARE_AUTOSUBSCRIBE_KEY: False,
 
112
        backend.UDF_AUTOSUBSCRIBE_KEY: False,
 
113
        backend.DOWNLOAD_KEY: -1,  # no limit
 
114
        backend.UPLOAD_KEY: -1,  # no limit
 
115
    }
 
116
 
 
117
    next_result = object()
 
118
    exposed_methods = [
 
119
        'account_info',  # account
 
120
        'devices_info', 'device_names_info',  # devices
 
121
        'change_device_settings', 'remove_device',
 
122
        'volumes_info', 'change_volume_settings',  # volumes
 
123
        'create_folder', 'validate_path_for_folder',
 
124
        'replications_info', 'change_replication_settings',  # replications
 
125
        'file_sync_status', 'enable_files', 'disable_files',  # files
 
126
        'connect_files', 'disconnect_files',
 
127
        'restart_files', 'start_files', 'stop_files',
 
128
        'file_sync_settings_info',
 
129
        'change_file_sync_settings',
 
130
        'restore_file_sync_settings',
 
131
        'shutdown',
 
132
    ]
 
133
 
 
134
 
 
135
class FakedConfirmDialog(object):
 
136
    """Fake a confirmation dialog."""
 
137
 
 
138
    response = args = kwargs = None
 
139
 
 
140
    @classmethod
 
141
    def warning(cls, *a, **kw):
 
142
        """Simulate a warning message."""
 
143
        cls.args = a
 
144
        cls.kwargs = kw
 
145
        return cls.response
 
146
 
 
147
 
 
148
class FakedFileDialog(object):
 
149
    """Fake a file chooser dialog."""
 
150
 
 
151
    response = args = kwargs = None
 
152
 
 
153
    # Invalid name "getExistingDirectory"
 
154
    # pylint: disable=C0103
 
155
 
 
156
    @classmethod
 
157
    def getExistingDirectory(cls, *a, **kw):
 
158
        """Simulate a directory chooser."""
 
159
        cls.args = a
 
160
        cls.kwargs = kw
 
161
        return cls.response
 
162
 
 
163
 
 
164
class BaseTestCase(TestCase):
 
165
    """Base Test Case."""
 
166
 
 
167
    innerclass_ui = None
 
168
    innerclass_name = None
 
169
    class_ui = None
 
170
    kwargs = {}
 
171
 
 
172
    @skip_if_abstract_class
 
173
    def setUp(self):
 
174
        super(BaseTestCase, self).setUp()
 
175
        self.patch(backend, 'ControlBackend', FakedControlPanelBackend)
 
176
        # self.class_ui is not callable
 
177
        # pylint: disable=E1102
 
178
        self.ui = self.class_ui(**self.kwargs)
 
179
        self.addCleanup(self.ui.destroy)
 
180
 
 
181
        if hasattr(self.ui, 'backend'):
 
182
            # clean backend calls
 
183
            self.ui.backend._called.clear()
 
184
 
 
185
    def get_pixmap_data(self, pixmap):
 
186
        """Get the raw data of a QPixmap."""
 
187
        byte_array = QtCore.QByteArray()
 
188
        array_buffer = QtCore.QBuffer(byte_array)
 
189
        pixmap.save(array_buffer, "PNG")
 
190
        return byte_array
 
191
 
 
192
    # pylint: disable=C0103
 
193
    def assertEqualPixmaps(self, pixmap1, pixmap2):
 
194
        """Compare two Qt pixmaps."""
 
195
        d1 = self.get_pixmap_data(pixmap1)
 
196
        d2 = self.get_pixmap_data(pixmap2)
 
197
        self.assertEqual(d1, d2)
 
198
    # pylint: enable=C0103
 
199
 
 
200
    def assert_backend_called(self, method_name, *args, **kwargs):
 
201
        """Check that the control panel backend 'method_name' was called."""
 
202
        self.assertIn(method_name, self.ui.backend._called)
 
203
        self.assertEqual(self.ui.backend._called[method_name], (args, kwargs))
 
204
 
 
205
    def test_init_loads_ui(self, expected_setup_ui=None):
 
206
        """The __init__ method loads the ui."""
 
207
        if self.innerclass_ui is None:
 
208
            return
 
209
        self.patch(self.innerclass_ui, self.innerclass_name, FakeUi)
 
210
        if getattr(self.class_ui, '_setup', None) is not None:
 
211
            self.patch(self.class_ui, '_setup', lambda *a: None)
 
212
        # pylint: disable=E1102
 
213
        self.ui = self.class_ui(**self.kwargs)
 
214
        # pylint: disable=E1101
 
215
 
 
216
        if expected_setup_ui is None:
 
217
            expected_setup_ui = self.ui
 
218
        else:
 
219
            expected_setup_ui = expected_setup_ui(self.ui)
 
220
        self.assertEqual(self.ui.ui._called,
 
221
                         {'setupUi': ((expected_setup_ui,), {})})