Merge lp:~wgrant/launchpad/bug-sharing-policy into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 15833
Proposed branch: lp:~wgrant/launchpad/bug-sharing-policy
Merge into: lp:launchpad
Diff against target: 564 lines (+235/-28)
10 files modified
lib/lp/bugs/browser/tests/test_bugs.py (+28/-1)
lib/lp/bugs/browser/tests/test_bugtarget_filebug.py (+47/-3)
lib/lp/bugs/interfaces/bugtarget.py (+23/-0)
lib/lp/bugs/mail/tests/test_handler.py (+24/-1)
lib/lp/bugs/tests/test_bugs_webservice.py (+25/-2)
lib/lp/code/model/branchnamespace.py (+2/-5)
lib/lp/code/model/tests/test_branchnamespace.py (+2/-2)
lib/lp/registry/enums.py (+8/-1)
lib/lp/registry/model/product.py (+10/-1)
lib/lp/registry/tests/test_product.py (+66/-12)
To merge this branch: bzr merge lp:~wgrant/launchpad/bug-sharing-policy
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+120385@code.launchpad.net

Commit message

Product.getAllowedBugInformationTypes and getDefaultBugInformationType now respect bug_sharing_policy.

Description of the change

This branch adjusts Product.getAllowedBugInformationTypes and Product.getDefaultBugInformationType to respect bug_sharing_policy, if it's set. If it's not set, private_bugs is respected. Not much code, but lots of tests to cover the various bug filing paths.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you.

