Merge lp:~mvo/software-center/support-multiple-exhibit-images into lp:software-center
- support-multiple-exhibit-images
- Merge into trunk
Proposed by
Michael Vogt
Status: | Merged |
---|---|
Merged at revision: | 3201 |
Proposed branch: | lp:~mvo/software-center/support-multiple-exhibit-images |
Merge into: | lp:software-center |
Diff against target: |
516 lines (+244/-182) 4 files modified
softwarecenter/ui/gtk3/views/lobbyview.py (+3/-0) softwarecenter/ui/gtk3/widgets/exhibits.py (+56/-37) tests/gtk3/test_catview.py (+3/-145) tests/gtk3/test_exhibits.py (+182/-0) |
To merge this branch: | bzr merge lp:~mvo/software-center/support-multiple-exhibit-images |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gary Lasker (community) | Approve | ||
Review via email: mp+125959@code.launchpad.net |
Commit message
Description of the change
This branch adds support for multiple images in the exhibit banners.
This is to fix #920542. It also does a bit of drive-by cleanup in the
testscases by extracting the exhibits testcase into its own file.
To post a comment you must log in.
- 3203. By Michael Vogt
-
add some debug code
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'softwarecenter/ui/gtk3/views/lobbyview.py' |
2 | --- softwarecenter/ui/gtk3/views/lobbyview.py 2012-09-20 01:09:57 +0000 |
3 | +++ softwarecenter/ui/gtk3/views/lobbyview.py 2012-09-24 15:24:22 +0000 |
4 | @@ -150,6 +150,9 @@ |
5 | exhibit.package_names.split(',')) |
6 | if available: |
7 | result.append(exhibit) |
8 | + else: |
9 | + LOG.warn("skipping exhibit for: '%r' not available" % ( |
10 | + exhibit.package_names)) |
11 | |
12 | # its ok if result is empty, since set_exhibits() will ignore |
13 | # empty lists |
14 | |
15 | === modified file 'softwarecenter/ui/gtk3/widgets/exhibits.py' |
16 | --- softwarecenter/ui/gtk3/widgets/exhibits.py 2012-09-12 14:08:18 +0000 |
17 | +++ softwarecenter/ui/gtk3/widgets/exhibits.py 2012-09-24 15:24:22 +0000 |
18 | @@ -86,10 +86,10 @@ |
19 | "webservice-office-zoho") |
20 | self.title_translated = _("Our star apps") |
21 | self.published = True |
22 | - self.banner_url = "file:%s" % (os.path.abspath(os.path.join( |
23 | - softwarecenter.paths.datadir, "default_banner/fallback.png"))) |
24 | + self.banner_urls = ["file:%s" % (os.path.abspath(os.path.join( |
25 | + softwarecenter.paths.datadir, "default_banner/fallback.png")))] |
26 | self.html = EXHIBIT_HTML % { |
27 | - 'banner_url': self.banner_url, |
28 | + 'banner_url': self.banner_urls[0], |
29 | 'title': _("Our star apps"), |
30 | 'subtitle': _("Come and explore our favourites"), |
31 | } |
32 | @@ -121,47 +121,66 @@ |
33 | self.show_all() |
34 | self.loader = SimpleFileDownloader() |
35 | self.loader.connect("file-download-complete", |
36 | - self.on_download_complete) |
37 | + self._on_one_download_complete) |
38 | self.loader.connect("error", |
39 | - self.on_download_error) |
40 | + self._on_download_error) |
41 | self.exhibit = None |
42 | - self.view.connect("notify::load-status", self._on_load_status) |
43 | - |
44 | - def _on_load_status(self, view, prop): |
45 | + self._downloaded_banner_images = [] |
46 | + self.view.connect( |
47 | + "notify::load-status", self._on_internal_renderer_load_status) |
48 | + |
49 | + def set_exhibit(self, exhibit): |
50 | + LOG.debug("set_exhibit: '%s'" % exhibit) |
51 | + self._downloaded_banner_images = [] |
52 | + self.exhibit = exhibit |
53 | + self._download_next_banner_image() |
54 | + |
55 | + def _on_download_error(self, loader, exception, error): |
56 | + LOG.warn("download failed: '%s', '%s'" % (exception, error)) |
57 | + |
58 | + def _on_one_download_complete(self, loader, path): |
59 | + LOG.debug("downloading of '%s' finished" % path) |
60 | + self._downloaded_banner_images.append(path) |
61 | + if len(self._downloaded_banner_images) < len(self.exhibit.banner_urls): |
62 | + self._download_next_banner_image() |
63 | + self._on_all_banner_images_downloaded() |
64 | + |
65 | + def _on_all_banner_images_downloaded(self): |
66 | + LOG.debug("downloading of all banner images finished") |
67 | + html = self.exhibit.html |
68 | + cache_dir = os.path.join( |
69 | + softwarecenter.paths.SOFTWARE_CENTER_CACHE_DIR, |
70 | + "download-cache") |
71 | + for url, local_file in zip(self.exhibit.banner_urls, |
72 | + self._downloaded_banner_images): |
73 | + # no need to mangle local urls |
74 | + if url.startswith("file"): |
75 | + continue |
76 | + scheme, netloc, server_path, para, query, frag = urlparse(url) |
77 | + image_name = os.path.basename(local_file) |
78 | + # replace the server side path with the local image name, this |
79 | + # assumes that the image always comes from the same server as |
80 | + # the html |
81 | + html = html.replace(server_path, image_name) |
82 | + self.exhibit.html = html |
83 | + LOG.debug("mangled html: '%s'" % html) |
84 | + self.view.load_string(html, "text/html", "UTF-8", |
85 | + "file:%s/" % cache_dir) |
86 | + |
87 | + def _download_next_banner_image(self): |
88 | + LOG.debug("_download_next_banner_image") |
89 | + self.loader.download_file( |
90 | + self.exhibit.banner_urls[len(self._downloaded_banner_images)], |
91 | + use_cache=True, |
92 | + simple_quoting_for_webkit=True) |
93 | + |
94 | + def _on_internal_renderer_load_status(self, view, prop): |
95 | + """Called when the rendering of the html banner is done""" |
96 | if view.get_property("load-status") == WebKit.LoadStatus.FINISHED: |
97 | # this needs to run with a timeout because otherwise the |
98 | # status is emited before the offscreen image is finihsed |
99 | GObject.timeout_add(100, lambda: self.emit("render-finished")) |
100 | |
101 | - def on_download_error(self, loader, exception, error): |
102 | - LOG.warn("download failed: '%s', '%s'" % (exception, error)) |
103 | - |
104 | - def on_download_complete(self, loader, path): |
105 | - image_name = os.path.basename(path) |
106 | - cache_dir = os.path.dirname(path) |
107 | - if hasattr(self.exhibit, "html") and self.exhibit.html: |
108 | - html = self.exhibit.html |
109 | - else: |
110 | - html = EXHIBIT_HTML % { |
111 | - 'banner_url': self.exhibit.banner_url, |
112 | - 'title': self.exhibit.title_translated, |
113 | - 'subtitle': "", |
114 | - } |
115 | - # replace the server side path with the local image name, this |
116 | - # assumes that the image always comes from the same server as |
117 | - # the html |
118 | - scheme, netloc, server_path, para, query, frag = urlparse( |
119 | - self.exhibit.banner_url) |
120 | - html = html.replace(server_path, image_name) |
121 | - self.view.load_string(html, "text/html", "UTF-8", |
122 | - "file:%s/" % cache_dir) |
123 | - |
124 | - def set_exhibit(self, exhibit): |
125 | - self.exhibit = exhibit |
126 | - self.loader.download_file(exhibit.banner_url, |
127 | - use_cache=True, |
128 | - simple_quoting_for_webkit=True) |
129 | - |
130 | |
131 | class ExhibitButton(Gtk.Button): |
132 | |
133 | |
134 | === modified file 'tests/gtk3/test_catview.py' |
135 | --- tests/gtk3/test_catview.py 2012-09-18 06:38:40 +0000 |
136 | +++ tests/gtk3/test_catview.py 2012-09-24 15:24:22 +0000 |
137 | @@ -6,11 +6,9 @@ |
138 | from tests.utils import ( |
139 | do_events, |
140 | do_events_with_sleep, |
141 | - FakedCache, |
142 | get_test_db, |
143 | get_test_gtk3_icon_cache, |
144 | make_recommender_agent_recommend_me_dict, |
145 | - ObjectWithSignals, |
146 | setup_test_env, |
147 | ) |
148 | setup_test_env() |
149 | @@ -19,7 +17,6 @@ |
150 | import softwarecenter.paths |
151 | |
152 | from softwarecenter.db.appfilter import AppFilter |
153 | -from softwarecenter.db.database import StoreDatabase |
154 | from softwarecenter.enums import (SortMethods, |
155 | TransactionTypes, |
156 | RecommenderFeedbackActions) |
157 | @@ -35,10 +32,10 @@ |
158 | def setUpClass(cls): |
159 | cls.db = get_test_db() |
160 | |
161 | - def setUp(self): |
162 | + def setUp(self, selected_category=None): |
163 | self._cat = None |
164 | self._app = None |
165 | - self.win = get_test_window_catview(self.db) |
166 | + self.win = get_test_window_catview(self.db, selected_category) |
167 | self.addCleanup(self.win.destroy) |
168 | self.notebook = self.win.get_child() |
169 | self.lobby = self.win.get_data("lobby") |
170 | @@ -122,19 +119,12 @@ |
171 | @patch('softwarecenter.ui.gtk3.widgets.recommendations.RecommenderAgent' |
172 | '.post_submit_profile') |
173 | def setUp(self, mock_query, mock_recommender_is_opted_in, mock_sso): |
174 | - self._cat = None |
175 | - self._app = None |
176 | # patch the recommender to specify that we are not opted-in at |
177 | # the start of each test |
178 | mock_recommender_is_opted_in.return_value = False |
179 | # we specify the "Internet" category because we do specific checks |
180 | # in the following tests that depend on this being the category choice |
181 | - self.win = get_test_window_catview(self.db, |
182 | - selected_category="Internet") |
183 | - self.addCleanup(self.win.destroy) |
184 | - self.notebook = self.win.get_child() |
185 | - self.lobby = self.win.get_data("lobby") |
186 | - self.subcat_view = self.win.get_data("subcat") |
187 | + super(RecommendationsTestCase, self).setUp(selected_category="Internet") |
188 | self.rec_panel = self.lobby.recommended_for_you_panel |
189 | |
190 | def test_recommended_for_you_opt_in_display(self): |
191 | @@ -371,138 +361,6 @@ |
192 | mock_result) |
193 | do_events() |
194 | |
195 | - |
196 | -class ExhibitsTestCase(unittest.TestCase): |
197 | - """The test suite for the exhibits carousel.""" |
198 | - |
199 | - def setUp(self): |
200 | - self.cache = FakedCache() |
201 | - self.db = StoreDatabase(cache=self.cache) |
202 | - self.lobby = lobbyview.LobbyView(cache=self.cache, db=self.db, |
203 | - icons=None, apps_filter=None) |
204 | - self.addCleanup(self.lobby.destroy) |
205 | - |
206 | - def _get_banner_from_lobby(self): |
207 | - return self.lobby.vbox.get_children()[-1].get_child() |
208 | - |
209 | - def test_featured_exhibit_by_default(self): |
210 | - """Show the featured exhibit before querying the remote service.""" |
211 | - self.lobby._append_banner_ads() |
212 | - |
213 | - banner = self._get_banner_from_lobby() |
214 | - self.assertEqual(1, len(banner.exhibits)) |
215 | - self.assertIsInstance(banner.exhibits[0], lobbyview.FeaturedExhibit) |
216 | - |
217 | - def test_no_exhibit_if_not_available(self): |
218 | - """The exhibit should not be shown if the package is not available.""" |
219 | - exhibit = Mock() |
220 | - exhibit.package_names = u'foobarbaz' |
221 | - |
222 | - sca = ObjectWithSignals() |
223 | - sca.query_exhibits = lambda: sca.emit('exhibits', sca, [exhibit]) |
224 | - |
225 | - with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
226 | - self.lobby._append_banner_ads() |
227 | - |
228 | - banner = self._get_banner_from_lobby() |
229 | - self.assertEqual(1, len(banner.exhibits)) |
230 | - self.assertIsInstance(banner.exhibits[0], lobbyview.FeaturedExhibit) |
231 | - |
232 | - def test_exhibit_if_available(self): |
233 | - """The exhibit should be shown if the package is available.""" |
234 | - exhibit = Mock() |
235 | - exhibit.package_names = u'foobarbaz' |
236 | - exhibit.banner_url = 'banner' |
237 | - exhibit.title_translated = '' |
238 | - |
239 | - self.cache[u'foobarbaz'] = Mock() |
240 | - |
241 | - sca = ObjectWithSignals() |
242 | - sca.query_exhibits = lambda: sca.emit('exhibits', sca, [exhibit]) |
243 | - |
244 | - with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
245 | - self.lobby._append_banner_ads() |
246 | - |
247 | - banner = self._get_banner_from_lobby() |
248 | - self.assertEqual(1, len(banner.exhibits)) |
249 | - self.assertIs(banner.exhibits[0], exhibit) |
250 | - |
251 | - def test_exhibit_if_mixed_availability(self): |
252 | - """The exhibit should be shown even if some are not available.""" |
253 | - # available exhibit |
254 | - exhibit = Mock() |
255 | - exhibit.package_names = u'foobarbaz' |
256 | - exhibit.banner_url = 'banner' |
257 | - exhibit.title_translated = '' |
258 | - |
259 | - self.cache[u'foobarbaz'] = Mock() |
260 | - |
261 | - # not available exhibit |
262 | - other = Mock() |
263 | - other.package_names = u'not-there' |
264 | - |
265 | - sca = ObjectWithSignals() |
266 | - sca.query_exhibits = lambda: sca.emit('exhibits', sca, |
267 | - [exhibit, other]) |
268 | - |
269 | - with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
270 | - self.lobby._append_banner_ads() |
271 | - |
272 | - banner = self._get_banner_from_lobby() |
273 | - self.assertEqual(1, len(banner.exhibits)) |
274 | - self.assertIs(banner.exhibits[0], exhibit) |
275 | - |
276 | - def test_exhibit_with_url(self): |
277 | - # available exhibit |
278 | - exhibit = Mock() |
279 | - exhibit.package_names = '' |
280 | - exhibit.click_url = 'http://example.com' |
281 | - exhibit.banner_url = 'banner' |
282 | - exhibit.title_translated = '' |
283 | - |
284 | - sca = ObjectWithSignals() |
285 | - sca.query_exhibits = lambda: sca.emit('exhibits', sca, |
286 | - [exhibit]) |
287 | - |
288 | - with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
289 | - # add the banners |
290 | - self.lobby._append_banner_ads() |
291 | - # fake click |
292 | - alloc = self.lobby.exhibit_banner.get_allocation() |
293 | - mock_event = Mock() |
294 | - mock_event.x = alloc.x |
295 | - mock_event.y = alloc.y |
296 | - with patch.object(self.lobby.exhibit_banner, 'emit') as mock_emit: |
297 | - self.lobby.exhibit_banner.on_button_press(None, mock_event) |
298 | - self.lobby.exhibit_banner.on_button_release(None, mock_event) |
299 | - mock_emit.assert_called() |
300 | - signal_name = mock_emit.call_args[0][0] |
301 | - call_exhibit = mock_emit.call_args[0][1] |
302 | - self.assertEqual(signal_name, "show-exhibits-clicked") |
303 | - self.assertEqual(call_exhibit.click_url, "http://example.com") |
304 | - |
305 | - def test_exhibit_with_featured_exhibit(self): |
306 | - """ regression test for bug #1023777 """ |
307 | - sca = ObjectWithSignals() |
308 | - sca.query_exhibits = lambda: sca.emit('exhibits', sca, |
309 | - [lobbyview.FeaturedExhibit()]) |
310 | - |
311 | - with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
312 | - # add the banners |
313 | - self.lobby._append_banner_ads() |
314 | - # fake click |
315 | - alloc = self.lobby.exhibit_banner.get_allocation() |
316 | - mock_event = Mock() |
317 | - mock_event.x = alloc.x |
318 | - mock_event.y = alloc.y |
319 | - with patch.object(self.lobby, 'emit') as mock_emit: |
320 | - self.lobby.exhibit_banner.on_button_press(None, mock_event) |
321 | - self.lobby.exhibit_banner.on_button_release(None, mock_event) |
322 | - mock_emit.assert_called() |
323 | - signal_name = mock_emit.call_args[0][0] |
324 | - call_category = mock_emit.call_args[0][1] |
325 | - self.assertEqual(signal_name, "category-selected") |
326 | - self.assertEqual(call_category.name, "Our star apps") |
327 | |
328 | if __name__ == "__main__": |
329 | unittest.main() |
330 | |
331 | === added file 'tests/gtk3/test_exhibits.py' |
332 | --- tests/gtk3/test_exhibits.py 1970-01-01 00:00:00 +0000 |
333 | +++ tests/gtk3/test_exhibits.py 2012-09-24 15:24:22 +0000 |
334 | @@ -0,0 +1,182 @@ |
335 | +import os |
336 | +import unittest |
337 | + |
338 | +from mock import patch, Mock |
339 | + |
340 | +from tests.utils import ( |
341 | + FakedCache, |
342 | + ObjectWithSignals, |
343 | + setup_test_env, |
344 | +) |
345 | +setup_test_env() |
346 | + |
347 | + |
348 | +from softwarecenter.db.database import StoreDatabase |
349 | +from softwarecenter.ui.gtk3.views import lobbyview |
350 | +from softwarecenter.ui.gtk3.widgets.exhibits import ( |
351 | + _HtmlRenderer, |
352 | + ) |
353 | + |
354 | + |
355 | +class ExhibitsTestCase(unittest.TestCase): |
356 | + """The test suite for the exhibits carousel.""" |
357 | + |
358 | + def setUp(self): |
359 | + self.cache = FakedCache() |
360 | + self.db = StoreDatabase(cache=self.cache) |
361 | + self.lobby = lobbyview.LobbyView(cache=self.cache, db=self.db, |
362 | + icons=None, apps_filter=None) |
363 | + self.addCleanup(self.lobby.destroy) |
364 | + |
365 | + def _get_banner_from_lobby(self): |
366 | + return self.lobby.vbox.get_children()[-1].get_child() |
367 | + |
368 | + def test_featured_exhibit_by_default(self): |
369 | + """Show the featured exhibit before querying the remote service.""" |
370 | + self.lobby._append_banner_ads() |
371 | + |
372 | + banner = self._get_banner_from_lobby() |
373 | + self.assertEqual(1, len(banner.exhibits)) |
374 | + self.assertIsInstance(banner.exhibits[0], lobbyview.FeaturedExhibit) |
375 | + |
376 | + def test_no_exhibit_if_not_available(self): |
377 | + """The exhibit should not be shown if the package is not available.""" |
378 | + exhibit = Mock() |
379 | + exhibit.package_names = u'foobarbaz' |
380 | + |
381 | + sca = ObjectWithSignals() |
382 | + sca.query_exhibits = lambda: sca.emit('exhibits', sca, [exhibit]) |
383 | + |
384 | + with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
385 | + self.lobby._append_banner_ads() |
386 | + |
387 | + banner = self._get_banner_from_lobby() |
388 | + self.assertEqual(1, len(banner.exhibits)) |
389 | + self.assertIsInstance(banner.exhibits[0], lobbyview.FeaturedExhibit) |
390 | + |
391 | + def test_exhibit_if_available(self): |
392 | + """The exhibit should be shown if the package is available.""" |
393 | + exhibit = Mock() |
394 | + exhibit.package_names = u'foobarbaz' |
395 | + exhibit.banner_urls = ['banner'] |
396 | + exhibit.title_translated = '' |
397 | + |
398 | + self.cache[u'foobarbaz'] = Mock() |
399 | + |
400 | + sca = ObjectWithSignals() |
401 | + sca.query_exhibits = lambda: sca.emit('exhibits', sca, [exhibit]) |
402 | + |
403 | + with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
404 | + self.lobby._append_banner_ads() |
405 | + |
406 | + banner = self._get_banner_from_lobby() |
407 | + self.assertEqual(1, len(banner.exhibits)) |
408 | + self.assertIs(banner.exhibits[0], exhibit) |
409 | + |
410 | + def test_exhibit_if_mixed_availability(self): |
411 | + """The exhibit should be shown even if some are not available.""" |
412 | + # available exhibit |
413 | + exhibit = Mock() |
414 | + exhibit.package_names = u'foobarbaz' |
415 | + exhibit.banner_urls = ['banner'] |
416 | + exhibit.title_translated = '' |
417 | + |
418 | + self.cache[u'foobarbaz'] = Mock() |
419 | + |
420 | + # not available exhibit |
421 | + other = Mock() |
422 | + other.package_names = u'not-there' |
423 | + |
424 | + sca = ObjectWithSignals() |
425 | + sca.query_exhibits = lambda: sca.emit('exhibits', sca, |
426 | + [exhibit, other]) |
427 | + |
428 | + with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
429 | + self.lobby._append_banner_ads() |
430 | + |
431 | + banner = self._get_banner_from_lobby() |
432 | + self.assertEqual(1, len(banner.exhibits)) |
433 | + self.assertIs(banner.exhibits[0], exhibit) |
434 | + |
435 | + def test_exhibit_with_url(self): |
436 | + # available exhibit |
437 | + exhibit = Mock() |
438 | + exhibit.package_names = '' |
439 | + exhibit.click_url = 'http://example.com' |
440 | + exhibit.banner_urls = ['banner'] |
441 | + exhibit.title_translated = '' |
442 | + |
443 | + sca = ObjectWithSignals() |
444 | + sca.query_exhibits = lambda: sca.emit('exhibits', sca, |
445 | + [exhibit]) |
446 | + |
447 | + with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
448 | + # add the banners |
449 | + self.lobby._append_banner_ads() |
450 | + # fake click |
451 | + alloc = self.lobby.exhibit_banner.get_allocation() |
452 | + mock_event = Mock() |
453 | + mock_event.x = alloc.x |
454 | + mock_event.y = alloc.y |
455 | + with patch.object(self.lobby.exhibit_banner, 'emit') as mock_emit: |
456 | + self.lobby.exhibit_banner.on_button_press(None, mock_event) |
457 | + self.lobby.exhibit_banner.on_button_release(None, mock_event) |
458 | + mock_emit.assert_called() |
459 | + signal_name = mock_emit.call_args[0][0] |
460 | + call_exhibit = mock_emit.call_args[0][1] |
461 | + self.assertEqual(signal_name, "show-exhibits-clicked") |
462 | + self.assertEqual(call_exhibit.click_url, "http://example.com") |
463 | + |
464 | + def test_exhibit_with_featured_exhibit(self): |
465 | + """ regression test for bug #1023777 """ |
466 | + sca = ObjectWithSignals() |
467 | + sca.query_exhibits = lambda: sca.emit('exhibits', sca, |
468 | + [lobbyview.FeaturedExhibit()]) |
469 | + |
470 | + with patch.object(lobbyview, 'SoftwareCenterAgent', lambda: sca): |
471 | + # add the banners |
472 | + self.lobby._append_banner_ads() |
473 | + # fake click |
474 | + alloc = self.lobby.exhibit_banner.get_allocation() |
475 | + mock_event = Mock() |
476 | + mock_event.x = alloc.x |
477 | + mock_event.y = alloc.y |
478 | + with patch.object(self.lobby, 'emit') as mock_emit: |
479 | + self.lobby.exhibit_banner.on_button_press(None, mock_event) |
480 | + self.lobby.exhibit_banner.on_button_release(None, mock_event) |
481 | + mock_emit.assert_called() |
482 | + signal_name = mock_emit.call_args[0][0] |
483 | + call_category = mock_emit.call_args[0][1] |
484 | + self.assertEqual(signal_name, "category-selected") |
485 | + self.assertEqual(call_category.name, "Our star apps") |
486 | + |
487 | + |
488 | +class HtmlRendererTestCase(unittest.TestCase): |
489 | + |
490 | + def test_multiple_images(self): |
491 | + downloader = ObjectWithSignals() |
492 | + downloader.download_file = lambda *args, **kwargs: downloader.emit( |
493 | + "file-download-complete", downloader, os.path.basename(args[0])) |
494 | + |
495 | + with patch("softwarecenter.ui.gtk3.widgets.exhibits." |
496 | + "SimpleFileDownloader", lambda: downloader): |
497 | + renderer = _HtmlRenderer() |
498 | + mock_exhibit = Mock() |
499 | + mock_exhibit.banner_urls = [ |
500 | + "http://example.com/path1/banner1.png", |
501 | + "http://example.com/path2/banner2.png", |
502 | + ] |
503 | + mock_exhibit.html = "url('/path1/banner1.png')#"\ |
504 | + "url('/path2/banner2.png')" |
505 | + |
506 | + renderer.set_exhibit(mock_exhibit) |
507 | + # assert the stuff we expected to get downloaded got downloaded |
508 | + self.assertEqual( |
509 | + renderer._downloaded_banner_images, |
510 | + ["banner1.png", "banner2.png"]) |
511 | + # test that the path mangling worked |
512 | + self.assertEqual( |
513 | + mock_exhibit.html, "url('banner1.png')#url('banner2.png')") |
514 | + |
515 | +if __name__ == "__main__": |
516 | + unittest.main() |
Thanks, Michael!