launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #06640
[Merge] lp:~sinzui/launchpad/entitlement-1 into lp:launchpad
Curtis Hovey has proposed merging lp:~sinzui/launchpad/entitlement-1 into lp:launchpad with lp:~sinzui/launchpad/pre-entitlement-1 as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #951151 in Launchpad itself: "give proprietary projects a complimentary commercial subscription"
https://bugs.launchpad.net/launchpad/+bug/951151
For more details, see:
https://code.launchpad.net/~sinzui/launchpad/entitlement-1/+merge/96835
Give proprietary projects a complimentary commercial subscriptions.
Pre-implementation: StevenK
We want to give proprietary projects complimentary commercial subscriptions
to ensure that projects can be configured setup to no disclose information
from the start. This solves two outstanding issues.
1. There is often a delay of hours from the the moment Lp tell a
maintainer how to purchase and commercial subscription and the time one
is applied. This affects Canonical staff that need to find someone who
can apply to commercial subscription so that proprietary features can be
enabled. We do not want to accidentally disclose proprietary information
while project setup is incomplete.
2. We commonly enable proprietary features for prospective commercial
customers, and leave notes on pages to prevent the project from being
disabled during the trial. We would prefer that users be able to try
proprietary without getting the assistance of staff via email and IRC.
This is an incremental change just issues the complimentary
commercial subscription.
--------------------------------------------------------------------
RULES
THIS BRANCH
* When a OTHER/PROPRIETARY license is added to a project, and the
project does not have any commercial subscriptions add a commercial
subscription that expires in 4 weeks.
* We check for previous active and expired commercial subscriptions
to ensure that users cannot get extra time by reconfiguring their
project.
* Product._setLicenses()
* Use StevenK's example from the LaunchpadFactory to create a
commercial subscription without a voucher.
FUTURE BRANCHES
* The UI and an email is sent to inform the user of the complimentary
commercial subscription and it will explain when it expires and how
to active the proprietary features. There is a link to purchase a
full subscription.
* This email probably replaces the existing email that explain Lp's
licensing and purchasing rules.
* At 4 weeks and 1 weeks before a commercial subscription expires, a
reminder is sent to purchase a commercial subscription.
* the email also explain that the project will be deactivated if the
subscription is not renewed and the project is still proprietary
to ensure proprietary is not added added.
* Users can choose an Open source license. Branches and bugs will
remain proprietary because we understand that confidential information
can never be disclosed, but new bugs and branches will be public...
the project's focus of development must be set to a public branch.
* Bonus points if there is a clear way to identify a Canonical owned
project and set the commercial subscription to expire in 10 years.
QA
* Visit https://qastaging.launchpad.net/projects/+new and create a
non-proprietary project.
* Verify it does not have a commercial subscription
* Use Change details to set the license to proprietary.
* Verify it has a commercial subscription that expires in one month.
* Verify a notice explains the situation and how to configure proprietary
features.
* Verify an email was sent to the maintainer explaining how to
purchase a commercial subscription and how to configure a proprietary
project.
* Visit https://qastaging.launchpad.net/projects/+new and create a
proprietary project.
* Verify it has a commercial subscription that expires in one month.
* Verify a notice explains the situation and how to configure proprietary
features.
* Verify an email was sent to the maintainer explaining how to
purchase a commercial subscription and how to configure a proprietary
project.
* Set default private_bugs and branches default forbidden.
* Set a branch as the development focus.
* Remove the proprietary license using Change details.
* Verify that the default private_bugs is still enabled.
* Verify that branches default forbidden is still true
* Force the license of both test projects to expire in less then a week.
* Verify an email was sent to the maintainer of both projects explaining
the situation.
* Force the license to expire.
* Verify the open project's default private bugs is False and that
you cannot set the value to True.
* Verify that default forbidden branches is False and that the project's
focus of development branch is unset.
* Set the open project project's license to proprietary
* Verify that a commercial subscription was not given to the project.
* Verify that the first project that was left as proprietary was
deactivated.
LINT
lib/lp/registry/model/product.py
lib/lp/registry/tests/test_product.py
TEST
./bin/test -vv -t ProductLicensingTestCase lp.registry.tests.test_product
IMPLEMENTATION
Updated the _setLicense() method to create a 30 day complimentary commercial
subscription if the project has a proprietary license and does not already
have a commercial_subscription. As was demonstrated by the factory method
that creates a CommercialSubscription for tests, Lp does not require a real
id that matches a voucher in the sales system, and there is no code that uses
the string we place in field. We can put any information we want to store
in the field that helps us identify how the commercial subscription was
authorised.
lib/lp/registry/model/product.py
lib/lp/registry/tests/test_product.py
--
https://code.launchpad.net/~sinzui/launchpad/entitlement-1/+merge/96835
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~sinzui/launchpad/entitlement-1 into lp:launchpad.
=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py 2012-03-09 21:30:28 +0000
+++ lib/lp/registry/model/product.py 2012-03-09 21:30:28 +0000
@@ -771,6 +771,18 @@
for license in licenses.difference(old_licenses):
ProductLicense(product=self, license=license)
get_property_cache(self)._cached_licenses = tuple(sorted(licenses))
+ if (License.OTHER_PROPRIETARY in licenses
+ and self.commercial_subscription is None):
+ lp_janitor = getUtility(ILaunchpadCelebrities).janitor
+ now = datetime.datetime.now(pytz.UTC)
+ date_expires = now + datetime.timedelta(days=30)
+ sales_system_id = 'complimentary-30-day-%s' % now
+ whiteboard = "Complimentary 30 day subscription."
+ subscription = CommercialSubscription(
+ product=self, date_starts=now, date_expires=date_expires,
+ registrant=lp_janitor, purchaser=lp_janitor,
+ sales_system_id=sales_system_id, whiteboard=whiteboard)
+ get_property_cache(self).commercial_subscription = subscription
licenses = property(_getLicenses, _setLicenses)
=== modified file 'lib/lp/registry/tests/test_product.py'
--- lib/lp/registry/tests/test_product.py 2012-03-09 21:30:28 +0000
+++ lib/lp/registry/tests/test_product.py 2012-03-09 21:30:28 +0000
@@ -10,6 +10,7 @@
import pytz
from testtools.matchers import MatchesAll
import transaction
+from zope.component import getUtility
from zope.security.interfaces import Unauthorized
from zope.security.proxy import removeSecurityProxy
@@ -19,6 +20,7 @@
IHasIcon,
IHasLogo,
IHasMugshot,
+ ILaunchpadCelebrities,
ILaunchpadUsage,
IServiceUsage,
)
@@ -35,6 +37,7 @@
)
from lp.registry.interfaces.product import (
IProduct,
+ IProductSet,
License,
)
from lp.registry.interfaces.series import SeriesStatus
@@ -503,6 +506,69 @@
self.assertRaises(
ValueError, setattr, product, 'licenses', ['bogus'])
+ def test_setLicense_non_proprietary(self):
+ # Non-proprietary projects are not given a complimentary
+ # commercial subscription.
+ product = self.factory.makeProduct(licenses=[License.MIT])
+ self.assertIsNone(product.commercial_subscription)
+
+ def test_setLicense_proprietary_with_commercial_subscription(self):
+ # Proprietary projects with existing commercial subscriptions are not
+ # given a complimentary commercial subscription.
+ product = self.factory.makeProduct()
+ self.factory.makeCommercialSubscription(product)
+ with celebrity_logged_in('admin'):
+ product.commercial_subscription.sales_system_id = 'testing'
+ date_expires = product.commercial_subscription.date_expires
+ with person_logged_in(product.owner):
+ product.licenses = [License.OTHER_PROPRIETARY]
+ with celebrity_logged_in('admin'):
+ self.assertEqual(
+ 'testing', product.commercial_subscription.sales_system_id)
+ self.assertEqual(
+ date_expires, product.commercial_subscription.date_expires)
+
+ def test_setLicense_proprietary_without_commercial_subscription(self):
+ # Proprietary projects without a commercial subscriptions are
+ # given a complimentary 30 day commercial subscription.
+ product = self.factory.makeProduct()
+ with person_logged_in(product.owner):
+ product.licenses = [License.OTHER_PROPRIETARY]
+ with celebrity_logged_in('admin'):
+ cs = product.commercial_subscription
+ self.assertIsNotNone(cs)
+ self.assertIn('complimentary-30-day', cs.sales_system_id)
+ now = datetime.datetime.now(pytz.UTC)
+ self.assertTrue(now >= cs.date_starts)
+ future_30_days = now + datetime.timedelta(days=30)
+ self.assertTrue(future_30_days >= cs.date_expires)
+ self.assertEqual(
+ "Complimentary 30 day subscription.", cs.whiteboard)
+ lp_janitor = getUtility(ILaunchpadCelebrities).janitor
+ self.assertEqual(lp_janitor, cs.registrant)
+ self.assertEqual(lp_janitor, cs.purchaser)
+
+ def test_new_proprietary_has_commercial_subscription(self):
+ # New proprietary projects are given a complimentary 30 day
+ # commercial subscription.
+ owner = self.factory.makePerson()
+ product = getUtility(IProductSet).createProduct(
+ owner, 'fnord', 'Fnord', 'Fnord', 'test 1', 'test 2',
+ licenses=[License.OTHER_PROPRIETARY])
+ with celebrity_logged_in('admin'):
+ cs = product.commercial_subscription
+ self.assertIsNotNone(cs)
+ self.assertIn('complimentary-30-day', cs.sales_system_id)
+ now = datetime.datetime.now(pytz.UTC)
+ self.assertTrue(now >= cs.date_starts)
+ future_30_days = now + datetime.timedelta(days=30)
+ self.assertTrue(future_30_days >= cs.date_expires)
+ self.assertEqual(
+ "Complimentary 30 day subscription.", cs.whiteboard)
+ lp_janitor = getUtility(ILaunchpadCelebrities).janitor
+ self.assertEqual(lp_janitor, cs.registrant)
+ self.assertEqual(lp_janitor, cs.purchaser)
+
class ProductSnapshotTestCase(TestCaseWithFactory):
"""Test product snapshots.