Merge lp:~abentley/launchpad/no-proprietary-linked-products into lp:launchpad

Proposed by Aaron Bentley
Status: Merged
Approved by: Aaron Bentley
Approved revision: no longer in the source branch.
Merged at revision: 16142
Proposed branch: lp:~abentley/launchpad/no-proprietary-linked-products
Merge into: lp:launchpad
Diff against target: 551 lines (+217/-16)
16 files modified
lib/lp/registry/browser/product.py (+7/-1)
lib/lp/registry/browser/productseries.py (+6/-2)
lib/lp/registry/browser/sourcepackage.py (+11/-1)
lib/lp/registry/browser/tests/test_product.py (+18/-1)
lib/lp/registry/browser/tests/test_productseries_views.py (+32/-1)
lib/lp/registry/browser/tests/test_sourcepackage_views.py (+38/-1)
lib/lp/registry/errors.py (+5/-0)
lib/lp/registry/model/packaging.py (+15/-3)
lib/lp/registry/model/product.py (+2/-0)
lib/lp/registry/model/productseries.py (+2/-2)
lib/lp/registry/model/sourcepackage.py (+2/-2)
lib/lp/registry/templates/productseries-index.pt (+2/-1)
lib/lp/registry/tests/test_packaging.py (+25/-0)
lib/lp/registry/tests/test_product.py (+12/-0)
lib/lp/registry/tests/test_productseries.py (+26/-1)
lib/lp/registry/tests/test_sourcepackage.py (+14/-0)
To merge this branch: bzr merge lp:~abentley/launchpad/no-proprietary-linked-products
Reviewer Review Type Date Requested Status
Deryck Hodge (community) Approve
Review via email: mp+129507@code.launchpad.net

Commit message

No packaging links for Proprietary products.

Description of the change

= Summary =
Fix bug #1063297: Linking a private project to an ubuntu source package breaks Ubuntu
== Proposed fix ==
Prevent creating packaging links for private products, prevent making packaged products proprietary

== Pre-implementation notes ==
None

== LOC Rationale ==
Part of Private Projects

== Implementation details ==
The restrictions are implemented on the model level, and the errors it emits are handled as user errors in the UI.

ProductSeries.setPackaging and SourcePackage.setPackaging are updated to use PackagingUtil.createPackaging instead of using the constructor directly.

PackagingUtil.createPackaging is updated to raise
CannotPackageProprietaryProduct if the productseries is private.

PackagingUtil.createPackaging is changed to a class method, and packagingEntryExists to a staticmethod to permit direct use.

ProductEditView is updated to handle CannotChangeInformationType, and to stay on the current page if there are errors.

ProductSeries is updated to add an error to the main page if CannotPackageProprietaryProduct is raised.

The validator for SourcePackageChangeUpstreamStepOne is updated to check whether the product is private. This affects both steps (i.e. SourcePackageChangeUpstreamStepOne.validateStep is run for StepTwo).

The packaging portal is hidden for private product series. (They should not have packagings, and should not be able to set them.)

== Tests ==
bin/test -t test_no_proprietary_if_packaging -t test_createPackaging_refuses_ -t test_error_on_proprietary_product -t test_proprietary_hides_packaging -t test_package_proprietary_error

== Demo and Q/A ==
Create a product series with a public project. Click on "trunk". Click on "Link to Ubuntu package". In another browser window, edit the project and set it to Proprietary. Enter a source package name and series. Click "Update". It should say "Only Public project series can be packaged, not Proprietary."

Go to a source package. Click "Choose another upstream project". Click "Link to Upstream Project". Enter the name of a proprietary product. It should say "Only Public project series can be packaged, not Proprietary."

Disable JavaScript. Create a public product and link its trunk to a source package. Click "Change details." Select "Proprietary". Click "change". It should say "Some series are packaged."

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/tests/test_productseries.py
  lib/lp/registry/errors.py
  lib/lp/registry/model/productseries.py
  lib/lp/registry/browser/sourcepackage.py
  lib/lp/registry/model/packaging.py
  lib/lp/registry/browser/product.py
  lib/lp/registry/tests/test_sourcepackage.py
  lib/lp/registry/tests/test_packaging.py
  lib/lp/registry/browser/productseries.py
  lib/lp/registry/browser/tests/test_product.py
  lib/lp/registry/browser/tests/test_sourcepackage_views.py
  lib/lp/registry/model/sourcepackage.py
  lib/lp/registry/model/product.py
  lib/lp/registry/templates/productseries-index.pt
  lib/lp/registry/tests/test_product.py
  lib/lp/registry/browser/tests/test_productseries_views.py

