Merge lp:~mvo/software-center/arb-partner-channels into lp:software-center

Proposed by Michael Vogt
Status: Merged
Merged at revision: 2702
Proposed branch: lp:~mvo/software-center/arb-partner-channels
Merge into: lp:software-center
Diff against target: 533 lines (+194/-52)
13 files modified
README (+1/-7)
data/channels/Ubuntu/ubuntu-extras.eula (+3/-0)
data/channels/Ubuntu/ubuntu-extras.list.in (+5/-0)
debian/README.source (+6/-0)
debian/control (+2/-1)
setup.py (+18/-6)
softwarecenter/db/update.py (+21/-6)
softwarecenter/distro/__init__.py (+10/-3)
softwarecenter/testutils.py (+39/-0)
softwarecenter/ui/gtk3/views/appdetailsview.py (+8/-5)
softwarecenter/version.py (+1/-1)
test/gtk3/test_appdetailsview.py (+22/-3)
test/test_database.py (+58/-20)
To merge this branch: bzr merge lp:~mvo/software-center/arb-partner-channels
Reviewer Review Type Date Requested Status
Gary Lasker (community) Approve
Review via email: mp+90408@code.launchpad.net

Description of the change

This branch adds support for extras.ubuntu.com and archive.canonical.com channel detection and adding via
software-center-agent. This means that we can server all the meta-data via the agent and software-center
will ask to add the channel (independent or partner) if its missing from the users sources.list.

To test it needs to be build first to ensure the channel file for extras is in place and include
SOFTWARE_CENTER_AGENT_INCLUDE_QA=1 when running it.

To post a comment you must log in.
2713. By Michael Vogt

REFACTOR: fix "Free" display for $0 apps and add test and a bit of refactor

Revision history for this message
Gary Lasker (gary-lasker) wrote :

I like this very much. Very nice, clean implementation and unit tests ftw!

