launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #00690
[Merge] lp:~jcsackett/launchpad/add-enums-to-models into lp:launchpad/devel
j.c.sackett has proposed merging lp:~jcsackett/launchpad/add-enums-to-models into lp:launchpad/devel with lp:~bac/launchpad/progress-enums as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers): code
= Summary =
IServiceUsage provides enums to give better data on how a product or distribution uses launchpad, in place of the old bool fields (e.g. official_rosetta). However, when we roll out these enums, they will default to UNKNOWN until we can migrate data.
This branch creates properties using the enums (moved to _[ENUM] format) to use the old bool data until data is set for the enum, so we can start using the enums in code.
== Proposed fix ==
Create properties using getters and setters to intelligent find the data from the new and old attributes, and set them properly moving forward.
== Pre-implementation notes ==
Talked with Curtis.
== Implementation details ==
As above.
This branch incorporates Brad's work on the progress bar, as they need to land together. ~bac/launchpad/progress-enums
== Tests ==
bin/test -vvc -t UsageEnums
== Demo and Q/A ==
Go to a project on launchpad.dev and ensure the configuration and status
links are correct.
= Launchpad lint =
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/registry/configure.zcml
lib/lp/registry/browser/product.py
lib/lp/registry/browser/tests/pillar-views.txt
lib/lp/registry/interfaces/product.py
lib/lp/registry/model/distribution.py
lib/lp/registry/model/product.py
lib/lp/registry/tests/test_distribution.py
lib/lp/registry/tests/test_product.py
./lib/lp/registry/interfaces/product.py
901: E301 expected 1 blank line, found 2
./lib/lp/registry/model/distribution.py
1181: E231 missing whitespace after ','
1185: E231 missing whitespace after ','
1197: E231 missing whitespace after ','
E301 from comment issue
E231 from creation of tuple (something = ('some tuple',))
--
https://code.launchpad.net/~jcsackett/launchpad/add-enums-to-models/+merge/33255
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jcsackett/launchpad/add-enums-to-models into lp:launchpad/devel.
=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml 2010-08-20 19:22:45 +0000
+++ lib/lp/registry/configure.zcml 2010-08-20 19:22:47 +0000
@@ -1090,7 +1090,7 @@
interface="lp.registry.interfaces.product.IProductEditRestricted"/>
<require
permission="launchpad.Edit"
- set_schema="lp.app.interfaces.launchpad.IServiceUsage"/>
+ set_schema="lp.app.interfaces.launchpad.IServiceUsage"/>
<require
permission="launchpad.Edit"
set_attributes="bug_reporting_guidelines
@@ -1109,6 +1109,7 @@
security_contact sourceforgeproject
summary title wikiurl"/>
+
<!-- mark 2006-04-10 I put "name" in the admin group because
with Bazaar now in place, lots of people can have personal
data published at product name-based locations (personal
@@ -1376,7 +1377,6 @@
for="lp.registry.interfaces.productseries.IProductSeries"
factory="lp.registry.browser.productseries.ProductSeriesBreadcrumb"
permission="zope.Public"/>
-
<!-- ProductSeriesSet -->
<class
@@ -1405,6 +1405,9 @@
permission="launchpad.Edit"
interface="lp.registry.interfaces.distribution.IDistributionEditRestricted"/>
<require
+ permission="launchpad.Edit"
+ set_schema="lp.app.interfaces.launchpad.IServiceUsage"/>
+ <require
permission="launchpad.Moderate"
interface="lp.registry.interfaces.distribution.IDistributionDriverRestricted"/>
<require
=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2010-08-16 01:58:24 +0000
+++ lib/lp/registry/model/distribution.py 2010-08-20 19:22:47 +0000
@@ -30,7 +30,6 @@
DecoratedResultSet)
from canonical.launchpad.components.storm_operators import FTQ, Match, RANK
from canonical.launchpad.interfaces.lpstorm import IStore
-from canonical.lazr.utils import safe_hasattr
from lp.registry.model.announcement import MakesAnnouncements
from lp.soyuz.model.archive import Archive
from lp.soyuz.model.binarypackagename import BinaryPackageName
@@ -198,7 +197,6 @@
else:
alsoProvides(self, IDerivativeDistribution)
-
@property
def uploaders(self):
"""See `IDistribution`."""
@@ -235,21 +233,85 @@
return True in (self.official_malone, self.official_rosetta,
self.official_blueprints, self.official_answers)
- answers_usage = EnumCol(
+ _answers_usage = EnumCol(
dbName="answers_usage", notNull=True,
schema=ServiceUsage,
default=ServiceUsage.UNKNOWN)
- blueprints_usage = EnumCol(
+
+ def _get_answers_usage(self):
+ if self._answers_usage != ServiceUsage.UNKNOWN:
+ # If someone has set something with the enum, use it.
+ return self._answers_usage
+ elif self.official_answers:
+ return ServiceUsage.LAUNCHPAD
+ return self._answers_usage
+
+ def _set_answers_usage(self, val):
+ self._answers_usage = val
+ if val == ServiceUsage.LAUNCHPAD:
+ self.official_answers = True
+ else:
+ self.official_answers = False
+
+ answers_usage = property(
+ _get_answers_usage,
+ _set_answers_usage,
+ doc="Indicates if the product uses the answers service.")
+
+ _blueprints_usage = EnumCol(
dbName="blueprints_usage", notNull=True,
schema=ServiceUsage,
default=ServiceUsage.UNKNOWN)
- translations_usage = EnumCol(
+
+ def _get_blueprints_usage(self):
+ if self._blueprints_usage != ServiceUsage.UNKNOWN:
+ # If someone has set something with the enum, use it.
+ return self._blueprints_usage
+ elif self.official_blueprints:
+ return ServiceUsage.LAUNCHPAD
+ return self._blueprints_usage
+
+ def _set_blueprints_usage(self, val):
+ self._blueprints_usage = val
+ if val == ServiceUsage.LAUNCHPAD:
+ self.official_blueprints = True
+ else:
+ self.official_blueprints = False
+
+ blueprints_usage = property(
+ _get_blueprints_usage,
+ _set_blueprints_usage,
+ doc="Indicates if the product uses the blueprints service.")
+
+ _translations_usage = EnumCol(
dbName="translations_usage", notNull=True,
schema=ServiceUsage,
default=ServiceUsage.UNKNOWN)
+
+ def _get_translations_usage(self):
+ if self._translations_usage != ServiceUsage.UNKNOWN:
+ # If someone has set something with the enum, use it.
+ return self._translations_usage
+ elif self.official_rosetta:
+ return ServiceUsage.LAUNCHPAD
+ return self._translations_usage
+
+ def _set_translations_usage(self, val):
+ self._translations_usage = val
+ if val == ServiceUsage.LAUNCHPAD:
+ self.official_rosetta = True
+ else:
+ self.official_rosetta = False
+
+ translations_usage = property(
+ _get_translations_usage,
+ _set_translations_usage,
+ doc="Indicates if the product uses the translations service.")
+
@property
def codehosting_usage(self):
return ServiceUsage.NOT_APPLICABLE
+
@property
def bug_tracking_usage(self):
if not self.official_malone:
@@ -476,9 +538,9 @@
if not self.full_functionality:
return None
- urls = {'http_base_url' : http_base_url,
- 'ftp_base_url' : ftp_base_url,
- 'rsync_base_url' : rsync_base_url}
+ urls = {'http_base_url': http_base_url,
+ 'ftp_base_url': ftp_base_url,
+ 'rsync_base_url': rsync_base_url}
for name, value in urls.items():
if value is not None:
urls[name] = IDistributionMirror[name].normalize(value)
@@ -691,7 +753,7 @@
# filter based on completion. see the implementation of
# Specification.is_complete() for more details
- completeness = Specification.completeness_clause
+ completeness = Specification.completeness_clause
if SpecificationFilter.COMPLETE in filter:
query += ' AND ( %s ) ' % completeness
@@ -1016,15 +1078,15 @@
find_spec = (
DistributionSourcePackageCache,
SourcePackageName,
- SQL('rank(fti, ftq(%s)) AS rank' % sqlvalues(text))
+ SQL('rank(fti, ftq(%s)) AS rank' % sqlvalues(text)),
)
origin = [
DistributionSourcePackageCache,
Join(
SourcePackageName,
DistributionSourcePackageCache.sourcepackagename ==
- SourcePackageName.id
- )
+ SourcePackageName.id,
+ ),
]
publishing_condition = ''
@@ -1065,8 +1127,7 @@
quote(text), quote_like(text), has_packaging_condition,
publishing_condition)
dsp_caches_with_ranks = store.using(*origin).find(
- find_spec, condition
- ).order_by('rank DESC')
+ find_spec, condition).order_by('rank DESC')
return dsp_caches_with_ranks
@@ -1085,8 +1146,7 @@
cache, source_package_name, rank = result
return DistributionSourcePackage(
self,
- source_package_name
- )
+ source_package_name)
# Return the decorated result set so the consumer of these
# results will only see DSPs
@@ -1150,7 +1210,7 @@
extra_clauses = (
BinaryPackageRelease.binarypackagenameID ==
DistroSeriesPackageCache.binarypackagenameID,
- Match(search_vector_column, query_function)
+ Match(search_vector_column, query_function),
)
where_spec = (self._binaryPackageSearchClause + extra_clauses)
@@ -1406,11 +1466,11 @@
# XXX Julian 2007-08-16
# These component names should be Soyuz-wide constants.
componentMapToArchivePurpose = {
- 'main' : ArchivePurpose.PRIMARY,
- 'restricted' : ArchivePurpose.PRIMARY,
- 'universe' : ArchivePurpose.PRIMARY,
- 'multiverse' : ArchivePurpose.PRIMARY,
- 'partner' : ArchivePurpose.PARTNER,
+ 'main': ArchivePurpose.PRIMARY,
+ 'restricted': ArchivePurpose.PRIMARY,
+ 'universe': ArchivePurpose.PRIMARY,
+ 'multiverse': ArchivePurpose.PRIMARY,
+ 'partner': ArchivePurpose.PARTNER,
'contrib': ArchivePurpose.PRIMARY,
'non-free': ArchivePurpose.PRIMARY,
}
=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py 2010-08-20 19:22:45 +0000
+++ lib/lp/registry/model/product.py 2010-08-20 19:22:47 +0000
@@ -261,24 +261,26 @@
# XXX Need to remove official_codehosting column from Product
# table.
return self.development_focus.branch is not None
+
@property
def official_anything(self):
return True in (self.official_malone, self.official_rosetta,
self.official_blueprints, self.official_answers,
self.official_codehosting)
- answers_usage = EnumCol(
+ _answers_usage = EnumCol(
dbName="answers_usage", notNull=True,
schema=ServiceUsage,
default=ServiceUsage.UNKNOWN)
- blueprints_usage = EnumCol(
+ _blueprints_usage = EnumCol(
dbName="blueprints_usage", notNull=True,
schema=ServiceUsage,
default=ServiceUsage.UNKNOWN)
- translations_usage = EnumCol(
+ _translations_usage = EnumCol(
dbName="translations_usage", notNull=True,
schema=ServiceUsage,
default=ServiceUsage.UNKNOWN)
+
@property
def codehosting_usage(self):
if self.development_focus.branch is None:
@@ -288,6 +290,7 @@
elif self.development_focus.branch.branch_type == BranchType.MIRRORED:
return ServiceUsage.EXTERNAL
return ServiceUsage.NOT_APPLICABLE
+
@property
def bug_tracking_usage(self):
if self.official_malone:
@@ -296,6 +299,7 @@
return ServiceUsage.UNKNOWN
else:
return ServiceUsage.EXTERNAL
+
@property
def uses_launchpad(self):
"""Does this distribution actually use Launchpad?"""
@@ -511,6 +515,66 @@
super(Product, self).__storm_invalidated__()
self._cached_licenses = None
+ def _get_answers_usage(self):
+ if self._answers_usage != ServiceUsage.UNKNOWN:
+ # If someone has set something with the enum, use it.
+ return self._answers_usage
+ elif self.official_answers:
+ return ServiceUsage.LAUNCHPAD
+ return self._answers_usage
+
+ def _set_answers_usage(self, val):
+ self._answers_usage = val
+ if val == ServiceUsage.LAUNCHPAD:
+ self.official_answers = True
+ else:
+ self.official_answers = False
+
+ answers_usage = property(
+ _get_answers_usage,
+ _set_answers_usage,
+ doc="Indicates if the product uses the answers service.")
+
+ def _get_blueprints_usage(self):
+ if self._blueprints_usage != ServiceUsage.UNKNOWN:
+ # If someone has set something with the enum, use it.
+ return self._blueprints_usage
+ elif self.official_blueprints:
+ return ServiceUsage.LAUNCHPAD
+ return self._blueprints_usage
+
+ def _set_blueprints_usage(self, val):
+ self._blueprints_usage = val
+ if val == ServiceUsage.LAUNCHPAD:
+ self.official_blueprints = True
+ else:
+ self.official_blueprints = False
+
+ blueprints_usage = property(
+ _get_blueprints_usage,
+ _set_blueprints_usage,
+ doc="Indicates if the product uses the blueprints service.")
+
+ def _get_translations_usage(self):
+ if self._translations_usage != ServiceUsage.UNKNOWN:
+ # If someone has set something with the enum, use it.
+ return self._translations_usage
+ elif self.official_rosetta:
+ return ServiceUsage.LAUNCHPAD
+ return self._translations_usage
+
+ def _set_translations_usage(self, val):
+ self._translations_usage = val
+ if val == ServiceUsage.LAUNCHPAD:
+ self.official_rosetta = True
+ else:
+ self.official_rosetta = False
+
+ translations_usage = property(
+ _get_translations_usage,
+ _set_translations_usage,
+ doc="Indicates if the product uses the translations service.")
+
def _getLicenses(self):
"""Get the licenses as a tuple."""
if self._cached_licenses is None:
=== modified file 'lib/lp/registry/tests/test_distribution.py'
--- lib/lp/registry/tests/test_distribution.py 2010-08-10 19:14:56 +0000
+++ lib/lp/registry/tests/test_distribution.py 2010-08-20 19:22:47 +0000
@@ -10,17 +10,155 @@
from lazr.lifecycle.snapshot import Snapshot
from lp.registry.tests.test_distroseries import (
TestDistroSeriesCurrentSourceReleases)
+from lp.app.enums import ServiceUsage
from lp.registry.interfaces.distroseries import NoSuchDistroSeries
from lp.registry.interfaces.series import SeriesStatus
from lp.registry.interfaces.distribution import IDistribution
from lp.soyuz.interfaces.distributionsourcepackagerelease import (
IDistributionSourcePackageRelease)
-from lp.testing import TestCaseWithFactory
+from lp.testing import (
+ login_person,
+ TestCaseWithFactory,
+ )
from canonical.testing.layers import (
DatabaseFunctionalLayer, LaunchpadFunctionalLayer)
+class TestDistributionUsageEnums(TestCaseWithFactory):
+ """Tests the usage enums for the distribution."""
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestDistributionUsageEnums, self).setUp()
+ self.distribution = self.factory.makeDistribution()
+
+ def test_answers_usage_no_data(self):
+ # By default, we don't know anything about a distribution
+ self.assertEqual(
+ ServiceUsage.UNKNOWN,
+ self.distribution.answers_usage)
+
+ def test_answers_usage_using_bool(self):
+ # If the old bool says they use Launchpad, return LAUNCHPAD
+ # if the ServiceUsage is unknown.
+ login_person(self.distribution.owner)
+ self.distribution.official_answers = True
+ self.assertEqual(
+ ServiceUsage.LAUNCHPAD,
+ self.distribution.answers_usage)
+
+ def test_answers_usage_with_enum_data(self):
+ # If the enum has something other than UNKNOWN as its status,
+ # use that.
+ login_person(self.distribution.owner)
+ self.distribution.answers_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ ServiceUsage.EXTERNAL,
+ self.distribution.answers_usage)
+
+ def test_answers_setter(self):
+ login_person(self.distribution.owner)
+ self.distribution.official_answers = True
+ self.distribution.answers_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ False,
+ self.distribution.official_answers)
+ self.distribution.answers_usage = ServiceUsage.LAUNCHPAD
+ self.assertEqual(
+ True,
+ self.distribution.official_answers)
+
+ def test_codehosting_usage(self):
+ # Only test get for codehosting; this has no setter because the
+ # state is derived from other data.
+ distribution = self.factory.makeDistribution()
+ self.assertEqual(
+ ServiceUsage.NOT_APPLICABLE,
+ distribution.codehosting_usage)
+
+ def test_translations_usage_no_data(self):
+ # By default, we don't know anything about a distribution
+ self.assertEqual(
+ ServiceUsage.UNKNOWN,
+ self.distribution.translations_usage)
+
+ def test_translations_usage_using_bool(self):
+ # If the old bool says they use Launchpad, return LAUNCHPAD
+ # if the ServiceUsage is unknown.
+ login_person(self.distribution.owner)
+ self.distribution.official_rosetta = True
+ self.assertEqual(
+ ServiceUsage.LAUNCHPAD,
+ self.distribution.translations_usage)
+
+ def test_translations_usage_with_enum_data(self):
+ # If the enum has something other than UNKNOWN as its status,
+ # use that.
+ login_person(self.distribution.owner)
+ self.distribution.translations_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ ServiceUsage.EXTERNAL,
+ self.distribution.translations_usage)
+
+ def test_translations_setter(self):
+ login_person(self.distribution.owner)
+ self.distribution.official_rosetta = True
+ self.distribution.translations_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ False,
+ self.distribution.official_rosetta)
+ self.distribution.translations_usage = ServiceUsage.LAUNCHPAD
+ self.assertEqual(
+ True,
+ self.distribution.official_rosetta)
+
+ def test_bug_tracking_usage(self):
+ # Only test get for bug_tracking; this has no setter because the
+ # state is derived from other data.
+ distribution = self.factory.makeDistribution()
+ self.assertEqual(
+ ServiceUsage.UNKNOWN,
+ distribution.bug_tracking_usage)
+
+ def test_blueprints_usage_no_data(self):
+ # By default, we don't know anything about a distribution
+ self.assertEqual(
+ ServiceUsage.UNKNOWN,
+ self.distribution.blueprints_usage)
+
+ def test_blueprints_usage_using_bool(self):
+ # If the old bool says they use Launchpad, return LAUNCHPAD
+ # if the ServiceUsage is unknown.
+ login_person(self.distribution.owner)
+ self.distribution.official_blueprints = True
+ self.assertEqual(
+ ServiceUsage.LAUNCHPAD,
+ self.distribution.blueprints_usage)
+
+ def test_blueprints_usage_with_enum_data(self):
+ # If the enum has something other than UNKNOWN as its status,
+ # use that.
+ login_person(self.distribution.owner)
+ self.distribution.blueprints_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ ServiceUsage.EXTERNAL,
+ self.distribution.blueprints_usage)
+
+ def test_blueprints_setter(self):
+ login_person(self.distribution.owner)
+ self.distribution.official_blueprints = True
+ self.distribution.blueprints_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ False,
+ self.distribution.official_blueprints)
+ self.distribution.blueprints_usage = ServiceUsage.LAUNCHPAD
+ self.assertEqual(
+ True,
+ self.distribution.official_blueprints)
+
+
class TestDistribution(TestCaseWithFactory):
layer = DatabaseFunctionalLayer
=== modified file 'lib/lp/registry/tests/test_product.py'
--- lib/lp/registry/tests/test_product.py 2010-08-10 19:14:56 +0000
+++ lib/lp/registry/tests/test_product.py 2010-08-20 19:22:47 +0000
@@ -14,18 +14,145 @@
from canonical.launchpad.ftests import login
from canonical.launchpad.testing.pages import (
find_main_content, get_feedback_messages, setupBrowser)
-from canonical.testing import LaunchpadFunctionalLayer
+from canonical.testing import (
+ DatabaseFunctionalLayer,
+ LaunchpadFunctionalLayer,
+ )
from canonical.launchpad.ftests import syncUpdate
from lazr.lifecycle.snapshot import Snapshot
+from lp.app.enums import ServiceUsage
from lp.registry.interfaces.person import IPersonSet
from lp.registry.interfaces.product import IProduct, License
from lp.registry.model.product import Product
from lp.registry.model.productlicense import ProductLicense
from lp.registry.model.commercialsubscription import (
CommercialSubscription)
-from lp.testing import TestCaseWithFactory
+from lp.testing import (
+ login_person,
+ TestCaseWithFactory,
+ )
+
+
+class TestProductUsageEnums(TestCaseWithFactory):
+ """Tests the usage enums for the product."""
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestProductUsageEnums, self).setUp()
+ self.product = self.factory.makeProduct()
+
+ def test_answers_usage_no_data(self):
+ # By default, we don't know anything about a product
+ self.assertEqual(ServiceUsage.UNKNOWN, self.product.answers_usage)
+
+ def test_answers_usage_using_bool(self):
+ # If the old bool says they use Launchpad, return LAUNCHPAD
+ # if the ServiceUsage is unknown.
+ login_person(self.product.owner)
+ self.product.official_answers = True
+ self.assertEqual(ServiceUsage.LAUNCHPAD, self.product.answers_usage)
+
+ def test_answers_usage_with_enum_data(self):
+ # If the enum has something other than UNKNOWN as its status,
+ # use that.
+ login_person(self.product.owner)
+ self.product.answers_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(ServiceUsage.EXTERNAL, self.product.answers_usage)
+
+ def test_answers_setter(self):
+ login_person(self.product.owner)
+ self.product.official_answers = True
+ self.product.answers_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ False,
+ self.product.official_answers)
+ self.product.answers_usage = ServiceUsage.LAUNCHPAD
+ self.assertEqual(
+ True,
+ self.product.official_answers)
+
+ def test_codehosting_usage(self):
+ # Only test get for codehosting; this has no setter because the
+ # state is derived from other data.
+ product = self.factory.makeProduct()
+ self.assertEqual(ServiceUsage.UNKNOWN, product.codehosting_usage)
+
+ def test_translations_usage_no_data(self):
+ # By default, we don't know anything about a product
+ self.assertEqual(
+ ServiceUsage.UNKNOWN,
+ self.product.translations_usage)
+
+ def test_translations_usage_using_bool(self):
+ # If the old bool says they use Launchpad, return LAUNCHPAD
+ # if the ServiceUsage is unknown.
+ login_person(self.product.owner)
+ self.product.official_rosetta = True
+ self.assertEqual(
+ ServiceUsage.LAUNCHPAD,
+ self.product.translations_usage)
+
+ def test_translations_usage_with_enum_data(self):
+ # If the enum has something other than UNKNOWN as its status,
+ # use that.
+ login_person(self.product.owner)
+ self.product.translations_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ ServiceUsage.EXTERNAL,
+ self.product.translations_usage)
+
+ def test_translations_setter(self):
+ login_person(self.product.owner)
+ self.product.official_rosetta = True
+ self.product.translations_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ False,
+ self.product.official_rosetta)
+ self.product.translations_usage = ServiceUsage.LAUNCHPAD
+ self.assertEqual(
+ True,
+ self.product.official_rosetta)
+
+ def test_bug_tracking_usage(self):
+ # Only test get for bug_tracking; this has no setter because the
+ # state is derived from other data.
+ product = self.factory.makeProduct()
+ self.assertEqual(ServiceUsage.UNKNOWN, product.bug_tracking_usage)
+
+ def test_blueprints_usage_no_data(self):
+ # By default, we don't know anything about a product
+ self.assertEqual(ServiceUsage.UNKNOWN, self.product.blueprints_usage)
+
+ def test_blueprints_usage_using_bool(self):
+ # If the old bool says they use Launchpad, return LAUNCHPAD
+ # if the ServiceUsage is unknown.
+ login_person(self.product.owner)
+ self.product.official_blueprints = True
+ self.assertEqual(
+ ServiceUsage.LAUNCHPAD,
+ self.product.blueprints_usage)
+
+ def test_blueprints_usage_with_enum_data(self):
+ # If the enum has something other than UNKNOWN as its status,
+ # use that.
+ login_person(self.product.owner)
+ self.product.blueprints_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(ServiceUsage.EXTERNAL, self.product.blueprints_usage)
+
+ def test_blueprints_setter(self):
+ login_person(self.product.owner)
+ self.product.official_blueprints = True
+ self.product.blueprints_usage = ServiceUsage.EXTERNAL
+ self.assertEqual(
+ False,
+ self.product.official_blueprints)
+ self.product.blueprints_usage = ServiceUsage.LAUNCHPAD
+ self.assertEqual(
+ True,
+ self.product.official_blueprints)
class TestProduct(TestCaseWithFactory):
Follow ups