Merge lp:~nataliabidart/ubuntuone-control-panel/confirm-before-delete into lp:ubuntuone-control-panel
- confirm-before-delete
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Natalia Bidart | ||||
Approved revision: | 54 | ||||
Merged at revision: | 54 | ||||
Proposed branch: | lp:~nataliabidart/ubuntuone-control-panel/confirm-before-delete | ||||
Merge into: | lp:ubuntuone-control-panel | ||||
Diff against target: |
704 lines (+168/-90) 6 files modified
data/device.ui (+9/-32) data/management.ui (+1/-1) ubuntuone/controlpanel/gtk/gui.py (+49/-32) ubuntuone/controlpanel/gtk/tests/__init__.py (+24/-6) ubuntuone/controlpanel/gtk/tests/test_gui.py (+83/-19) ubuntuone/controlpanel/tests/__init__.py (+2/-0) |
||||
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-control-panel/confirm-before-delete | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Roman Yepishev (community) | fieldtest | Approve | |
Review via email:
|
Commit message
- When removing a device, a confirmation dialog is raised (LP: #706888).
Description of the change
To post a comment you must log in.
- 54. By Natalia Bidart
-
Spacing to devices.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Roman Yepishev (rye) wrote : | # |
To clarify possible confusion about my review here's a true and non-joking summary:
I ran this branch, i clicked on delete. If I confirm the removal then device gets removed. If I decline the removal then device is not removed. Result: Approve during fieldtest.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'data/device.ui' | |||
2 | --- data/device.ui 2011-01-24 13:40:10 +0000 | |||
3 | +++ data/device.ui 2011-01-25 12:57:15 +0000 | |||
4 | @@ -12,65 +12,53 @@ | |||
5 | 12 | </object> | 12 | </object> |
6 | 13 | <object class="GtkVBox" id="itself"> | 13 | <object class="GtkVBox" id="itself"> |
7 | 14 | <property name="visible">True</property> | 14 | <property name="visible">True</property> |
9 | 15 | <property name="can_focus">False</property> | 15 | <property name="border_width">10</property> |
10 | 16 | <property name="spacing">5</property> | 16 | <property name="spacing">5</property> |
11 | 17 | <child> | 17 | <child> |
12 | 18 | <object class="GtkHBox" id="hbox1"> | 18 | <object class="GtkHBox" id="hbox1"> |
13 | 19 | <property name="visible">True</property> | 19 | <property name="visible">True</property> |
16 | 20 | <property name="can_focus">False</property> | 20 | <property name="spacing">10</property> |
15 | 21 | <property name="spacing">15</property> | ||
17 | 22 | <child> | 21 | <child> |
18 | 23 | <object class="GtkVBox" id="vbox1"> | 22 | <object class="GtkVBox" id="vbox1"> |
19 | 24 | <property name="visible">True</property> | 23 | <property name="visible">True</property> |
20 | 25 | <property name="can_focus">False</property> | ||
21 | 26 | <property name="spacing">5</property> | 24 | <property name="spacing">5</property> |
22 | 27 | <child> | 25 | <child> |
23 | 28 | <object class="GtkHBox" id="hbox2"> | 26 | <object class="GtkHBox" id="hbox2"> |
24 | 29 | <property name="visible">True</property> | 27 | <property name="visible">True</property> |
25 | 30 | <property name="can_focus">False</property> | ||
26 | 31 | <child> | 28 | <child> |
27 | 32 | <object class="GtkImage" id="device_type"> | 29 | <object class="GtkImage" id="device_type"> |
28 | 33 | <property name="visible">True</property> | 30 | <property name="visible">True</property> |
29 | 34 | <property name="can_focus">False</property> | ||
30 | 35 | <property name="icon_name">computer</property> | 31 | <property name="icon_name">computer</property> |
31 | 36 | </object> | 32 | </object> |
32 | 37 | <packing> | 33 | <packing> |
33 | 38 | <property name="expand">False</property> | 34 | <property name="expand">False</property> |
34 | 39 | <property name="fill">True</property> | ||
35 | 40 | <property name="position">0</property> | 35 | <property name="position">0</property> |
36 | 41 | </packing> | 36 | </packing> |
37 | 42 | </child> | 37 | </child> |
38 | 43 | <child> | 38 | <child> |
39 | 44 | <object class="GtkLabel" id="device_name"> | 39 | <object class="GtkLabel" id="device_name"> |
40 | 45 | <property name="visible">True</property> | 40 | <property name="visible">True</property> |
41 | 46 | <property name="can_focus">False</property> | ||
42 | 47 | <property name="xalign">0</property> | 41 | <property name="xalign">0</property> |
43 | 48 | <property name="xpad">5</property> | 42 | <property name="xpad">5</property> |
44 | 49 | <property name="label">My Laptop</property> | 43 | <property name="label">My Laptop</property> |
45 | 50 | <property name="wrap">True</property> | 44 | <property name="wrap">True</property> |
46 | 51 | </object> | 45 | </object> |
47 | 52 | <packing> | 46 | <packing> |
48 | 53 | <property name="expand">True</property> | ||
49 | 54 | <property name="fill">True</property> | ||
50 | 55 | <property name="position">1</property> | 47 | <property name="position">1</property> |
51 | 56 | </packing> | 48 | </packing> |
52 | 57 | </child> | 49 | </child> |
53 | 58 | </object> | 50 | </object> |
54 | 59 | <packing> | 51 | <packing> |
55 | 60 | <property name="expand">True</property> | ||
56 | 61 | <property name="fill">True</property> | ||
57 | 62 | <property name="position">0</property> | 52 | <property name="position">0</property> |
58 | 63 | </packing> | 53 | </packing> |
59 | 64 | </child> | 54 | </child> |
60 | 65 | <child> | 55 | <child> |
61 | 66 | <object class="GtkAlignment" id="alignment1"> | 56 | <object class="GtkAlignment" id="alignment1"> |
62 | 67 | <property name="visible">True</property> | 57 | <property name="visible">True</property> |
63 | 68 | <property name="can_focus">False</property> | ||
64 | 69 | <property name="left_padding">25</property> | 58 | <property name="left_padding">25</property> |
65 | 70 | <child> | 59 | <child> |
66 | 71 | <object class="GtkTable" id="throttling"> | 60 | <object class="GtkTable" id="throttling"> |
67 | 72 | <property name="visible">True</property> | 61 | <property name="visible">True</property> |
68 | 73 | <property name="can_focus">False</property> | ||
69 | 74 | <property name="n_rows">3</property> | 62 | <property name="n_rows">3</property> |
70 | 75 | <property name="n_columns">2</property> | 63 | <property name="n_columns">2</property> |
71 | 76 | <property name="column_spacing">3</property> | 64 | <property name="column_spacing">3</property> |
72 | @@ -81,15 +69,13 @@ | |||
73 | 81 | <property name="visible">True</property> | 69 | <property name="visible">True</property> |
74 | 82 | <property name="can_focus">True</property> | 70 | <property name="can_focus">True</property> |
75 | 83 | <property name="receives_default">False</property> | 71 | <property name="receives_default">False</property> |
76 | 84 | <property name="use_action_appearance">False</property> | ||
77 | 85 | <property name="draw_indicator">True</property> | 72 | <property name="draw_indicator">True</property> |
79 | 86 | <signal name="toggled" handler="on_limit_bandwidth_toggled" swapped="no"/> | 73 | <signal name="toggled" handler="on_limit_bandwidth_toggled"/> |
80 | 87 | </object> | 74 | </object> |
81 | 88 | </child> | 75 | </child> |
82 | 89 | <child> | 76 | <child> |
83 | 90 | <object class="GtkLabel" id="max_upload_speed_label"> | 77 | <object class="GtkLabel" id="max_upload_speed_label"> |
84 | 91 | <property name="visible">True</property> | 78 | <property name="visible">True</property> |
85 | 92 | <property name="can_focus">False</property> | ||
86 | 93 | <property name="xalign">1</property> | 79 | <property name="xalign">1</property> |
87 | 94 | <property name="xpad">5</property> | 80 | <property name="xpad">5</property> |
88 | 95 | <property name="label" translatable="yes">Max upload speed (KiB/s)</property> | 81 | <property name="label" translatable="yes">Max upload speed (KiB/s)</property> |
89 | @@ -103,7 +89,6 @@ | |||
90 | 103 | <child> | 89 | <child> |
91 | 104 | <object class="GtkLabel" id="max_download_speed_label"> | 90 | <object class="GtkLabel" id="max_download_speed_label"> |
92 | 105 | <property name="visible">True</property> | 91 | <property name="visible">True</property> |
93 | 106 | <property name="can_focus">False</property> | ||
94 | 107 | <property name="xalign">1</property> | 92 | <property name="xalign">1</property> |
95 | 108 | <property name="xpad">5</property> | 93 | <property name="xpad">5</property> |
96 | 109 | <property name="label" translatable="yes">Max download speed (KiB/s)</property> | 94 | <property name="label" translatable="yes">Max download speed (KiB/s)</property> |
97 | @@ -121,7 +106,7 @@ | |||
98 | 121 | <property name="activates_default">True</property> | 106 | <property name="activates_default">True</property> |
99 | 122 | <property name="invisible_char_set">True</property> | 107 | <property name="invisible_char_set">True</property> |
100 | 123 | <property name="adjustment">adjustment1</property> | 108 | <property name="adjustment">adjustment1</property> |
102 | 124 | <signal name="value-changed" handler="on_max_upload_speed_value_changed" swapped="no"/> | 109 | <signal name="value_changed" handler="on_max_upload_speed_value_changed"/> |
103 | 125 | </object> | 110 | </object> |
104 | 126 | <packing> | 111 | <packing> |
105 | 127 | <property name="left_attach">1</property> | 112 | <property name="left_attach">1</property> |
106 | @@ -140,7 +125,7 @@ | |||
107 | 140 | <property name="activates_default">True</property> | 125 | <property name="activates_default">True</property> |
108 | 141 | <property name="invisible_char_set">True</property> | 126 | <property name="invisible_char_set">True</property> |
109 | 142 | <property name="adjustment">adjustment2</property> | 127 | <property name="adjustment">adjustment2</property> |
111 | 143 | <signal name="value-changed" handler="on_max_download_speed_value_changed" swapped="no"/> | 128 | <signal name="value_changed" handler="on_max_download_speed_value_changed"/> |
112 | 144 | </object> | 129 | </object> |
113 | 145 | <packing> | 130 | <packing> |
114 | 146 | <property name="left_attach">1</property> | 131 | <property name="left_attach">1</property> |
115 | @@ -157,31 +142,28 @@ | |||
116 | 157 | </object> | 142 | </object> |
117 | 158 | <packing> | 143 | <packing> |
118 | 159 | <property name="expand">False</property> | 144 | <property name="expand">False</property> |
119 | 160 | <property name="fill">True</property> | ||
120 | 161 | <property name="position">1</property> | 145 | <property name="position">1</property> |
121 | 162 | </packing> | 146 | </packing> |
122 | 163 | </child> | 147 | </child> |
123 | 164 | </object> | 148 | </object> |
124 | 165 | <packing> | 149 | <packing> |
125 | 166 | <property name="expand">False</property> | 150 | <property name="expand">False</property> |
126 | 167 | <property name="fill">True</property> | ||
127 | 168 | <property name="position">0</property> | 151 | <property name="position">0</property> |
128 | 169 | </packing> | 152 | </packing> |
129 | 170 | </child> | 153 | </child> |
130 | 171 | <child> | 154 | <child> |
131 | 172 | <object class="GtkVButtonBox" id="vbuttonbox1"> | 155 | <object class="GtkVButtonBox" id="vbuttonbox1"> |
132 | 173 | <property name="visible">True</property> | 156 | <property name="visible">True</property> |
133 | 174 | <property name="can_focus">False</property> | ||
134 | 175 | <property name="layout_style">center</property> | 157 | <property name="layout_style">center</property> |
135 | 176 | <child> | 158 | <child> |
136 | 177 | <object class="GtkButton" id="remove"> | 159 | <object class="GtkButton" id="remove"> |
138 | 178 | <property name="label" translatable="yes">Remove from my personal cloud</property> | 160 | <property name="label">gtk-remove</property> |
139 | 179 | <property name="visible">True</property> | 161 | <property name="visible">True</property> |
140 | 180 | <property name="can_focus">True</property> | 162 | <property name="can_focus">True</property> |
141 | 181 | <property name="receives_default">True</property> | 163 | <property name="receives_default">True</property> |
145 | 182 | <property name="use_action_appearance">False</property> | 164 | <property name="use_stock">True</property> |
146 | 183 | <signal name="activate" handler="on_remove_clicked" swapped="no"/> | 165 | <signal name="clicked" handler="on_remove_clicked"/> |
147 | 184 | <signal name="clicked" handler="on_remove_clicked" swapped="no"/> | 166 | <signal name="activate" handler="on_remove_clicked"/> |
148 | 185 | </object> | 167 | </object> |
149 | 186 | <packing> | 168 | <packing> |
150 | 187 | <property name="expand">False</property> | 169 | <property name="expand">False</property> |
151 | @@ -192,7 +174,6 @@ | |||
152 | 192 | </object> | 174 | </object> |
153 | 193 | <packing> | 175 | <packing> |
154 | 194 | <property name="expand">False</property> | 176 | <property name="expand">False</property> |
155 | 195 | <property name="fill">True</property> | ||
156 | 196 | <property name="pack_type">end</property> | 177 | <property name="pack_type">end</property> |
157 | 197 | <property name="position">1</property> | 178 | <property name="position">1</property> |
158 | 198 | </packing> | 179 | </packing> |
159 | @@ -200,18 +181,14 @@ | |||
160 | 200 | </object> | 181 | </object> |
161 | 201 | <packing> | 182 | <packing> |
162 | 202 | <property name="expand">False</property> | 183 | <property name="expand">False</property> |
163 | 203 | <property name="fill">True</property> | ||
164 | 204 | <property name="position">0</property> | 184 | <property name="position">0</property> |
165 | 205 | </packing> | 185 | </packing> |
166 | 206 | </child> | 186 | </child> |
167 | 207 | <child> | 187 | <child> |
168 | 208 | <object class="GtkLabel" id="warning_label"> | 188 | <object class="GtkLabel" id="warning_label"> |
169 | 209 | <property name="visible">True</property> | 189 | <property name="visible">True</property> |
170 | 210 | <property name="can_focus">False</property> | ||
171 | 211 | </object> | 190 | </object> |
172 | 212 | <packing> | 191 | <packing> |
173 | 213 | <property name="expand">True</property> | ||
174 | 214 | <property name="fill">True</property> | ||
175 | 215 | <property name="position">1</property> | 192 | <property name="position">1</property> |
176 | 216 | </packing> | 193 | </packing> |
177 | 217 | </child> | 194 | </child> |
178 | 218 | 195 | ||
179 | === modified file 'data/management.ui' | |||
180 | --- data/management.ui 2011-01-21 21:43:01 +0000 | |||
181 | +++ data/management.ui 2011-01-25 12:57:15 +0000 | |||
182 | @@ -98,7 +98,7 @@ | |||
183 | 98 | </child> | 98 | </child> |
184 | 99 | <child> | 99 | <child> |
185 | 100 | <object class="GtkRadioButton" id="volumes_button"> | 100 | <object class="GtkRadioButton" id="volumes_button"> |
187 | 101 | <property name="label" translatable="yes">Cloud Storage</property> | 101 | <property name="label" translatable="yes">Cloud Folders</property> |
188 | 102 | <property name="visible">True</property> | 102 | <property name="visible">True</property> |
189 | 103 | <property name="can_focus">True</property> | 103 | <property name="can_focus">True</property> |
190 | 104 | <property name="receives_default">False</property> | 104 | <property name="receives_default">False</property> |
191 | 105 | 105 | ||
192 | === modified file 'ubuntuone/controlpanel/gtk/gui.py' | |||
193 | --- ubuntuone/controlpanel/gtk/gui.py 2011-01-24 14:09:48 +0000 | |||
194 | +++ ubuntuone/controlpanel/gtk/gui.py 2011-01-25 12:57:15 +0000 | |||
195 | @@ -182,7 +182,7 @@ | |||
196 | 182 | self.connect('delete-event', lambda w, e: gtk.main_quit()) | 182 | self.connect('delete-event', lambda w, e: gtk.main_quit()) |
197 | 183 | self.show() | 183 | self.show() |
198 | 184 | 184 | ||
200 | 185 | self.control_panel = ControlPanel(window_id=self.window.xid) | 185 | self.control_panel = ControlPanel(main_window=self) |
201 | 186 | self.add(self.control_panel) | 186 | self.add(self.control_panel) |
202 | 187 | 187 | ||
203 | 188 | logger.info('Starting %s pointing at panel: %r.', | 188 | logger.info('Starting %s pointing at panel: %r.', |
204 | @@ -209,17 +209,17 @@ | |||
205 | 209 | 209 | ||
206 | 210 | # should not be any larger than 736x525 | 210 | # should not be any larger than 736x525 |
207 | 211 | 211 | ||
209 | 212 | def __init__(self, window_id=0): | 212 | def __init__(self, main_window): |
210 | 213 | gtk.Notebook.__init__(self) | 213 | gtk.Notebook.__init__(self) |
212 | 214 | self._window_id = window_id | 214 | self.main_window = main_window |
213 | 215 | 215 | ||
214 | 216 | self.set_show_tabs(False) | 216 | self.set_show_tabs(False) |
215 | 217 | self.set_show_border(False) | 217 | self.set_show_border(False) |
216 | 218 | 218 | ||
218 | 219 | self.overview = OverviewPanel(window_id=self._window_id) | 219 | self.overview = OverviewPanel(main_window=main_window) |
219 | 220 | self.insert_page(self.overview, position=0) | 220 | self.insert_page(self.overview, position=0) |
220 | 221 | 221 | ||
222 | 222 | self.management = ManagementPanel() | 222 | self.management = ManagementPanel(main_window=main_window) |
223 | 223 | self.insert_page(self.management, position=1) | 223 | self.insert_page(self.management, position=1) |
224 | 224 | 224 | ||
225 | 225 | self.overview.connect('credentials-found', | 225 | self.overview.connect('credentials-found', |
226 | @@ -320,7 +320,7 @@ | |||
227 | 320 | CONNECT = _('Connect to Ubuntu One') | 320 | CONNECT = _('Connect to Ubuntu One') |
228 | 321 | BULLET = '<span foreground="%s">✔</span>' % ORANGE | 321 | BULLET = '<span foreground="%s">✔</span>' % ORANGE |
229 | 322 | 322 | ||
231 | 323 | def __init__(self, messages=None, window_id=0): | 323 | def __init__(self, main_window, messages=None): |
232 | 324 | GreyableBin.__init__(self) | 324 | GreyableBin.__init__(self) |
233 | 325 | ControlPanelMixin.__init__(self, filename='overview.ui') | 325 | ControlPanelMixin.__init__(self, filename='overview.ui') |
234 | 326 | self.add(self.itself) | 326 | self.add(self.itself) |
235 | @@ -332,9 +332,9 @@ | |||
236 | 332 | self.join_now_button.get_child().set_markup(label) | 332 | self.join_now_button.get_child().set_markup(label) |
237 | 333 | self.connect_button.set_uri(self.CONNECT) | 333 | self.connect_button.set_uri(self.CONNECT) |
238 | 334 | 334 | ||
239 | 335 | self.main_window = main_window | ||
240 | 335 | self._credentials_are_new = False | 336 | self._credentials_are_new = False |
241 | 336 | self._messages = messages | 337 | self._messages = messages |
242 | 337 | self._window_id = window_id | ||
243 | 338 | self._build_messages() | 338 | self._build_messages() |
244 | 339 | self.show() | 339 | self.show() |
245 | 340 | 340 | ||
246 | @@ -404,7 +404,7 @@ | |||
247 | 404 | def on_join_now_button_clicked(self, *a, **kw): | 404 | def on_join_now_button_clicked(self, *a, **kw): |
248 | 405 | """User wants to join now.""" | 405 | """User wants to join now.""" |
249 | 406 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, | 406 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, |
251 | 407 | WINDOW_ID_KEY: str(self._window_id), | 407 | WINDOW_ID_KEY: str(self.main_window.window.xid), |
252 | 408 | PING_URL_KEY: U1_PING_URL} | 408 | PING_URL_KEY: U1_PING_URL} |
253 | 409 | self.sso_backend.register(U1_APP_NAME, settings, | 409 | self.sso_backend.register(U1_APP_NAME, settings, |
254 | 410 | reply_handler=NO_OP, error_handler=error_handler) | 410 | reply_handler=NO_OP, error_handler=error_handler) |
255 | @@ -414,7 +414,7 @@ | |||
256 | 414 | def on_connect_button_clicked(self, *a, **kw): | 414 | def on_connect_button_clicked(self, *a, **kw): |
257 | 415 | """User wants to connect now.""" | 415 | """User wants to connect now.""" |
258 | 416 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, | 416 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, |
260 | 417 | WINDOW_ID_KEY: str(self._window_id), | 417 | WINDOW_ID_KEY: str(self.main_window.window.xid), |
261 | 418 | PING_URL_KEY: U1_PING_URL} | 418 | PING_URL_KEY: U1_PING_URL} |
262 | 419 | self.sso_backend.login(U1_APP_NAME, settings, | 419 | self.sso_backend.login(U1_APP_NAME, settings, |
263 | 420 | reply_handler=NO_OP, error_handler=error_handler) | 420 | reply_handler=NO_OP, error_handler=error_handler) |
264 | @@ -476,7 +476,7 @@ | |||
265 | 476 | TYPE = _('Account type') | 476 | TYPE = _('Account type') |
266 | 477 | EMAIL = _('Email address') | 477 | EMAIL = _('Email address') |
267 | 478 | 478 | ||
269 | 479 | def __init__(self): | 479 | def __init__(self, main_window=None): |
270 | 480 | UbuntuOneBin.__init__(self) | 480 | UbuntuOneBin.__init__(self) |
271 | 481 | ControlPanelMixin.__init__(self, filename='dashboard.ui') | 481 | ControlPanelMixin.__init__(self, filename='dashboard.ui') |
272 | 482 | self.add(self.itself) | 482 | self.add(self.itself) |
273 | @@ -512,10 +512,10 @@ | |||
274 | 512 | class VolumesPanel(UbuntuOneBin, ControlPanelMixin): | 512 | class VolumesPanel(UbuntuOneBin, ControlPanelMixin): |
275 | 513 | """The volumes panel.""" | 513 | """The volumes panel.""" |
276 | 514 | 514 | ||
281 | 515 | TITLE = _('Select which folders from your cloud you want synchronized ' | 515 | TITLE = _('Select the folders from your cloud that you want synchronized ' |
282 | 516 | 'on this device.') | 516 | 'in this device.') |
283 | 517 | MY_FOLDERS = _('Mine') | 517 | MY_FOLDERS = _('My folders') |
284 | 518 | ALWAYS_SUBSCRIBED = _('Always in your personal cloud storage!') | 518 | ALWAYS_SUBSCRIBED = _('Always in sync!') |
285 | 519 | FREE_SPACE = _('%(free_space)s available storage') | 519 | FREE_SPACE = _('%(free_space)s available storage') |
286 | 520 | CONTACT_ICON_NAME = 'system-users' | 520 | CONTACT_ICON_NAME = 'system-users' |
287 | 521 | FOLDER_ICON_NAME = 'folder' | 521 | FOLDER_ICON_NAME = 'folder' |
288 | @@ -525,7 +525,7 @@ | |||
289 | 525 | ROOT = '%s - <span foreground="%s" font_size="small">%s</span>' | 525 | ROOT = '%s - <span foreground="%s" font_size="small">%s</span>' |
290 | 526 | NO_VOLUMES = _('No folders to show.') | 526 | NO_VOLUMES = _('No folders to show.') |
291 | 527 | 527 | ||
293 | 528 | def __init__(self): | 528 | def __init__(self, main_window=None): |
294 | 529 | UbuntuOneBin.__init__(self) | 529 | UbuntuOneBin.__init__(self) |
295 | 530 | ControlPanelMixin.__init__(self, filename='volumes.ui') | 530 | ControlPanelMixin.__init__(self, filename='volumes.ui') |
296 | 531 | self.add(self.itself) | 531 | self.add(self.itself) |
297 | @@ -639,7 +639,7 @@ | |||
298 | 639 | 639 | ||
299 | 640 | TITLE = _('Manage permissions for shares made to other users.') | 640 | TITLE = _('Manage permissions for shares made to other users.') |
300 | 641 | 641 | ||
302 | 642 | def __init__(self): | 642 | def __init__(self, main_window=None): |
303 | 643 | UbuntuOneBin.__init__(self) | 643 | UbuntuOneBin.__init__(self) |
304 | 644 | ControlPanelMixin.__init__(self) | 644 | ControlPanelMixin.__init__(self) |
305 | 645 | self.show_all() | 645 | self.show_all() |
306 | @@ -652,11 +652,13 @@ | |||
307 | 652 | DEVICE_CHANGE_ERROR = _('The settings could not be changed,\n' | 652 | DEVICE_CHANGE_ERROR = _('The settings could not be changed,\n' |
308 | 653 | 'previous values were restored.') | 653 | 'previous values were restored.') |
309 | 654 | DEVICE_REMOVAL_ERROR = _('The device could not be removed.') | 654 | DEVICE_REMOVAL_ERROR = _('The device could not be removed.') |
310 | 655 | REMOVABLE_PREFIX = 'Ubuntu One @ ' | ||
311 | 655 | 656 | ||
313 | 656 | def __init__(self): | 657 | def __init__(self, confirm_remove_dialog=None): |
314 | 657 | gtk.EventBox.__init__(self) | 658 | gtk.EventBox.__init__(self) |
315 | 658 | ControlPanelMixin.__init__(self, filename='device.ui') | 659 | ControlPanelMixin.__init__(self, filename='device.ui') |
316 | 659 | 660 | ||
317 | 661 | self.confirm_dialog = confirm_remove_dialog | ||
318 | 660 | self._updating = False | 662 | self._updating = False |
319 | 661 | self._last_settings = {} | 663 | self._last_settings = {} |
320 | 662 | self.id = None | 664 | self.id = None |
321 | @@ -714,9 +716,15 @@ | |||
322 | 714 | 716 | ||
323 | 715 | def on_remove_clicked(self, widget): | 717 | def on_remove_clicked(self, widget): |
324 | 716 | """Remove button was clicked or activated.""" | 718 | """Remove button was clicked or activated.""" |
328 | 717 | self.backend.remove_device(self.id, | 719 | response = gtk.RESPONSE_YES |
329 | 718 | reply_handler=NO_OP, error_handler=error_handler) | 720 | if self.confirm_dialog is not None: |
330 | 719 | self.set_sensitive(False) | 721 | response = self.confirm_dialog.run() |
331 | 722 | self.confirm_dialog.hide() | ||
332 | 723 | |||
333 | 724 | if response == gtk.RESPONSE_YES: | ||
334 | 725 | self.backend.remove_device(self.id, | ||
335 | 726 | reply_handler=NO_OP, error_handler=error_handler) | ||
336 | 727 | self.set_sensitive(False) | ||
337 | 720 | 728 | ||
338 | 721 | @_block_signals | 729 | @_block_signals |
339 | 722 | def update(self, **kwargs): | 730 | def update(self, **kwargs): |
340 | @@ -738,8 +746,9 @@ | |||
341 | 738 | self.id = kwargs['device_id'] | 746 | self.id = kwargs['device_id'] |
342 | 739 | 747 | ||
343 | 740 | if 'device_name' in kwargs: | 748 | if 'device_name' in kwargs: |
346 | 741 | name = '<span font_size="large"><b>%s</b></span>' | 749 | name = kwargs['device_name'].replace(self.REMOVABLE_PREFIX, '') |
347 | 742 | self.device_name.set_markup(name % kwargs['device_name']) | 750 | name = '<span font_size="large"><b>%s</b></span>' % name |
348 | 751 | self.device_name.set_markup(name) | ||
349 | 743 | 752 | ||
350 | 744 | if 'device_type' in kwargs: | 753 | if 'device_type' in kwargs: |
351 | 745 | dtype = kwargs['device_type'] | 754 | dtype = kwargs['device_type'] |
352 | @@ -818,16 +827,24 @@ | |||
353 | 818 | class DevicesPanel(UbuntuOneBin, ControlPanelMixin): | 827 | class DevicesPanel(UbuntuOneBin, ControlPanelMixin): |
354 | 819 | """The devices panel.""" | 828 | """The devices panel.""" |
355 | 820 | 829 | ||
357 | 821 | TITLE = _('The devices in your personal cloud are listed below.') | 830 | TITLE = _('The devices synced with your personal cloud are listed below.') |
358 | 822 | NO_DEVICES = _('No devices to show.') | 831 | NO_DEVICES = _('No devices to show.') |
359 | 832 | CONFIRM_REMOVE = _('Are you sure you want to remove this device ' | ||
360 | 833 | 'from Ubuntu One?') | ||
361 | 823 | 834 | ||
363 | 824 | def __init__(self): | 835 | def __init__(self, main_window=None): |
364 | 825 | UbuntuOneBin.__init__(self) | 836 | UbuntuOneBin.__init__(self) |
365 | 826 | ControlPanelMixin.__init__(self, filename='devices.ui') | 837 | ControlPanelMixin.__init__(self, filename='devices.ui') |
366 | 827 | self.add(self.itself) | 838 | self.add(self.itself) |
367 | 828 | self.show() | 839 | self.show() |
368 | 829 | 840 | ||
369 | 830 | self._devices = {} | 841 | self._devices = {} |
370 | 842 | kw = dict(parent=main_window, | ||
371 | 843 | flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, | ||
372 | 844 | type=gtk.MESSAGE_WARNING, | ||
373 | 845 | buttons=gtk.BUTTONS_YES_NO, | ||
374 | 846 | message_format=self.CONFIRM_REMOVE) | ||
375 | 847 | self.confirm_remove_dialog = gtk.MessageDialog(**kw) | ||
376 | 831 | 848 | ||
377 | 832 | self.backend.connect_to_signal('DevicesInfoReady', | 849 | self.backend.connect_to_signal('DevicesInfoReady', |
378 | 833 | self.on_devices_info_ready) | 850 | self.on_devices_info_ready) |
379 | @@ -849,7 +866,7 @@ | |||
380 | 849 | 866 | ||
381 | 850 | odd_row_color = self.message.style.bg[gtk.STATE_NORMAL] | 867 | odd_row_color = self.message.style.bg[gtk.STATE_NORMAL] |
382 | 851 | for i, device_info in enumerate(info): | 868 | for i, device_info in enumerate(info): |
384 | 852 | device = Device() | 869 | device = Device(confirm_remove_dialog=self.confirm_remove_dialog) |
385 | 853 | device_info['device_name'] = device_info.pop('name', '') | 870 | device_info['device_name'] = device_info.pop('name', '') |
386 | 854 | device_info['device_type'] = device_info.pop('type', | 871 | device_info['device_type'] = device_info.pop('type', |
387 | 855 | DEVICE_TYPE_COMPUTER) | 872 | DEVICE_TYPE_COMPUTER) |
388 | @@ -1086,7 +1103,7 @@ | |||
389 | 1086 | CONTACTS = _('Contacts (Evolution)') | 1103 | CONTACTS = _('Contacts (Evolution)') |
390 | 1087 | NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.') | 1104 | NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.') |
391 | 1088 | 1105 | ||
393 | 1089 | def __init__(self): | 1106 | def __init__(self, main_window=None): |
394 | 1090 | UbuntuOneBin.__init__(self) | 1107 | UbuntuOneBin.__init__(self) |
395 | 1091 | ControlPanelMixin.__init__(self, filename='services.ui') | 1108 | ControlPanelMixin.__init__(self, filename='services.ui') |
396 | 1092 | self.add(self.itself) | 1109 | self.add(self.itself) |
397 | @@ -1333,7 +1350,7 @@ | |||
398 | 1333 | 1350 | ||
399 | 1334 | QUOTA_LABEL = _('%(used)s used of %(total)s (%(percentage).1f%%)') | 1351 | QUOTA_LABEL = _('%(used)s used of %(total)s (%(percentage).1f%%)') |
400 | 1335 | 1352 | ||
402 | 1336 | def __init__(self): | 1353 | def __init__(self, main_window=None): |
403 | 1337 | gtk.VBox.__init__(self) | 1354 | gtk.VBox.__init__(self) |
404 | 1338 | ControlPanelMixin.__init__(self, filename='management.ui') | 1355 | ControlPanelMixin.__init__(self, filename='management.ui') |
405 | 1339 | self.add(self.itself) | 1356 | self.add(self.itself) |
406 | @@ -1353,11 +1370,11 @@ | |||
407 | 1353 | self.status_label = FileSyncStatus() | 1370 | self.status_label = FileSyncStatus() |
408 | 1354 | self.status_box.pack_end(self.status_label, expand=False) | 1371 | self.status_box.pack_end(self.status_label, expand=False) |
409 | 1355 | 1372 | ||
415 | 1356 | self.dashboard = DashboardPanel() | 1373 | self.dashboard = DashboardPanel(main_window=main_window) |
416 | 1357 | self.volumes = VolumesPanel() | 1374 | self.volumes = VolumesPanel(main_window=main_window) |
417 | 1358 | self.shares = SharesPanel() | 1375 | self.shares = SharesPanel(main_window=main_window) |
418 | 1359 | self.devices = DevicesPanel() | 1376 | self.devices = DevicesPanel(main_window=main_window) |
419 | 1360 | self.services = ServicesPanel() | 1377 | self.services = ServicesPanel(main_window=main_window) |
420 | 1361 | 1378 | ||
421 | 1362 | cb = lambda button, page_num: self.notebook.set_current_page(page_num) | 1379 | cb = lambda button, page_num: self.notebook.set_current_page(page_num) |
422 | 1363 | self.tabs = (u'dashboard', u'volumes', u'shares', | 1380 | self.tabs = (u'dashboard', u'volumes', u'shares', |
423 | 1364 | 1381 | ||
424 | === modified file 'ubuntuone/controlpanel/gtk/tests/__init__.py' | |||
425 | --- ubuntuone/controlpanel/gtk/tests/__init__.py 2011-01-21 02:29:20 +0000 | |||
426 | +++ ubuntuone/controlpanel/gtk/tests/__init__.py 2011-01-25 12:57:15 +0000 | |||
427 | @@ -66,14 +66,14 @@ | |||
428 | 66 | } | 66 | } |
429 | 67 | 67 | ||
430 | 68 | FAKE_DEVICES_INFO = [ | 68 | FAKE_DEVICES_INFO = [ |
436 | 69 | {'device_id': '0', 'name': 'Foo', 'type': 'Computer', | 69 | {'device_id': '0', 'name': 'Ubuntu One @ Foo', 'type': 'Computer', |
437 | 70 | 'is_local': '', 'configurable': ''}, | 70 | 'is_local': '', 'configurable': ''}, |
438 | 71 | {'device_id': '1', 'name': 'Bar', 'type': 'Phone', | 71 | {'device_id': '1', 'name': 'Ubuntu One @ Bar', 'type': 'Phone', |
439 | 72 | 'is_local': '', 'configurable': ''}, | 72 | 'is_local': '', 'configurable': ''}, |
440 | 73 | {'device_id': '2', 'name': 'Z', 'type': 'Computer', | 73 | {'device_id': '2', 'name': 'Ubuntu One @ Z', 'type': 'Computer', |
441 | 74 | 'is_local': '', 'configurable': 'True', 'limit_bandwidth': '', | 74 | 'is_local': '', 'configurable': 'True', 'limit_bandwidth': '', |
442 | 75 | 'max_upload_speed': '0', 'max_download_speed': '0'}, | 75 | 'max_upload_speed': '0', 'max_download_speed': '0'}, |
444 | 76 | {'device_id': '1258-6854', 'name': 'Baz', 'type': 'Computer', | 76 | {'device_id': '1258-6854', 'name': 'Ubuntu One @ Baz', 'type': 'Computer', |
445 | 77 | 'is_local': 'True', 'configurable': 'True', 'limit_bandwidth': 'True', | 77 | 'is_local': 'True', 'configurable': 'True', 'limit_bandwidth': 'True', |
446 | 78 | 'max_upload_speed': '1000', 'max_download_speed': '72548'}, # local | 78 | 'max_upload_speed': '1000', 'max_download_speed': '72548'}, # local |
447 | 79 | ] | 79 | ] |
448 | @@ -195,3 +195,21 @@ | |||
449 | 195 | yield | 195 | yield |
450 | 196 | self._installed[package_name] = True | 196 | self._installed[package_name] = True |
451 | 197 | gui.package_manager.return_value(FakedTransaction([package_name])) | 197 | gui.package_manager.return_value(FakedTransaction([package_name])) |
452 | 198 | |||
453 | 199 | |||
454 | 200 | class FakedConfirmDialog(object): | ||
455 | 201 | """Fake a confirmation dialog.""" | ||
456 | 202 | |||
457 | 203 | def __init__(self, *args, **kwargs): | ||
458 | 204 | self._args = args | ||
459 | 205 | self._kwargs = kwargs | ||
460 | 206 | self.was_run = False | ||
461 | 207 | self.is_visible = True | ||
462 | 208 | self.show = lambda: setattr(self, 'is_visible', True) | ||
463 | 209 | self.hide = lambda: setattr(self, 'is_visible', False) | ||
464 | 210 | self.response_code = None | ||
465 | 211 | |||
466 | 212 | def run(self): | ||
467 | 213 | """Set flag and return 'self.response_code'.""" | ||
468 | 214 | self.was_run = True | ||
469 | 215 | return self.response_code | ||
470 | 198 | 216 | ||
471 | === modified file 'ubuntuone/controlpanel/gtk/tests/test_gui.py' | |||
472 | --- ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-01-21 21:43:01 +0000 | |||
473 | +++ ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-01-25 12:57:15 +0000 | |||
474 | @@ -29,7 +29,7 @@ | |||
475 | 29 | FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, | 29 | FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, |
476 | 30 | FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, USER_HOME, | 30 | FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, USER_HOME, |
477 | 31 | FakedNMState, FakedSSOBackend, FakedSessionBus, FakedInterface, | 31 | FakedNMState, FakedSSOBackend, FakedSessionBus, FakedInterface, |
479 | 32 | FakedPackageManager, | 32 | FakedPackageManager, FakedConfirmDialog, |
480 | 33 | ) | 33 | ) |
481 | 34 | from ubuntuone.controlpanel.tests import TOKEN, TestCase | 34 | from ubuntuone.controlpanel.tests import TOKEN, TestCase |
482 | 35 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( | 35 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( |
483 | @@ -55,6 +55,7 @@ | |||
484 | 55 | self.patch(gui.os.path, 'expanduser', | 55 | self.patch(gui.os.path, 'expanduser', |
485 | 56 | lambda path: path.replace('~', USER_HOME)) | 56 | lambda path: path.replace('~', USER_HOME)) |
486 | 57 | self.patch(gui.gtk, 'main', lambda: None) | 57 | self.patch(gui.gtk, 'main', lambda: None) |
487 | 58 | self.patch(gui.gtk, 'MessageDialog', FakedConfirmDialog) | ||
488 | 58 | self.patch(gui.dbus, 'SessionBus', FakedSessionBus) | 59 | self.patch(gui.dbus, 'SessionBus', FakedSessionBus) |
489 | 59 | self.patch(gui.dbus, 'Interface', FakedInterface) | 60 | self.patch(gui.dbus, 'Interface', FakedInterface) |
490 | 60 | self.patch(gui.networkstate, 'NetworkManagerState', FakedNMState) | 61 | self.patch(gui.networkstate, 'NetworkManagerState', FakedNMState) |
491 | @@ -171,11 +172,9 @@ | |||
492 | 171 | self.assertIsInstance(self.ui.control_panel, gui.ControlPanel) | 172 | self.assertIsInstance(self.ui.control_panel, gui.ControlPanel) |
493 | 172 | self.assertTrue(self.ui.control_panel.get_visible()) | 173 | self.assertTrue(self.ui.control_panel.get_visible()) |
494 | 173 | 174 | ||
500 | 174 | def test_window_id_is_passed_to_child(self): | 175 | def test_main_window_is_passed_to_child(self): |
501 | 175 | """The child gets the window_id.""" | 176 | """The child gets the main_window.""" |
502 | 176 | assert self.ui.window is not None | 177 | self.assertEqual(self.ui.control_panel.main_window, self.ui) |
498 | 177 | self.assertEqual(self.ui.control_panel._window_id, | ||
499 | 178 | self.ui.window.xid) | ||
503 | 179 | 178 | ||
504 | 180 | def test_icon_name_is_correct(self): | 179 | def test_icon_name_is_correct(self): |
505 | 181 | """The icon name is correct.""" | 180 | """The icon name is correct.""" |
506 | @@ -225,7 +224,7 @@ | |||
507 | 225 | """The test suite for the control panel itself.""" | 224 | """The test suite for the control panel itself.""" |
508 | 226 | 225 | ||
509 | 227 | klass = gui.ControlPanel | 226 | klass = gui.ControlPanel |
511 | 228 | kwargs = {'window_id': 7} | 227 | kwargs = {'main_window': object()} |
512 | 229 | 228 | ||
513 | 230 | def assert_current_tab_correct(self, expected_tab): | 229 | def assert_current_tab_correct(self, expected_tab): |
514 | 231 | """Check that the wiget 'expected_tab' is the current page.""" | 230 | """Check that the wiget 'expected_tab' is the current page.""" |
515 | @@ -251,9 +250,10 @@ | |||
516 | 251 | self.assertIsInstance(self.ui.overview, gui.OverviewPanel) | 250 | self.assertIsInstance(self.ui.overview, gui.OverviewPanel) |
517 | 252 | self.assert_current_tab_correct(self.ui.overview) | 251 | self.assert_current_tab_correct(self.ui.overview) |
518 | 253 | 252 | ||
522 | 254 | def test_window_id_is_passed_to_child(self): | 253 | def test_main_window_is_passed_to_child(self): |
523 | 255 | """The child gets the window_id.""" | 254 | """The child gets the main_window.""" |
524 | 256 | self.assertEqual(self.ui.overview._window_id, self.kwargs['window_id']) | 255 | self.assertEqual(self.ui.overview.main_window, |
525 | 256 | self.kwargs['main_window']) | ||
526 | 257 | 257 | ||
527 | 258 | def test_on_show_management_panel(self): | 258 | def test_on_show_management_panel(self): |
528 | 259 | """A ManagementPanel is shown when the callback is executed.""" | 259 | """A ManagementPanel is shown when the callback is executed.""" |
529 | @@ -392,7 +392,7 @@ | |||
530 | 392 | """The test suite for the overview panel.""" | 392 | """The test suite for the overview panel.""" |
531 | 393 | 393 | ||
532 | 394 | klass = gui.OverviewPanel | 394 | klass = gui.OverviewPanel |
534 | 395 | kwargs = {'messages': None, 'window_id': 8} | 395 | kwargs = {'messages': None, 'main_window': gui.gtk.Window()} |
535 | 396 | ui_filename = 'overview.ui' | 396 | ui_filename = 'overview.ui' |
536 | 397 | 397 | ||
537 | 398 | def test_is_a_greyable_bin(self): | 398 | def test_is_a_greyable_bin(self): |
538 | @@ -591,24 +591,32 @@ | |||
539 | 591 | 591 | ||
540 | 592 | def test_join_now_button_clicked(self): | 592 | def test_join_now_button_clicked(self): |
541 | 593 | """Test the 'join now' button callback.""" | 593 | """Test the 'join now' button callback.""" |
542 | 594 | self.kwargs['main_window'].show() # ensure parent window is realized | ||
543 | 595 | self.addCleanup(self.kwargs['main_window'].hide) | ||
544 | 596 | |||
545 | 594 | self.ui.join_now_button.clicked() | 597 | self.ui.join_now_button.clicked() |
546 | 595 | 598 | ||
547 | 599 | window_id = self.kwargs['main_window'].window.xid | ||
548 | 596 | args = (gui.U1_APP_NAME, | 600 | args = (gui.U1_APP_NAME, |
549 | 597 | {gui.TC_URL_KEY: gui.U1_TC_URL, | 601 | {gui.TC_URL_KEY: gui.U1_TC_URL, |
550 | 598 | gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, | 602 | gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
552 | 599 | gui.WINDOW_ID_KEY: str(self.kwargs['window_id']), | 603 | gui.WINDOW_ID_KEY: str(window_id), |
553 | 600 | gui.PING_URL_KEY: gui.U1_PING_URL}) | 604 | gui.PING_URL_KEY: gui.U1_PING_URL}) |
554 | 601 | self.assert_backend_called('register', args, | 605 | self.assert_backend_called('register', args, |
555 | 602 | backend=self.ui.sso_backend) | 606 | backend=self.ui.sso_backend) |
556 | 603 | 607 | ||
557 | 604 | def test_connect_button_clicked(self): | 608 | def test_connect_button_clicked(self): |
558 | 605 | """Test the 'join now' button callback.""" | 609 | """Test the 'join now' button callback.""" |
559 | 610 | self.kwargs['main_window'].show() # ensure parent window is realized | ||
560 | 611 | self.addCleanup(self.kwargs['main_window'].hide) | ||
561 | 612 | |||
562 | 606 | self.ui.connect_button.clicked() | 613 | self.ui.connect_button.clicked() |
563 | 607 | 614 | ||
564 | 615 | window_id = self.kwargs['main_window'].window.xid | ||
565 | 608 | args = (gui.U1_APP_NAME, | 616 | args = (gui.U1_APP_NAME, |
566 | 609 | {gui.TC_URL_KEY: gui.U1_TC_URL, | 617 | {gui.TC_URL_KEY: gui.U1_TC_URL, |
567 | 610 | gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, | 618 | gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION, |
569 | 611 | gui.WINDOW_ID_KEY: str(self.kwargs['window_id']), | 619 | gui.WINDOW_ID_KEY: str(window_id), |
570 | 612 | gui.PING_URL_KEY: gui.U1_PING_URL}) | 620 | gui.PING_URL_KEY: gui.U1_PING_URL}) |
571 | 613 | self.assert_backend_called('login', args, | 621 | self.assert_backend_called('login', args, |
572 | 614 | backend=self.ui.sso_backend) | 622 | backend=self.ui.sso_backend) |
573 | @@ -967,8 +975,8 @@ | |||
574 | 967 | """Assert that the device has the values from expected.""" | 975 | """Assert that the device has the values from expected.""" |
575 | 968 | self.assertEqual(device.id, | 976 | self.assertEqual(device.id, |
576 | 969 | expected['device_id']) | 977 | expected['device_id']) |
579 | 970 | self.assertEqual(device.device_name.get_text(), | 978 | value = expected['device_name'].replace(self.ui.REMOVABLE_PREFIX, '') |
580 | 971 | expected['device_name']) | 979 | self.assertEqual(device.device_name.get_text(), value) |
581 | 972 | self.assertEqual(device.device_type.get_icon_name()[0], | 980 | self.assertEqual(device.device_type.get_icon_name()[0], |
582 | 973 | expected['device_type'].lower()) | 981 | expected['device_type'].lower()) |
583 | 974 | self.assertEqual(device.is_local, | 982 | self.assertEqual(device.is_local, |
584 | @@ -1040,13 +1048,13 @@ | |||
585 | 1040 | def test_update_device_name(self): | 1048 | def test_update_device_name(self): |
586 | 1041 | """A device can be updated from a dict.""" | 1049 | """A device can be updated from a dict.""" |
587 | 1042 | value = 'The death star' | 1050 | value = 'The death star' |
589 | 1043 | self.ui.update(device_name=value) | 1051 | self.ui.update(device_name=self.ui.REMOVABLE_PREFIX + value) |
590 | 1044 | self.assertEqual(value, self.ui.device_name.get_text()) | 1052 | self.assertEqual(value, self.ui.device_name.get_text()) |
591 | 1045 | 1053 | ||
592 | 1046 | def test_update_unicode_device_name(self): | 1054 | def test_update_unicode_device_name(self): |
593 | 1047 | """A device can be updated from a dict.""" | 1055 | """A device can be updated from a dict.""" |
594 | 1048 | value = u'Ñoño Ñandú' | 1056 | value = u'Ñoño Ñandú' |
596 | 1049 | self.ui.update(device_name=value) | 1057 | self.ui.update(device_name=self.ui.REMOVABLE_PREFIX + value) |
597 | 1050 | self.assertEqual(value, self.ui.device_name.get_text()) | 1058 | self.assertEqual(value, self.ui.device_name.get_text()) |
598 | 1051 | 1059 | ||
599 | 1052 | def test_update_device_type_computer(self): | 1060 | def test_update_device_type_computer(self): |
600 | @@ -1237,11 +1245,53 @@ | |||
601 | 1237 | 'Must be disabled after other device removal error.') | 1245 | 'Must be disabled after other device removal error.') |
602 | 1238 | 1246 | ||
603 | 1239 | 1247 | ||
604 | 1248 | class RemoveDeviceTestCase(DeviceTestCase): | ||
605 | 1249 | """The test suite for the device widget when prompting for removal.""" | ||
606 | 1250 | |||
607 | 1251 | confirm_dialog = FakedConfirmDialog() | ||
608 | 1252 | kwargs = {'confirm_remove_dialog': confirm_dialog} | ||
609 | 1253 | |||
610 | 1254 | def test_remove(self): | ||
611 | 1255 | """Clicking on remove calls the backend properly.""" | ||
612 | 1256 | self.confirm_dialog.response_code = gui.gtk.RESPONSE_YES | ||
613 | 1257 | super(RemoveDeviceTestCase, self).test_remove() | ||
614 | 1258 | |||
615 | 1259 | def test_on_device_removal_error_other_id(self): | ||
616 | 1260 | """On other device removal error, do nothing.""" | ||
617 | 1261 | self.confirm_dialog.response_code = gui.gtk.RESPONSE_YES | ||
618 | 1262 | parent_test = super(RemoveDeviceTestCase, self) | ||
619 | 1263 | parent_test.test_on_device_removal_error_other_id() | ||
620 | 1264 | |||
621 | 1265 | def test_remove_shows_confirmation_dialog(self): | ||
622 | 1266 | """Clicking on remove displays a confirmation dialog.""" | ||
623 | 1267 | self.ui.remove.clicked() | ||
624 | 1268 | |||
625 | 1269 | self.assertTrue(self.confirm_dialog.was_run, 'dialog was run') | ||
626 | 1270 | self.assertFalse(self.confirm_dialog.is_visible, 'dialog was hid') | ||
627 | 1271 | |||
628 | 1272 | def test_remove_does_not_call_backend_if_dialog_closed(self): | ||
629 | 1273 | """Backend is not called if users closes the confirmation dialog.""" | ||
630 | 1274 | self.confirm_dialog.response_code = gui.gtk.RESPONSE_DELETE_EVENT | ||
631 | 1275 | self.ui.remove.clicked() | ||
632 | 1276 | |||
633 | 1277 | self.assertNotIn('remove_device', self.ui.backend._called) | ||
634 | 1278 | self.assertTrue(self.ui.is_sensitive()) | ||
635 | 1279 | |||
636 | 1280 | def test_remove_does_not_call_backend_if_answer_is_no(self): | ||
637 | 1281 | """Backend is not called if users clicks on 'No'.""" | ||
638 | 1282 | self.confirm_dialog.response_code = gui.gtk.RESPONSE_NO | ||
639 | 1283 | self.ui.remove.clicked() | ||
640 | 1284 | |||
641 | 1285 | self.assertNotIn('remove_device', self.ui.backend._called) | ||
642 | 1286 | self.assertTrue(self.ui.is_sensitive()) | ||
643 | 1287 | |||
644 | 1288 | |||
645 | 1240 | class DevicesTestCase(ControlPanelMixinTestCase): | 1289 | class DevicesTestCase(ControlPanelMixinTestCase): |
646 | 1241 | """The test suite for the devices panel.""" | 1290 | """The test suite for the devices panel.""" |
647 | 1242 | 1291 | ||
648 | 1243 | klass = gui.DevicesPanel | 1292 | klass = gui.DevicesPanel |
649 | 1244 | ui_filename = 'devices.ui' | 1293 | ui_filename = 'devices.ui' |
650 | 1294 | kwargs = {'main_window': object()} | ||
651 | 1245 | 1295 | ||
652 | 1246 | def setUp(self): | 1296 | def setUp(self): |
653 | 1247 | super(DevicesTestCase, self).setUp() | 1297 | super(DevicesTestCase, self).setUp() |
654 | @@ -1259,6 +1309,18 @@ | |||
655 | 1259 | """Is visible.""" | 1309 | """Is visible.""" |
656 | 1260 | self.assertTrue(self.ui.get_visible()) | 1310 | self.assertTrue(self.ui.get_visible()) |
657 | 1261 | 1311 | ||
658 | 1312 | def test_confirm_remove_dialog(self): | ||
659 | 1313 | """The confirmation dialog is correct.""" | ||
660 | 1314 | dialog = self.ui.confirm_remove_dialog | ||
661 | 1315 | |||
662 | 1316 | self.assertEqual(dialog._args, ()) | ||
663 | 1317 | flags = gui.gtk.DIALOG_MODAL | gui.gtk.DIALOG_DESTROY_WITH_PARENT | ||
664 | 1318 | kwargs = dict(parent=self.kwargs['main_window'], | ||
665 | 1319 | flags=flags, type=gui.gtk.MESSAGE_WARNING, | ||
666 | 1320 | buttons=gui.gtk.BUTTONS_YES_NO, | ||
667 | 1321 | message_format=self.ui.CONFIRM_REMOVE) | ||
668 | 1322 | self.assertEqual(dialog._kwargs, kwargs) | ||
669 | 1323 | |||
670 | 1262 | def test_backend_signals(self): | 1324 | def test_backend_signals(self): |
671 | 1263 | """The proper signals are connected to the backend.""" | 1325 | """The proper signals are connected to the backend.""" |
672 | 1264 | self.assertEqual(self.ui.backend._signals['DevicesInfoReady'], | 1326 | self.assertEqual(self.ui.backend._signals['DevicesInfoReady'], |
673 | @@ -1312,8 +1374,8 @@ | |||
674 | 1312 | self.assertIsInstance(child, gui.Device) | 1374 | self.assertIsInstance(child, gui.Device) |
675 | 1313 | 1375 | ||
676 | 1314 | self.assertEqual(device['device_id'], child.id) | 1376 | self.assertEqual(device['device_id'], child.id) |
679 | 1315 | self.assertEqual(device['device_name'], | 1377 | value = device['device_name'].replace(child.REMOVABLE_PREFIX, '') |
680 | 1316 | child.device_name.get_text()) | 1378 | self.assertEqual(value, child.device_name.get_text()) |
681 | 1317 | self.assertEqual(device['device_type'].lower(), | 1379 | self.assertEqual(device['device_type'].lower(), |
682 | 1318 | child.device_type.get_icon_name()[0]) | 1380 | child.device_type.get_icon_name()[0]) |
683 | 1319 | self.assertEqual(bool(device['is_local']), | 1381 | self.assertEqual(bool(device['is_local']), |
684 | @@ -1331,6 +1393,8 @@ | |||
685 | 1331 | self.assertEqual(value, | 1393 | self.assertEqual(value, |
686 | 1332 | child.max_download_speed.get_value_as_int()) | 1394 | child.max_download_speed.get_value_as_int()) |
687 | 1333 | 1395 | ||
688 | 1396 | self.assertIs(child.confirm_dialog, self.ui.confirm_remove_dialog) | ||
689 | 1397 | |||
690 | 1334 | def test_on_devices_info_ready_have_devices_cached(self): | 1398 | def test_on_devices_info_ready_have_devices_cached(self): |
691 | 1335 | """The devices are cached for further removal.""" | 1399 | """The devices are cached for further removal.""" |
692 | 1336 | self.ui.on_devices_info_ready(FAKE_DEVICES_INFO) | 1400 | self.ui.on_devices_info_ready(FAKE_DEVICES_INFO) |
693 | 1337 | 1401 | ||
694 | === modified file 'ubuntuone/controlpanel/tests/__init__.py' | |||
695 | --- ubuntuone/controlpanel/tests/__init__.py 2011-01-20 14:31:24 +0000 | |||
696 | +++ ubuntuone/controlpanel/tests/__init__.py 2011-01-25 12:57:15 +0000 | |||
697 | @@ -205,6 +205,8 @@ | |||
698 | 205 | class TestCase(BaseTestCase): | 205 | class TestCase(BaseTestCase): |
699 | 206 | """Basics for testing.""" | 206 | """Basics for testing.""" |
700 | 207 | 207 | ||
701 | 208 | assertIs = BaseTestCase.assertIdentical | ||
702 | 209 | |||
703 | 208 | def setUp(self): | 210 | def setUp(self): |
704 | 209 | self._called = False | 211 | self._called = False |
705 | 210 | 212 |
Control Panel has asked me whether I want to remove the device. I just could not say no!