launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06597
[Merge] lp:~sinzui/launchpad/commercial-project-picker into lp:launchpad
Curtis Hovey has proposed merging lp:~sinzui/launchpad/commercial-project-picker into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #930309 in Launchpad itself: "Commercial subscription information in the target picker looks like a Launchpad-Id"
https://bugs.launchpad.net/launchpad/+bug/930309
For more details, see:
https://code.launchpad.net/~sinzui/launchpad/commercial-project-picker/+merge/95970
Include commercial subscription in the picker details.
Launchpad bug: https://bugs.launchpad.net/bugs/930309
Pre-implementation: jcsackett
The CommercialProjects vocabulary appends parenthetical subscription
information to the project displayname. This looks very in the picker,
and can be confused with the Launchpad-Id. The information often
overruns the space for the entry and is not shown.
--------------------------------------------------------------------
RULES
* If the project has a commercial subscription, append it to the
picker entry details.
* This could be a performance issue.
Checking commercial_subscriptionID should mitigate the cost of
adding the subscription information. Only projects with a commercial
subscription will get an additional DB check.
Maybe the commercial subscription information can be gotten in bulk.
* Oh, commercial_subscription isn't in the schema; it is a cached attr
on Product.
* There are three states to present in the picker
A. commercial subscription: None
B. Commercial subscription: Active
C. Commercial subscription: Expired
QA
* Visit a bug on qastaging.
* Choose the retarget it.
* Search for a commercial project.
* Expand the some of the entries to see the details.
* Verify the entry shows commercial subscription information.
Verify the commercial project entry states that it has an active
commercial subscription.
LINT
lib/lp/app/browser/vocabulary.py
lib/lp/app/browser/tests/test_vocabulary.py
lib/lp/registry/vocabularies.py
lib/lp/registry/interfaces/product.py
lib/lp/registry/tests/test_commercialprojects_vocabularies.py
TEST
./bin/test -vvc lp.app.browser.tests.test_vocabulary
./bin/test -vvc lp.registry.tests.test_commercialprojects_vocabularies
IMPLEMENTATION
Added getCommercialSubscription() to TargetPickerEntrySourceAdapter that
returns None for all target types. Added getCommercialSubscription to
the IProduct subclass to summarise the commercial subscription info.
Removed a duplicate call to getMaintainer() in the base class. Add
has_current_commercial_subscription to IProduct because the model method
was private.
lib/lp/app/browser/vocabulary.py
lib/lp/app/browser/tests/test_vocabulary.py
lib/lp/registry/interfaces/product.py
Removed the overloading the of project's displayname that looked like a
Launchpad-Id and could overrun the picker overlay..
lib/lp/registry/tests/test_commercialprojects_vocabularies.py
lib/lp/registry/vocabularies.py
--
https://code.launchpad.net/~sinzui/launchpad/commercial-project-picker/+merge/95970
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~sinzui/launchpad/commercial-project-picker into lp:launchpad.
=== modified file 'lib/lp/app/browser/tests/test_vocabulary.py'
--- lib/lp/app/browser/tests/test_vocabulary.py 2012-01-01 02:58:52 +0000
+++ lib/lp/app/browser/tests/test_vocabulary.py 2012-03-05 18:47:22 +0000
@@ -35,6 +35,7 @@
VocabularyFilter,
)
from lp.testing import (
+ celebrity_logged_in,
login_person,
TestCaseWithFactory,
)
@@ -318,6 +319,31 @@
'http://launchpad.dev/fnord',
self.getPickerEntry(product).alt_title_link)
+ def test_provides_commercial_subscription_none(self):
+ product = self.factory.makeProduct(name='fnord')
+ self.assertEqual(
+ 'Commercial Subscription: None',
+ self.getPickerEntry(product).details[1])
+
+ def test_provides_commercial_subscription_active(self):
+ product = self.factory.makeProduct(name='fnord')
+ self.factory.makeCommercialSubscription(product)
+ self.assertEqual(
+ 'Commercial Subscription: Active',
+ self.getPickerEntry(product).details[1])
+
+ def test_provides_commercial_subscription_expired(self):
+ product = self.factory.makeProduct(name='fnord')
+ self.factory.makeCommercialSubscription(product)
+ import datetime
+ import pytz
+ then = datetime.datetime(2005, 6, 15, 0, 0, 0, 0, pytz.UTC)
+ with celebrity_logged_in('admin'):
+ product.commercial_subscription.date_expires = then
+ self.assertEqual(
+ 'Commercial Subscription: Expired',
+ self.getPickerEntry(product).details[1])
+
class TestProjectGroupPickerEntrySourceAdapter(TestCaseWithFactory):
=== modified file 'lib/lp/app/browser/vocabulary.py'
--- lib/lp/app/browser/vocabulary.py 2012-02-22 05:22:13 +0000
+++ lib/lp/app/browser/vocabulary.py 2012-03-05 18:47:22 +0000
@@ -235,6 +235,10 @@
"""Gets the maintainer information for the target picker entry."""
raise NotImplemented
+ def getCommercialSubscription(self, target):
+ """Gets the commercial subscription details for the target."""
+ return None
+
def getPickerEntries(self, term_values, context_object, **kwarg):
"""See `IPickerEntrySource`"""
entries = (
@@ -265,7 +269,11 @@
maintainer = self.getMaintainer(target)
if maintainer is not None:
picker_entry.details.append(
- 'Maintainer: %s' % self.getMaintainer(target))
+ 'Maintainer: %s' % maintainer)
+ commercial_subscription = self.getCommercialSubscription(target)
+ if commercial_subscription is not None:
+ picker_entry.details.append(
+ 'Commercial Subscription: %s' % commercial_subscription)
return entries
@@ -342,6 +350,16 @@
"""See `TargetPickerEntrySource`"""
return target.summary
+ def getCommercialSubscription(self, target):
+ """See `TargetPickerEntrySource`"""
+ if target.commercial_subscription:
+ if target.has_current_commercial_subscription:
+ return 'Active'
+ else:
+ return 'Expired'
+ else:
+ return 'None'
+
@adapter(IDistribution)
class DistributionPickerEntrySourceAdapter(TargetPickerEntrySourceAdapter):
=== modified file 'lib/lp/registry/interfaces/product.py'
--- lib/lp/registry/interfaces/product.py 2012-02-14 07:06:37 +0000
+++ lib/lp/registry/interfaces/product.py 2012-03-05 18:47:22 +0000
@@ -729,6 +729,9 @@
"Whether the project's licensing requires a new "
"commercial subscription to use launchpad.")))
+ has_current_commercial_subscription = Attribute("""
+ Whether the project has a current commercial subscription.""")
+
license_status = Attribute("""
Whether the license is OPENSOURCE, UNREVIEWED, or PROPRIETARY.""")
=== modified file 'lib/lp/registry/tests/test_commercialprojects_vocabularies.py'
--- lib/lp/registry/tests/test_commercialprojects_vocabularies.py 2012-02-28 04:24:19 +0000
+++ lib/lp/registry/tests/test_commercialprojects_vocabularies.py 2012-03-05 18:47:22 +0000
@@ -5,7 +5,6 @@
__metaclass__ = type
-from lp.app.browser.tales import DateTimeFormatterAPI
from lp.registry.interfaces.product import License
from lp.registry.vocabularies import CommercialProjectsVocabulary
from lp.services.identity.interfaces.emailaddress import EmailAddressStatus
@@ -96,23 +95,12 @@
self.assertEqual(
0, len(self.vocab.searchForTerms('norwegian-blue-widget')))
- def test_toTerm_no_subscription(self):
- # Commercial project terms contain subscription information.
- term = self.vocab.toTerm(self.maintained_project)
- self.assertEqual(self.maintained_project, term.value)
- self.assertEqual('open-widget', term.token)
- self.assertEqual('Open-widget (no subscription)', term.title)
-
- def test_toTerm_with_subscription(self):
- # Commercial project terms contain subscription information.
- self.factory.makeCommercialSubscription(self.maintained_project)
- cs = self.maintained_project.commercial_subscription
- expiration_date = DateTimeFormatterAPI(cs.date_expires).displaydate()
- term = self.vocab.toTerm(self.maintained_project)
- self.assertEqual(self.maintained_project, term.value)
- self.assertEqual('open-widget', term.token)
- self.assertEqual(
- 'Open-widget (expires %s)' % expiration_date, term.title)
+ def test_toTerm(self):
+ # Commercial project terms contain subscription information.
+ term = self.vocab.toTerm(self.maintained_project)
+ self.assertEqual(self.maintained_project, term.value)
+ self.assertEqual('open-widget', term.token)
+ self.assertEqual('Open-widget', term.title)
def test_getTermByToken_user(self):
# The term for a token in the vocabulary is returned for maintained
=== modified file 'lib/lp/registry/vocabularies.py'
--- lib/lp/registry/vocabularies.py 2012-02-13 21:01:51 +0000
+++ lib/lp/registry/vocabularies.py 2012-03-05 18:47:22 +0000
@@ -98,7 +98,6 @@
removeSecurityProxy,
)
-from lp.app.browser.tales import DateTimeFormatterAPI
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.blueprints.interfaces.specification import ISpecification
from lp.bugs.interfaces.bugtask import IBugTask
@@ -1536,15 +1535,7 @@
def toTerm(self, project):
"""Return the term for this object."""
- if project.commercial_subscription is None:
- sub_status = "(no subscription)"
- else:
- date_formatter = DateTimeFormatterAPI(
- project.commercial_subscription.date_expires)
- sub_status = "(expires %s)" % date_formatter.displaydate()
- return SimpleTerm(project,
- project.name,
- '%s %s' % (project.displayname, sub_status))
+ return SimpleTerm(project, project.name, project.displayname)
def getTermByToken(self, token):
"""Return the term for the given token."""