Logo Search packages:      
Sourcecode: ubuntuone-control-panel version File versions  Download package


# -*- coding: utf-8 -*-

# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
# Copyright 2010 Canonical Ltd.
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# PURPOSE.  See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.

"""The test suite for the GTK UI for the control panel for Ubuntu One."""

import logging

from collections import defaultdict

from ubuntuone.devtools.handlers import MementoHandler

from ubuntuone.controlpanel.backend import ControlBackend
from ubuntuone.controlpanel.gtk import gui
from ubuntuone.controlpanel.gtk.tests.test_package_manager import (
from ubuntuone.controlpanel.tests import TestCase

# Attribute 'yyy' defined outside __init__, access to a protected member
# pylint: disable=W0201, W0212

FAKE_ACCOUNT_INFO = {'type': 'Payed', 'name': 'Test me',
    'email': 'test.com', 'quota_total': '12345', 'quota_used': '9999'}

USER_HOME = '/home/tester'

ROOT = {
    u'volume_id': '', u'path': '/home/tester/My Ubuntu',
    u'subscribed': 'True', u'type': ControlBackend.ROOT_TYPE,

    u'volume_id': u'58236', u'subscribed': u'True',
    u'type': ControlBackend.FOLDER_TYPE,
    u'path': u'/home/tester/.ubuntuone/Purchased from Ubuntu One',
    u'suggested_path': u'~/.ubuntuone/Purchased from Ubuntu One',

    {u'volume_id': u'0', u'path': u'/home/tester/foo',
     u'suggested_path': u'~/foo', u'subscribed': u'',
     u'type': ControlBackend.FOLDER_TYPE},
    {u'volume_id': u'1', u'path': u'/home/tester/bar',
     u'suggested_path': u'~/bar', u'subscribed': u'True',
     u'type': ControlBackend.FOLDER_TYPE},
    {u'volume_id': u'2', u'path': u'/home/tester/baz',
     u'suggested_path': u'~/baz', u'subscribed': u'True',
     u'type': ControlBackend.FOLDER_TYPE},

    {u'volume_id': u'1234', u'name': u'do',
     u'path': u'/home/tester/.local/share/ubuntuone/shares/do from Other User',
     u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE},
    {u'volume_id': u'5678', u'name': u're',
     u'path': u'/home/tester/.local/share/ubuntuone/shares/re from Other User',
     u'subscribed': u'True', u'type': ControlBackend.SHARE_TYPE},

    (u'', u'147852369', [ROOT] + FAKE_FOLDERS_INFO),
    (u'Other User', gui.VolumesPanel.MIN_SIZE_FULL, FAKE_SHARES_INFO),

    (u'', u'500', [ROOT]),
    (u'No free space', u'0',
     [{u'volume_id': u'0', u'name': u'full', u'path': u'full-share',
       u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE}]),
    (u'Almost no free space', gui.VolumesPanel.MIN_SIZE_FULL - 1,
     [{u'volume_id': u'1', u'name': u'almostfull', u'path': u'almost-full',
       u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE}]),

    'device_id': '1258-6854', 'device_name': 'Baz', 'device_type': 'Computer',
    'is_local': 'True', 'configurable': 'True', 'limit_bandwidth': 'True',
    'max_upload_speed': '1000', 'max_download_speed': '72548',
    'show_all_notifications': 'True',

    {'device_id': '0', 'name': 'Ubuntu One @ Foo', 'type': 'Computer',
     'is_local': '', 'configurable': ''},
    {'device_id': '1', 'name': 'Ubuntu One @ Bar', 'type': 'Phone',
     'is_local': '', 'configurable': ''},
    {'device_id': '2', 'name': 'Ubuntu One @ Z', 'type': 'Computer',
     'is_local': '', 'configurable': 'True', 'limit_bandwidth': '',
     'max_upload_speed': '0', 'max_download_speed': '0',
     'show_all_notifications': ''},
    {'device_id': '1258-6854', 'name': 'Ubuntu One @ Baz', 'type': 'Computer',
     'is_local': 'True', 'configurable': 'True', 'limit_bandwidth': 'True',
     'max_upload_speed': '1000', 'max_download_speed': '72548',
     'show_all_notifications': 'True'},  # local

    {'replication_id': 'foo', 'name': 'Bar',
     'enabled': 'True', 'dependency': ''},
    {'replication_id': 'yadda', 'name': 'Foo',
     'enabled': '', 'dependency': 'a very weird one'},
    {'replication_id': 'yoda', 'name': 'Figthers',
     'enabled': 'True', 'dependency': 'other dep'},

00123 class FakedObject(object):
    """Fake an object, record every call."""

    exposed_methods = []

    def __init__(self, *args, **kwargs):
        self._args = args
        self._kwargs = kwargs
        self._called = {}
        for i in self.exposed_methods:
            setattr(self, i, self._record_call(i))

00135     def _record_call(self, func_name):
        """Store values when calling 'func_name'."""

        def inner(*args, **kwargs):
            """Fake 'func_name'."""
            self._called[func_name] = (args, kwargs)

        return inner

00145 class FakedNMState(FakedObject):
    """Fake a NetworkManagerState."""

    exposed_methods = ['find_online_state']

00151 class FakedDBusBackend(FakedObject):
    """Fake a DBus Backend."""

    bus_name = None
    object_path = None
    iface = None

    def __init__(self, obj, dbus_interface, *args, **kwargs):
        if dbus_interface != self.iface:
            raise TypeError()
        self._signals = defaultdict(list)
        super(FakedDBusBackend, self).__init__(*args, **kwargs)

00164     def connect_to_signal(self, signal, handler):
        """Bind 'handler' to be callback'd when 'signal' is fired."""

00169 class FakedSSOBackend(FakedDBusBackend):
    """Fake a SSO Backend, act as a dbus.Interface."""

    bus_name = gui.ubuntu_sso.DBUS_BUS_NAME
    object_path = gui.ubuntu_sso.DBUS_CREDENTIALS_PATH
    iface = gui.ubuntu_sso.DBUS_CREDENTIALS_IFACE
    exposed_methods = ['find_credentials', 'clear_credentials',
                       'login', 'register']

00179 class FakedControlPanelBackend(FakedDBusBackend):
    """Fake a Control Panel Backend, act as a dbus.Interface."""

    bus_name = gui.DBUS_BUS_NAME
    object_path = gui.DBUS_PREFERENCES_PATH
    exposed_methods = [
        'account_info',  # account
        'devices_info', 'change_device_settings', 'remove_device',  # devices
        'volumes_info', 'change_volume_settings',  # volumes
        'replications_info', 'change_replication_settings',  # replications
        'file_sync_status', 'enable_files', 'disable_files',  # files
        'connect_files', 'disconnect_files',
        'restart_files', 'start_files', 'stop_files', 'shutdown',

00196 class FakeControlPanelBackend(FakedDBusBackend):
    """Fake a Control Panel Service, act as a dbus.Interface."""

    bus_name = gui.DBUS_BUS_NAME_GUI
    object_path = gui.DBUS_PATH_GUI
    iface = gui.DBUS_IFACE_GUI
    exposed_methods = ['draw_attention', 'switch_to']

00205 class FakedSessionBus(object):
    """Fake a session bus."""

00208     def get_object(self, bus_name, object_path, introspect=True,
                   follow_name_owner_changes=False, **kwargs):
        """Return a faked proxy for the given remote object."""
        return None

00214 class FakedInterface(object):
    """Fake a dbus interface."""

    def __new__(cls, obj, dbus_interface, *args, **kwargs):
        if dbus_interface == gui.DBUS_PREFERENCES_IFACE:
            return FakedControlPanelBackend(obj, dbus_interface,
                                            *args, **kwargs)
        if dbus_interface == gui.ubuntu_sso.DBUS_CREDENTIALS_IFACE:
            return FakedSSOBackend(obj, dbus_interface, *args, **kwargs)
        if dbus_interface == gui.DBUS_IFACE_GUI:
            return FakeControlPanelBackend(
                obj, dbus_interface, *args, **kwargs)

00228 class FakedPackageManager(object):
    """Faked a package manager."""

    def __init__(self):
        self._installed = {}
        self.is_installed = lambda package_name: \
            self._installed.setdefault(package_name, False)

00237     def install(self, package_name):
        """Install 'package_name' if is not installed in this system."""
        self._installed[package_name] = True

00244 class FakedConfirmDialog(object):
    """Fake a confirmation dialog."""

    def __init__(self, *args, **kwargs):
        self._args = args
        self._kwargs = kwargs
        self.was_run = False
        self.is_visible = False
        self.markup = kwargs.get('message_format', None)
        self.show = lambda: setattr(self, 'is_visible', True)
        self.hide = lambda: setattr(self, 'is_visible', False)
        self.response_code = None

00257     def run(self):
        """Set flag and return 'self.response_code'."""
        self.was_run = True
        return self.response_code

00262     def set_markup(self, msg):
        """Set the markup."""
        self.markup = msg

00267 class BaseTestCase(TestCase):
    """Basics for testing."""

    # self.klass is not callable
    # pylint: disable=E1102
    klass = None
    kwargs = {}

    def setUp(self):
        super(BaseTestCase, self).setUp()
        self.patch(gui.os.path, 'expanduser',
                   lambda path: path.replace('~', USER_HOME))
        self.patch(gui.gtk, 'main', lambda: None)
        self.patch(gui.gtk, 'MessageDialog', FakedConfirmDialog)
        self.patch(gui.dbus, 'SessionBus', FakedSessionBus)
        self.patch(gui.dbus, 'Interface', FakedInterface)
        self.patch(gui.networkstate, 'NetworkManagerState', FakedNMState)
        self.patch(gui.package_manager, 'PackageManager', FakedPackageManager)

        if self.klass is not None:
            self.ui = self.klass(**self.kwargs)

        self.memento = MementoHandler()

    def tearDown(self):
            del self.ui
            self.ui = None
        except AttributeError:
        super(BaseTestCase, self).tearDown()

00302     def assert_image_equal(self, image, filename):
        """Check that expected and actual represent the same image."""
        pb = gui.gtk.gdk.pixbuf_new_from_file(gui.get_data_file(filename))
        self.assertEqual(image.get_pixbuf().get_pixels(), pb.get_pixels())

00307     def assert_backend_called(self, method_name, args, backend=None):
        """Check that the control panel backend 'method_name' was called."""
        if backend is None:
            backend = self.ui.backend
        self.assertIn(method_name, backend._called)
        kwargs = {'reply_handler': gui.NO_OP,
                  'error_handler': gui.error_handler}
        self.assertEqual(backend._called[method_name], (args, kwargs))

00316     def assert_warning_correct(self, warning, text):
        """Check that 'warning' is visible, showing 'text'."""
        self.assertTrue(warning.get_visible(), 'Must be visible.')
        self.assertEqual(warning.get_label(), gui.WARNING_MARKUP % text)

00321     def assert_function_decorated(self, decorator, func):
        """Check that 'func' is decorated with 'decorator'."""
        expected = decorator(lambda: None)
        self.assertEqual(expected.func_code, func.im_func.func_code)

Generated by  Doxygen 1.6.0   Back to index