Merge lp:~diegosarmentero/ubuntuone-windows-installer/connect-files into lp:ubuntuone-windows-installer

Proposed by Diego Sarmentero
Status: Merged
Approved by: Natalia Bidart
Approved revision: 98
Merged at revision: 85
Proposed branch: lp:~diegosarmentero/ubuntuone-windows-installer/connect-files
Merge into: lp:ubuntuone-windows-installer
Diff against target: 401 lines (+133/-90)
7 files modified
ubuntuone_installer/gui/qt/gui.py (+3/-0)
ubuntuone_installer/gui/qt/preferences.py (+1/-0)
ubuntuone_installer/gui/qt/tests/__init__.py (+49/-0)
ubuntuone_installer/gui/qt/tests/test_gui.py (+10/-1)
ubuntuone_installer/gui/qt/tests/test_local_folders.py (+47/-71)
ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py (+21/-17)
ubuntuone_installer/gui/qt/utils/windows.py (+2/-1)
To merge this branch: bzr merge lp:~diegosarmentero/ubuntuone-windows-installer/connect-files
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+79611@code.launchpad.net

Commit message

Fixed: Should call self.backend.connect_files as soon as valid credentials are created (LP: #852085).

Description of the change

Fixed: Should call self.backend.connect_files as soon as valid credentials are created (LP: #852085).

To post a comment you must log in.
83. By Diego Sarmentero

Fixed lint issues.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

* Unless I'm missing something, there is no need to define:

    @defer.inlineCallbacks
    def connect_file_sync(self):
        """Connect file sync service on login successful."""
        yield self.backend.connect_files()

you can just call self.backend.connect_files() in initializePage.

* On the other hand, the FakedBackend does not need to define the clear() method (AFAIK) and the self.properties['connect_files'] is not used, ergo not needed?

* There is a lint issue.

review: Needs Fixing
84. By Diego Sarmentero

Fixed lint issue.
Modified connect_sync_files

85. By Diego Sarmentero

Conflict resolved.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

== Python Lint Notices ==

ubuntuone_installer/gui/qt/tests/__init__.py:
    62: [C0111, FakeBackend] Missing docstring

ubuntuone_installer/gui/qt/utils/windows.py:
    41: [E0611] No name 'tools' in module 'ubuntuone.platform'

The last warning should be disabled (can't be fixed).

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) wrote :

Besides the lint problem Natalia mentioned, the code looks god to me.

review: Approve
86. By Diego Sarmentero

Fixed lint issues.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> Besides the lint problem Natalia mentioned, the code looks god to me.

Fixed remaining lint issue about tools

87. By Diego Sarmentero

Fixed lint issue

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Conflict in:

Text conflict in ubuntuone_installer/gui/qt/utils/windows.py
1 conflicts encountered.

review: Needs Fixing
Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> Conflict in:
>
> Text conflict in ubuntuone_installer/gui/qt/utils/windows.py
> 1 conflicts encountered.

Fixed

88. By Diego Sarmentero

Fixed conflict.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

So, perhaps I was not clear before... but I still see no point in having this patched connect_files method:

    def connect_files(self, func=None):
        """Fake connect_files"""
        self.properties['connect_files_called'] = True
        self.properties['connect_files'] = func

Why do we need the func=None parameter, if the original method does not receive any paramter? Why are we storing the func value, if then we're just passing None and testing against it?

Also, the self._called = self has no much sense as well, as far as I can see.

If I understand the fake correctly, I think this is a simpler option:

class FakeBackend(object):

    """Fake ControlBackend."""

    def __init__(self, *args, **kwargs):
        self.called = []
        self.clear = lambda: None
        self.connect_files = lambda: self.called.append('connect_files')

and have the test only test for assertEqual(called, ['connect_files']).

review: Needs Fixing
89. By Diego Sarmentero

Tests Fixed.

90. By Diego Sarmentero

Conflict resolved.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Tests errors after the merge with trunk:

===============================================================================
[FAIL]
Traceback (most recent call last):
  File "/usr/lib/pymodules/python2.7/ubuntuone-dev-tools/ubuntuone/devtools/testing/txcheck.py", line 355, in run
    raise problem
ubuntuone.devtools.testing.txcheck.MissingReturnValue: MissingReturnValue for ubuntuone_installer.gui.qt.tests.test_gui.SuccesPageTestCase.setUp

ubuntuone.devtools.testing.txcheck.TXCheckTest.runTest
===============================================================================
[FAIL]
Traceback (most recent call last):
  File "/usr/lib/pymodules/python2.7/ubuntuone-dev-tools/ubuntuone/devtools/testing/txcheck.py", line 355, in run
    raise problem
ubuntuone.devtools.testing.txcheck.SuperResultDiscarded: SuperResultDiscarded for ubuntuone_installer.gui.qt.tests.test_gui.SuccesPageTestCase.setUp

ubuntuone.devtools.testing.txcheck.TXCheckTest.runTest
-------------------------------------------------------------------------------
Ran 146 tests in 6.151s

FAILED (failures=2, successes=146)

review: Needs Fixing
91. By Diego Sarmentero

Test fixed.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

C'mon! :-)

ubuntuone_installer/gui/qt/tests/__init__.py:
    73: [E0202, FakeBackend.clear] An attribute inherited from FakeBackend hide this method

review: Needs Fixing
92. By Diego Sarmentero

Fixed lint issues

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

As per our latest conversation with Diego, we'd need to unify all the fakes control panel backend that are all around.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> As per our latest conversation with Diego, we'd need to unify all the fakes
> control panel backend that are all around.

Refactor done!

93. By Diego Sarmentero

Unified Backend Fakes.

94. By Diego Sarmentero

Fixed tests.

95. By Diego Sarmentero

Tests fixed.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

== Python Lint Notices ==

ubuntuone_installer/gui/qt/tests/test_local_folders.py:
    42: [C0103] Invalid name "backend_account_info_data" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)
    46: [C0103] Invalid name "backend_volume_info_data" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)

ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py:
    40: [C0103] Invalid name "backend_volume_info_data_sync" (should match (([A-Z_][A-Z0-9_]*)|(__.*__))$)

