Merge lp:~nataliabidart/ubuntuone-control-panel/letmeremove into lp:ubuntuone-control-panel
- letmeremove
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged |
---|---|
Approved by: | Alejandro J. Cura |
Approved revision: | 189 |
Merged at revision: | 188 |
Proposed branch: | lp:~nataliabidart/ubuntuone-control-panel/letmeremove |
Merge into: | lp:ubuntuone-control-panel |
Diff against target: |
583 lines (+243/-131) 9 files modified
data/qt/device.ui (+8/-1) data/qt/devices.ui (+69/-105) ubuntuone/controlpanel/gui/qt/device.py (+36/-9) ubuntuone/controlpanel/gui/qt/devices.py (+5/-1) ubuntuone/controlpanel/gui/qt/loadingoverlay.py (+2/-1) ubuntuone/controlpanel/gui/qt/tests/__init__.py (+3/-0) ubuntuone/controlpanel/gui/qt/tests/test_device.py (+89/-4) ubuntuone/controlpanel/gui/qt/tests/test_devices.py (+14/-2) ubuntuone/controlpanel/gui/tests/__init__.py (+17/-8) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-control-panel/letmeremove |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alejandro J. Cura (community) | Approve | ||
Roberto Alsina (community) | Approve | ||
Review via email: mp+68444@code.launchpad.net |
Commit message
- Local device can now be removed (LP: #810662).
Description of the change
To post a comment you must log in.
- 188. By Natalia Bidart
-
Added code to remove local device once removed.
- 189. By Natalia Bidart
-
Merged trunk in.
Revision history for this message
Alejandro J. Cura (alecu) wrote : | # |
Clean code, tests pass, works irl. Approved!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/qt/device.ui' |
2 | --- data/qt/device.ui 2011-07-11 11:19:09 +0000 |
3 | +++ data/qt/device.ui 2011-07-19 19:17:30 +0000 |
4 | @@ -24,7 +24,7 @@ |
5 | <item> |
6 | <widget class="QLabel" name="device_name_label"> |
7 | <property name="text"> |
8 | - <string>Another device</string> |
9 | + <string>Local device</string> |
10 | </property> |
11 | </widget> |
12 | </item> |
13 | @@ -41,6 +41,13 @@ |
14 | </property> |
15 | </spacer> |
16 | </item> |
17 | + <item> |
18 | + <widget class="QPushButton" name="remove_device_button"> |
19 | + <property name="text"> |
20 | + <string>Delete device</string> |
21 | + </property> |
22 | + </widget> |
23 | + </item> |
24 | </layout> |
25 | </widget> |
26 | <resources> |
27 | |
28 | === modified file 'data/qt/devices.ui' |
29 | --- data/qt/devices.ui 2011-07-11 11:19:09 +0000 |
30 | +++ data/qt/devices.ui 2011-07-19 19:17:30 +0000 |
31 | @@ -6,8 +6,8 @@ |
32 | <rect> |
33 | <x>0</x> |
34 | <y>0</y> |
35 | - <width>688</width> |
36 | - <height>371</height> |
37 | + <width>325</width> |
38 | + <height>252</height> |
39 | </rect> |
40 | </property> |
41 | <property name="windowTitle"> |
42 | @@ -21,111 +21,75 @@ |
43 | <number>0</number> |
44 | </property> |
45 | <item> |
46 | - <widget class="QFrame" name="frame"> |
47 | - <property name="frameShape"> |
48 | - <enum>QFrame::StyledPanel</enum> |
49 | - </property> |
50 | - <property name="frameShadow"> |
51 | - <enum>QFrame::Raised</enum> |
52 | - </property> |
53 | - <layout class="QVBoxLayout" name="verticalLayout_2"> |
54 | - <item> |
55 | - <layout class="QHBoxLayout" name="horizontalLayout_2"> |
56 | - <item> |
57 | - <layout class="QVBoxLayout" name="local_device_box"/> |
58 | - </item> |
59 | - <item> |
60 | - <spacer name="horizontalSpacer_2"> |
61 | - <property name="orientation"> |
62 | - <enum>Qt::Horizontal</enum> |
63 | - </property> |
64 | - <property name="sizeHint" stdset="0"> |
65 | - <size> |
66 | - <width>40</width> |
67 | - <height>20</height> |
68 | - </size> |
69 | - </property> |
70 | - </spacer> |
71 | - </item> |
72 | - <item> |
73 | - <widget class="QPushButton" name="delete_device_button"> |
74 | - <property name="text"> |
75 | - <string>Delete device</string> |
76 | - </property> |
77 | - </widget> |
78 | - </item> |
79 | - </layout> |
80 | - </item> |
81 | - <item> |
82 | - <layout class="QHBoxLayout" name="horizontalLayout"> |
83 | - <item> |
84 | - <widget class="QLabel" name="other_devices_label"> |
85 | - <property name="text"> |
86 | - <string>Other devices</string> |
87 | - </property> |
88 | - </widget> |
89 | - </item> |
90 | - <item> |
91 | - <spacer name="horizontalSpacer"> |
92 | - <property name="orientation"> |
93 | - <enum>Qt::Horizontal</enum> |
94 | - </property> |
95 | - <property name="sizeHint" stdset="0"> |
96 | - <size> |
97 | - <width>40</width> |
98 | - <height>20</height> |
99 | - </size> |
100 | - </property> |
101 | - </spacer> |
102 | - </item> |
103 | - </layout> |
104 | - </item> |
105 | - <item> |
106 | - <widget class="QListWidget" name="list_devices"> |
107 | - <property name="alternatingRowColors"> |
108 | - <bool>true</bool> |
109 | - </property> |
110 | - <property name="iconSize"> |
111 | - <size> |
112 | - <width>32</width> |
113 | - <height>32</height> |
114 | - </size> |
115 | - </property> |
116 | - <property name="spacing"> |
117 | - <number>0</number> |
118 | - </property> |
119 | - <property name="selectionRectVisible"> |
120 | - <bool>false</bool> |
121 | - </property> |
122 | - </widget> |
123 | - </item> |
124 | - <item> |
125 | - <layout class="QHBoxLayout" name="horizontalLayout_3"> |
126 | - <item> |
127 | - <widget class="QPushButton" name="manage_devices_button"> |
128 | - <property name="sizePolicy"> |
129 | - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
130 | - <horstretch>0</horstretch> |
131 | - <verstretch>0</verstretch> |
132 | - </sizepolicy> |
133 | - </property> |
134 | - <property name="layoutDirection"> |
135 | - <enum>Qt::RightToLeft</enum> |
136 | - </property> |
137 | - <property name="text"> |
138 | - <string>Go to the web page to manage your other devices</string> |
139 | - </property> |
140 | - <property name="icon"> |
141 | - <iconset resource="images.qrc"> |
142 | - <normaloff>:/external_icon_white.png</normaloff>:/external_icon_white.png</iconset> |
143 | - </property> |
144 | - </widget> |
145 | - </item> |
146 | - </layout> |
147 | - </item> |
148 | - </layout> |
149 | + <layout class="QVBoxLayout" name="local_device_box"/> |
150 | + </item> |
151 | + <item> |
152 | + <layout class="QHBoxLayout" name="horizontalLayout"> |
153 | + <item> |
154 | + <widget class="QLabel" name="other_devices_label"> |
155 | + <property name="text"> |
156 | + <string>Other devices</string> |
157 | + </property> |
158 | + </widget> |
159 | + </item> |
160 | + <item> |
161 | + <spacer name="horizontalSpacer"> |
162 | + <property name="orientation"> |
163 | + <enum>Qt::Horizontal</enum> |
164 | + </property> |
165 | + <property name="sizeHint" stdset="0"> |
166 | + <size> |
167 | + <width>40</width> |
168 | + <height>20</height> |
169 | + </size> |
170 | + </property> |
171 | + </spacer> |
172 | + </item> |
173 | + </layout> |
174 | + </item> |
175 | + <item> |
176 | + <widget class="QListWidget" name="list_devices"> |
177 | + <property name="alternatingRowColors"> |
178 | + <bool>true</bool> |
179 | + </property> |
180 | + <property name="iconSize"> |
181 | + <size> |
182 | + <width>32</width> |
183 | + <height>32</height> |
184 | + </size> |
185 | + </property> |
186 | + <property name="spacing"> |
187 | + <number>0</number> |
188 | + </property> |
189 | + <property name="selectionRectVisible"> |
190 | + <bool>false</bool> |
191 | + </property> |
192 | </widget> |
193 | </item> |
194 | + <item> |
195 | + <layout class="QHBoxLayout" name="horizontalLayout_3"> |
196 | + <item> |
197 | + <widget class="QPushButton" name="manage_devices_button"> |
198 | + <property name="sizePolicy"> |
199 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
200 | + <horstretch>0</horstretch> |
201 | + <verstretch>0</verstretch> |
202 | + </sizepolicy> |
203 | + </property> |
204 | + <property name="layoutDirection"> |
205 | + <enum>Qt::RightToLeft</enum> |
206 | + </property> |
207 | + <property name="text"> |
208 | + <string>Go to the web page to manage your other devices</string> |
209 | + </property> |
210 | + <property name="icon"> |
211 | + <iconset resource="images.qrc"> |
212 | + <normaloff>:/external_icon_white.png</normaloff>:/external_icon_white.png</iconset> |
213 | + </property> |
214 | + </widget> |
215 | + </item> |
216 | + </layout> |
217 | + </item> |
218 | </layout> |
219 | </widget> |
220 | <resources> |
221 | |
222 | === modified file 'ubuntuone/controlpanel/gui/qt/device.py' |
223 | --- ubuntuone/controlpanel/gui/qt/device.py 2011-07-11 18:00:59 +0000 |
224 | +++ ubuntuone/controlpanel/gui/qt/device.py 2011-07-19 19:17:30 +0000 |
225 | @@ -18,22 +18,30 @@ |
226 | |
227 | """The user interface for the control panel for Ubuntu One.""" |
228 | |
229 | -from PyQt4 import QtGui |
230 | - |
231 | +from PyQt4 import QtGui, QtCore |
232 | + |
233 | +from twisted.internet import defer |
234 | + |
235 | +from ubuntuone.controlpanel.backend import ( |
236 | + DEVICE_TYPE_COMPUTER, |
237 | + DEVICE_TYPE_PHONE, |
238 | +) |
239 | +from ubuntuone.controlpanel.gui import DEVICE_CONFIRM_REMOVE |
240 | from ubuntuone.controlpanel.gui.qt.ui import device_ui |
241 | |
242 | COMPUTER_ICON = "computer" |
243 | PHONE_ICON = "phone" |
244 | DEFAULT_ICON = COMPUTER_ICON |
245 | |
246 | -COMPUTER_TYPE = "Computer" |
247 | -PHONE_TYPE = "Phone" |
248 | - |
249 | DEVICE_TYPE_TO_ICON_MAP = { |
250 | - COMPUTER_TYPE: COMPUTER_ICON, |
251 | - PHONE_TYPE: PHONE_ICON, |
252 | + DEVICE_TYPE_COMPUTER: COMPUTER_ICON, |
253 | + DEVICE_TYPE_PHONE: PHONE_ICON, |
254 | } |
255 | |
256 | +CANCEL = QtGui.QMessageBox.Cancel |
257 | +NO = QtGui.QMessageBox.No |
258 | +YES = QtGui.QMessageBox.Yes |
259 | + |
260 | |
261 | def icon_name_from_type(device_type): |
262 | """Get the icon name for the device.""" |
263 | @@ -44,11 +52,16 @@ |
264 | class DeviceWidget(QtGui.QWidget): |
265 | """The widget for each device in the control panel.""" |
266 | |
267 | - def __init__(self, *args): |
268 | + removed = QtCore.pyqtSignal() |
269 | + removeCanceled = QtCore.pyqtSignal() |
270 | + |
271 | + def __init__(self, backend, device_id, **kwargs): |
272 | """Initialize the UI of the widget.""" |
273 | - QtGui.QWidget.__init__(self, *args) |
274 | + QtGui.QWidget.__init__(self, **kwargs) |
275 | self.ui = device_ui.Ui_Form() |
276 | self.ui.setupUi(self) |
277 | + self.id = device_id |
278 | + self.backend = backend |
279 | |
280 | def update_device_info(self, device_info): |
281 | """Update the device info.""" |
282 | @@ -57,6 +70,20 @@ |
283 | pixmap = QtGui.QPixmap(pixmap_name) |
284 | self.ui.device_icon_label.setPixmap(pixmap) |
285 | |
286 | + @defer.inlineCallbacks |
287 | + @QtCore.pyqtSlot() |
288 | + def on_remove_device_button_clicked(self): |
289 | + """The user wants to remove this device.""" |
290 | + msg = DEVICE_CONFIRM_REMOVE |
291 | + buttons = YES | NO |
292 | + response = QtGui.QMessageBox.warning(self, '', msg, buttons, NO) |
293 | + |
294 | + if response == YES: |
295 | + yield self.backend.remove_device(device_id=self.id) |
296 | + self.removed.emit() |
297 | + else: |
298 | + self.removeCanceled.emit() |
299 | + |
300 | |
301 | def get_device_for_list_widget(device_info): |
302 | """Return a QListWidgetItem representing a device with the proper info.""" |
303 | |
304 | === modified file 'ubuntuone/controlpanel/gui/qt/devices.py' |
305 | --- ubuntuone/controlpanel/gui/qt/devices.py 2011-07-10 21:35:02 +0000 |
306 | +++ ubuntuone/controlpanel/gui/qt/devices.py 2011-07-19 19:17:30 +0000 |
307 | @@ -81,8 +81,12 @@ |
308 | |
309 | def update_local_device(self, device_info): |
310 | """Update the info for the local device.""" |
311 | - device_widget = device.DeviceWidget() |
312 | + device_widget = device.DeviceWidget(backend=self.backend, |
313 | + device_id=device_info['device_id']) |
314 | device_widget.update_device_info(device_info) |
315 | + f = lambda: self.clear_device_info(self.ui.local_device_box) |
316 | + device_widget.removed.connect(f) |
317 | + |
318 | self.ui.local_device_box.addWidget(device_widget) |
319 | |
320 | def create_remote_device(self, device_info): |
321 | |
322 | === modified file 'ubuntuone/controlpanel/gui/qt/loadingoverlay.py' |
323 | --- ubuntuone/controlpanel/gui/qt/loadingoverlay.py 2011-07-12 18:47:13 +0000 |
324 | +++ ubuntuone/controlpanel/gui/qt/loadingoverlay.py 2011-07-19 19:17:30 +0000 |
325 | @@ -62,7 +62,8 @@ |
326 | |
327 | def eventFilter(self, obj, event): |
328 | """Filter events from Frame content to draw the dot animation.""" |
329 | - if obj == self.ui.frm_box and event.type() == QtCore.QEvent.Paint: |
330 | + if getattr(self, 'ui', None) is not None and \ |
331 | + obj == self.ui.frm_box and event.type() == QtCore.QEvent.Paint: |
332 | painter = QtGui.QPainter() |
333 | painter.begin(obj) |
334 | painter.setRenderHint(QtGui.QPainter.Antialiasing, True) |
335 | |
336 | === modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py' |
337 | --- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-07-13 18:45:43 +0000 |
338 | +++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-07-19 19:17:30 +0000 |
339 | @@ -40,6 +40,7 @@ |
340 | "name": "desktop i5", |
341 | "is_local": False, |
342 | "configurable": False, |
343 | + "device_id": '1258-6854', |
344 | } |
345 | |
346 | SAMPLE_PHONE_INFO = { |
347 | @@ -47,6 +48,7 @@ |
348 | "name": "nokia 1100", |
349 | "is_local": False, |
350 | "configurable": False, |
351 | + "device_id": '987456-2321', |
352 | } |
353 | |
354 | SAMPLE_DEVICES_INFO = [ |
355 | @@ -55,6 +57,7 @@ |
356 | "name": "toshiba laptop", |
357 | "is_local": True, |
358 | "configurable": False, |
359 | + "device_id": '0000', |
360 | }, |
361 | SAMPLE_COMPUTER_INFO, |
362 | SAMPLE_PHONE_INFO, |
363 | |
364 | === modified file 'ubuntuone/controlpanel/gui/qt/tests/test_device.py' |
365 | --- ubuntuone/controlpanel/gui/qt/tests/test_device.py 2011-07-13 18:45:43 +0000 |
366 | +++ ubuntuone/controlpanel/gui/qt/tests/test_device.py 2011-07-19 19:17:30 +0000 |
367 | @@ -20,9 +20,20 @@ |
368 | |
369 | from PyQt4 import QtGui |
370 | |
371 | +from twisted.internet import defer |
372 | + |
373 | from ubuntuone.controlpanel.gui.qt import device as gui |
374 | -from ubuntuone.controlpanel.gui.qt.tests import (BaseTestCase, |
375 | - SAMPLE_COMPUTER_INFO, SAMPLE_PHONE_INFO) |
376 | +from ubuntuone.controlpanel.gui.qt.tests import ( |
377 | + BaseTestCase, |
378 | + FakedConfirmDialog, |
379 | + FakedControlPanelBackend, |
380 | + SAMPLE_COMPUTER_INFO, |
381 | + SAMPLE_PHONE_INFO, |
382 | +) |
383 | + |
384 | +# Access to a protected member |
385 | +# Instance of 'ControlBackend' has no '_called' member |
386 | +# pylint: disable=W0212, E1103 |
387 | |
388 | |
389 | class DeviceWidgetTestCase(BaseTestCase): |
390 | @@ -31,6 +42,17 @@ |
391 | innerclass_ui = gui.device_ui |
392 | innerclass_name = "Ui_Form" |
393 | class_ui = gui.DeviceWidget |
394 | + backend = FakedControlPanelBackend() |
395 | + device_id = 'zaraza' |
396 | + kwargs = {'backend': backend, 'device_id': device_id} |
397 | + |
398 | + def test_has_id(self): |
399 | + """The device as an id, None by default.""" |
400 | + self.assertEqual(self.ui.id, self.device_id) |
401 | + |
402 | + def test_has_backend(self): |
403 | + """The device as a backend, None by default.""" |
404 | + self.assertIs(self.ui.backend, self.backend) |
405 | |
406 | def test_update_device_info(self): |
407 | """The widget is updated with the info.""" |
408 | @@ -48,8 +70,8 @@ |
409 | |
410 | def test_icon_name_from_type(self): |
411 | """Get the right icon name for a device type.""" |
412 | - self.assertIconMatchesType(gui.COMPUTER_TYPE, gui.COMPUTER_ICON) |
413 | - self.assertIconMatchesType(gui.PHONE_TYPE, gui.PHONE_ICON) |
414 | + self.assertIconMatchesType(gui.DEVICE_TYPE_COMPUTER, gui.COMPUTER_ICON) |
415 | + self.assertIconMatchesType(gui.DEVICE_TYPE_PHONE, gui.PHONE_ICON) |
416 | self.assertIconMatchesType("other random type", gui.COMPUTER_ICON) |
417 | |
418 | def _test_update_device_info_sets_right_icon(self, info): |
419 | @@ -77,3 +99,66 @@ |
420 | info = SAMPLE_PHONE_INFO |
421 | item = gui.get_device_for_list_widget(info) |
422 | self.assertEqual(item.text(), info["name"]) |
423 | + |
424 | + |
425 | +class RemoveDeviceTestCase(DeviceWidgetTestCase): |
426 | + """The test suite for the device deletion.""" |
427 | + |
428 | + @defer.inlineCallbacks |
429 | + def setUp(self): |
430 | + yield super(RemoveDeviceTestCase, self).setUp() |
431 | + FakedConfirmDialog.response = gui.NO |
432 | + FakedConfirmDialog.args = None |
433 | + FakedConfirmDialog.kwargs = None |
434 | + self.patch(gui.QtGui, 'QMessageBox', FakedConfirmDialog) |
435 | + |
436 | + def test_remove_device_opens_confirmation_dialog(self): |
437 | + """A confirmation dialog is opened when user clicks 'delete device'.""" |
438 | + self.ui.ui.remove_device_button.click() |
439 | + |
440 | + msg = gui.DEVICE_CONFIRM_REMOVE |
441 | + buttons = gui.YES | gui.NO |
442 | + self.assertEqual(FakedConfirmDialog.args, |
443 | + (self.ui, '', msg, buttons, gui.NO)) |
444 | + self.assertEqual(FakedConfirmDialog.kwargs, {}) |
445 | + |
446 | + def test_remove_device_does_not_remove_if_answer_is_no(self): |
447 | + """The device is not removed is answer is No.""" |
448 | + FakedConfirmDialog.response = gui.NO |
449 | + self.ui.removed.connect(self._set_called) |
450 | + self.ui.ui.remove_device_button.click() |
451 | + |
452 | + self.assertNotIn('remove_device', self.ui.backend._called) |
453 | + self.assertEqual(self._called, False) |
454 | + |
455 | + def test_remove_device_does_remove_if_answer_is_yes(self): |
456 | + """The device is removed is answer is Yes.""" |
457 | + FakedConfirmDialog.response = gui.YES |
458 | + self.ui.ui.remove_device_button.click() |
459 | + |
460 | + self.assert_backend_called('remove_device', device_id=self.device_id) |
461 | + |
462 | + @defer.inlineCallbacks |
463 | + def test_remove_device_emits_signal_when_removed(self): |
464 | + """The signal 'removed' is emitted when removed.""" |
465 | + d = defer.Deferred() |
466 | + |
467 | + def check(device_id): |
468 | + """Fire deferred when the device was removed.""" |
469 | + d.callback(device_id) |
470 | + |
471 | + FakedConfirmDialog.response = gui.YES |
472 | + self.ui.removed.connect(self._set_called) |
473 | + self.patch(self.ui.backend, 'remove_device', check) |
474 | + self.ui.ui.remove_device_button.click() |
475 | + |
476 | + yield d |
477 | + self.assertEqual(self._called, ((), {})) |
478 | + |
479 | + def test_remove_device_emits_signal_when_not_removed(self): |
480 | + """The signal 'removeCanceled' is emitted when user cancels removal.""" |
481 | + FakedConfirmDialog.response = gui.NO |
482 | + self.ui.removeCanceled.connect(self._set_called) |
483 | + self.ui.ui.remove_device_button.click() |
484 | + |
485 | + self.assertEqual(self._called, ((), {})) |
486 | |
487 | === modified file 'ubuntuone/controlpanel/gui/qt/tests/test_devices.py' |
488 | --- ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2011-07-11 11:19:09 +0000 |
489 | +++ ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2011-07-19 19:17:30 +0000 |
490 | @@ -22,6 +22,7 @@ |
491 | |
492 | from ubuntuone.controlpanel.gui.qt import devices as gui |
493 | from ubuntuone.controlpanel.gui.qt.tests import ( |
494 | + FakedConfirmDialog, |
495 | SAMPLE_DEVICES_INFO, |
496 | ) |
497 | from ubuntuone.controlpanel.gui.qt.tests.test_ubuntuonebin import ( |
498 | @@ -40,6 +41,7 @@ |
499 | def setUp(self): |
500 | yield super(DevicesPanelTestCase, self).setUp() |
501 | self.ui.backend.next_result = SAMPLE_DEVICES_INFO |
502 | + self.patch(gui.QtGui, 'QMessageBox', FakedConfirmDialog) |
503 | |
504 | def test_is_processing_while_asking_info(self): |
505 | """The ui is processing while the contents are loaded.""" |
506 | @@ -76,9 +78,10 @@ |
507 | local, remote = SAMPLE_DEVICES_INFO[0], SAMPLE_DEVICES_INFO[1:] |
508 | |
509 | self.assertEqual(self.ui.ui.local_device_box.count(), 1) |
510 | - local_device = self.ui.ui.local_device_box.itemAt(0) |
511 | - self.assertEqual(local_device.widget().ui.device_name_label.text(), |
512 | + local_device = self.ui.ui.local_device_box.itemAt(0).widget() |
513 | + self.assertEqual(local_device.ui.device_name_label.text(), |
514 | local['name']) |
515 | + self.assertEqual(local_device.id, local['device_id']) |
516 | |
517 | self.assertEqual(self.ui.ui.list_devices.count(), |
518 | len(remote)) |
519 | @@ -97,3 +100,12 @@ |
520 | self.ui.ui.manage_devices_button.click() |
521 | |
522 | self.assertEqual(self._called, ((gui.EDIT_DEVICES_LINK,), {})) |
523 | + |
524 | + def test_remove_device_widget_after_removal(self): |
525 | + """When a device widget was deleted, remove it from the UI.""" |
526 | + self.ui.process_info(SAMPLE_DEVICES_INFO) |
527 | + |
528 | + local_device = self.ui.ui.local_device_box.itemAt(0).widget() |
529 | + local_device.removed.emit() |
530 | + |
531 | + self.assertTrue(self.ui.ui.local_device_box.itemAt(0) is None) |
532 | |
533 | === modified file 'ubuntuone/controlpanel/gui/tests/__init__.py' |
534 | --- ubuntuone/controlpanel/gui/tests/__init__.py 2011-07-01 12:39:37 +0000 |
535 | +++ ubuntuone/controlpanel/gui/tests/__init__.py 2011-07-19 19:17:30 +0000 |
536 | @@ -21,7 +21,11 @@ |
537 | import os |
538 | |
539 | from ubuntuone.controlpanel import gui |
540 | -from ubuntuone.controlpanel.backend import ControlBackend |
541 | +from ubuntuone.controlpanel.backend import ( |
542 | + ControlBackend, |
543 | + DEVICE_TYPE_COMPUTER, |
544 | + DEVICE_TYPE_PHONE, |
545 | +) |
546 | from ubuntuone.controlpanel.tests import USER_HOME, ROOT_PATH |
547 | |
548 | # Attribute 'yyy' defined outside __init__, access to a protected member |
549 | @@ -95,22 +99,27 @@ |
550 | FAKE_VOLUMES_MINIMAL_INFO = [(u'', u'147852369', [ROOT, MUSIC_FOLDER])] |
551 | |
552 | FAKE_DEVICE_INFO = { |
553 | - 'device_id': '1258-6854', 'device_name': 'Baz', 'device_type': 'Computer', |
554 | + 'device_id': '1258-6854', 'device_name': 'Baz', |
555 | + 'device_type': DEVICE_TYPE_COMPUTER, |
556 | 'is_local': 'True', 'configurable': 'True', 'limit_bandwidth': 'True', |
557 | 'max_upload_speed': '1000', 'max_download_speed': '72548', |
558 | 'show_all_notifications': 'True', |
559 | } |
560 | |
561 | FAKE_DEVICES_INFO = [ |
562 | - {'device_id': '0', 'name': 'Ubuntu One @ Foo', 'type': 'Computer', |
563 | - 'is_local': '', 'configurable': ''}, |
564 | - {'device_id': '1', 'name': 'Ubuntu One @ Bar', 'type': 'Phone', |
565 | - 'is_local': '', 'configurable': ''}, |
566 | - {'device_id': '2', 'name': 'Ubuntu One @ Z', 'type': 'Computer', |
567 | + {'device_id': '0', 'name': 'Ubuntu One @ Foo', |
568 | + 'type': DEVICE_TYPE_COMPUTER, |
569 | + 'is_local': '', 'configurable': ''}, |
570 | + {'device_id': '1', 'name': 'Ubuntu One @ Bar', |
571 | + 'type': DEVICE_TYPE_PHONE, |
572 | + 'is_local': '', 'configurable': ''}, |
573 | + {'device_id': '2', 'name': 'Ubuntu One @ Z', |
574 | + 'type': DEVICE_TYPE_COMPUTER, |
575 | 'is_local': '', 'configurable': 'True', 'limit_bandwidth': '', |
576 | 'max_upload_speed': '0', 'max_download_speed': '0', |
577 | 'show_all_notifications': ''}, |
578 | - {'device_id': '1258-6854', 'name': 'Ubuntu One @ Baz', 'type': 'Computer', |
579 | + {'device_id': '1258-6854', 'name': 'Ubuntu One @ Baz', |
580 | + 'type': DEVICE_TYPE_COMPUTER, |
581 | 'is_local': 'True', 'configurable': 'True', 'limit_bandwidth': 'True', |
582 | 'max_upload_speed': '1000', 'max_download_speed': '72548', |
583 | 'show_all_notifications': 'True'}, # local |
+1