Merge lp:~nataliabidart/magicicada-gui/bind-more-signals into lp:magicicada-gui
- bind-more-signals
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Facundo Batista | ||||||||||||||||
Approved revision: | 24 | ||||||||||||||||
Merged at revision: | 20 | ||||||||||||||||
Proposed branch: | lp:~nataliabidart/magicicada-gui/bind-more-signals | ||||||||||||||||
Merge into: | lp:magicicada-gui | ||||||||||||||||
Diff against target: |
820 lines (+525/-96) 3 files modified
data/media/active.svg (+203/-0) magicicada/__init__.py (+56/-50) magicicada/tests/test_magicicada.py (+266/-46) |
||||||||||||||||
To merge this branch: | bzr merge lp:~nataliabidart/magicicada-gui/bind-more-signals | ||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Facundo Batista | Approve | ||
Review via email: mp+25813@code.launchpad.net |
Commit message
Description of the change
Binding callbacks for started/stopped, connected/
To post a comment you must log in.
- 24. By Natalia Bidart
-
Tweaks.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'data/media/active-016.png' |
2 | Binary files data/media/active-016.png 1970-01-01 00:00:00 +0000 and data/media/active-016.png 2010-05-22 03:21:24 +0000 differ |
3 | === added file 'data/media/active.svg' |
4 | --- data/media/active.svg 1970-01-01 00:00:00 +0000 |
5 | +++ data/media/active.svg 2010-05-22 03:21:24 +0000 |
6 | @@ -0,0 +1,203 @@ |
7 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
8 | +<!-- Created with Inkscape (http://www.inkscape.org/) --> |
9 | + |
10 | +<svg |
11 | + xmlns:dc="http://purl.org/dc/elements/1.1/" |
12 | + xmlns:cc="http://creativecommons.org/ns#" |
13 | + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
14 | + xmlns:svg="http://www.w3.org/2000/svg" |
15 | + xmlns="http://www.w3.org/2000/svg" |
16 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
17 | + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
18 | + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
19 | + width="425.71429" |
20 | + height="461.42856" |
21 | + id="svg2" |
22 | + sodipodi:version="0.32" |
23 | + inkscape:version="0.47 r22583" |
24 | + version="1.0" |
25 | + sodipodi:docname="active.svg" |
26 | + inkscape:output_extension="org.inkscape.output.svg.inkscape"> |
27 | + <defs |
28 | + id="defs4"> |
29 | + <linearGradient |
30 | + id="linearGradient3250"> |
31 | + <stop |
32 | + style="stop-color:#b8b8b8;stop-opacity:0;" |
33 | + offset="0" |
34 | + id="stop3252" /> |
35 | + <stop |
36 | + id="stop3258" |
37 | + offset="0.40588239" |
38 | + style="stop-color:#b8b8b8;stop-opacity:1;" /> |
39 | + <stop |
40 | + style="stop-color:#b8b8b8;stop-opacity:0;" |
41 | + offset="1" |
42 | + id="stop3254" /> |
43 | + </linearGradient> |
44 | + <linearGradient |
45 | + id="linearGradient3224"> |
46 | + <stop |
47 | + style="stop-color:#ffffff;stop-opacity:1;" |
48 | + offset="0" |
49 | + id="stop3226" /> |
50 | + <stop |
51 | + style="stop-color:#c8c8c8;stop-opacity:1;" |
52 | + offset="1" |
53 | + id="stop3228" /> |
54 | + </linearGradient> |
55 | + <linearGradient |
56 | + id="linearGradient3214"> |
57 | + <stop |
58 | + style="stop-color:#3b3b3b;stop-opacity:1;" |
59 | + offset="0" |
60 | + id="stop3216" /> |
61 | + <stop |
62 | + style="stop-color:#afafaf;stop-opacity:1;" |
63 | + offset="1" |
64 | + id="stop3218" /> |
65 | + </linearGradient> |
66 | + <linearGradient |
67 | + id="linearGradient3176"> |
68 | + <stop |
69 | + style="stop-color:#c1ffb6;stop-opacity:1;" |
70 | + offset="0" |
71 | + id="stop3178" /> |
72 | + <stop |
73 | + id="stop3184" |
74 | + offset="0.40630153" |
75 | + style="stop-color:#00e632;stop-opacity:1;" /> |
76 | + <stop |
77 | + style="stop-color:#1c3a4f;stop-opacity:1" |
78 | + offset="1" |
79 | + id="stop3180" /> |
80 | + </linearGradient> |
81 | + <inkscape:perspective |
82 | + sodipodi:type="inkscape:persp3d" |
83 | + inkscape:vp_x="0 : 526.18109 : 1" |
84 | + inkscape:vp_y="0 : 1000 : 0" |
85 | + inkscape:vp_z="744.09448 : 526.18109 : 1" |
86 | + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |
87 | + id="perspective10" /> |
88 | + <inkscape:perspective |
89 | + id="perspective2390" |
90 | + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" |
91 | + inkscape:vp_z="744.09448 : 526.18109 : 1" |
92 | + inkscape:vp_y="0 : 1000 : 0" |
93 | + inkscape:vp_x="0 : 526.18109 : 1" |
94 | + sodipodi:type="inkscape:persp3d" /> |
95 | + <radialGradient |
96 | + inkscape:collect="always" |
97 | + xlink:href="#linearGradient3176" |
98 | + id="radialGradient3182" |
99 | + cx="346.42856" |
100 | + cy="338.07645" |
101 | + fx="346.42856" |
102 | + fy="338.07645" |
103 | + r="165.71428" |
104 | + gradientUnits="userSpaceOnUse" |
105 | + gradientTransform="matrix(-1.2831103,0.3438084,-0.3438084,-1.2831103,907.16815,652.76078)" /> |
106 | + <radialGradient |
107 | + inkscape:collect="always" |
108 | + xlink:href="#linearGradient3214" |
109 | + id="radialGradient3220" |
110 | + cx="317.60519" |
111 | + cy="539.41315" |
112 | + fx="317.60519" |
113 | + fy="539.41315" |
114 | + r="165.53342" |
115 | + gradientTransform="matrix(1,0,0,0.2054734,0,428.57808)" |
116 | + gradientUnits="userSpaceOnUse" /> |
117 | + <radialGradient |
118 | + inkscape:collect="always" |
119 | + xlink:href="#linearGradient3224" |
120 | + id="radialGradient3230" |
121 | + cx="317.60394" |
122 | + cy="220.94547" |
123 | + fx="317.60394" |
124 | + fy="220.94547" |
125 | + r="164.06058" |
126 | + gradientTransform="matrix(1.0076229,0,0,0.1968921,-2.4553843,177.59098)" |
127 | + gradientUnits="userSpaceOnUse" /> |
128 | + <linearGradient |
129 | + inkscape:collect="always" |
130 | + xlink:href="#linearGradient3250" |
131 | + id="linearGradient3256" |
132 | + x1="318.47412" |
133 | + y1="651.00037" |
134 | + x2="309.90268" |
135 | + y2="413.85742" |
136 | + gradientUnits="userSpaceOnUse" |
137 | + spreadMethod="pad" /> |
138 | + <radialGradient |
139 | + inkscape:collect="always" |
140 | + xlink:href="#linearGradient3214" |
141 | + id="radialGradient3274" |
142 | + gradientUnits="userSpaceOnUse" |
143 | + gradientTransform="matrix(1,0,0,0.2054734,11.428571,428.57808)" |
144 | + cx="317.60519" |
145 | + cy="539.41315" |
146 | + fx="317.60519" |
147 | + fy="539.41315" |
148 | + r="165.53342" /> |
149 | + <radialGradient |
150 | + inkscape:collect="always" |
151 | + xlink:href="#linearGradient3224" |
152 | + id="radialGradient3276" |
153 | + gradientUnits="userSpaceOnUse" |
154 | + gradientTransform="matrix(1.0076229,0,0,0.1922742,8.9731871,177.85367)" |
155 | + cx="317.60394" |
156 | + cy="220.94547" |
157 | + fx="317.60394" |
158 | + fy="220.94547" |
159 | + r="164.06058" /> |
160 | + </defs> |
161 | + <sodipodi:namedview |
162 | + id="base" |
163 | + pagecolor="#ffffff" |
164 | + bordercolor="#666666" |
165 | + borderopacity="1.0" |
166 | + gridtolerance="10000" |
167 | + guidetolerance="10" |
168 | + objecttolerance="10" |
169 | + inkscape:pageopacity="0.0" |
170 | + inkscape:pageshadow="2" |
171 | + inkscape:zoom="0.70710678" |
172 | + inkscape:cx="577.43933" |
173 | + inkscape:cy="433.43027" |
174 | + inkscape:document-units="px" |
175 | + inkscape:current-layer="layer1" |
176 | + showgrid="false" |
177 | + inkscape:window-width="1250" |
178 | + inkscape:window-height="775" |
179 | + inkscape:window-x="0" |
180 | + inkscape:window-y="0" |
181 | + inkscape:window-maximized="1" /> |
182 | + <metadata |
183 | + id="metadata7"> |
184 | + <rdf:RDF> |
185 | + <cc:Work |
186 | + rdf:about=""> |
187 | + <dc:format>image/svg+xml</dc:format> |
188 | + <dc:type |
189 | + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
190 | + </cc:Work> |
191 | + </rdf:RDF> |
192 | + </metadata> |
193 | + <g |
194 | + inkscape:label="Layer 1" |
195 | + inkscape:groupmode="layer" |
196 | + id="layer1" |
197 | + transform="translate(-105.61697,-158.14316)"> |
198 | + <path |
199 | + sodipodi:type="arc" |
200 | + style="opacity:1;fill:url(#radialGradient3182);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" |
201 | + id="path2396" |
202 | + sodipodi:cx="323.57144" |
203 | + sodipodi:cy="389.50504" |
204 | + sodipodi:rx="165.71428" |
205 | + sodipodi:ry="165.71428" |
206 | + d="m 489.28572,389.50504 c 0,91.52146 -74.19281,165.71427 -165.71428,165.71427 -91.52147,0 -165.71428,-74.19281 -165.71428,-165.71427 0,-91.52147 74.19281,-165.71428 165.71428,-165.71428 91.52147,0 165.71428,74.19281 165.71428,165.71428 z" |
207 | + transform="translate(5.643371,-11.272676)" /> |
208 | + </g> |
209 | +</svg> |
210 | |
211 | === modified file 'magicicada/__init__.py' |
212 | --- magicicada/__init__.py 2010-05-17 16:10:28 +0000 |
213 | +++ magicicada/__init__.py 2010-05-22 03:21:24 +0000 |
214 | @@ -28,8 +28,8 @@ |
215 | from twisted.internet import gtk2reactor # for gtk-2.0 |
216 | gtk2reactor.install() |
217 | |
218 | +from magicicada import syncdaemon |
219 | from magicicada.helpers import get_data_file, get_builder, NO_OP |
220 | -from magicicada.syncdaemon import SyncDaemon |
221 | |
222 | CONTENT_QUEUE = 'content' |
223 | META_QUEUE = 'meta' |
224 | @@ -42,7 +42,8 @@ |
225 | 'online': _('Service reached Nirvana.'), |
226 | } |
227 | |
228 | - def __init__(self, launchpad_available=False, on_destroy=NO_OP): |
229 | + def __init__(self, launchpad_available=False, on_destroy=NO_OP, |
230 | + syncdaemon_class=syncdaemon.SyncDaemon): |
231 | """Init.""" |
232 | self.builder = get_builder('gui.glade') |
233 | self.builder.connect_signals(self) |
234 | @@ -59,8 +60,8 @@ |
235 | |
236 | animation_filename = get_data_file('media', 'loader-ball.gif') |
237 | self.loading_animation = gtk.gdk.PixbufAnimation(animation_filename) |
238 | - |
239 | - self.started = self.connected = self.online = False |
240 | + active_filename = get_data_file('media', 'active-016.png') |
241 | + self.active_indicator = gtk.gdk.pixbuf_new_from_file(active_filename) |
242 | |
243 | widgets = ( |
244 | 'start', 'stop', 'connect', 'disconnect', # toolbar buttons |
245 | @@ -81,16 +82,26 @@ |
246 | |
247 | self.main_window.show() |
248 | |
249 | - self.sd = SyncDaemon() |
250 | + self.sd = syncdaemon_class() |
251 | + self.sd.on_started_callback = self.on_started |
252 | + self.sd.on_stopped_callback = self.on_stopped |
253 | + self.sd.on_connected_callback = self.on_connected |
254 | + self.sd.on_disconnected_callback = self.on_disconnected |
255 | + self.sd.on_online_callback = self.on_online |
256 | + self.sd.on_offline_callback = self.on_offline |
257 | + self.sd.status_changed_callback = self.on_status_changed |
258 | self.sd.content_queue_changed_callback = self.on_content_queue_changed |
259 | self.sd.meta_queue_changed_callback = self.on_meta_queue_changed |
260 | |
261 | + self.widget_enabled = lambda w: \ |
262 | + w.get_property('visible') and w.is_sensitive() |
263 | + |
264 | # GTK callbacks |
265 | |
266 | def on_main_window_destroy(self, widget, data=None): |
267 | """Called when the MagicicadaWindow is closed.""" |
268 | # Clean up code for saving application state should be added here. |
269 | - if self.started: |
270 | + if self.widget_enabled(self.stop): |
271 | self.on_stop_clicked(self.stop) |
272 | self.sd.shutdown() |
273 | self.on_destroy() |
274 | @@ -106,46 +117,39 @@ |
275 | |
276 | def on_start_clicked(self, widget, data=None): |
277 | """Start syncdaemon.""" |
278 | - self.started = True |
279 | - self.connect.set_sensitive(True) |
280 | + self.sd.start() |
281 | self.start.hide() |
282 | + self.stop.set_sensitive(False) |
283 | self.stop.show() |
284 | - |
285 | - self.doing_something(self.is_started) |
286 | + self.start_loading(self.is_started) |
287 | |
288 | def on_stop_clicked(self, widget, data=None): |
289 | """Stop syncdaemon.""" |
290 | - assert self.started |
291 | - |
292 | - if self.connected: |
293 | + if self.widget_enabled(self.disconnect): |
294 | self.on_disconnect_clicked(self.disconnect) |
295 | self.connect.set_sensitive(False) |
296 | |
297 | - self.started = False |
298 | self.start.show() |
299 | + self.start.set_sensitive(False) |
300 | self.stop.hide() |
301 | |
302 | - self.on_stopped() |
303 | + self.sd.quit() |
304 | |
305 | def on_connect_clicked(self, widget, data=None): |
306 | """Connect syncdaemon.""" |
307 | - assert self.started |
308 | - self.connected = True |
309 | + self.sd.connect() |
310 | self.connect.hide() |
311 | + self.disconnect.set_sensitive(False) |
312 | self.disconnect.show() |
313 | - |
314 | - self.on_started() |
315 | - self.doing_something(self.is_connected) |
316 | + self.start_loading(self.is_connected) |
317 | |
318 | def on_disconnect_clicked(self, widget, data=None): |
319 | """Disconnect syncdaemon.""" |
320 | - assert self.started |
321 | - assert self.connected |
322 | - self.connected = False |
323 | self.connect.show() |
324 | + self.connect.set_sensitive(False) |
325 | self.disconnect.hide() |
326 | |
327 | - self.on_disconnected() |
328 | + self.sd.disconnect() |
329 | |
330 | def on_status_icon_activate(self, widget, data=None): |
331 | """Systray icon was clicked.""" |
332 | @@ -158,43 +162,45 @@ |
333 | |
334 | def on_started(self, *args, **kwargs): |
335 | """Callback'ed when syncadaemon is started.""" |
336 | - self.stop_doing_something(self.is_started) |
337 | - self.status_label.set_text(self.STATUS['started']) |
338 | + self.stop.set_sensitive(True) |
339 | + self.activate_indicator(self.is_started) |
340 | + self.connect.set_sensitive(True) |
341 | |
342 | def on_stopped(self, *args, **kwargs): |
343 | """Callback'ed when syncadaemon is stopped.""" |
344 | - |
345 | - self.stop_doing_something(self.is_started, sensitive=False) |
346 | - |
347 | - self.is_started.set_sensitive(False) |
348 | - self.is_connected.set_sensitive(False) |
349 | - self.is_online.set_sensitive(False) |
350 | + self.start.set_sensitive(True) |
351 | + |
352 | + self.activate_indicator(self.is_started, sensitive=False) |
353 | + self.activate_indicator(self.is_connected, sensitive=False) |
354 | + self.activate_indicator(self.is_online, sensitive=False) |
355 | |
356 | def on_connected(self, *args, **kwargs): |
357 | """Callback'ed when syncadaemon is connected.""" |
358 | - self.is_connected.set_sensitive(True) |
359 | - self.doing_something(self.is_online) |
360 | - self.status_label.set_text(self.STATUS['connected']) |
361 | + self.disconnect.set_sensitive(True) |
362 | + self.activate_indicator(self.is_connected) |
363 | + self.start_loading(self.is_online) |
364 | + self.start_loading(self.is_online) |
365 | |
366 | def on_disconnected(self, *args, **kwargs): |
367 | """Callback'ed when syncadaemon is disconnected.""" |
368 | - |
369 | - self.stop_doing_something(self.is_connected, sensitive=False) |
370 | - |
371 | - self.is_connected.set_sensitive(False) |
372 | - self.is_online.set_sensitive(False) |
373 | + self.connect.set_sensitive(True) |
374 | + |
375 | + self.activate_indicator(self.is_connected, sensitive=False) |
376 | + self.activate_indicator(self.is_online, sensitive=False) |
377 | |
378 | def on_online(self, *args, **kwargs): |
379 | """Callback'ed when syncadaemon is online.""" |
380 | - self.is_onlined.set_sensitive(True) |
381 | - self.status_label.set_text(self.STATUS['online']) |
382 | + self.is_online.set_sensitive(True) |
383 | + self.activate_indicator(self.is_online) |
384 | |
385 | def on_offline(self, *args, **kwargs): |
386 | """Callback'ed when syncadaemon is offline.""" |
387 | - |
388 | - self.stop_doing_something(self.is_online, sensitive=False) |
389 | - |
390 | - self.is_online.set_sensitive(False) |
391 | + self.activate_indicator(self.is_online, sensitive=False) |
392 | + |
393 | + def on_status_changed(self, name, description, is_error, is_connected, |
394 | + is_online, queues, connection): |
395 | + """Callback'ed when the SD status changed.""" |
396 | + self.status_label.set_text(description) |
397 | |
398 | def _on_queue_changed(self, queue_name, items, *args, **kwargs): |
399 | """Callback'ed when a queue changed.""" |
400 | @@ -218,12 +224,12 @@ |
401 | |
402 | # custom |
403 | |
404 | - def doing_something(self, what): |
405 | + def start_loading(self, what): |
406 | """Set a loader animation on 'what'.""" |
407 | what.set_sensitive(True) |
408 | what.set_from_animation(self.loading_animation) |
409 | |
410 | - def stop_doing_something(self, what, sensitive=True): |
411 | - """Set a loader animation on 'what'.""" |
412 | - what.set_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_BUTTON) |
413 | + def activate_indicator(self, what, sensitive=True): |
414 | + """Set ready pixbuf on 'what' and make it 'sensitive'.""" |
415 | what.set_sensitive(sensitive) |
416 | + what.set_from_pixbuf(self.active_indicator) |
417 | |
418 | === modified file 'magicicada/tests/test_magicicada.py' |
419 | --- magicicada/tests/test_magicicada.py 2010-05-17 16:10:28 +0000 |
420 | +++ magicicada/tests/test_magicicada.py 2010-05-22 03:21:24 +0000 |
421 | @@ -26,9 +26,8 @@ |
422 | |
423 | from twisted.trial.unittest import TestCase |
424 | |
425 | -from magicicada import MagicicadaUI, CONTENT_QUEUE, META_QUEUE |
426 | +from magicicada import MagicicadaUI, CONTENT_QUEUE, META_QUEUE, syncdaemon |
427 | from magicicada.helpers import get_builder, NO_OP |
428 | -from magicicada.syncdaemon import SyncDaemon, QueueData |
429 | |
430 | DEFAULT_TIMEOUT = 200 |
431 | |
432 | @@ -47,8 +46,20 @@ |
433 | """A faked syncdaemon.""" |
434 | |
435 | def __init__(self): |
436 | + self.on_started_callback = NO_OP |
437 | + self.on_stopped_callback = NO_OP |
438 | + self.on_connected_callback = NO_OP |
439 | + self.on_disconnected_callback = NO_OP |
440 | + self.on_online_callback = NO_OP |
441 | + self.on_offline_callback = NO_OP |
442 | + self.status_changed_callback = NO_OP |
443 | self.content_queue_changed_callback = NO_OP |
444 | self.meta_queue_changed_callback = NO_OP |
445 | + self.shutdown = NO_OP |
446 | + self.start = NO_OP |
447 | + self.quit = NO_OP |
448 | + self.connect = NO_OP |
449 | + self.disconnect = NO_OP |
450 | |
451 | |
452 | class MagicicadaUITestCase(TestCase): |
453 | @@ -57,31 +68,50 @@ |
454 | def setUp(self): |
455 | """Init.""" |
456 | self.builder = get_builder('gui.glade') |
457 | - self.ui = MagicicadaUI() |
458 | + self.ui = MagicicadaUI(syncdaemon_class=FakedSyncdaemon) |
459 | self._called = False |
460 | + self.set_called = lambda *_: setattr(self, '_called', True) |
461 | |
462 | def tearDown(self): |
463 | - """Clenaup.""" |
464 | + """Cleanup.""" |
465 | self.ui.on_main_window_destroy(self.ui.main_window) |
466 | self._called = False |
467 | self.builder = None |
468 | |
469 | + def assert_indicator_disabled(self, indicator): |
470 | + """Test that 'indicator' is not sensitive.""" |
471 | + self.assertFalse(indicator.is_sensitive(), 'indicator is not sensitive') |
472 | + |
473 | + def assert_indicator_ready(self, indicator): |
474 | + """Test that 'indicator' is sensitive and green.""" |
475 | + self.assertTrue(indicator.is_sensitive(), 'indicator is sensitive') |
476 | + expected = indicator.get_pixbuf() # a test on its own |
477 | + self.assertEqual(self.ui.active_indicator, expected, |
478 | + 'indicator is the correct pixbuf') |
479 | + |
480 | + def assert_indicator_loading(self, indicator): |
481 | + """Test that 'indicator' is sensitive and loading.""" |
482 | + self.assertTrue(indicator.is_sensitive(), 'indicator is sensitive') |
483 | + expected = indicator.get_animation() # a test on its own |
484 | + self.assertEqual(self.ui.loading_animation, expected, |
485 | + 'indicator is the correct animation') |
486 | + |
487 | + |
488 | +class MagicicadaUIBasicTestCase(MagicicadaUITestCase): |
489 | + """UI test cases for basic state.""" |
490 | + |
491 | def test_init_creates_sd_instance(self): |
492 | """SyncDaemon instance is created at creation time.""" |
493 | - self.assertTrue(isinstance(self.ui.sd, SyncDaemon)) |
494 | + self.assertTrue(self.ui.sd is not None) |
495 | + self.assertTrue(isinstance(self.ui.sd, FakedSyncdaemon)) |
496 | |
497 | def test_destroy_shutdowns_sd_instance(self): |
498 | """SyncDaemon instance is shutdown at destroy time.""" |
499 | - self.patch(self.ui.sd, 'shutdown', |
500 | - lambda *_: setattr(self, '_called', True)) |
501 | + self.patch(self.ui.sd, 'shutdown', self.set_called) |
502 | self.ui.on_main_window_destroy(self.ui.main_window) |
503 | self.assertTrue(self._called, |
504 | 'syncdaemon.shutdown must be called at destroy time.') |
505 | |
506 | - |
507 | -class MagicicadaUIStartupTestCase(MagicicadaUITestCase): |
508 | - """UI test cases for startup state.""" |
509 | - |
510 | def test_main_window_is_visible(self): |
511 | """UI can be created.""" |
512 | self.assertTrue(self.ui.main_window.get_property('visible')) |
513 | @@ -99,52 +129,110 @@ |
514 | self.assertFalse(self.ui.stop.get_property('visible')) |
515 | self.assertFalse(self.ui.disconnect.get_property('visible')) |
516 | |
517 | - def test_not_started_not_connected_not_online(self): |
518 | - """Test default values for flags.""" |
519 | - self.assertFalse(self.ui.started) |
520 | - self.assertFalse(self.ui.connected) |
521 | - self.assertFalse(self.ui.online) |
522 | - |
523 | def test_indicators_are_non_sensitive(self): |
524 | """Test default sensitivity for indicators.""" |
525 | - #import pdb; pdb.set_trace() |
526 | self.assertFalse(self.ui.is_started.is_sensitive()) |
527 | self.assertFalse(self.ui.is_connected.is_sensitive()) |
528 | self.assertFalse(self.ui.is_online.is_sensitive()) |
529 | |
530 | + def test_update_is_correct(self): |
531 | + """Update updates.""" |
532 | + # XXX: TODO |
533 | + |
534 | |
535 | class MagicicadaUIClickedTestCase(MagicicadaUITestCase): |
536 | """UI test cases.""" |
537 | |
538 | - def test_started_if_start_clicked(self): |
539 | - """Test started if Start was clicked.""" |
540 | + def test_on_start_clicked(self): |
541 | + """Test on_start_clicked.""" |
542 | self.ui.on_start_clicked(self.ui.start) |
543 | - self.assertTrue(self.ui.started) |
544 | - self.assertFalse(self.ui.connected) |
545 | - self.assertFalse(self.ui.online) |
546 | |
547 | - def test_can_connect_can_stop_if_start_clicked(self): |
548 | - """Test Connect and Stop are enabled if Start was clicked.""" |
549 | - self.ui.on_start_clicked(self.ui.start) |
550 | self.assertFalse(self.ui.start.get_property('visible')) |
551 | self.assertTrue(self.ui.stop.get_property('visible')) |
552 | - self.assertTrue(self.ui.connect.is_sensitive()) |
553 | - |
554 | - def test_connected_if_connect_clicked(self): |
555 | - """Test connected if Connect was clicked.""" |
556 | - self.ui.on_start_clicked(self.ui.start) # need to be started |
557 | - self.ui.on_connect_clicked(self.ui.connect) |
558 | - |
559 | - self.assertTrue(self.ui.started) |
560 | - self.assertTrue(self.ui.connected) |
561 | - self.assertFalse(self.ui.online) |
562 | - |
563 | - def test_can_disconnect_if_connect_clicked(self): |
564 | - """Test Disconnect is enabled if Connect was clicked.""" |
565 | - self.ui.on_start_clicked(self.ui.start) # need to be started |
566 | - self.ui.on_connect_clicked(self.ui.connect) |
567 | + self.assertFalse(self.ui.stop.is_sensitive()) |
568 | + |
569 | + self.assert_indicator_loading(self.ui.is_started) |
570 | + self.assert_indicator_disabled(self.ui.is_connected) |
571 | + self.assert_indicator_disabled(self.ui.is_online) |
572 | + |
573 | + def test_on_start_clicked_starts_syncdaemon(self): |
574 | + """Test on_start_clicked.""" |
575 | + self.patch(self.ui.sd, 'start', self.set_called) |
576 | + self.ui.on_start_clicked(self.ui.start) |
577 | + self.assertTrue(self._called, 'syncdaemon.start was called.') |
578 | + |
579 | + def test_on_connect_clicked(self): |
580 | + """Test on_connect_clicked.""" |
581 | + self.ui.on_start_clicked(self.ui.start) # need to be started |
582 | + self.ui.on_started() |
583 | + self.ui.on_connect_clicked(self.ui.connect) |
584 | + |
585 | self.assertFalse(self.ui.connect.get_property('visible')) |
586 | self.assertTrue(self.ui.disconnect.get_property('visible')) |
587 | + self.assertFalse(self.ui.disconnect.is_sensitive()) |
588 | + |
589 | + self.assert_indicator_ready(self.ui.is_started) |
590 | + self.assert_indicator_loading(self.ui.is_connected) |
591 | + self.assert_indicator_disabled(self.ui.is_online) |
592 | + |
593 | + def test_on_connect_clicked_connects_syncdaemon(self): |
594 | + """Test on_connect_clicked.""" |
595 | + self.patch(self.ui.sd, 'connect', self.set_called) |
596 | + self.ui.on_connect_clicked(self.ui.connect) |
597 | + self.assertTrue(self._called, 'syncdaemon.connect was called.') |
598 | + |
599 | + def test_on_stop_clicked(self): |
600 | + """Test on_stop_clicked.""" |
601 | + self.ui.on_start_clicked(self.ui.start) |
602 | + self.ui.on_started() |
603 | + assert not self.ui.widget_enabled(self.ui.disconnect) |
604 | + self.patch(self.ui, 'on_disconnect_clicked', self.set_called) |
605 | + self.ui.on_stop_clicked(self.ui.stop) |
606 | + |
607 | + self.assertFalse(self._called, 'on_disconnect_clicked was not called.') |
608 | + |
609 | + self.assertTrue(self.ui.start.get_property('visible')) |
610 | + self.assertFalse(self.ui.start.is_sensitive()) |
611 | + self.assertFalse(self.ui.stop.get_property('visible')) |
612 | + |
613 | + self.assertTrue(self.ui.connect.get_property('visible')) |
614 | + self.assertFalse(self.ui.connect.is_sensitive()) |
615 | + self.assertFalse(self.ui.disconnect.get_property('visible')) |
616 | + |
617 | + def test_on_stop_clicked_if_connected(self): |
618 | + """Test on_stop_clicked.""" |
619 | + self.ui.on_start_clicked(self.ui.start) |
620 | + self.ui.on_started() |
621 | + self.ui.on_connect_clicked(self.ui.connect) |
622 | + self.ui.on_connected() |
623 | + self.patch(self.ui, 'on_disconnect_clicked', self.set_called) |
624 | + self.ui.on_stop_clicked(self.ui.stop) |
625 | + |
626 | + self.assertTrue(self._called, 'on_disconnect_clicked was called.') |
627 | + |
628 | + def test_on_stop_clicked_stops_syncdaemon(self): |
629 | + """Test on_stop_clicked.""" |
630 | + self.patch(self.ui.sd, 'quit', self.set_called) |
631 | + self.ui.on_stop_clicked(self.ui.stop) |
632 | + self.assertTrue(self._called, 'syncdaemon.quit was called.') |
633 | + |
634 | + def test_on_disconnect_clicked(self): |
635 | + """Test on_disconnect_clicked.""" |
636 | + self.ui.on_start_clicked(self.ui.start) |
637 | + self.ui.on_started() |
638 | + self.ui.on_connect_clicked(self.ui.connect) |
639 | + self.ui.on_connected() |
640 | + self.ui.on_disconnect_clicked(self.ui.disconnect) |
641 | + |
642 | + self.assertTrue(self.ui.connect.get_property('visible')) |
643 | + self.assertFalse(self.ui.connect.is_sensitive()) |
644 | + self.assertFalse(self.ui.disconnect.get_property('visible')) |
645 | + |
646 | + def test_on_disconnect_clicked_disconnects_syncdaemon(self): |
647 | + """Test on_disconnect_clicked.""" |
648 | + self.patch(self.ui.sd, 'disconnect', self.set_called) |
649 | + self.ui.on_disconnect_clicked(self.ui.disconnect) |
650 | + self.assertTrue(self._called, 'syncdaemon.disconnect was called.') |
651 | |
652 | |
653 | class MagicicadaUISystrayIconTestCase(MagicicadaUITestCase): |
654 | @@ -165,7 +253,7 @@ |
655 | |
656 | |
657 | class _MagicicadaUIQueueTestCase(MagicicadaUITestCase): |
658 | - """Abstratc UI test cases for a queue views.""" |
659 | + """Abstratc UI test cases for queue tree views.""" |
660 | |
661 | queue = None |
662 | |
663 | @@ -183,8 +271,9 @@ |
664 | """Build some data to pass to queue changed callback.""" |
665 | items = [] |
666 | for i in xrange(limit): |
667 | - cq = QueueData(operation='operation %i' % i, path='path %i' % i, |
668 | - node='node %i' % i, share='share %i' % i) |
669 | + cq = syncdaemon.QueueData(operation='operation %i' % i, |
670 | + path='path %i' % i, node='node %i' % i, |
671 | + share='share %i' % i) |
672 | items.append(cq) |
673 | return items |
674 | |
675 | @@ -242,12 +331,143 @@ |
676 | |
677 | |
678 | class MagicicadaUIContentQueueTestCase(_MagicicadaUIQueueTestCase): |
679 | - """UI test cases for content queue views.""" |
680 | + """UI test cases for content queue view.""" |
681 | |
682 | queue = CONTENT_QUEUE |
683 | |
684 | |
685 | class MagicicadaUIMetaQueueTestCase(_MagicicadaUIQueueTestCase): |
686 | - """UI test cases for meta queue views.""" |
687 | + """UI test cases for meta queue view.""" |
688 | |
689 | queue = META_QUEUE |
690 | + |
691 | + |
692 | +class MagicicadaUIStatusTestCase(MagicicadaUITestCase): |
693 | + """UI test cases for the status label.""" |
694 | + |
695 | + def setUp(self): |
696 | + """Init.""" |
697 | + super(MagicicadaUIStatusTestCase, self).setUp() |
698 | + |
699 | + def test_callback_is_connected(self): |
700 | + """Status callback is connected.""" |
701 | + self.assertEqual(self.ui.sd.status_changed_callback, |
702 | + self.ui.on_status_changed, |
703 | + 'status_changed callback must be set') |
704 | + |
705 | + def test_on_status_changed_updates_status_label(self): |
706 | + """On status changed the status label is updated.""" |
707 | + kwargs = dict(name='test', description='the status for testing', |
708 | + is_error=False, is_connected=True, is_online=False, |
709 | + queues=None, connection=None) |
710 | + self.ui.on_status_changed(**kwargs) |
711 | + self.assertEqual(self.ui.status_label.get_text(), kwargs['description']) |
712 | + |
713 | + |
714 | +class MagicicadaUIConnectionTestCase(MagicicadaUITestCase): |
715 | + """UI test cases for.""" |
716 | + |
717 | + def setUp(self): |
718 | + """Init.""" |
719 | + super(MagicicadaUIConnectionTestCase, self).setUp() |
720 | + |
721 | + def test_all_disabled_at_startup(self): |
722 | + """Indicators are all disabled at startup.""" |
723 | + self.assert_indicator_disabled(self.ui.is_started) |
724 | + self.assert_indicator_disabled(self.ui.is_connected) |
725 | + self.assert_indicator_disabled(self.ui.is_online) |
726 | + |
727 | + def test_callback_are_connected(self): |
728 | + """Connection callbacks are connected.""" |
729 | + for callback in ('on_started', 'on_stopped', |
730 | + 'on_connected', 'on_disconnected', |
731 | + 'on_online', 'on_offline'): |
732 | + sd_cb = getattr(self.ui.sd, '%s_callback' % callback) |
733 | + ui_cb = getattr(self.ui, callback) |
734 | + self.assertEqual(sd_cb, ui_cb, |
735 | + '%s callback must be set' % callback) |
736 | + |
737 | + def test_on_started_is_correct(self): |
738 | + """On SD started, the UI enables connect and indicator.""" |
739 | + # must have click start first |
740 | + self.ui.on_start_clicked(self.ui.start) |
741 | + assert not self.ui.stop.is_sensitive() |
742 | + assert not self.ui.connect.is_sensitive() |
743 | + |
744 | + self.ui.on_started() |
745 | + |
746 | + self.assertTrue(self.ui.stop.is_sensitive()) |
747 | + self.assertTrue(self.ui.connect.is_sensitive()) |
748 | + self.assert_indicator_ready(self.ui.is_started) |
749 | + self.assert_indicator_disabled(self.ui.is_connected) |
750 | + self.assert_indicator_disabled(self.ui.is_online) |
751 | + |
752 | + def test_on_connected_is_correct(self): |
753 | + """On SD connected, the UI enables indicator.""" |
754 | + self.ui.on_start_clicked(self.ui.start) |
755 | + self.ui.on_started() |
756 | + self.ui.on_connect_clicked(self.ui.start) |
757 | + assert not self.ui.disconnect.is_sensitive() |
758 | + |
759 | + self.ui.on_connected() |
760 | + |
761 | + self.assertTrue(self.ui.disconnect.is_sensitive()) |
762 | + self.assert_indicator_ready(self.ui.is_started) |
763 | + self.assert_indicator_ready(self.ui.is_connected) |
764 | + self.assert_indicator_loading(self.ui.is_online) |
765 | + |
766 | + def test_on_online_is_correct(self): |
767 | + """On SD online, the UI enables indicator.""" |
768 | + self.ui.on_start_clicked(self.ui.start) |
769 | + self.ui.on_started() |
770 | + self.ui.on_connect_clicked(self.ui.connect) |
771 | + self.ui.on_connected() |
772 | + |
773 | + self.ui.on_online() |
774 | + |
775 | + self.assert_indicator_ready(self.ui.is_started) |
776 | + self.assert_indicator_ready(self.ui.is_connected) |
777 | + self.assert_indicator_ready(self.ui.is_online) |
778 | + |
779 | + def test_on_stopped_is_correct(self): |
780 | + """On SD stopped, the UI disables stop and indicator.""" |
781 | + self.ui.on_start_clicked(self.ui.start) |
782 | + self.ui.on_started() |
783 | + self.ui.on_stop_clicked(self.ui.stop) |
784 | + |
785 | + self.ui.on_stopped() |
786 | + |
787 | + self.assertTrue(self.ui.start.is_sensitive()) |
788 | + self.assertTrue(self.ui.start.get_property('visible')) |
789 | + self.assert_indicator_disabled(self.ui.is_started) |
790 | + self.assert_indicator_disabled(self.ui.is_connected) |
791 | + self.assert_indicator_disabled(self.ui.is_online) |
792 | + |
793 | + def test_on_disconnected_is_correct(self): |
794 | + """On SD disconnected, the UI disables connect and indicator.""" |
795 | + self.ui.on_start_clicked(self.ui.start) |
796 | + self.ui.on_started() |
797 | + self.ui.on_connect_clicked(self.ui.connect) |
798 | + self.ui.on_connected() |
799 | + self.ui.on_disconnect_clicked(self.ui.disconnect) |
800 | + |
801 | + self.ui.on_disconnected() |
802 | + |
803 | + self.assertTrue(self.ui.connect.is_sensitive()) |
804 | + self.assert_indicator_ready(self.ui.is_started) |
805 | + self.assert_indicator_disabled(self.ui.is_connected) |
806 | + self.assert_indicator_disabled(self.ui.is_online) |
807 | + |
808 | + def test_on_offline_is_correct(self): |
809 | + """On SD offline, the UI disables indicator.""" |
810 | + self.ui.on_start_clicked(self.ui.start) |
811 | + self.ui.on_started() |
812 | + self.ui.on_connect_clicked(self.ui.connect) |
813 | + self.ui.on_connected() |
814 | + |
815 | + self.ui.on_offline() |
816 | + |
817 | + self.assert_indicator_ready(self.ui.is_started) |
818 | + self.assert_indicator_ready(self.ui.is_connected) |
819 | + self.assert_indicator_disabled(self.ui.is_online) |
820 | + |
Go forward!