To post a comment you must log in.
Revision history for this message
Deryck Hodge (deryck) wrote :

Looks good to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/product.py'
2--- lib/lp/registry/browser/product.py 2012-10-11 12:41:43 +0000
3+++ lib/lp/registry/browser/product.py 2012-10-12 20:19:21 +0000
4@@ -156,6 +156,7 @@
5 PillarViewMixin,
6 )
7 from lp.registry.browser.productseries import get_series_branch_error
8+from lp.registry.errors import CannotChangeInformationType
9 from lp.registry.interfaces.pillar import IPillarNameSet
10 from lp.registry.interfaces.product import (
11 IProduct,
12@@ -1397,6 +1398,8 @@
13 def next_url(self):
14 """See `LaunchpadFormView`."""
15 if self.context.active:
16+ if len(self.errors) > 0:
17+ return None
18 return canonical_url(self.context)
19 else:
20 return canonical_url(getUtility(IProductSet))
21@@ -1438,7 +1441,10 @@
22
23 @action("Change", name='change')
24 def change_action(self, action, data):
25- self.updateContextFromData(data)
26+ try:
27+ self.updateContextFromData(data)
28+ except CannotChangeInformationType as e:
29+ self.setFieldError('information_type', str(e))
30
31
32 class ProductValidationMixin:
33
34=== modified file 'lib/lp/registry/browser/productseries.py'
35--- lib/lp/registry/browser/productseries.py 2012-10-10 20:23:48 +0000
36+++ lib/lp/registry/browser/productseries.py 2012-10-12 20:19:21 +0000
37@@ -111,6 +111,7 @@
38 InvolvedMenu,
39 PillarInvolvementView,
40 )
41+from lp.registry.errors import CannotPackageProprietaryProduct
42 from lp.registry.interfaces.packaging import (
43 IPackaging,
44 IPackagingUtil,
45@@ -636,8 +637,11 @@
46 sourcepackagename, distroseries, productseries=self.context):
47 # There is no change.
48 return
49- self.context.setPackaging(
50- distroseries, sourcepackagename, self.user)
51+ try:
52+ self.context.setPackaging(
53+ distroseries, sourcepackagename, self.user)
54+ except CannotPackageProprietaryProduct, e:
55+ self.request.response.addErrorNotification(str(e))
56
57
58 class ProductSeriesEditView(LaunchpadEditFormView):
59
60=== modified file 'lib/lp/registry/browser/sourcepackage.py'
61--- lib/lp/registry/browser/sourcepackage.py 2012-01-03 05:05:39 +0000
62+++ lib/lp/registry/browser/sourcepackage.py 2012-10-12 20:19:21 +0000
63@@ -1,4 +1,4 @@
64-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
65+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
66 # GNU Affero General Public License version 3 (see the file LICENSE).
67
68 """Browser views for sourcepackages."""
69@@ -302,6 +302,16 @@
70 self.next_step = SourcePackageChangeUpstreamStepTwo
71 self.request.form['product'] = data['product']
72
73+ def validateStep(self, data):
74+ super(SourcePackageChangeUpstreamStepOne, self).validateStep(data)
75+ product = data.get('product')
76+ if product is None:
77+ return
78+ if product.private:
79+ self.setFieldError('product',
80+ 'Only Public projects can be packaged, not %s.' %
81+ data['product'].information_type.title)
82+
83 @property
84 def register_upstream_url(self):
85 return get_register_upstream_url(self.context)
86
87=== modified file 'lib/lp/registry/browser/tests/test_product.py'
88--- lib/lp/registry/browser/tests/test_product.py 2012-10-10 13:56:03 +0000
89+++ lib/lp/registry/browser/tests/test_product.py 2012-10-12 20:19:21 +0000
90@@ -432,7 +432,7 @@
91 cache.objects['team_membership_policy_data'])
92
93
94-class TestProductEditView(TestCaseWithFactory):
95+class TestProductEditView(BrowserTestCase):
96 """Tests for the ProductEditView"""
97
98 layer = DatabaseFunctionalLayer
99@@ -481,6 +481,23 @@
100 # the product when the information type is changed.
101 self.assertIsNotNone(updated_product.commercial_subscription)
102
103+ def test_change_information_type_proprietary_packaged(self):
104+ # It should be an error to make a Product private if it is packaged.
105+ self.useFixture(FeatureFixture(
106+ {u'disclosure.private_projects.enabled': u'on'}))
107+ product = self.factory.makeProduct()
108+ sourcepackage = self.factory.makeSourcePackage()
109+ sourcepackage.setPackaging(product.development_focus, product.owner)
110+ browser = self.getViewBrowser(product, '+edit', user=product.owner)
111+ info_type = browser.getControl(name='field.information_type')
112+ info_type.value = ['PROPRIETARY']
113+ old_url = browser.url
114+ browser.getControl('Change').click()
115+ self.assertEqual(old_url, browser.url)
116+ tag = Tag('error', 'div', text='Some series are packaged.',
117+ attrs={'class': 'message'})
118+ self.assertThat(browser.contents, HTMLContains(tag))
119+
120 def test_change_information_type_public(self):
121 owner = self.factory.makePerson(name='pting')
122 product = self.factory.makeProduct(
123
124=== modified file 'lib/lp/registry/browser/tests/test_productseries_views.py'
125--- lib/lp/registry/browser/tests/test_productseries_views.py 2012-06-19 18:27:50 +0000
126+++ lib/lp/registry/browser/tests/test_productseries_views.py 2012-10-12 20:19:21 +0000
127@@ -1,4 +1,4 @@
128-# Copyright 2011 Canonical Ltd. This software is licensed under the
129+# Copyright 2011-2012 Canonical Ltd. This software is licensed under the
130 # GNU Affero General Public License version 3 (see the file LICENSE).
131
132 """View tests for ProductSeries pages."""
133@@ -7,7 +7,9 @@
134
135
136 import soupmatchers
137+from testtools.matchers import Not
138
139+from lp.app.enums import InformationType
140 from lp.bugs.interfaces.bugtask import (
141 BugTaskStatus,
142 BugTaskStatusSearch,
143@@ -58,6 +60,35 @@
144 browser = self.getViewBrowser(series)
145 self.assertThat(browser.contents, soupmatchers.HTMLContains(tag))
146
147+ def test_package_proprietary_error(self):
148+ """Packaging a proprietary product produces an error."""
149+ product = self.factory.makeProduct(
150+ information_type=InformationType.PROPRIETARY)
151+ productseries = self.factory.makeProductSeries(product=product)
152+ ubuntu_series = self.factory.makeUbuntuDistroSeries()
153+ sp = self.factory.makeSourcePackage(distroseries=ubuntu_series,
154+ publish=True)
155+ browser = self.getViewBrowser(productseries, '+ubuntupkg')
156+ browser.getControl('Source Package Name').value = (
157+ sp.sourcepackagename.name)
158+ browser.getControl(ubuntu_series.displayname).selected = True
159+ browser.getControl('Update').click()
160+ tag = soupmatchers.Tag(
161+ 'error-div', 'div', attrs={'class': 'error message'},
162+ text='Only Public project series can be packaged, not'
163+ ' Proprietary.')
164+ self.assertThat(browser.contents, soupmatchers.HTMLContains(tag))
165+
166+ def test_proprietary_hides_packaging(self):
167+ """Proprietary, Embargoed lack "Distribution packaging" sections."""
168+ product = self.factory.makeProduct(
169+ information_type=InformationType.PROPRIETARY)
170+ series = self.factory.makeProductSeries(product=product)
171+ browser = self.getViewBrowser(series)
172+ tag = soupmatchers.Tag(
173+ 'portlet-packages', True, attrs={'id': 'portlet-packages'})
174+ self.assertThat(browser.contents, Not(soupmatchers.HTMLContains(tag)))
175+
176
177 class TestProductSeriesStatus(TestCaseWithFactory):
178 """Tests for ProductSeries:+status."""
179
180=== modified file 'lib/lp/registry/browser/tests/test_sourcepackage_views.py'
181--- lib/lp/registry/browser/tests/test_sourcepackage_views.py 2012-09-18 20:38:09 +0000
182+++ lib/lp/registry/browser/tests/test_sourcepackage_views.py 2012-10-12 20:19:21 +0000
183@@ -1,4 +1,4 @@
184-# Copyright 2010-2011 Canonical Ltd. This software is licensed under the
185+# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
186 # GNU Affero General Public License version 3 (see the file LICENSE).
187
188 """Tests for SourcePackage view code."""
189@@ -12,6 +12,7 @@
190 from zope.interface import implements
191 from zope.security.proxy import removeSecurityProxy
192
193+from lp.app.enums import InformationType
194 from lp.registry.browser.sourcepackage import (
195 get_register_upstream_url,
196 PackageUpstreamTracking,
197@@ -25,6 +26,7 @@
198 from lp.registry.interfaces.sourcepackage import ISourcePackage
199 from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
200 from lp.testing import (
201+ BrowserTestCase,
202 person_logged_in,
203 TestCaseWithFactory,
204 )
205@@ -287,3 +289,38 @@
206 menu, user = self.makeSourcePackageOverviewMenu(True, None)
207 with person_logged_in(user):
208 self.assertFalse(menu.remove_packaging().enabled)
209+
210+
211+class TestSourcePackageChangeUpstreamView(BrowserTestCase):
212+
213+ layer = DatabaseFunctionalLayer
214+
215+ def test_error_on_proprietary_product(self):
216+ """Packaging cannot be created for PROPRIETARY products"""
217+ product = self.factory.makeProduct(
218+ information_type=InformationType.PROPRIETARY)
219+ ubuntu_series = self.factory.makeUbuntuDistroSeries()
220+ sp = self.factory.makeSourcePackage(distroseries=ubuntu_series)
221+ browser = self.getViewBrowser(sp, '+edit-packaging')
222+ browser.getControl('Project').value = product.name
223+ browser.getControl('Continue').click()
224+ self.assertIn(
225+ 'Only Public projects can be packaged, not Proprietary.',
226+ browser.contents)
227+
228+ def test_error_on_proprietary_productseries(self):
229+ """Packaging cannot be created for PROPRIETARY productseries"""
230+ product = self.factory.makeProduct()
231+ series = self.factory.makeProductSeries(product=product)
232+ ubuntu_series = self.factory.makeUbuntuDistroSeries()
233+ sp = self.factory.makeSourcePackage(distroseries=ubuntu_series)
234+ browser = self.getViewBrowser(sp, '+edit-packaging')
235+ browser.getControl('Project').value = product.name
236+ browser.getControl('Continue').click()
237+ with person_logged_in(product.owner):
238+ product.information_type = InformationType.PROPRIETARY
239+ browser.getControl(series.displayname).selected = True
240+ browser.getControl('Change').click()
241+ self.assertIn(
242+ 'Only Public projects can be packaged, not Proprietary.',
243+ browser.contents)
244
245=== modified file 'lib/lp/registry/errors.py'
246--- lib/lp/registry/errors.py 2012-09-04 04:27:53 +0000
247+++ lib/lp/registry/errors.py 2012-10-12 20:19:21 +0000
248@@ -9,6 +9,7 @@
249 'CannotDeleteCommercialSubscription',
250 'CannotTransitionToCountryMirror',
251 'CommercialSubscribersOnly',
252+ 'CannotPackageProprietaryProduct',
253 'CountryMirrorAlreadySet',
254 'DeleteSubscriptionError',
255 'InvalidFilename',
256@@ -202,3 +203,7 @@
257 @error_status(httplib.BAD_REQUEST)
258 class CannotChangeInformationType(Exception):
259 """The information type cannot be changed."""
260+
261+
262+class CannotPackageProprietaryProduct(Exception):
263+ """Raised when a non-PUBLIC product's series is linked to a package."""
264
265=== modified file 'lib/lp/registry/model/packaging.py'
266--- lib/lp/registry/model/packaging.py 2012-09-19 14:23:35 +0000
267+++ lib/lp/registry/model/packaging.py 2012-10-12 20:19:21 +0000
268@@ -16,7 +16,9 @@
269 from zope.interface import implements
270 from zope.security.interfaces import Unauthorized
271
272+from lp.app.enums import InformationType
273 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
274+from lp.registry.errors import CannotPackageProprietaryProduct
275 from lp.registry.interfaces.packaging import (
276 IPackaging,
277 IPackagingUtil,
278@@ -95,17 +97,26 @@
279 """Utilities for Packaging."""
280 implements(IPackagingUtil)
281
282- def createPackaging(self, productseries, sourcepackagename,
283+ @classmethod
284+ def createPackaging(cls, productseries, sourcepackagename,
285 distroseries, packaging, owner):
286 """See `IPackaging`.
287
288 Raises an assertion error if there is already packaging for
289 the sourcepackagename in the distroseries.
290 """
291- if self.packagingEntryExists(sourcepackagename, distroseries):
292+ if cls.packagingEntryExists(sourcepackagename, distroseries):
293 raise AssertionError(
294 "A packaging entry for %s in %s already exists." %
295 (sourcepackagename.name, distroseries.name))
296+ # XXX: AaronBentley: 2012-08-12 bug=1066063 Cannot adapt ProductSeries
297+ # to IInformationType.
298+ # info_type = IInformationType(productseries).information_type
299+ info_type = productseries.product.information_type
300+ if info_type != InformationType.PUBLIC:
301+ raise CannotPackageProprietaryProduct(
302+ "Only Public project series can be packaged, not %s."
303+ % info_type.title)
304 return Packaging(productseries=productseries,
305 sourcepackagename=sourcepackagename,
306 distroseries=distroseries,
307@@ -126,7 +137,8 @@
308 distroseries.parent.name, distroseries.name))
309 packaging.destroySelf()
310
311- def packagingEntryExists(self, sourcepackagename, distroseries,
312+ @staticmethod
313+ def packagingEntryExists(sourcepackagename, distroseries,
314 productseries=None):
315 """See `IPackaging`."""
316 criteria = dict(
317
318=== modified file 'lib/lp/registry/model/product.py'
319--- lib/lp/registry/model/product.py 2012-10-11 07:35:25 +0000
320+++ lib/lp/registry/model/product.py 2012-10-12 20:19:21 +0000
321@@ -438,6 +438,8 @@
322 # If you have a commercial subscription, but it's not current, you
323 # cannot set the information type to a PROPRIETARY type.
324 if not self._SO_creating and value in PROPRIETARY_INFORMATION_TYPES:
325+ if not self.packagings.is_empty():
326+ raise CannotChangeInformationType('Some series are packaged.')
327 # Create the complimentary commercial subscription for the product.
328 self._ensure_complimentary_subscription()
329
330
331=== modified file 'lib/lp/registry/model/productseries.py'
332--- lib/lp/registry/model/productseries.py 2012-10-06 23:40:20 +0000
333+++ lib/lp/registry/model/productseries.py 2012-10-12 20:19:21 +0000
334@@ -71,7 +71,7 @@
335 HasMilestonesMixin,
336 Milestone,
337 )
338-from lp.registry.model.packaging import Packaging
339+from lp.registry.model.packaging import PackagingUtil
340 from lp.registry.model.productrelease import ProductRelease
341 from lp.registry.model.series import SeriesMixin
342 from lp.services.database.constants import UTC_NOW
343@@ -504,7 +504,7 @@
344
345 # ok, we didn't find a packaging record that matches, let's go ahead
346 # and create one
347- pkg = Packaging(
348+ pkg = PackagingUtil.createPackaging(
349 distroseries=distroseries,
350 sourcepackagename=sourcepackagename,
351 productseries=self,
352
353=== modified file 'lib/lp/registry/model/sourcepackage.py'
354--- lib/lp/registry/model/sourcepackage.py 2012-09-26 05:21:07 +0000
355+++ lib/lp/registry/model/sourcepackage.py 2012-10-12 20:19:21 +0000
356@@ -54,7 +54,7 @@
357 ISourcePackageFactory,
358 )
359 from lp.registry.model.hasdrivers import HasDriversMixin
360-from lp.registry.model.packaging import Packaging
361+from lp.registry.model.packaging import Packaging, PackagingUtil
362 from lp.registry.model.suitesourcepackage import SuiteSourcePackage
363 from lp.services.database.lpstorm import IStore
364 from lp.services.database.sqlbase import (
365@@ -523,7 +523,7 @@
366 # Delete the current packaging and create a new one so
367 # that the translation sharing jobs are started.
368 self.direct_packaging.destroySelf()
369- Packaging(
370+ PackagingUtil.createPackaging(
371 distroseries=self.distroseries,
372 sourcepackagename=self.sourcepackagename,
373 productseries=productseries, owner=owner,
374
375=== modified file 'lib/lp/registry/templates/productseries-index.pt'
376--- lib/lp/registry/templates/productseries-index.pt 2012-02-01 15:31:32 +0000
377+++ lib/lp/registry/templates/productseries-index.pt 2012-10-12 20:19:21 +0000
378@@ -154,7 +154,8 @@
379 tal:content="structure context/@@+portlet-latestbugs"
380 tal:condition="context/@@+get-involved/official_malone" />
381
382- <div tal:content="structure context/@@+portlet-packages" />
383+ <div tal:content="structure context/@@+portlet-packages"
384+ tal:condition="not: context/product/private" />
385 </div>
386
387 <div class="yui-u">
388
389=== modified file 'lib/lp/registry/tests/test_packaging.py'
390--- lib/lp/registry/tests/test_packaging.py 2012-09-19 16:56:38 +0000
391+++ lib/lp/registry/tests/test_packaging.py 2012-10-12 20:19:21 +0000
392@@ -11,10 +11,13 @@
393 ObjectCreatedEvent,
394 ObjectDeletedEvent,
395 )
396+from testtools.testcase import ExpectedException
397 from zope.component import getUtility
398 from zope.security.interfaces import Unauthorized
399 from zope.security.proxy import removeSecurityProxy
400
401+from lp.app.enums import InformationType
402+from lp.registry.errors import CannotPackageProprietaryProduct
403 from lp.registry.interfaces.distribution import IDistributionSet
404 from lp.registry.interfaces.packaging import (
405 IPackagingUtil,
406@@ -169,6 +172,28 @@
407 self.productseries, self.sourcepackagename, self.distroseries,
408 PackagingType.PRIME, self.owner)
409
410+ def test_createPackaging_refuses_PROPRIETARY(self):
411+ """Packaging cannot be created for PROPRIETARY productseries"""
412+ product = self.factory.makeProduct(
413+ information_type=InformationType.PROPRIETARY)
414+ series = self.factory.makeProductSeries(product=product)
415+ with ExpectedException(CannotPackageProprietaryProduct,
416+ 'Only Public project series can be packaged, not Proprietary.'):
417+ self.packaging_util.createPackaging(
418+ series, self.sourcepackagename, self.distroseries,
419+ PackagingType.PRIME, owner=self.owner)
420+
421+ def test_createPackaging_refuses_EMBARGOED(self):
422+ """Packaging cannot be created for EMBARGOED productseries"""
423+ product = self.factory.makeProduct(
424+ information_type=InformationType.EMBARGOED)
425+ series = self.factory.makeProductSeries(product=product)
426+ with ExpectedException(CannotPackageProprietaryProduct,
427+ 'Only Public project series can be packaged, not Embargoed.'):
428+ self.packaging_util.createPackaging(
429+ series, self.sourcepackagename, self.distroseries,
430+ PackagingType.PRIME, owner=self.owner)
431+
432
433 class TestPackagingEntryExists(PackagingUtilMixin, TestCaseWithFactory):
434 """Test PackagingUtil.packagingEntryExists."""
435
436=== modified file 'lib/lp/registry/tests/test_product.py'
437--- lib/lp/registry/tests/test_product.py 2012-10-11 04:21:07 +0000
438+++ lib/lp/registry/tests/test_product.py 2012-10-12 20:19:21 +0000
439@@ -513,6 +513,18 @@
440 CannotChangeInformationType, 'Answers is enabled.'):
441 product.information_type = InformationType.PROPRIETARY
442
443+ def test_no_proprietary_if_packaging(self):
444+ # information_type cannot be set to proprietary while any
445+ # productseries are packaged.
446+ product = self.factory.makeProduct(
447+ licenses=[License.OTHER_PROPRIETARY])
448+ series = self.factory.makeProductSeries(product=product)
449+ self.factory.makePackagingLink(productseries=series)
450+ with person_logged_in(product.owner):
451+ with ExpectedException(
452+ CannotChangeInformationType, 'Some series are packaged.'):
453+ product.information_type = InformationType.PROPRIETARY
454+
455
456 class TestProductBugInformationTypes(TestCaseWithFactory):
457
458
459=== modified file 'lib/lp/registry/tests/test_productseries.py'
460--- lib/lp/registry/tests/test_productseries.py 2012-01-01 02:58:52 +0000
461+++ lib/lp/registry/tests/test_productseries.py 2012-10-12 20:19:21 +0000
462@@ -1,14 +1,17 @@
463-# Copyright 2010-2011 Canonical Ltd. This software is licensed under the
464+# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
465 # GNU Affero General Public License version 3 (see the file LICENSE).
466
467 """Tests for ProductSeries and ProductSeriesSet."""
468
469 __metaclass__ = type
470
471+from testtools.testcase import ExpectedException
472 import transaction
473 from zope.component import getUtility
474 from zope.security.proxy import removeSecurityProxy
475
476+from lp.app.enums import InformationType
477+from lp.registry.errors import CannotPackageProprietaryProduct
478 from lp.registry.interfaces.distribution import IDistributionSet
479 from lp.registry.interfaces.distroseries import IDistroSeriesSet
480 from lp.registry.interfaces.productseries import (
481@@ -138,6 +141,28 @@
482 distroseries=self.ubuntu_series)
483 return sourcepackage
484
485+ def test_refuses_PROPRIETARY(self):
486+ """Packaging cannot be created for PROPRIETARY productseries"""
487+ product = self.factory.makeProduct(
488+ information_type=InformationType.PROPRIETARY)
489+ series = self.factory.makeProductSeries(product=product)
490+ sp = self.makeSourcePackage()
491+ with ExpectedException(CannotPackageProprietaryProduct,
492+ 'Only Public project series can be packaged, not Proprietary.'):
493+ series.setPackaging(
494+ sp.distroseries, sp.sourcepackagename, series.owner)
495+
496+ def test_refuses_EMBARGOED(self):
497+ """Packaging cannot be created for EMBARGOED productseries"""
498+ product = self.factory.makeProduct(
499+ information_type=InformationType.EMBARGOED)
500+ sp = self.makeSourcePackage()
501+ series = self.factory.makeProductSeries(product=product)
502+ with ExpectedException(CannotPackageProprietaryProduct,
503+ 'Only Public project series can be packaged, not Embargoed.'):
504+ series.setPackaging(
505+ sp.distroseries, sp.sourcepackagename, series.owner)
506+
507 def test_setPackaging_two_packagings(self):
508 # More than one sourcepackage from the same distroseries
509 # can be linked to a productseries.
510
511=== modified file 'lib/lp/registry/tests/test_sourcepackage.py'
512--- lib/lp/registry/tests/test_sourcepackage.py 2012-09-19 14:23:35 +0000
513+++ lib/lp/registry/tests/test_sourcepackage.py 2012-10-12 20:19:21 +0000
514@@ -11,16 +11,19 @@
515 )
516 from storm.locals import Store
517 import transaction
518+from testtools.testcase import ExpectedException
519 from zope.component import getUtility
520 from zope.interface.verify import verifyObject
521 from zope.security.checker import canAccess
522 from zope.security.management import checkPermission
523 from zope.security.proxy import removeSecurityProxy
524
525+from lp.app.enums import InformationType
526 from lp.app.interfaces.launchpad import ILaunchpadCelebrities
527 from lp.code.model.seriessourcepackagebranch import (
528 SeriesSourcePackageBranchSet,
529 )
530+from lp.registry.errors import CannotPackageProprietaryProduct
531 from lp.registry.interfaces.distribution import NoPartnerArchive
532 from lp.registry.interfaces.pocket import PackagePublishingPocket
533 from lp.registry.interfaces.series import SeriesStatus
534@@ -322,6 +325,17 @@
535 self.assertIsInstance(event2, ObjectDeletedEvent)
536 self.assertIsInstance(event3, ObjectCreatedEvent)
537
538+ def test_refuses_PROPRIETARY(self):
539+ """Packaging cannot be created for PROPRIETARY productseries"""
540+ product = self.factory.makeProduct(
541+ information_type=InformationType.PROPRIETARY)
542+ series = self.factory.makeProductSeries(product=product)
543+ ubuntu_series = self.factory.makeUbuntuDistroSeries()
544+ sp = self.factory.makeSourcePackage(distroseries=ubuntu_series)
545+ with ExpectedException(CannotPackageProprietaryProduct,
546+ 'Only Public project series can be packaged, not Proprietary.'):
547+ sp.setPackaging(series, series.owner)
548+
549 def test_setPackagingReturnSharingDetailPermissions__ordinary_user(self):
550 """An ordinary user can create a packaging link but he cannot
551 set the series' branch or translation syncronisation settings,