review: Needs Fixing
96. By Diego Sarmentero

Fixed lint issues.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

> == Python Lint Notices ==
>
> ubuntuone_installer/gui/qt/tests/test_local_folders.py:
> 42: [C0103] Invalid name "backend_account_info_data" (should match
> (([A-Z_][A-Z0-9_]*)|(__.*__))$)
> 46: [C0103] Invalid name "backend_volume_info_data" (should match
> (([A-Z_][A-Z0-9_]*)|(__.*__))$)
>
> ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py:
> 40: [C0103] Invalid name "backend_volume_info_data_sync" (should match
> (([A-Z_][A-Z0-9_]*)|(__.*__))$)

Fixed

97. By Diego Sarmentero

merge

98. By Diego Sarmentero

Lint issues fixed.

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntuone_installer/gui/qt/gui.py'
2--- ubuntuone_installer/gui/qt/gui.py 2011-10-17 15:11:02 +0000
3+++ ubuntuone_installer/gui/qt/gui.py 2011-11-08 12:07:43 +0000
4@@ -49,6 +49,7 @@
5 SuccessController,
6 )
7
8+from ubuntuone.controlpanel import backend
9 from ubuntuone.controlpanel.gui.qt.loadingoverlay import LoadingOverlay
10
11 from ubuntuone.platform.credentials import (
12@@ -214,6 +215,7 @@
13 def __init__(self, parent=None):
14 super(SuccessPage, self).__init__(
15 Ui_SuccessPage(), SuccessController(), parent)
16+ self.backend = backend.ControlBackend()
17 self.finish_button = None
18 self.next_button = None
19
20@@ -236,6 +238,7 @@
21 self.next_button.setDefault(True)
22 self.next_button.style().unpolish(self.next_button)
23 self.next_button.style().polish(self.next_button)
24+ self.backend.connect_files()
25
26 def nextId(self):
27 """Provide the next id."""
28
29=== modified file 'ubuntuone_installer/gui/qt/preferences.py'
30--- ubuntuone_installer/gui/qt/preferences.py 2011-09-09 19:13:49 +0000
31+++ ubuntuone_installer/gui/qt/preferences.py 2011-11-08 12:07:43 +0000
32@@ -45,6 +45,7 @@
33 # pylint: disable=C0103
34
35 def initializePage(self):
36+ """Initialize the page before the Wizard show it."""
37 self.wizard().setOption(QtGui.QWizard.HaveCustomButton1, True)
38 self.wizard().setOption(QtGui.QWizard.HaveCustomButton2, True)
39 # This is just to catch an exception thrown when nothing
40
41=== modified file 'ubuntuone_installer/gui/qt/tests/__init__.py'
42--- ubuntuone_installer/gui/qt/tests/__init__.py 2011-10-28 11:00:42 +0000
43+++ ubuntuone_installer/gui/qt/tests/__init__.py 2011-11-08 12:07:43 +0000
44@@ -60,6 +60,55 @@
45 self.target(*args)
46
47
48+class FakeBackend(object):
49+
50+ """Fake ControlBackend."""
51+
52+ account_info_data = None
53+ volumes_info_data = None
54+
55+ def __init__(self, *args, **kwargs):
56+ self.called = []
57+ self._called = self
58+ self.clear = lambda: None
59+ self.connect_files = lambda: self.called.append('connect_files')
60+ self._is_valid = True
61+ self.volume_setings_changes = []
62+ self.folders_created = []
63+
64+ def account_info(self, *args):
65+ """Fake account info."""
66+ return defer.succeed(self.account_info_data)
67+
68+ def volumes_info(self, *args):
69+ """Fake volumes info."""
70+ return defer.succeed(self.volumes_info_data)
71+
72+ def validate_path_for_folder(self, path):
73+ """Fake folder validation."""
74+ return self._is_valid
75+
76+ def change_volume_settings(self, *args):
77+ """Fake change volume settings."""
78+ self.volume_setings_changes.append(args)
79+
80+ def create_folder(self, *args):
81+ """Fake folder creation."""
82+ self.folders_created.append(args)
83+
84+
85+class FakeFailingBackend(object):
86+ """Fake Control Panel backend that fails."""
87+
88+ def account_info(self, *args):
89+ """Fake account info."""
90+ return defer.fail(Exception())
91+
92+ def volumes_info(self, *args):
93+ """Fake account info."""
94+ return defer.fail(Exception())
95+
96+
97 class FakeController(object):
98
99 """A fake controller for the tests."""
100
101=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
102--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-10-28 11:00:42 +0000
103+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-11-08 12:07:43 +0000
104@@ -28,6 +28,7 @@
105 from ubuntuone_installer.gui.qt import gui, forgotten, utils
106 from ubuntuone_installer.gui.qt.tests import (
107 BaseTestCase,
108+ FakeBackend,
109 FakeController,
110 FakeOverlay,
111 FakeSignal,
112@@ -119,6 +120,7 @@
113 self.patch(qt.preferences, "PreferencesPanel", FakePreferencesPanel)
114 self.patch(qt.folders, "FoldersPanel", FakeFoldersPanel)
115 self.patch(gui.qt.utils, "add_syncdaemon_to_autostart", NO_OP)
116+ self.patch(gui.backend, "ControlBackend", FakeBackend)
117 yield super(MainWindowTestCase, self).setUp()
118 setup_page = self.ui.page(self.ui.setup_account_page_id)
119 setup_page.initializePage()
120@@ -655,6 +657,12 @@
121
122 class_ui = gui.SuccessPage
123
124+ @defer.inlineCallbacks
125+ def setUp(self):
126+ """Initialize this test instance."""
127+ self.patch(gui.backend, "ControlBackend", FakeBackend)
128+ yield super(SuccesPageTestCase, self).setUp()
129+
130 def test_after_initialize(self):
131 """Check the page is initialized correctly."""
132 wizard = FakeMainWindow()
133@@ -673,10 +681,11 @@
134 QtGui.QWizard.NextButton])
135 self.assertTrue(self.ui.next_button.isDefault())
136 self.assertFalse(self.ui.finish_button.isDefault())
137+ self.assertEqual(self.ui.backend.called, ['connect_files'])
138
139
140 class SignInPageTestCase(BaseTestCase):
141- """Test the SuccessPage code."""
142+ """Test the SignInPage code."""
143
144 @defer.inlineCallbacks
145 def setUp(self):
146
147=== modified file 'ubuntuone_installer/gui/qt/tests/test_local_folders.py'
148--- ubuntuone_installer/gui/qt/tests/test_local_folders.py 2011-10-28 11:00:42 +0000
149+++ ubuntuone_installer/gui/qt/tests/test_local_folders.py 2011-11-08 12:07:43 +0000
150@@ -19,6 +19,7 @@
151 """Tests for the local folders page."""
152
153 import os
154+import copy
155 import Queue
156 import shutil
157 import tempfile
158@@ -28,10 +29,44 @@
159
160 from ubuntuone_installer.gui import NEXT
161 from ubuntuone_installer.gui.qt import local_folders
162-from ubuntuone_installer.gui.qt.tests import BaseTestCase, TestCase
163+from ubuntuone_installer.gui.qt.tests import (
164+ BaseTestCase,
165+ FakeBackend,
166+ FakeFailingBackend,
167+ TestCase,
168+)
169 from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
170
171
172+# Define backend data for account_info and volume_info
173+BACKEND_ACCOUNT_INFO_DATA = {
174+ "quota_total": 1000,
175+ "quota_used": 200,
176+ }
177+BACKEND_VOLUME_INFO_DATA = ((None, None,
178+ [
179+ {
180+ 'type': u'UDF',
181+ 'path': os.path.expanduser(u'~/xyzzy'),
182+ 'volume_id': 'asdfgh',
183+ 'subscribed': True,
184+ },
185+ {
186+ 'type': u'UDF',
187+ 'path': os.path.expanduser(u'~/zxyzzy'),
188+ 'volume_id': 'qwerty',
189+ 'subscribed': False,
190+ },
191+ {
192+ 'type': u'SHARE',
193+ 'path': os.path.expanduser(u'~/foobar'),
194+ 'volume_id': 'shared',
195+ 'subscribed': False,
196+ },
197+ ],
198+ ),)
199+
200+
201 class FakeFileDialog(object):
202
203 """A fake QFileDialog class."""
204@@ -56,72 +91,6 @@
205 self._warning = (args, kwargs)
206
207
208-class FakeCPBackend(object):
209- """Fake Control Panel backend."""
210-
211- def __init__(self):
212- """Initialize."""
213- self._is_valid = True
214- self.volume_setings_changes = []
215- self.folders_created = []
216-
217- def account_info(self, *args):
218- """Fake account info."""
219- return defer.succeed({
220- "quota_total": 1000,
221- "quota_used": 200,
222- })
223-
224- def volumes_info(self, *args):
225- """Fake volumes info."""
226- return defer.succeed(((None, None,
227- [
228- {
229- 'type': u'UDF',
230- 'path': os.path.expanduser(u'~/xyzzy'),
231- 'volume_id': 'asdfgh',
232- 'subscribed': True,
233- },
234- {
235- 'type': u'UDF',
236- 'path': os.path.expanduser(u'~/zxyzzy'),
237- 'volume_id': 'qwerty',
238- 'subscribed': False,
239- },
240- {
241- 'type': u'SHARE',
242- 'path': os.path.expanduser(u'~/foobar'),
243- 'volume_id': 'shared',
244- 'subscribed': False,
245- },
246- ],
247- ),))
248-
249- def validate_path_for_folder(self, path):
250- """Fake folder validation."""
251- return self._is_valid
252-
253- def change_volume_settings(self, *args):
254- """Fake change volume settings."""
255- self.volume_setings_changes.append(args)
256-
257- def create_folder(self, *args):
258- """Fake folder creation."""
259- self.folders_created.append(args)
260-
261-
262-class FakeFailingCPBackend(object):
263- """Fake Control Panel backend that fails."""
264-
265- def account_info(self, *args):
266- """Fake account info."""
267- return defer.fail(Exception())
268-
269- def volumes_info(self, *args):
270- """Fake account info."""
271- return defer.fail(Exception())
272-
273-
274 class FakeCalculateSize(object):
275
276 """A fake CalculateSize."""
277@@ -181,7 +150,11 @@
278 f.close()
279 self.addCleanup(shutil.rmtree, self.tmpdir)
280 self.fake_wizard = FakeMainWindow()
281- self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
282+ self.patch(local_folders.backend, "ControlBackend", FakeBackend)
283+ self.patch(FakeBackend, "account_info_data",
284+ copy.copy(BACKEND_ACCOUNT_INFO_DATA))
285+ self.patch(FakeBackend, "volumes_info_data",
286+ copy.copy(BACKEND_VOLUME_INFO_DATA))
287 yield super(LocalFoldersWithGetSizeTestCase, self).setUp()
288 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
289
290@@ -223,7 +196,11 @@
291 self.tmpdir = tempfile.mkdtemp()
292 self.addCleanup(shutil.rmtree, self.tmpdir)
293 self.fake_wizard = FakeMainWindow()
294- self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
295+ self.patch(local_folders.backend, "ControlBackend", FakeBackend)
296+ self.patch(FakeBackend, "account_info_data",
297+ copy.copy(BACKEND_ACCOUNT_INFO_DATA))
298+ self.patch(FakeBackend, "volumes_info_data",
299+ copy.copy(BACKEND_VOLUME_INFO_DATA))
300 self.patch(os.path, 'getsize', lambda *args: 0)
301 yield super(LocalFoldersTestCase, self).setUp()
302 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
303@@ -536,8 +513,7 @@
304
305 def test_exception_on_account_info(self):
306 """When account_info fails, nothing should happen."""
307- self.patch(self.ui,
308- "cp_backend", FakeFailingCPBackend())
309+ self.patch(self.ui, "cp_backend", FakeFailingBackend())
310 self.ui.get_info()
311 # Still here
312
313
314=== modified file 'ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py'
315--- ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py 2011-10-28 11:00:42 +0000
316+++ ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py 2011-11-08 12:07:43 +0000
317@@ -25,25 +25,26 @@
318
319 from ubuntuone_installer.gui import NEXT
320 from ubuntuone_installer.gui.qt import sync_now_or_later
321-from ubuntuone_installer.gui.qt.tests import BaseTestCase
322+from ubuntuone_installer.gui.qt.tests import (
323+ BaseTestCase,
324+ FakeBackend,
325+)
326 from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
327 from ubuntuone_installer.gui.qt.tests.test_local_folders import (
328- FakeCPBackend,
329+ BACKEND_ACCOUNT_INFO_DATA,
330+ BACKEND_VOLUME_INFO_DATA,
331 )
332
333
334-class FakeEmptyCPBackend(FakeCPBackend):
335- """A CP backend that returns only one folder."""
336- def volumes_info(self, *args):
337- """Fake volumes info."""
338- return defer.succeed(((None, None,
339- [
340- {
341- 'type': u'ROOT',
342- 'path': os.path.expanduser(u'~/Ubuntu One'),
343- 'volume_id': 'asdfgh',
344- 'subscribed': True,
345- }]),))
346+# Define backend data for account_info and volume_info
347+BACKEND_VOLUME_INFO_DATA_SYNC = ((None, None,
348+ [
349+ {
350+ 'type': u'ROOT',
351+ 'path': os.path.expanduser(u'~/Ubuntu One'),
352+ 'volume_id': 'asdfgh',
353+ 'subscribed': True,
354+ }]),)
355
356
357 class SyncNowOrLaterTestCase(BaseTestCase):
358@@ -57,7 +58,9 @@
359 yield super(SyncNowOrLaterTestCase, self).setUp()
360 self.main_window = FakeMainWindow()
361 self.patch(self.ui, "wizard", lambda: self.main_window)
362- self.patch(sync_now_or_later.backend, "ControlBackend", FakeCPBackend)
363+ self.patch(sync_now_or_later.backend, "ControlBackend", FakeBackend)
364+ self.patch(FakeBackend, "account_info_data", BACKEND_ACCOUNT_INFO_DATA)
365+ self.patch(FakeBackend, "volumes_info_data", BACKEND_VOLUME_INFO_DATA)
366
367 @defer.inlineCallbacks
368 def test_has_folders_in_cloud(self):
369@@ -68,8 +71,9 @@
370 @defer.inlineCallbacks
371 def test_has_no_folders_in_cloud(self):
372 """test behaviour when the user has no folders in the cloud."""
373- self.patch(sync_now_or_later.backend,
374- "ControlBackend", FakeEmptyCPBackend)
375+ self.patch(sync_now_or_later.backend, "ControlBackend", FakeBackend)
376+ self.patch(FakeBackend, "volumes_info_data",
377+ BACKEND_VOLUME_INFO_DATA_SYNC)
378 yield self.ui.get_info()
379 self.assertFalse(self.ui.has_cloud_folders)
380
381
382=== modified file 'ubuntuone_installer/gui/qt/utils/windows.py'
383--- ubuntuone_installer/gui/qt/utils/windows.py 2011-10-20 14:33:35 +0000
384+++ ubuntuone_installer/gui/qt/utils/windows.py 2011-11-08 12:07:43 +0000
385@@ -41,6 +41,7 @@
386 # pylint: disable=E0611
387 from ubuntuone.platform import tools
388 # pylint: enable=E0611
389+
390 from ubuntuone.platform.credentials import CredentialsManagementTool
391
392 AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
393@@ -202,7 +203,7 @@
394 # XXXX to be replaced by calls to xdg_base_directory's
395 # special_folders. Also the correct funtion to call is
396 # ShGetFolderPath per http://msdn.microsoft.com/en-us
397- # /library/windows/desktop/bb762204(v=vs.85).aspx
398+ # /library/windows/desktop/bb762204(v=vs.85).aspx
399 dll = ctypes.windll.shell32
400 buf = ctypes.create_unicode_buffer(300)
401 dll.SHGetSpecialFolderPathW(None, buf, CSIDL_PERSONAL, False)

Subscribers

People subscribed via source and target branches