This is going to be great to have. Thank you for doing this work, mvo!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README'
2--- README 2012-01-18 21:27:30 +0000
3+++ README 2012-01-27 13:16:06 +0000
4@@ -41,23 +41,17 @@
5
6 The following environment is suported:
7
8-SOFTWARE_CENTER_USE_GCONF_PROXY - set user proxy instead of using system-wide
9-SOFTWARE_CENTER_USE_BUILTIN_LOGIN - use built-in login instead of ubuntu-sso-client
10-SOFTWARE_CENTER_APPDETAILS_WEBKIT - use the webkit appdetails instead of gtk
11-APPVIEW_DEBUG_TERMS - show debug output for the terms in a search
12 SOFTWARE_CENTER_AGENT_HOST - use a alternative hosts to query for pay software
13 SOFTWARE_CENTER_REVIEWS_HOST - a alternative host for the ratings&reviews
14 SOFTWARE_CENTER_DEBUG_HTTP - enable httplib2 debuging
15-
16 SOFTWARE_CENTER_IPSUM_REVIEWS - geneate random reviews
17 SOFTWARE_CENTER_FAKE_REVIEW_API - use a fake server for all review network operations
18-SOFTWARE_CENTER_OLD_PATHBAR - use old pathbar code
19-SOFTWARE_CENTER_SEARCHES_SORT_MODE={popcon,alphabetic,xapian}
20 SOFTWARE_CENTER_GWIBBER_MOCK_USERS=2 - use mock gwibber service
21 SOFTWARE_CENTER_AGENT_INCLUDE_QA - show not yet QA apps available from the agent
22 SOFTWARE_CENTER_NET_DISCONNECTED - make software-center's netstatus module believe network manager is in a disconnected state
23 SOFTWARE_CENTER_WEBLIVE_HOST - overwrite default weblive server
24 SOFTWARE_CENTER_DISTRO_CODENAME - overwrite "lsb_release -c -s" output
25+SOFTWARE_CENTER_ARCHITECTURE - overwrite the current architecture
26 SOFTWARE_CENTER_NO_SC_AGENT - disable the software-center-agent
27 SOFTWARE_CENTER_DEBUG_TABS - show notebook tabs for debugging
28
29
30=== added directory 'data/channels'
31=== added directory 'data/channels/Ubuntu'
32=== added file 'data/channels/Ubuntu/ubuntu-extras.eula'
33--- data/channels/Ubuntu/ubuntu-extras.eula 1970-01-01 00:00:00 +0000
34+++ data/channels/Ubuntu/ubuntu-extras.eula 2012-01-27 13:16:06 +0000
35@@ -0,0 +1,3 @@
36+The Ubuntu independent channel contains applications that are
37+available for Ubuntu from third-party software developers
38+who want to ship their latest software.
39\ No newline at end of file
40
41=== added file 'data/channels/Ubuntu/ubuntu-extras.list.in'
42--- data/channels/Ubuntu/ubuntu-extras.list.in 1970-01-01 00:00:00 +0000
43+++ data/channels/Ubuntu/ubuntu-extras.list.in 2012-01-27 13:16:06 +0000
44@@ -0,0 +1,5 @@
45+
46+## This software is not part of Ubuntu, but is offered by third-party
47+## developers who want to ship their latest software.
48+deb http://extras.ubuntu.com/ubuntu/ #DISTROSERIES# main
49+deb-src http://extras.ubuntu.com/ubuntu/ #DISTROSERIES# main
50
51=== added file 'debian/README.source'
52--- debian/README.source 1970-01-01 00:00:00 +0000
53+++ debian/README.source 2012-01-27 13:16:06 +0000
54@@ -0,0 +1,6 @@
55+This package should be build using bzr-buildpackage to ensure
56+that the pre-build hooks are executed. This includes running
57+the internal tests. If you don't want to do this, use:
58+ DEB_BUILD_OPTIONS=nocheck bzr-buildpackage
59+
60+ -- Michael Vogt <michael.vogt@ubuntu.com>, Fri, 27 Jan 2012 11:42:27 +0100
61
62=== modified file 'debian/control'
63--- debian/control 2012-01-25 08:08:50 +0000
64+++ debian/control 2012-01-27 13:16:06 +0000
65@@ -44,7 +44,8 @@
66 ubuntu-sso-client (>= 0.99.6),
67 python-piston-mini-client (>= 0.1+bzr29),
68 oneconf (>= 0.2.6),
69- python-debtagshw
70+ python-debtagshw,
71+ ubuntu-extras-keyring
72 Recommends: lsb-release,
73 gir1.2-launchpad-integration-3.0,
74 apt-xapian-index (>= 0.38ubuntu1),
75
76=== modified file 'setup.py'
77--- setup.py 2012-01-03 11:27:15 +0000
78+++ setup.py 2012-01-27 13:16:06 +0000
79@@ -1,11 +1,12 @@
80 #!/usr/bin/env python
81
82+import platform
83 import distutils
84 import fnmatch
85 import glob
86 import os
87 import re
88-from subprocess import Popen, PIPE, call
89+from subprocess import call
90 import sys
91
92 from distutils.core import setup
93@@ -50,16 +51,22 @@
94 gtkbuilder, flags=re.DOTALL)
95 open(fname, "w").write(gtkbuilder)
96
97+def merge_extras_ubuntu_com_channel_file():
98+ # update ubuntu-extras.list.in (this will not be part of debian as
99+ # its killed of in debian/rules on a non-ubuntu build)
100+ DISTROSERIES = platform.dist()[2]
101+ channelfile = "data/channels/Ubuntu/ubuntu-extras.list"
102+ s=open(channelfile+".in").read()
103+ open(channelfile, "w").write(s.replace("#DISTROSERIES#", DISTROSERIES))
104+
105
106 # update version.py
107 line = open("debian/changelog").readline()
108 m = re.match("^[\w-]+ \(([\w\.~]+)\) ([\w-]+);", line)
109 VERSION = m.group(1)
110 CODENAME = m.group(2)
111-DISTRO = Popen(
112- ["lsb_release", "-s", "-i"], stdout=PIPE).communicate()[0].strip()
113-RELEASE = Popen(
114- ["lsb_release", "-s", "-r"], stdout=PIPE).communicate()[0].strip()
115+DISTRO = platform.dist()[0]
116+RELEASE = platform.dist()[1]
117 open("softwarecenter/version.py", "w").write("""
118 VERSION='%s'
119 CODENAME='%s'
120@@ -67,9 +74,11 @@
121 RELEASE='%s'
122 """ % (VERSION, CODENAME, DISTRO, RELEASE))
123
124+
125 # update po4a
126 if sys.argv[1] == "build":
127 merge_authors_into_about_dialog()
128+ merge_extras_ubuntu_com_channel_file()
129 call(["po4a", "po/help/po4a.conf"])
130
131 # real setup
132@@ -131,12 +140,15 @@
133 glob.glob("data/images/*.gif")),
134 ('share/software-center/icons/',
135 glob.glob("data/emblems/*.png")),
136- # xpian
137+ # xapian
138 ('share/apt-xapian-index/plugins',
139 glob.glob("apt-xapian-index-plugin/*.py")),
140 # apport
141 ('share/apport/package-hooks/',
142 ['debian/source_software-center.py']),
143+ # extra software channels (can be distro specific)
144+ ('/usr/share/app-install/channels/',
145+ glob.glob("data/channels/%s/*" % DISTRO) ),
146 ],
147 cmdclass={"build": build_extra.build_extra,
148 "build_i18n": build_i18n.build_i18n,
149
150=== modified file 'softwarecenter/db/update.py'
151--- softwarecenter/db/update.py 2012-01-26 22:11:41 +0000
152+++ softwarecenter/db/update.py 2012-01-27 13:16:06 +0000
153@@ -18,8 +18,9 @@
154 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
155
156 import logging
157+import json
158+import re
159 import os
160-import json
161 import string
162 import shutil
163 import xapian
164@@ -50,6 +51,7 @@
165
166 from gettext import gettext as _
167 from glob import glob
168+from urlparse import urlparse
169
170 import softwarecenter.paths
171
172@@ -165,6 +167,7 @@
173 }
174
175 def __init__(self, sca_application):
176+ # the piston object we got from software-center-agent
177 self.sca_application = sca_application
178 self.origin = "software-center-agent"
179 self._apply_exceptions()
180@@ -191,6 +194,15 @@
181 if not hasattr(self.sca_application, 'categories'):
182 self.sca_application.categories = ""
183
184+ # detect if its for the partner channel and set the channel
185+ # attribute appropriately so that the channel-adding magic works
186+ u = urlparse(self.sca_application.archive_root)
187+ if u.scheme == "http" and u.netloc == "archive.canonical.com":
188+ distroseries = get_distro().get_codename()
189+ self.sca_application.channel = "%s-partner" % distroseries
190+ if u.scheme == "http" and u.netloc == "extras.ubuntu.com":
191+ self.sca_application.channel = "ubuntu-extras"
192+
193 def get_desktop(self, key, translated=True):
194 if key in self.STATIC_DATA:
195 return self.STATIC_DATA[key]
196@@ -668,6 +680,7 @@
197 else:
198 name = parser.get_desktop("Name")
199 untranslated_name = parser.get_desktop("Name", translated=False)
200+
201 doc.set_data(name)
202 doc.add_value(XapianValues.APPNAME_UNTRANSLATED, untranslated_name)
203
204@@ -728,7 +741,8 @@
205 # date published
206 if parser.has_option_desktop("X-AppInstall-Date-Published"):
207 date_published = parser.get_desktop("X-AppInstall-Date-Published")
208- if date_published:
209+ if (date_published and
210+ re.match("\d+-\d+-\d+ \d+:\d+:\d+", date_published)):
211 # strip the subseconds from the end of the published date string
212 date_published = str(date_published).split(".")[0]
213 doc.add_value(XapianValues.DATE_PUBLISHED,
214@@ -763,10 +777,11 @@
215 # PPA (third party stuff)
216 if parser.has_option_desktop("X-AppInstall-PPA"):
217 archive_ppa = parser.get_desktop("X-AppInstall-PPA")
218- doc.add_value(XapianValues.ARCHIVE_PPA, archive_ppa)
219- # add archive origin data here so that its available even if
220- # the PPA is not (yet) enabled
221- doc.add_term("XOO"+"lp-ppa-%s" % archive_ppa.replace("/", "-"))
222+ if archive_ppa:
223+ doc.add_value(XapianValues.ARCHIVE_PPA, archive_ppa)
224+ # add archive origin data here so that its available even if
225+ # the PPA is not (yet) enabled
226+ doc.add_term("XOO"+"lp-ppa-%s" % archive_ppa.replace("/", "-"))
227 # screenshot (for third party)
228 if parser.has_option_desktop("X-AppInstall-Screenshot-Url"):
229 url = parser.get_desktop("X-AppInstall-Screenshot-Url")
230
231=== modified file 'softwarecenter/distro/__init__.py'
232--- softwarecenter/distro/__init__.py 2011-12-02 14:16:26 +0000
233+++ softwarecenter/distro/__init__.py 2012-01-27 13:16:06 +0000
234@@ -25,7 +25,7 @@
235
236 from softwarecenter.utils import UnimplementedError, utf8
237
238-log = logging.getLogger(__name__)
239+LOG = logging.getLogger(__name__)
240
241
242 class Distro(object):
243@@ -75,7 +75,9 @@
244 """ The codename of the distro, e.g. lucid """
245 # for tests and similar
246 if "SOFTWARE_CENTER_DISTRO_CODENAME" in os.environ:
247- return os.environ["SOFTWARE_CENTER_DISTRO_CODENAME"]
248+ distrocode = os.environ["SOFTWARE_CENTER_DISTRO_CODENAME"]
249+ LOG.warn("overriding distro codename to '%s'" % distrocode)
250+ return distrocode
251 # normal behavior
252 if not hasattr(self, "_distro_code_name"):
253 self._distro_code_name = platform.dist()[2]
254@@ -155,7 +157,7 @@
255 def _get_distro():
256 distro_info = platform.linux_distribution()
257 distro_id = distro_info[0]
258- log.debug("get_distro: '%s'", distro_id)
259+ LOG.debug("get_distro: '%s'", distro_id)
260 # start with a import, this gives us only a softwarecenter module
261 module = __import__(distro_id, globals(), locals(), [], -1)
262 # get the right class and instanciate it
263@@ -168,6 +170,11 @@
264 return distro_instance
265
266 def get_current_arch():
267+ # for tests and similar
268+ if "SOFTWARE_CENTER_ARCHITECTURE" in os.environ:
269+ arch = os.environ["SOFTWARE_CENTER_ARCHITECTURE"]
270+ LOG.warn("overriding architecture to '%s'" % arch)
271+ return arch
272 return get_distro().get_architecture()
273
274 def get_foreign_architectures():
275
276=== modified file 'softwarecenter/testutils.py'
277--- softwarecenter/testutils.py 2012-01-26 10:35:55 +0000
278+++ softwarecenter/testutils.py 2012-01-27 13:16:06 +0000
279@@ -151,3 +151,42 @@
280 import softwarecenter.paths
281 softwarecenter.paths.datadir = os.path.join(basedir, "data")
282 softwarecenter.paths.SOFTWARE_CENTER_CACHE_DIR = tempfile.mkdtemp()
283+
284+
285+# factory stuff for the agent
286+def make_software_center_agent_app_dict():
287+ app_dict = {
288+ u'archive_root' : 'http://private-ppa.launchpad.net/',
289+ u'archive_id': u'commercial-ppa-uploaders/photobomb',
290+ u'description': u"Easy and Social Image Editor\nPhotobomb "
291+ u"give you easy access to images in your "
292+ u"social networking feeds, pictures on ...",
293+ u'name': u'Photobomb',
294+ u'package_name': u'photobomb',
295+ u'signing_key_id': u'1024R/75254D99',
296+ u'screenshot_url': 'http://software-center.ubuntu.com/site_media/screenshots/2011/08/Screenshot.png',
297+ u'license': 'Proprietary',
298+ u'support_url': 'mailto:support@example.com',
299+ u'series': { 'oneiric' : ['i386', 'amd64'],
300+ 'natty' : ['i386', 'amd64'],
301+ },
302+ u'channel' : 'For Purchase',
303+ u'icon_url' : 'http://software-center.ubuntu.com/site_media/icons/2011/08/64_Chainz.png',
304+ u'categories': 'Game;LogicGame',
305+ }
306+ return app_dict
307+
308+def make_software_center_agent_subscription_dict(app_dict):
309+ subscription_dict = {
310+ u'application': app_dict,
311+ u'deb_line': u'deb https://some.user:ABCDEFGHIJKLMNOP@'
312+ u'private-ppa.launchpad.net/commercial-ppa-uploaders/'
313+ u'photobomb/ubuntu natty main',
314+ u'distro_series': {u'code_name': u'natty', u'version': u'11.04'},
315+ u'failures': [],
316+ u'open_id': u'https://login.ubuntu.com/+id/ABCDEF',
317+ u'purchase_date': u'2011-09-16 06:37:52',
318+ u'purchase_price': u'2.99',
319+ u'state': u'Complete',
320+ }
321+ return subscription_dict
322
323=== modified file 'softwarecenter/ui/gtk3/views/appdetailsview.py'
324--- softwarecenter/ui/gtk3/views/appdetailsview.py 2012-01-26 19:50:25 +0000
325+++ softwarecenter/ui/gtk3/views/appdetailsview.py 2012-01-27 13:16:06 +0000
326@@ -212,9 +212,15 @@
327 self.label.set_markup(m)
328 return
329
330+ def get_label(self):
331+ return self.label.get_text()
332+
333 def set_button_label(self, label):
334 self.button.set_label(label)
335 return
336+
337+ def get_button_label(self):
338+ return self.button.get_label()
339
340 def configure(self, app_details, state):
341 LOG.debug("configure %s state=%s pkgstate=%s" % (
342@@ -332,11 +338,8 @@
343 if app_details.pkgname== SOFTWARE_CENTER_PKGNAME:
344 self.set_label(_("Removed (close it and it'll be gone)"))
345 else:
346- if app_details.price:
347- self.set_label(app_details.price)
348- else:
349- # TRANSLATORS: Free here means Gratis
350- self.set_label(_("Free"))
351+ # TRANSLATORS: Free here means Gratis
352+ self.set_label(_("Free"))
353 if app_details.hardware_requirements_satisfied:
354 self.set_button_label(_('Install'))
355 else:
356
357=== modified file 'softwarecenter/version.py'
358--- softwarecenter/version.py 2012-01-06 09:15:09 +0000
359+++ softwarecenter/version.py 2012-01-27 13:16:06 +0000
360@@ -1,5 +1,5 @@
361
362-VERSION='5.1.5'
363+VERSION='5.1.7.1'
364 CODENAME='UNRELEASED'
365 DISTRO='Ubuntu'
366 RELEASE='12.04'
367
368=== modified file 'test/gtk3/test_appdetailsview.py'
369--- test/gtk3/test_appdetailsview.py 2012-01-26 15:47:29 +0000
370+++ test/gtk3/test_appdetailsview.py 2012-01-27 13:16:06 +0000
371@@ -50,9 +50,9 @@
372 do_events()
373 self.assertTrue(self.view.videoplayer.get_property("visible"))
374
375- def test_page(self):
376+ def test_page_pkgstatusbar(self):
377 # show app
378- app = Application("", "software-center")
379+ app = Application("", "abiword")
380 self.view.show_app(app)
381 do_events()
382
383@@ -62,8 +62,19 @@
384 mock_details = mock_app.get_details(None)
385 mock_details.purchase_date = "2011-11-20 17:45:01"
386 mock_details._error_not_found = "error not found"
387+ mock_details.price = "1.00"
388+ mock_details.pkgname = "abiword"
389 self.view.app_details = mock_details
390
391+ # the states and what labels we expect in the pkgstatusbar
392+ # first string is status text, second is button text
393+ pkg_states_to_labels = {
394+ PkgStates.INSTALLED : ("Purchased on 2011-11-20", "Remove"),
395+ PkgStates.UNINSTALLED : ('Free', 'Install'),
396+ PkgStates.NEEDS_PURCHASE : ('US$ 1.00', u'Buy\u2026'),
397+ PkgStates.PURCHASED_BUT_REPO_MUST_BE_ENABLED : ('Purchased on 2011-11-20', 'Install'),
398+ }
399+
400 # show a app through the various states
401 for var in vars(PkgStates):
402 # FIXME: this just ensures we are not crashing, also
403@@ -75,6 +86,14 @@
404 self.view.app = None
405 # show it
406 self.view.show_app(mock_app)
407+ if state in pkg_states_to_labels:
408+ label, button_label = pkg_states_to_labels[state]
409+ self.assertEqual(
410+ self.view.pkg_statusbar.get_label(),
411+ label.decode("utf-8"))
412+ self.assertEqual(
413+ self.view.pkg_statusbar.get_button_label().decode("utf-8"),
414+ button_label)
415
416 def test_app_icon_loading(self):
417 # get icon
418@@ -374,5 +393,5 @@
419
420 if __name__ == "__main__":
421 import logging
422- logging.basicConfig(level=logging.DEBUG)
423+ #logging.basicConfig(level=logging.DEBUG)
424 unittest.main()
425
426=== modified file 'test/test_database.py'
427--- test/test_database.py 2012-01-26 12:45:40 +0000
428+++ test/test_database.py 2012-01-27 13:16:06 +0000
429@@ -25,6 +25,7 @@
430 update_from_appstream_xml,
431 update_from_software_center_agent,
432 SCAPurchasedApplicationParser,
433+ SCAApplicationParser,
434 )
435 from softwarecenter.distro import get_distro
436 from softwarecenter.enums import (
437@@ -34,6 +35,8 @@
438 from softwarecenter.testutils import (
439 get_test_db,
440 get_test_pkg_info,
441+ make_software_center_agent_subscription_dict,
442+ make_software_center_agent_app_dict,
443 )
444
445
446@@ -417,26 +420,8 @@
447
448 def make_purchased_app_details(db=None, supported_series=None):
449 """Return an AppDetail instance with the required attributes."""
450- subscription = {
451- u'application': {
452- u'archive_id': u'commercial-ppa-uploaders/photobomb',
453- u'description': u"Easy and Social Image Editor\nPhotobomb "
454- u"give you easy access to images in your "
455- u"social networking feeds, pictures on ...",
456- u'name': u'Photobomb',
457- u'package_name': u'photobomb',
458- u'signing_key_id': u'1024R/75254D99'
459- },
460- u'deb_line': u'deb https://some.user:ABCDEFGHIJKLMNOP@'
461- u'private-ppa.launchpad.net/commercial-ppa-uploaders/'
462- u'photobomb/ubuntu natty main',
463- u'distro_series': {u'code_name': u'natty', u'version': u'11.04'},
464- u'failures': [],
465- u'open_id': u'https://login.ubuntu.com/+id/ABCDEF',
466- u'purchase_date': u'2011-09-16 06:37:52',
467- u'purchase_price': u'2.99',
468- u'state': u'Complete',
469- }
470+ app = make_software_center_agent_app_dict()
471+ subscription = make_software_center_agent_subscription_dict(app)
472
473 if supported_series != None:
474 subscription['application']['series'] = supported_series
475@@ -459,6 +444,59 @@
476 return app_details
477
478
479+class AppDetailsSCAApplicationParser(unittest.TestCase):
480+
481+ def setUp(self):
482+ self.db = get_test_db()
483+
484+ def _get_app_details_from_app_dict(self, app_dict):
485+ item = PistonResponseObject.from_dict(app_dict)
486+ parser = SCAApplicationParser(item)
487+ doc = make_doc_from_parser(parser, self.db._aptcache)
488+ app_details = AppDetails(self.db, doc)
489+ return app_details
490+
491+ @patch('os.path.exists')
492+ def test_channel_detection_partner(self, mock):
493+ # we need to patch os.path.exists as "AppDetails.channelname" will
494+ # check if there is a matching channel description file on disk
495+ os.path.exists.return_value = True
496+ # setup dict
497+ app_dict = make_software_center_agent_app_dict()
498+ app_dict["archive_root"] = "http://archive.canonical.com/"
499+ app_details = self._get_app_details_from_app_dict(app_dict)
500+ # ensure that archive.canonical.com archive roots are detected
501+ # as the partner channel
502+ dist = get_distro().get_codename()
503+ self.assertEqual(app_details.channelname, "%s-partner" % dist)
504+
505+ @patch('os.path.exists')
506+ def test_channel_detection_extras(self, mock):
507+ # we need to patch os.path.exists as "AppDetails.channelname" will
508+ # check if there is a matching channel description file on disk
509+ os.path.exists.return_value = True
510+ # setup dict
511+ app_dict = make_software_center_agent_app_dict()
512+ app_dict["archive_root"] = "http://extras.ubuntu.com/"
513+ app_details = self._get_app_details_from_app_dict(app_dict)
514+ # ensure that archive.canonical.com archive roots are detected
515+ # as the partner channel
516+ self.assertEqual(app_details.channelname, "ubuntu-extras")
517+
518+ def test_date_no_published(self):
519+ app_dict = make_software_center_agent_app_dict()
520+ app_dict["date_published"] = "None"
521+ app_details = self._get_app_details_from_app_dict(app_dict)
522+ # ensure that archive.canonical.com archive roots are detected
523+ # as the partner channel
524+ self.assertEqual(app_details.date_published, "")
525+ # and again
526+ app_dict["date_published"] = "2012-01-21 02:15:10.358926"
527+ app_details = self._get_app_details_from_app_dict(app_dict)
528+ # ensure that archive.canonical.com archive roots are detected
529+ # as the partner channel
530+ self.assertEqual(app_details.date_published, "2012-01-21 02:15:10")
531+
532
533 class AppDetailsPkgStateTestCase(unittest.TestCase):
534

Subscribers

People subscribed via source and target branches