I Suppose my branch to remove the commercial admin restriction needs to land after yours so that I can remove the test hacks.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/browser/tests/test_bugs.py'
--- lib/lp/bugs/browser/tests/test_bugs.py 2012-08-08 11:48:29 +0000
+++ lib/lp/bugs/browser/tests/test_bugs.py 2012-08-20 13:34:33 +0000
@@ -12,7 +12,11 @@
12from lp.bugs.interfaces.bugtask import BugTaskStatus12from lp.bugs.interfaces.bugtask import BugTaskStatus
13from lp.bugs.interfaces.malone import IMaloneApplication13from lp.bugs.interfaces.malone import IMaloneApplication
14from lp.bugs.publisher import BugsLayer14from lp.bugs.publisher import BugsLayer
15from lp.registry.enums import InformationType15from lp.registry.enums import (
16 BugSharingPolicy,
17 InformationType,
18 )
19from lp.registry.interfaces.person import IPersonSet
16from lp.registry.interfaces.product import License20from lp.registry.interfaces.product import License
17from lp.services.webapp.publisher import canonical_url21from lp.services.webapp.publisher import canonical_url
18from lp.testing import (22from lp.testing import (
@@ -24,6 +28,7 @@
24 )28 )
25from lp.testing.layers import DatabaseFunctionalLayer29from lp.testing.layers import DatabaseFunctionalLayer
26from lp.testing.pages import find_tag_by_id30from lp.testing.pages import find_tag_by_id
31from lp.testing.sampledata import COMMERCIAL_ADMIN_EMAIL
27from lp.testing.views import create_initialized_view32from lp.testing.views import create_initialized_view
2833
2934
@@ -175,6 +180,28 @@
175 project.owner, 'title', 'description', project, private=False)180 project.owner, 'title', 'description', project, private=False)
176 self.assertEqual(InformationType.PUBLIC, bug.information_type)181 self.assertEqual(InformationType.PUBLIC, bug.information_type)
177182
183 def test_createBug_default_sharing_policy_proprietary(self):
184 # createBug() does not adapt the default kwargs when they are none.
185 project = self.factory.makeProduct(
186 licenses=[License.OTHER_PROPRIETARY])
187 comadmin = getUtility(IPersonSet).getByEmail(COMMERCIAL_ADMIN_EMAIL)
188 project.setBugSharingPolicy(
189 BugSharingPolicy.PROPRIETARY_OR_PUBLIC, comadmin)
190 bug = self.application.createBug(
191 project.owner, 'title', 'description', project)
192 self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
193
194 def test_createBug_public_bug_sharing_policy_proprietary(self):
195 # createBug() adapts a kwarg to InformationType if one is is not None.
196 project = self.factory.makeProduct(
197 licenses=[License.OTHER_PROPRIETARY])
198 comadmin = getUtility(IPersonSet).getByEmail(COMMERCIAL_ADMIN_EMAIL)
199 project.setBugSharingPolicy(
200 BugSharingPolicy.PROPRIETARY_OR_PUBLIC, comadmin)
201 bug = self.application.createBug(
202 project.owner, 'title', 'description', project, private=False)
203 self.assertEqual(InformationType.PUBLIC, bug.information_type)
204
178 def test_createBug_default_private_bugs_false(self):205 def test_createBug_default_private_bugs_false(self):
179 # createBug() does not adapt the default kwargs when they are none.206 # createBug() does not adapt the default kwargs when they are none.
180 project = self.factory.makeProduct(207 project = self.factory.makeProduct(
181208
=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_filebug.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_filebug.py 2012-08-14 01:57:17 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_filebug.py 2012-08-20 13:34:33 +0000
@@ -25,9 +25,11 @@
25 )25 )
26from lp.bugs.publisher import BugsLayer26from lp.bugs.publisher import BugsLayer
27from lp.registry.enums import (27from lp.registry.enums import (
28 BugSharingPolicy,
28 InformationType,29 InformationType,
29 PRIVATE_INFORMATION_TYPES,30 PRIVATE_INFORMATION_TYPES,
30 )31 )
32from lp.registry.interfaces.person import IPersonSet
31from lp.registry.interfaces.projectgroup import IProjectGroup33from lp.registry.interfaces.projectgroup import IProjectGroup
32from lp.services.webapp.servers import LaunchpadTestRequest34from lp.services.webapp.servers import LaunchpadTestRequest
33from lp.testing import (35from lp.testing import (
@@ -41,6 +43,7 @@
41 find_main_content,43 find_main_content,
42 find_tag_by_id,44 find_tag_by_id,
43 )45 )
46from lp.testing.sampledata import COMMERCIAL_ADMIN_EMAIL
44from lp.testing.views import (47from lp.testing.views import (
45 create_initialized_view,48 create_initialized_view,
46 create_view,49 create_view,
@@ -353,7 +356,7 @@
353 self.assertEqual(expected_guidelines, view.bug_reporting_guidelines)356 self.assertEqual(expected_guidelines, view.bug_reporting_guidelines)
354357
355 def filebug_via_view(self, private_bugs=False, information_type=None,358 def filebug_via_view(self, private_bugs=False, information_type=None,
356 extra_data_token=None):359 bug_sharing_policy=None, extra_data_token=None):
357 form = {360 form = {
358 'field.title': 'A bug',361 'field.title': 'A bug',
359 'field.comment': 'A comment',362 'field.comment': 'A comment',
@@ -364,6 +367,11 @@
364 product = self.factory.makeProduct(official_malone=True)367 product = self.factory.makeProduct(official_malone=True)
365 if private_bugs:368 if private_bugs:
366 removeSecurityProxy(product).private_bugs = True369 removeSecurityProxy(product).private_bugs = True
370 if bug_sharing_policy:
371 self.factory.makeCommercialSubscription(product=product)
372 comadmin = getUtility(IPersonSet).getByEmail(
373 COMMERCIAL_ADMIN_EMAIL)
374 product.setBugSharingPolicy(bug_sharing_policy, comadmin)
367 with person_logged_in(product.owner):375 with person_logged_in(product.owner):
368 view = create_view(376 view = create_view(
369 product, '+filebug', method='POST', form=form,377 product, '+filebug', method='POST', form=form,
@@ -397,6 +405,15 @@
397 InformationType.USERDATA, view.default_information_type)405 InformationType.USERDATA, view.default_information_type)
398 self.assertEqual(InformationType.USERDATA, bug.information_type)406 self.assertEqual(InformationType.USERDATA, bug.information_type)
399407
408 def test_filebug_information_type_with_bug_sharing_policy(self):
409 # If we don't specify the bug's information_type, it follows the
410 # target's getDefaultBugInformationType().
411 bug, view = self.filebug_via_view(
412 bug_sharing_policy=BugSharingPolicy.PROPRIETARY)
413 self.assertEqual(
414 InformationType.PROPRIETARY, view.default_information_type)
415 self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
416
400 def test_filebug_information_type_with_public_blob(self):417 def test_filebug_information_type_with_public_blob(self):
401 # Bugs filed with an apport blob that doesn't request privacy418 # Bugs filed with an apport blob that doesn't request privacy
402 # are public by default.419 # are public by default.
@@ -414,7 +431,7 @@
414 InformationType.USERDATA, view.default_information_type)431 InformationType.USERDATA, view.default_information_type)
415 self.assertEqual(InformationType.USERDATA, bug.information_type)432 self.assertEqual(InformationType.USERDATA, bug.information_type)
416433
417 def test_filebug_information_type_normal_projects(self):434 def test_filebug_information_type_public_policy(self):
418 # The vocabulary for information_type when filing a bug is created435 # The vocabulary for information_type when filing a bug is created
419 # correctly for non commercial projects.436 # correctly for non commercial projects.
420 product = self.factory.makeProduct(official_malone=True)437 product = self.factory.makeProduct(official_malone=True)
@@ -425,6 +442,20 @@
425 soup = BeautifulSoup(html)442 soup = BeautifulSoup(html)
426 self.assertIsNone(soup.find('label', text="Proprietary"))443 self.assertIsNone(soup.find('label', text="Proprietary"))
427444
445 def test_filebug_information_type_proprietary_policy(self):
446 # The vocabulary for information_type when filing a bug is created
447 # correctly for a project with a proprietary sharing policy.
448 product = self.factory.makeProduct(official_malone=True)
449 self.factory.makeCommercialSubscription(product=product)
450 comadmin = getUtility(IPersonSet).getByEmail(COMMERCIAL_ADMIN_EMAIL)
451 product.setBugSharingPolicy(BugSharingPolicy.PROPRIETARY, comadmin)
452 with person_logged_in(product.owner):
453 view = create_initialized_view(
454 product, '+filebug', principal=product.owner)
455 html = view.render()
456 soup = BeautifulSoup(html)
457 self.assertIsNotNone(soup.find('label', text="Proprietary"))
458
428 def test_filebug_information_type_vocabulary(self):459 def test_filebug_information_type_vocabulary(self):
429 # The vocabulary for information_type when filing a bug is created460 # The vocabulary for information_type when filing a bug is created
430 # correctly.461 # correctly.
@@ -455,7 +486,8 @@
455486
456 layer = DatabaseFunctionalLayer487 layer = DatabaseFunctionalLayer
457488
458 def filebug_via_view(self, private_bugs=False, security_related=False):489 def filebug_via_view(self, private_bugs=False, bug_sharing_policy=None,
490 security_related=False):
459 form = {491 form = {
460 'field.title': 'A bug',492 'field.title': 'A bug',
461 'field.comment': 'A comment',493 'field.comment': 'A comment',
@@ -465,6 +497,11 @@
465 product = self.factory.makeProduct(official_malone=True)497 product = self.factory.makeProduct(official_malone=True)
466 if private_bugs:498 if private_bugs:
467 removeSecurityProxy(product).private_bugs = True499 removeSecurityProxy(product).private_bugs = True
500 if bug_sharing_policy:
501 self.factory.makeCommercialSubscription(product=product)
502 comadmin = getUtility(IPersonSet).getByEmail(
503 COMMERCIAL_ADMIN_EMAIL)
504 product.setBugSharingPolicy(bug_sharing_policy, comadmin)
468 anyone = self.factory.makePerson()505 anyone = self.factory.makePerson()
469 with person_logged_in(anyone):506 with person_logged_in(anyone):
470 view = create_initialized_view(507 view = create_initialized_view(
@@ -499,6 +536,13 @@
499 bug = self.filebug_via_view(private_bugs=True)536 bug = self.filebug_via_view(private_bugs=True)
500 self.assertEqual(InformationType.USERDATA, bug.information_type)537 self.assertEqual(InformationType.USERDATA, bug.information_type)
501538
539 def test_filebug_with_proprietary_sharing(self):
540 # Non security related bugs are PROPRIETARY for products with a
541 # proprietary sharing policy.
542 bug = self.filebug_via_view(
543 bug_sharing_policy=BugSharingPolicy.PROPRIETARY)
544 self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
545
502 def test_filebug_view_renders_security_related(self):546 def test_filebug_view_renders_security_related(self):
503 # The security_related checkbox is rendered for non bug supervisors.547 # The security_related checkbox is rendered for non bug supervisors.
504 product = self.factory.makeProduct(official_malone=True)548 product = self.factory.makeProduct(official_malone=True)
505549
=== modified file 'lib/lp/bugs/interfaces/bugtarget.py'
--- lib/lp/bugs/interfaces/bugtarget.py 2012-08-08 03:45:16 +0000
+++ lib/lp/bugs/interfaces/bugtarget.py 2012-08-20 13:34:33 +0000
@@ -18,6 +18,8 @@
18 'IOfficialBugTagTargetPublic',18 'IOfficialBugTagTargetPublic',
19 'IOfficialBugTagTargetRestricted',19 'IOfficialBugTagTargetRestricted',
20 'ISeriesBugTarget',20 'ISeriesBugTarget',
21 'POLICY_ALLOWED_TYPES',
22 'POLICY_DEFAULT_TYPES',
21 ]23 ]
2224
2325
@@ -59,6 +61,12 @@
59 BugTagsSearchCombinator,61 BugTagsSearchCombinator,
60 IBugTaskSearch,62 IBugTaskSearch,
61 )63 )
64from lp.registry.enums import (
65 BugSharingPolicy,
66 FREE_INFORMATION_TYPES,
67 InformationType,
68 NON_EMBARGOED_INFORMATION_TYPES,
69 )
62from lp.services.fields import Tag70from lp.services.fields import Tag
6371
6472
@@ -197,6 +205,21 @@
197 vocabulary=BugBlueprintSearch, required=False))205 vocabulary=BugBlueprintSearch, required=False))
198206
199207
208POLICY_ALLOWED_TYPES = {
209 BugSharingPolicy.PUBLIC: FREE_INFORMATION_TYPES,
210 BugSharingPolicy.PUBLIC_OR_PROPRIETARY: NON_EMBARGOED_INFORMATION_TYPES,
211 BugSharingPolicy.PROPRIETARY_OR_PUBLIC: NON_EMBARGOED_INFORMATION_TYPES,
212 BugSharingPolicy.PROPRIETARY: (InformationType.PROPRIETARY,),
213 }
214
215POLICY_DEFAULT_TYPES = {
216 BugSharingPolicy.PUBLIC: InformationType.PUBLIC,
217 BugSharingPolicy.PUBLIC_OR_PROPRIETARY: InformationType.PUBLIC,
218 BugSharingPolicy.PROPRIETARY_OR_PUBLIC: InformationType.PROPRIETARY,
219 BugSharingPolicy.PROPRIETARY: InformationType.PROPRIETARY,
220 }
221
222
200class IHasBugs(Interface):223class IHasBugs(Interface):
201 """An entity which has a collection of bug tasks."""224 """An entity which has a collection of bug tasks."""
202225
203226
=== modified file 'lib/lp/bugs/mail/tests/test_handler.py'
--- lib/lp/bugs/mail/tests/test_handler.py 2012-05-04 00:03:07 +0000
+++ lib/lp/bugs/mail/tests/test_handler.py 2012-08-20 13:34:33 +0000
@@ -28,7 +28,11 @@
28 MaloneHandler,28 MaloneHandler,
29 )29 )
30from lp.bugs.model.bugnotification import BugNotification30from lp.bugs.model.bugnotification import BugNotification
31from lp.registry.enums import InformationType31from lp.registry.enums import (
32 BugSharingPolicy,
33 InformationType,
34 )
35from lp.registry.interfaces.person import IPersonSet
32from lp.services.config import config36from lp.services.config import config
33from lp.services.identity.interfaces.emailaddress import EmailAddressStatus37from lp.services.identity.interfaces.emailaddress import EmailAddressStatus
34from lp.services.mail import stub38from lp.services.mail import stub
@@ -48,6 +52,7 @@
48 LaunchpadZopelessLayer,52 LaunchpadZopelessLayer,
49 )53 )
50from lp.testing.mail_helpers import pop_notifications54from lp.testing.mail_helpers import pop_notifications
55from lp.testing.sampledata import COMMERCIAL_ADMIN_EMAIL
5156
5257
53class TestMaloneHandler(TestCaseWithFactory):58class TestMaloneHandler(TestCaseWithFactory):
@@ -253,6 +258,24 @@
253 self.assertEqual(1, len(bug.bugtasks))258 self.assertEqual(1, len(bug.bugtasks))
254 self.assertEqual(project, bug.bugtasks[0].target)259 self.assertEqual(project, bug.bugtasks[0].target)
255260
261 def test_new_bug_with_sharing_policy_proprietary(self):
262 project = self.factory.makeProduct(name='fnord')
263 self.factory.makeCommercialSubscription(product=project)
264 comadmin = getUtility(IPersonSet).getByEmail(COMMERCIAL_ADMIN_EMAIL)
265 project.setBugSharingPolicy(BugSharingPolicy.PROPRIETARY, comadmin)
266 transaction.commit()
267 handler = MaloneHandler()
268 with person_logged_in(project.owner):
269 msg = self.factory.makeSignedMessage(
270 body='borked\n affects fnord',
271 subject='subject borked',
272 to_address='new@bugs.launchpad.dev')
273 handler.process(msg, msg['To'])
274 notification = self.getLatestBugNotification()
275 bug = notification.bug
276 self.assertEqual([project.owner], list(bug.getDirectSubscribers()))
277 self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
278
256 def test_new_bug_with_one_misplaced_affects_line(self):279 def test_new_bug_with_one_misplaced_affects_line(self):
257 # Affects commands in the wrong position are processed as the user280 # Affects commands in the wrong position are processed as the user
258 # intended when the bug is new and there is only one affects.281 # intended when the bug is new and there is only one affects.
259282
=== modified file 'lib/lp/bugs/tests/test_bugs_webservice.py'
--- lib/lp/bugs/tests/test_bugs_webservice.py 2012-08-08 07:22:51 +0000
+++ lib/lp/bugs/tests/test_bugs_webservice.py 2012-08-20 13:34:33 +0000
@@ -19,11 +19,18 @@
19 Equals,19 Equals,
20 LessThan,20 LessThan,
21 )21 )
22from zope.component import getMultiAdapter22from zope.component import (
23 getMultiAdapter,
24 getUtility,
25 )
2326
24from lp.bugs.browser.bugtask import get_comments_for_bugtask27from lp.bugs.browser.bugtask import get_comments_for_bugtask
25from lp.bugs.interfaces.bug import IBug28from lp.bugs.interfaces.bug import IBug
26from lp.registry.enums import InformationType29from lp.registry.enums import (
30 BugSharingPolicy,
31 InformationType,
32 )
33from lp.registry.interfaces.person import IPersonSet
27from lp.registry.interfaces.product import License34from lp.registry.interfaces.product import License
28from lp.services.webapp import snapshot35from lp.services.webapp import snapshot
29from lp.services.webapp.servers import LaunchpadTestRequest36from lp.services.webapp.servers import LaunchpadTestRequest
@@ -45,6 +52,7 @@
45from lp.testing.pages import LaunchpadWebServiceCaller52from lp.testing.pages import LaunchpadWebServiceCaller
46from lp.testing.sampledata import (53from lp.testing.sampledata import (
47 ADMIN_EMAIL,54 ADMIN_EMAIL,
55 COMMERCIAL_ADMIN_EMAIL,
48 USER_EMAIL,56 USER_EMAIL,
49 )57 )
5058
@@ -399,3 +407,18 @@
399 target=api_url(project), title='title', description='desc',407 target=api_url(project), title='title', description='desc',
400 private=True)408 private=True)
401 self.assertEqual('Private', bug.information_type)409 self.assertEqual('Private', bug.information_type)
410
411 def test_default_sharing_policy_proprietary(self):
412 # Verify the path through user submission, to MaloneApplication to
413 # BugSet, and back to the user creates a private bug according
414 # to the project's bug sharing policy.
415 project = self.factory.makeProduct(
416 licenses=[License.OTHER_PROPRIETARY])
417 comadmin = getUtility(IPersonSet).getByEmail(COMMERCIAL_ADMIN_EMAIL)
418 project.setBugSharingPolicy(
419 BugSharingPolicy.PROPRIETARY_OR_PUBLIC, comadmin)
420 webservice = launchpadlib_for('test', 'salgado')
421 bugs_collection = webservice.load('/bugs')
422 bug = bugs_collection.createBug(
423 target=api_url(project), title='title', description='desc')
424 self.assertEqual('Proprietary', bug.information_type)
402425
=== modified file 'lib/lp/code/model/branchnamespace.py'
--- lib/lp/code/model/branchnamespace.py 2012-08-16 21:57:43 +0000
+++ lib/lp/code/model/branchnamespace.py 2012-08-20 13:34:33 +0000
@@ -47,6 +47,8 @@
47from lp.code.model.branch import Branch47from lp.code.model.branch import Branch
48from lp.registry.enums import (48from lp.registry.enums import (
49 BranchSharingPolicy,49 BranchSharingPolicy,
50 FREE_INFORMATION_TYPES,
51 FREE_PRIVATE_INFORMATION_TYPES,
50 InformationType,52 InformationType,
51 PersonVisibility,53 PersonVisibility,
52 NON_EMBARGOED_INFORMATION_TYPES,54 NON_EMBARGOED_INFORMATION_TYPES,
@@ -82,11 +84,6 @@
82 )84 )
8385
8486
85FREE_PRIVATE_INFORMATION_TYPES = (
86 InformationType.PRIVATESECURITY, InformationType.USERDATA)
87FREE_INFORMATION_TYPES = (
88 PUBLIC_INFORMATION_TYPES + FREE_PRIVATE_INFORMATION_TYPES)
89
90POLICY_ALLOWED_TYPES = {87POLICY_ALLOWED_TYPES = {
91 BranchSharingPolicy.PUBLIC: FREE_INFORMATION_TYPES,88 BranchSharingPolicy.PUBLIC: FREE_INFORMATION_TYPES,
92 BranchSharingPolicy.PUBLIC_OR_PROPRIETARY: NON_EMBARGOED_INFORMATION_TYPES,89 BranchSharingPolicy.PUBLIC_OR_PROPRIETARY: NON_EMBARGOED_INFORMATION_TYPES,
9390
=== modified file 'lib/lp/code/model/tests/test_branchnamespace.py'
--- lib/lp/code/model/tests/test_branchnamespace.py 2012-08-17 04:48:04 +0000
+++ lib/lp/code/model/tests/test_branchnamespace.py 2012-08-20 13:34:33 +0000
@@ -32,14 +32,14 @@
32 )32 )
33from lp.code.interfaces.branchtarget import IBranchTarget33from lp.code.interfaces.branchtarget import IBranchTarget
34from lp.code.model.branchnamespace import (34from lp.code.model.branchnamespace import (
35 FREE_INFORMATION_TYPES,
36 FREE_PRIVATE_INFORMATION_TYPES,
37 PackageNamespace,35 PackageNamespace,
38 PersonalNamespace,36 PersonalNamespace,
39 ProductNamespace,37 ProductNamespace,
40 )38 )
41from lp.registry.enums import (39from lp.registry.enums import (
42 BranchSharingPolicy,40 BranchSharingPolicy,
41 FREE_INFORMATION_TYPES,
42 FREE_PRIVATE_INFORMATION_TYPES,
43 InformationType,43 InformationType,
44 NON_EMBARGOED_INFORMATION_TYPES,44 NON_EMBARGOED_INFORMATION_TYPES,
45 PersonVisibility,45 PersonVisibility,
4646
=== modified file 'lib/lp/registry/enums.py'
--- lib/lp/registry/enums.py 2012-08-16 21:57:43 +0000
+++ lib/lp/registry/enums.py 2012-08-20 13:34:33 +0000
@@ -10,6 +10,8 @@
10 'DistroSeriesDifferenceStatus',10 'DistroSeriesDifferenceStatus',
11 'DistroSeriesDifferenceType',11 'DistroSeriesDifferenceType',
12 'EXCLUSIVE_TEAM_POLICY',12 'EXCLUSIVE_TEAM_POLICY',
13 'FREE_INFORMATION_TYPES',
14 'FREE_PRIVATE_INFORMATION_TYPES',
13 'INCLUSIVE_TEAM_POLICY',15 'INCLUSIVE_TEAM_POLICY',
14 'InformationType',16 'InformationType',
15 'NON_EMBARGOED_INFORMATION_TYPES',17 'NON_EMBARGOED_INFORMATION_TYPES',
@@ -77,7 +79,6 @@
77PUBLIC_INFORMATION_TYPES = (79PUBLIC_INFORMATION_TYPES = (
78 InformationType.PUBLIC, InformationType.PUBLICSECURITY)80 InformationType.PUBLIC, InformationType.PUBLICSECURITY)
7981
80
81PRIVATE_INFORMATION_TYPES = (82PRIVATE_INFORMATION_TYPES = (
82 InformationType.PRIVATESECURITY, InformationType.USERDATA,83 InformationType.PRIVATESECURITY, InformationType.USERDATA,
83 InformationType.PROPRIETARY, InformationType.EMBARGOED)84 InformationType.PROPRIETARY, InformationType.EMBARGOED)
@@ -90,6 +91,12 @@
90SECURITY_INFORMATION_TYPES = (91SECURITY_INFORMATION_TYPES = (
91 InformationType.PUBLICSECURITY, InformationType.PRIVATESECURITY)92 InformationType.PUBLICSECURITY, InformationType.PRIVATESECURITY)
9293
94FREE_PRIVATE_INFORMATION_TYPES = (
95 InformationType.PRIVATESECURITY, InformationType.USERDATA)
96
97FREE_INFORMATION_TYPES = (
98 PUBLIC_INFORMATION_TYPES + FREE_PRIVATE_INFORMATION_TYPES)
99
93100
94class SharingPermission(DBEnumeratedType):101class SharingPermission(DBEnumeratedType):
95 """Sharing permission.102 """Sharing permission.
96103
=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py 2012-08-17 05:05:37 +0000
+++ lib/lp/registry/model/product.py 2012-08-20 13:34:33 +0000
@@ -91,6 +91,10 @@
91from lp.blueprints.model.sprint import HasSprintsMixin91from lp.blueprints.model.sprint import HasSprintsMixin
92from lp.bugs.interfaces.bugsummary import IBugSummaryDimension92from lp.bugs.interfaces.bugsummary import IBugSummaryDimension
93from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor93from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
94from lp.bugs.interfaces.bugtarget import (
95 POLICY_ALLOWED_TYPES,
96 POLICY_DEFAULT_TYPES,
97 )
94from lp.bugs.interfaces.bugtaskfilter import OrderedBugTask98from lp.bugs.interfaces.bugtaskfilter import OrderedBugTask
95from lp.bugs.model.bugtarget import (99from lp.bugs.model.bugtarget import (
96 BugTargetBase,100 BugTargetBase,
@@ -595,6 +599,9 @@
595599
596 def getAllowedBugInformationTypes(self):600 def getAllowedBugInformationTypes(self):
597 """See `IProduct.`"""601 """See `IProduct.`"""
602 if self.bug_sharing_policy is not None:
603 return POLICY_ALLOWED_TYPES[self.bug_sharing_policy]
604
598 types = set(InformationType.items)605 types = set(InformationType.items)
599 types.discard(InformationType.PROPRIETARY)606 types.discard(InformationType.PROPRIETARY)
600 types.discard(InformationType.EMBARGOED)607 types.discard(InformationType.EMBARGOED)
@@ -602,7 +609,9 @@
602609
603 def getDefaultBugInformationType(self):610 def getDefaultBugInformationType(self):
604 """See `IDistribution.`"""611 """See `IDistribution.`"""
605 if self.private_bugs:612 if self.bug_sharing_policy is not None:
613 return POLICY_DEFAULT_TYPES[self.bug_sharing_policy]
614 elif self.private_bugs:
606 return InformationType.USERDATA615 return InformationType.USERDATA
607 else:616 else:
608 return InformationType.PUBLIC617 return InformationType.PUBLIC
609618
=== modified file 'lib/lp/registry/tests/test_product.py'
--- lib/lp/registry/tests/test_product.py 2012-08-17 05:05:37 +0000
+++ lib/lp/registry/tests/test_product.py 2012-08-20 13:34:33 +0000
@@ -32,6 +32,7 @@
32 BranchSharingPolicy,32 BranchSharingPolicy,
33 BugSharingPolicy,33 BugSharingPolicy,
34 EXCLUSIVE_TEAM_POLICY,34 EXCLUSIVE_TEAM_POLICY,
35 FREE_INFORMATION_TYPES,
35 INCLUSIVE_TEAM_POLICY,36 INCLUSIVE_TEAM_POLICY,
36 InformationType,37 InformationType,
37 )38 )
@@ -44,6 +45,7 @@
44 IAccessPolicySource,45 IAccessPolicySource,
45 )46 )
46from lp.registry.interfaces.oopsreferences import IHasOOPSReferences47from lp.registry.interfaces.oopsreferences import IHasOOPSReferences
48from lp.registry.interfaces.person import IPersonSet
47from lp.registry.interfaces.product import (49from lp.registry.interfaces.product import (
48 IProduct,50 IProduct,
49 IProductSet,51 IProductSet,
@@ -79,6 +81,7 @@
79 get_feedback_messages,81 get_feedback_messages,
80 setupBrowser,82 setupBrowser,
81 )83 )
84from lp.testing.sampledata import COMMERCIAL_ADMIN_EMAIL
82from lp.translations.enums import TranslationPermission85from lp.translations.enums import TranslationPermission
83from lp.translations.interfaces.customlanguagecode import (86from lp.translations.interfaces.customlanguagecode import (
84 IHasCustomLanguageCodes,87 IHasCustomLanguageCodes,
@@ -377,26 +380,77 @@
377 grantees = set([grant.grantee for grant in grants])380 grantees = set([grant.grantee for grant in grants])
378 self.assertEqual(expected_grantess, grantees)381 self.assertEqual(expected_grantess, grantees)
379382
380 def test_getAllowedBugInformationTypes(self):383
381 # All projects currently support just the non-proprietary384class TestProductBugInformationTypes(TestCaseWithFactory):
382 # information types.385
386 layer = DatabaseFunctionalLayer
387
388 def makeProductWithPolicy(self, bug_sharing_policy, private_bugs=False):
389 product = self.factory.makeProduct(private_bugs=private_bugs)
390 self.factory.makeCommercialSubscription(product=product)
391 comadmin = getUtility(IPersonSet).getByEmail(COMMERCIAL_ADMIN_EMAIL)
392 product.setBugSharingPolicy(bug_sharing_policy, comadmin)
393 return product
394
395 def test_no_policy(self):
396 # New projects can only use the non-proprietary information
397 # types.
398 product = self.factory.makeProduct()
383 self.assertContentEqual(399 self.assertContentEqual(
384 [InformationType.PUBLIC, InformationType.PUBLICSECURITY,400 FREE_INFORMATION_TYPES, product.getAllowedBugInformationTypes())
385 InformationType.PRIVATESECURITY, InformationType.USERDATA],
386 self.factory.makeProduct().getAllowedBugInformationTypes())
387
388 def test_getDefaultBugInformationType_public(self):
389 # The default information type for normal projects is PUBLIC.
390 product = self.factory.makeProduct()
391 self.assertEqual(401 self.assertEqual(
392 InformationType.PUBLIC, product.getDefaultBugInformationType())402 InformationType.PUBLIC, product.getDefaultBugInformationType())
393403
394 def test_getDefaultBugInformationType_private(self):404 def test_legacy_private_bugs(self):
395 # private_bugs overrides the default information type to USERDATA.405 # The deprecated private_bugs attribute overrides the default
406 # information type to USERDATA.
396 product = self.factory.makeProduct(private_bugs=True)407 product = self.factory.makeProduct(private_bugs=True)
408 self.assertContentEqual(
409 FREE_INFORMATION_TYPES, product.getAllowedBugInformationTypes())
397 self.assertEqual(410 self.assertEqual(
398 InformationType.USERDATA, product.getDefaultBugInformationType())411 InformationType.USERDATA, product.getDefaultBugInformationType())
399412
413 def test_sharing_policy_overrides_private_bugs(self):
414 # bug_sharing_policy overrides private_bugs.
415 product = self.makeProductWithPolicy(
416 BugSharingPolicy.PUBLIC, private_bugs=True)
417 self.assertContentEqual(
418 FREE_INFORMATION_TYPES, product.getAllowedBugInformationTypes())
419 self.assertEqual(
420 InformationType.PUBLIC, product.getDefaultBugInformationType())
421
422 def test_sharing_policy_public_or_proprietary(self):
423 # bug_sharing_policy can enable Proprietary.
424 product = self.makeProductWithPolicy(
425 BugSharingPolicy.PUBLIC_OR_PROPRIETARY)
426 self.assertContentEqual(
427 FREE_INFORMATION_TYPES + (InformationType.PROPRIETARY,),
428 product.getAllowedBugInformationTypes())
429 self.assertEqual(
430 InformationType.PUBLIC,
431 product.getDefaultBugInformationType())
432
433 def test_sharing_policy_proprietary_or_public(self):
434 # bug_sharing_policy can enable and default to Proprietary.
435 product = self.makeProductWithPolicy(
436 BugSharingPolicy.PROPRIETARY_OR_PUBLIC)
437 self.assertContentEqual(
438 FREE_INFORMATION_TYPES + (InformationType.PROPRIETARY,),
439 product.getAllowedBugInformationTypes())
440 self.assertEqual(
441 InformationType.PROPRIETARY,
442 product.getDefaultBugInformationType())
443
444 def test_sharing_policy_proprietary(self):
445 # bug_sharing_policy can enable only Proprietary.
446 product = self.makeProductWithPolicy(BugSharingPolicy.PROPRIETARY)
447 self.assertContentEqual(
448 [InformationType.PROPRIETARY],
449 product.getAllowedBugInformationTypes())
450 self.assertEqual(
451 InformationType.PROPRIETARY,
452 product.getDefaultBugInformationType())
453
400454
401class TestProductFiles(TestCase):455class TestProductFiles(TestCase):
402 """Tests for downloadable product files."""456 """Tests for downloadable product files."""