Merge lp:~nataliabidart/software-center/cant-stop-the-music into lp:software-center/5.2
- cant-stop-the-music
- Merge into 5.2
Status: | Merged |
---|---|
Merged at revision: | 3050 |
Proposed branch: | lp:~nataliabidart/software-center/cant-stop-the-music |
Merge into: | lp:software-center/5.2 |
Diff against target: |
491 lines (+165/-59) 8 files modified
softwarecenter/ui/gtk3/session/navhistory.py (+2/-3) softwarecenter/ui/gtk3/session/viewmanager.py (+5/-0) softwarecenter/ui/gtk3/views/appdetailsview.py (+9/-8) softwarecenter/ui/gtk3/widgets/videoplayer.py (+3/-0) test/gtk3/test_appdetailsview.py (+58/-45) test/gtk3/test_appmanager.py (+2/-1) test/gtk3/test_viewmanager.py (+59/-0) test/gtk3/test_widgets.py (+27/-2) |
To merge this branch: | bzr merge lp:~nataliabidart/software-center/cant-stop-the-music |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Vogt | Approve | ||
Review via email: mp+110607@code.launchpad.net |
Commit message
- Stop the video if user navigates away from an app details page
(LP: #1003954).
Description of the change
Michael Vogt (mvo) wrote : | # |
Michael Vogt (mvo) wrote : | # |
(oh, and I love your branch names)
Natalia Bidart (nataliabidart) wrote : | # |
> Thanks Natalia, this is great work!
>
> There is one small issue:
> - navigate to "plutoids"
> - click on "back"
> - click on "forward"
> - the video frame is now blank because on navigation to the page the url is
> not updated
> (as the view is "clever" and remembers that it does not need to reload the
> page)
>
> It would be great if you could have a look at this.
Nice catch! Will be fixing this ASAP.
> Another thought for trunk would be to decouple the "stop" from the
> ViewManager.
> signals or functions like "enter-page", "leave-page" so that the page itself
> can do the magic that needs
> to be done (like stop video or store the vadjustment in the applist). What do
> you think about
> this?
I would love that considering that the current proposed solution couples the different modules too much.
You want me to propose a branch against trunk? is it ok if trunk and 5.2 start diverging?
Michael Vogt (mvo) wrote : | # |
On Mon, Jun 18, 2012 at 11:51:34AM -0000, Natalia Bidart wrote:
> > Thanks Natalia, this is great work!
> >
> > There is one small issue:
> > - navigate to "plutoids"
> > - click on "back"
> > - click on "forward"
> > - the video frame is now blank because on navigation to the page the url is
> > not updated
> > (as the view is "clever" and remembers that it does not need to reload the
> > page)
> >
> > It would be great if you could have a look at this.
>
> Nice catch! Will be fixing this ASAP.
Thanks!
> > Another thought for trunk would be to decouple the "stop" from the
> > ViewManager.
> > signals or functions like "enter-page", "leave-page" so that the page itself
> > can do the magic that needs
> > to be done (like stop video or store the vadjustment in the applist). What do
> > you think about
> > this?
>
> I would love that considering that the current proposed solution couples the different modules too much.
>
> You want me to propose a branch against trunk? is it ok if trunk and 5.2 start diverging?
I think for 5.2 this branch is perfect as it makes the SRU upload
easier (small amount of code changes etc). For the improved fix we
should target trunk and I think its ok if the two branches diverge,
its a unavoidable in the longer term anyway :)
Cheers,
Michael
- 3053. By Natalia Bidart
-
Ensure that video gets updated when navigating back to an already visited app.
Michael Vogt (mvo) wrote : | # |
Thanks for the fix, this looks fine now. Plus I appreciate the cleanup in the test, e.g. the new
"set_mock_
Preview Diff
1 | === modified file 'softwarecenter/ui/gtk3/session/navhistory.py' |
2 | --- softwarecenter/ui/gtk3/session/navhistory.py 2012-03-15 00:16:03 +0000 |
3 | +++ softwarecenter/ui/gtk3/session/navhistory.py 2012-06-18 14:42:18 +0000 |
4 | @@ -124,9 +124,8 @@ |
5 | |
6 | def __str__(self): |
7 | facet = self.pane.pane_name.replace(' ', '')[:6] |
8 | - return utf8("%s:%s %s") % (facet, |
9 | - self.page, |
10 | - self.view_state) |
11 | + result = utf8("%s:%s %s") % (facet, self.page, self.view_state) |
12 | + return result |
13 | |
14 | def navigate_to(self): |
15 | """ |
16 | |
17 | === modified file 'softwarecenter/ui/gtk3/session/viewmanager.py' |
18 | --- softwarecenter/ui/gtk3/session/viewmanager.py 2012-04-16 21:51:02 +0000 |
19 | +++ softwarecenter/ui/gtk3/session/viewmanager.py 2012-06-18 14:42:18 +0000 |
20 | @@ -177,6 +177,11 @@ |
21 | if ni.pane.is_applist_view_showing(): |
22 | v = ni.pane.app_view.tree_view_scroll.get_vadjustment() |
23 | ni.view_state.vadjustment = v.get_value() |
24 | + # if there is a video playing, stop it |
25 | + try: |
26 | + ni.pane.app_details_view.videoplayer.stop() |
27 | + except AttributeError: |
28 | + pass |
29 | |
30 | if callback is None: |
31 | callback = pane.get_callback_for_page(page, view_state) |
32 | |
33 | === modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py' |
34 | --- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-05-22 07:29:34 +0000 |
35 | +++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-06-18 14:42:18 +0000 |
36 | @@ -1565,6 +1565,7 @@ |
37 | self._update_pkg_info_table(app_details) |
38 | self._update_warning_bar(app_details) |
39 | # self._update_addons_minimal(app_details) |
40 | + self._update_app_video(app_details) |
41 | |
42 | # depending on pkg install state set action labels |
43 | self.pkg_statusbar.configure(app_details, app_details.pkg_state) |
44 | @@ -2042,7 +2043,7 @@ |
45 | self.section = section |
46 | |
47 | |
48 | -def get_test_window_appdetails(): |
49 | +def get_test_window_appdetails(pkgname="totem"): |
50 | |
51 | from softwarecenter.db.pkginfo import get_pkg_info |
52 | cache = get_pkg_info() |
53 | @@ -2068,12 +2069,6 @@ |
54 | scroll = Gtk.ScrolledWindow() |
55 | view = AppDetailsView(db, distro, icons, cache, datadir) |
56 | |
57 | - import sys |
58 | - if len(sys.argv) > 1: |
59 | - pkgname = sys.argv[1] |
60 | - else: |
61 | - pkgname = "totem" |
62 | - |
63 | view.show_app(Application("", pkgname)) |
64 | #view.show_app(Application("Pay App Example", "pay-app")) |
65 | #view.show_app(Application("3D Chess", "3dchess")) |
66 | @@ -2105,7 +2100,13 @@ |
67 | view.show_app(Application("Movie Player", "totem")) |
68 | return True |
69 | |
70 | - win = get_test_window_appdetails() |
71 | + import sys |
72 | + if len(sys.argv) > 1: |
73 | + pkgname = sys.argv[1] |
74 | + else: |
75 | + pkgname = "totem" |
76 | + |
77 | + win = get_test_window_appdetails(pkgname=pkgname) |
78 | |
79 | # keep it spinning to test for re-draw issues and memleaks |
80 | #view = win.get_data("view") |
81 | |
82 | === modified file 'softwarecenter/ui/gtk3/widgets/videoplayer.py' |
83 | --- softwarecenter/ui/gtk3/widgets/videoplayer.py 2012-04-18 21:04:11 +0000 |
84 | +++ softwarecenter/ui/gtk3/widgets/videoplayer.py 2012-06-18 14:42:18 +0000 |
85 | @@ -91,6 +91,9 @@ |
86 | base_uri = "http://www.ubuntu.com" |
87 | self.webkit.load_html_string(html, base_uri) |
88 | |
89 | + def stop(self): |
90 | + self.webkit.load_uri('') |
91 | + |
92 | |
93 | # AKA the-segfault-edition-with-no-documentation |
94 | class VideoPlayerGtk3(Gtk.VBox): |
95 | |
96 | === modified file 'test/gtk3/test_appdetailsview.py' |
97 | --- test/gtk3/test_appdetailsview.py 2012-04-17 14:27:43 +0000 |
98 | +++ test/gtk3/test_appdetailsview.py 2012-06-18 14:42:18 +0000 |
99 | @@ -20,10 +20,11 @@ |
100 | from test.test_database import make_purchased_app_details |
101 | |
102 | |
103 | - |
104 | # window destory timeout |
105 | TIMEOUT=100 |
106 | |
107 | + |
108 | + |
109 | class TestAppdetailsView(unittest.TestCase): |
110 | |
111 | def setUp(self): |
112 | @@ -34,6 +35,16 @@ |
113 | GObject.timeout_add(TIMEOUT, lambda: self.win.destroy()) |
114 | Gtk.main() |
115 | |
116 | + def set_mock_app_and_details(self, app_name="software-center", **kwargs): |
117 | + app = Application("", app_name) |
118 | + mock_app = get_mock_app_from_real_app(app) |
119 | + mock_details = mock_app.get_details(None) |
120 | + for attr, value in kwargs.iteritems(): |
121 | + setattr(mock_details, attr, value) |
122 | + |
123 | + self.view.app = mock_app |
124 | + self.view.app_details = mock_details |
125 | + |
126 | def test_videoplayer(self): |
127 | # show app with no video |
128 | app = Application("", "2vcard") |
129 | @@ -42,34 +53,30 @@ |
130 | self.assertFalse(self.view.videoplayer.get_property("visible")) |
131 | |
132 | # create app with video and ensure its visible |
133 | - app = Application("", "synaptic") |
134 | - mock = get_mock_app_from_real_app(app) |
135 | - details = mock.get_details(None) |
136 | - # this is a example html - any html5 video will do |
137 | - details.video_url = "http://people.canonical.com/~mvo/totem.html" |
138 | - self.view.show_app(mock) |
139 | + self.set_mock_app_and_details( |
140 | + app_name="synaptic", |
141 | + # this is a example html - any html5 video will do |
142 | + video_url="http://people.canonical.com/~mvo/totem.html") |
143 | + self.view.show_app(self.view.app) |
144 | do_events() |
145 | self.assertTrue(self.view.videoplayer.get_property("visible")) |
146 | - |
147 | + |
148 | def test_page_pkgstates(self): |
149 | - # show app |
150 | + # show app |
151 | app = Application("", "abiword") |
152 | self.view.show_app(app) |
153 | do_events() |
154 | - |
155 | + |
156 | # check that the action bar is given initial focus in the view |
157 | self.assertTrue(self.view.pkg_statusbar.button.is_focus()) |
158 | |
159 | # create mock app |
160 | - mock_app = get_mock_app_from_real_app(app) |
161 | - self.view.app = mock_app |
162 | - mock_details = mock_app.get_details(None) |
163 | - mock_details.purchase_date = "2011-11-20 17:45:01" |
164 | - mock_details._error_not_found = "error not found" |
165 | - mock_details.price = "1.00" |
166 | - mock_details.pkgname = "abiword" |
167 | - mock_details.error = "error-text" |
168 | - self.view.app_details = mock_details |
169 | + self.set_mock_app_and_details( |
170 | + app_name="abiword", purchase_date="2011-11-20 17:45:01", |
171 | + _error_not_found="error not found", price="1.00", |
172 | + pkgname="abiword", error="error-text") |
173 | + mock_app = self.view.app |
174 | + mock_details = self.view.app_details |
175 | |
176 | # the states and what labels we expect in the pkgstatusbar |
177 | # first string is status text, second is button text |
178 | @@ -101,7 +108,7 @@ |
179 | if state in pkg_states_to_labels: |
180 | label, button_label = pkg_states_to_labels[state] |
181 | self.assertEqual( |
182 | - self.view.pkg_statusbar.get_label(), |
183 | + self.view.pkg_statusbar.get_label(), |
184 | label.decode("utf-8")) |
185 | self.assertEqual( |
186 | self.view.pkg_statusbar.get_button_label().decode("utf-8"), |
187 | @@ -122,15 +129,10 @@ |
188 | |
189 | def test_app_icon_loading(self): |
190 | # get icon |
191 | - app = Application("", "software-center") |
192 | - mock_app = get_mock_app_from_real_app(app) |
193 | - self.view.app = mock_app |
194 | - mock_details = mock_app.get_details(None) |
195 | - mock_details.cached_icon_file_path = "download-icon-test" |
196 | - mock_details.icon = "favicon.ico" |
197 | - mock_details.icon_url = "http://de.wikipedia.org/favicon.ico" |
198 | - self.view.app_details = mock_details |
199 | - self.view.show_app(mock_app) |
200 | + self.set_mock_app_and_details( |
201 | + cached_icon_file_path="download-icon-test", icon="favicon.ico", |
202 | + icon_url="http://de.wikipedia.org/favicon.ico") |
203 | + self.view.show_app(self.view.app) |
204 | do_events() |
205 | # ensure the icon is there |
206 | # FIXME: ensure that the icon is really downloaded |
207 | @@ -250,10 +252,21 @@ |
208 | self.view._submit_reviews_done_callback(None, 0) |
209 | |
210 | self.assertTrue(button.is_sensitive()) |
211 | - |
212 | + |
213 | + def test_show_app_twice_plays_video(self): |
214 | + video_url = "http://people.canonical.com/~mvo/totem.html" |
215 | + self.set_mock_app_and_details(video_url=video_url) |
216 | + |
217 | + self.view.show_app(self.view.app) |
218 | + self.assertEqual(self.view.videoplayer.uri, video_url) |
219 | + |
220 | + self.view.videoplayer.uri = None |
221 | + self.view.show_app(self.view.app) |
222 | + self.assertEqual(self.view.videoplayer.uri, video_url) |
223 | + |
224 | |
225 | class MultipleVersionsTestCase(unittest.TestCase): |
226 | - |
227 | + |
228 | @classmethod |
229 | def setUpClass(cls): |
230 | # Set these as class attributes as we don't modify either |
231 | @@ -278,7 +291,7 @@ |
232 | self.view.show_app(self.app_mock) |
233 | self.assertFalse(self.view.pkg_statusbar.combo_multiple_versions.get_visible()) |
234 | # switch to not-automatic app with different description |
235 | - self.app_mock.details.get_not_automatic_archive_versions = lambda: [ |
236 | + self.app_mock.details.get_not_automatic_archive_versions = lambda: [ |
237 | ("5.0", "precise"), |
238 | ("12.0", "precise-backports"), |
239 | ] |
240 | @@ -290,7 +303,7 @@ |
241 | def test_combo_multiple_versions(self): |
242 | self.app_mock.details.get_not_automatic_archive_versions = lambda: [ |
243 | ("5.0", "precise"), |
244 | - ("12.0", "precise-backports") |
245 | + ("12.0", "precise-backports") |
246 | ] |
247 | # ensure that the right method is called |
248 | self.app_mock.details.force_not_automatic_archive_suite = Mock() |
249 | @@ -305,7 +318,7 @@ |
250 | def test_installed_multiple_version_default(self): |
251 | self.app_mock.details.get_not_automatic_archive_versions = lambda: [ |
252 | ("5.0", "precise"), |
253 | - ("12.0", "precise-backports") |
254 | + ("12.0", "precise-backports") |
255 | ] |
256 | self.app_mock.details.pkg_state = PkgStates.INSTALLED |
257 | self.app_mock.details.version = "12.0" |
258 | @@ -332,10 +345,10 @@ |
259 | #self.assertEqual(call_args, (("precise",), {})) |
260 | # ensure the button changes |
261 | self.assertEqual(self.view.pkg_statusbar.button.get_label(), "Change") |
262 | - |
263 | + |
264 | |
265 | class HardwareRequirementsTestCase(unittest.TestCase): |
266 | - |
267 | + |
268 | @classmethod |
269 | def setUpClass(cls): |
270 | # Set these as class attributes as we don't modify either |
271 | @@ -356,7 +369,7 @@ |
272 | self.app_mock.details.pkg_state = PkgStates.UNINSTALLED |
273 | |
274 | def test_show_hardware_requirements(self): |
275 | - self.app_mock.details.hardware_requirements = { |
276 | + self.app_mock.details.hardware_requirements = { |
277 | 'hardware::video:opengl' : 'yes', |
278 | 'hardware::gps' : 'no', |
279 | } |
280 | @@ -378,7 +391,7 @@ |
281 | self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE |
282 | self.view.show_app(self.app_mock) |
283 | self.assertEqual( |
284 | - self.view.pkg_statusbar.button.get_label(), |
285 | + self.view.pkg_statusbar.button.get_label(), |
286 | _(u"Buy Anyway\u2026").encode("utf-8")) |
287 | # check if the warning bar is displayed |
288 | self.assertTrue(self.view.pkg_warningbar.get_property("visible")) |
289 | @@ -401,13 +414,13 @@ |
290 | self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE |
291 | self.view.show_app(self.app_mock) |
292 | self.assertEqual( |
293 | - self.view.pkg_statusbar.button.get_label(), |
294 | + self.view.pkg_statusbar.button.get_label(), |
295 | _(u'Buy\u2026').encode("utf-8")) |
296 | # check if the warning bar is invisible |
297 | self.assertFalse(self.view.pkg_warningbar.get_property("visible")) |
298 | |
299 | class RegionRequirementsTestCase(unittest.TestCase): |
300 | - |
301 | + |
302 | @classmethod |
303 | def setUpClass(cls): |
304 | # Set these as class attributes as we don't modify either |
305 | @@ -438,7 +451,7 @@ |
306 | self.app_mock.details.pkg_state = PkgStates.NEEDS_PURCHASE |
307 | self.view.show_app(self.app_mock) |
308 | self.assertEqual( |
309 | - self.view.pkg_statusbar.button.get_label(), |
310 | + self.view.pkg_statusbar.button.get_label(), |
311 | _(u"Buy Anyway\u2026").encode("utf-8")) |
312 | # check if the warning bar is displayed |
313 | self.assertTrue(self.view.pkg_warningbar.get_property("visible")) |
314 | @@ -537,9 +550,9 @@ |
315 | self.assertEqual( |
316 | [method_name], |
317 | all_method_calls) |
318 | - |
319 | + |
320 | class AppRecommendationsTestCase(unittest.TestCase): |
321 | - |
322 | + |
323 | @classmethod |
324 | def setUpClass(cls): |
325 | # Set these as class attributes as we don't modify either |
326 | @@ -558,11 +571,11 @@ |
327 | app = Application("", "pitivi") |
328 | self.app_mock = get_mock_app_from_real_app(app) |
329 | self.app_mock.details.pkg_state = PkgStates.UNINSTALLED |
330 | - |
331 | + |
332 | def on_query_done(self, recagent, data): |
333 | print "query done, data: '%s'" % data |
334 | self.loop.quit() |
335 | - |
336 | + |
337 | def on_query_error(self, recagent, error): |
338 | print "query error received: ", error |
339 | self.loop.quit() |
340 | |
341 | === modified file 'test/gtk3/test_appmanager.py' |
342 | --- test/gtk3/test_appmanager.py 2012-01-16 14:42:49 +0000 |
343 | +++ test/gtk3/test_appmanager.py 2012-06-18 14:42:18 +0000 |
344 | @@ -14,6 +14,7 @@ |
345 | from softwarecenter.ui.gtk3.session.appmanager import ( |
346 | ApplicationManager, get_appmanager) |
347 | |
348 | + |
349 | class TestAppManager(unittest.TestCase): |
350 | """ tests the appmanager """ |
351 | |
352 | @@ -38,7 +39,7 @@ |
353 | # test creating it twice raises a error |
354 | self.assertRaises( |
355 | ValueError, ApplicationManager, self.db, self.backend, self.icons) |
356 | - |
357 | + |
358 | def test_appmanager(self): |
359 | app_manager = get_appmanager() |
360 | self.assertNotEqual(app_manager, None) |
361 | |
362 | === added file 'test/gtk3/test_viewmanager.py' |
363 | --- test/gtk3/test_viewmanager.py 1970-01-01 00:00:00 +0000 |
364 | +++ test/gtk3/test_viewmanager.py 2012-06-18 14:42:18 +0000 |
365 | @@ -0,0 +1,59 @@ |
366 | +#!/usr/bin/python |
367 | + |
368 | +import unittest |
369 | + |
370 | +from gi.repository import Gtk |
371 | +from mock import Mock |
372 | + |
373 | +from testutils import setup_test_env |
374 | +setup_test_env() |
375 | + |
376 | +from softwarecenter.ui.gtk3.panes import availablepane, softwarepane |
377 | +from softwarecenter.ui.gtk3.session.viewmanager import ( |
378 | + ViewManager, |
379 | + get_viewmanager |
380 | +) |
381 | + |
382 | + |
383 | +class TestViewManager(unittest.TestCase): |
384 | + """Test suite for the viewmanager.""" |
385 | + |
386 | + def setUp(self): |
387 | + # create it once, it becomes global instance |
388 | + self.vm = get_viewmanager() |
389 | + if self.vm is None: |
390 | + self.vm = ViewManager(Gtk.Notebook()) |
391 | + |
392 | + self.addCleanup(self.vm.destroy) |
393 | + |
394 | + def test_get_viewmanager(self): |
395 | + view_manager = get_viewmanager() |
396 | + self.assertNotEqual(view_manager, None) |
397 | + # is a singleton singleton |
398 | + view_manager2 = get_viewmanager() |
399 | + self.assertIs(view_manager, view_manager2) |
400 | + # test creating it twice raises a error |
401 | + self.assertRaises(ValueError, ViewManager, Gtk.Notebook()) |
402 | + |
403 | + def test_display_page_stops_video(self): |
404 | + called = [] |
405 | + # navigate to an app details view with video |
406 | + pane = Mock() |
407 | + pane.pane_name = 'MockPane' |
408 | + pane.is_applist_view_showing = lambda: False |
409 | + pane.app_details_view.videoplayer.stop = lambda: called.append('stop') |
410 | + self.vm.display_page( |
411 | + pane, page=availablepane.AvailablePane.Pages.DETAILS, |
412 | + view_state=softwarepane.DisplayState()) |
413 | + |
414 | + other_pane = Mock() |
415 | + other_pane.pane_name = 'MockPane' |
416 | + self.vm.display_page( |
417 | + other_pane, page=availablepane.AvailablePane.Pages.DETAILS, |
418 | + view_state=softwarepane.DisplayState()) |
419 | + |
420 | + self.assertEqual(called, ['stop']) |
421 | + |
422 | + |
423 | +if __name__ == "__main__": |
424 | + unittest.main() |
425 | |
426 | === modified file 'test/gtk3/test_widgets.py' |
427 | --- test/gtk3/test_widgets.py 2012-04-12 07:46:56 +0000 |
428 | +++ test/gtk3/test_widgets.py 2012-06-18 14:42:18 +0000 |
429 | @@ -10,6 +10,7 @@ |
430 | from testutils import setup_test_env, do_events |
431 | setup_test_env() |
432 | from softwarecenter.utils import utf8 |
433 | +from softwarecenter.ui.gtk3.widgets import videoplayer |
434 | from softwarecenter.ui.gtk3.widgets.reviews import get_test_reviews_window |
435 | from softwarecenter.ui.gtk3.widgets.labels import ( |
436 | HardwareRequirementsLabel, HardwareRequirementsBox) |
437 | @@ -118,13 +119,13 @@ |
438 | GObject.timeout_add(TIMEOUT, lambda: win.destroy()) |
439 | Gtk.main() |
440 | |
441 | - |
442 | def test_apptreeview(self): |
443 | from softwarecenter.ui.gtk3.widgets.apptreeview import get_test_window |
444 | win = get_test_window() |
445 | GObject.timeout_add(TIMEOUT, lambda: win.destroy()) |
446 | Gtk.main() |
447 | |
448 | + |
449 | class TestHWRequirements(unittest.TestCase): |
450 | |
451 | HW_TEST_RESULT = { 'hardware::gps' : 'yes', |
452 | @@ -177,7 +178,7 @@ |
453 | # test seting it again |
454 | box.set_hardware_requirements(self.HW_TEST_RESULT) |
455 | self.assertEqual(len(box.get_children()), 2) |
456 | - |
457 | + |
458 | |
459 | class TestUIReviewsList(unittest.TestCase): |
460 | def setUp(self): |
461 | @@ -241,6 +242,30 @@ |
462 | _('Be the first to contribute a review for this application')) |
463 | |
464 | |
465 | +class VideoPlayerTestCase(unittest.TestCase): |
466 | + |
467 | + def setUp(self): |
468 | + super(VideoPlayerTestCase, self).setUp() |
469 | + self.webkit_uri = None |
470 | + self.vp = videoplayer.VideoPlayer() |
471 | + self.vp.webkit.load_uri = lambda uri: setattr(self, 'webkit_uri', uri) |
472 | + self.vp.webkit.get_uri = lambda: self.webkit_uri |
473 | + self.addCleanup(self.vp.destroy) |
474 | + |
475 | + def test_uri(self): |
476 | + self.assertEqual(self.vp.uri, '') |
477 | + |
478 | + expected_uri = 'file://test' |
479 | + self.vp.uri = expected_uri |
480 | + |
481 | + self.assertEqual(self.vp.uri, expected_uri) |
482 | + self.assertEqual(self.vp.webkit.get_uri(), self.vp.uri) |
483 | + |
484 | + def test_stop(self): |
485 | + self.vp.uri = 'http://foo.bar.baz' |
486 | + self.vp.stop() |
487 | + |
488 | + self.assertEqual(self.vp.webkit.get_uri(), '') |
489 | |
490 | |
491 | if __name__ == "__main__": |
Thanks Natalia, this is great work!
There is one small issue:
- navigate to "plutoids"
- click on "back"
- click on "forward"
- the video frame is now blank because on navigation to the page the url is not updated
(as the view is "clever" and remembers that it does not need to reload the page)
It would be great if you could have a look at this.
Another thought for trunk would be to decouple the "stop" from the ViewManager. display_ page and add
signals or functions like "enter-page", "leave-page" so that the page itself can do the magic that needs
to be done (like stop video or store the vadjustment in the applist). What do you think about
this?