Merge lp:~wgrant/launchpad/edit-stacked-information-type into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: Ian Booth
Approved revision: no longer in the source branch.
Merged at revision: 15621
Proposed branch: lp:~wgrant/launchpad/edit-stacked-information-type
Merge into: lp:launchpad
Diff against target: 156 lines (+46/-59)
2 files modified
lib/lp/code/browser/branch.py (+28/-55)
lib/lp/code/browser/tests/test_branch.py (+18/-4)
To merge this branch: bzr merge lp:~wgrant/launchpad/edit-stacked-information-type
Reviewer Review Type Date Requested Status
Ian Booth (community) Approve
Review via email: mp+114767@code.launchpad.net

Commit message

Stop special-casing private stacked-on branches so much on Branch:+edit.

Description of the change

This branch simplifies BranchEditView's handling of the information type of branches stacked on private branches. Previously it replaced the usual radio buttons with a disabled checkbox, and some text describing why it's locked. I've integrated this into the normal information type widget, so if the stacked-on branch is private it'll display only (branch.stacked_on.information_type, branch.information_type), allowing the user to make it consistent by switching to the matching type.

There's no replacement for the warning text describing why the choices are restricted, but the case is uncommon enough that we probably don't care. It's already restricted by branch visibility policies without a corresponding warning.

To post a comment you must log in.
Revision history for this message
Ian Booth (wallyworld) wrote :

Looks great.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/code/browser/branch.py'
--- lib/lp/code/browser/branch.py 2012-07-12 21:56:46 +0000
+++ lib/lp/code/browser/branch.py 2012-07-13 01:31:19 +0000
@@ -48,9 +48,7 @@
48from lazr.uri import URI48from lazr.uri import URI
49import pytz49import pytz
50import simplejson50import simplejson
51from zope.app.form import CustomWidgetFactory
52from zope.app.form.browser import TextAreaWidget51from zope.app.form.browser import TextAreaWidget
53from zope.app.form.browser.boolwidgets import CheckBoxWidget
54from zope.component import (52from zope.component import (
55 getUtility,53 getUtility,
56 queryAdapter,54 queryAdapter,
@@ -124,11 +122,7 @@
124from lp.code.interfaces.branchcollection import IAllBranches122from lp.code.interfaces.branchcollection import IAllBranches
125from lp.code.interfaces.branchmergeproposal import IBranchMergeProposal123from lp.code.interfaces.branchmergeproposal import IBranchMergeProposal
126from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference124from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference
127from lp.registry.enums import (125from lp.registry.enums import InformationType
128 InformationType,
129 PRIVATE_INFORMATION_TYPES,
130 PUBLIC_INFORMATION_TYPES,
131 )
132from lp.registry.interfaces.person import IPersonSet126from lp.registry.interfaces.person import IPersonSet
133from lp.registry.interfaces.productseries import IProductSeries127from lp.registry.interfaces.productseries import IProductSeries
134from lp.registry.vocabularies import (128from lp.registry.vocabularies import (
@@ -1033,34 +1027,7 @@
10331027
1034 def setUpFields(self):1028 def setUpFields(self):
1035 super(BranchEditView, self).setUpFields()1029 super(BranchEditView, self).setUpFields()
1036 # This is to prevent users from converting push/import
1037 # branches to pull branches.
1038 branch = self.context1030 branch = self.context
1039 if branch.private:
1040 # If this branch is stacked on a private branch, render some text
1041 # to inform the user the information type cannot be changed.
1042 if (branch.stacked_on and branch.stacked_on.information_type in
1043 PRIVATE_INFORMATION_TYPES):
1044 stacked_info_type = branch.stacked_on.information_type.title
1045 private_info = Bool(
1046 __name__="private",
1047 title=_("Branch is %s" % stacked_info_type),
1048 description=_(
1049 "This branch is %(info_type)s because it is "
1050 "stacked on a %(info_type)s branch." % {
1051 'info_type': stacked_info_type}))
1052 private_info_field = form.Fields(
1053 private_info, render_context=self.render_context)
1054 self.form_fields = (private_info_field
1055 + self.form_fields.omit('information_type'))
1056 new_field_names = self.field_names
1057 index = new_field_names.index('information_type')
1058 new_field_names[index] = 'private'
1059 self.form_fields = self.form_fields.select(*new_field_names)
1060 self.form_fields['private'].custom_widget = (
1061 CustomWidgetFactory(
1062 CheckBoxWidget, extra='disabled="disabled"'))
1063
1064 # If the user can administer branches, then they should be able to1031 # If the user can administer branches, then they should be able to
1065 # assign the ownership of the branch to any valid person or team.1032 # assign the ownership of the branch to any valid person or team.
1066 if check_permission('launchpad.Admin', branch):1033 if check_permission('launchpad.Admin', branch):
@@ -1109,27 +1076,33 @@
1109 bug with an obscure type.1076 bug with an obscure type.
1110 """1077 """
1111 allowed_types = self.context.getAllowedInformationTypes(self.user)1078 allowed_types = self.context.getAllowedInformationTypes(self.user)
1112 shown_types = (1079
1113 InformationType.PUBLIC,1080 # If we're stacked on a private branch, only show that
1114 InformationType.USERDATA,1081 # information type.
1115 InformationType.PROPRIETARY,1082 if self.context.stacked_on and self.context.stacked_on.private:
1116 )1083 shown_types = set([self.context.stacked_on.information_type])
11171084 else:
1118 # We only show Embargoed Security and Unembargoed Security1085 shown_types = (
1119 # if the branch is linked to a bug with one of those types,1086 InformationType.PUBLIC,
1120 # as they're confusing and not generally useful otherwise.1087 InformationType.USERDATA,
1121 # Once Proprietary is fully deployed, User Data should be1088 InformationType.PROPRIETARY,
1122 # added here.1089 )
1123 hidden_types = (1090
1124 InformationType.UNEMBARGOEDSECURITY,1091 # We only show Embargoed Security and Unembargoed Security
1125 InformationType.EMBARGOEDSECURITY,1092 # if the branch is linked to a bug with one of those types,
1126 )1093 # as they're confusing and not generally useful otherwise.
1127 if set(allowed_types).intersection(hidden_types):1094 # Once Proprietary is fully deployed, User Data should be
1128 params = BugTaskSearchParams(1095 # added here.
1129 user=self.user, linked_branches=self.context.id,1096 hidden_types = (
1130 information_type=hidden_types)1097 InformationType.UNEMBARGOEDSECURITY,
1131 if getUtility(IBugTaskSet).searchBugIds(params).count() > 0:1098 InformationType.EMBARGOEDSECURITY,
1132 shown_types += hidden_types1099 )
1100 if set(allowed_types).intersection(hidden_types):
1101 params = BugTaskSearchParams(
1102 user=self.user, linked_branches=self.context.id,
1103 information_type=hidden_types)
1104 if getUtility(IBugTaskSet).searchBugIds(params).count() > 0:
1105 shown_types += hidden_types
11331106
1134 # Now take the intersection of the allowed and shown types.1107 # Now take the intersection of the allowed and shown types.
1135 combined_types = set(allowed_types).intersection(shown_types)1108 combined_types = set(allowed_types).intersection(shown_types)
11361109
=== modified file 'lib/lp/code/browser/tests/test_branch.py'
--- lib/lp/code/browser/tests/test_branch.py 2012-07-12 09:13:16 +0000
+++ lib/lp/code/browser/tests/test_branch.py 2012-07-13 01:31:19 +0000
@@ -36,10 +36,7 @@
36 BranchVisibilityRule,36 BranchVisibilityRule,
37 )37 )
38from lp.registry.enums import InformationType38from lp.registry.enums import InformationType
39from lp.registry.interfaces.person import (39from lp.registry.interfaces.person import PersonVisibility
40 PersonVisibility,
41 TeamSubscriptionPolicy,
42 )
43from lp.services.config import config40from lp.services.config import config
44from lp.services.database.constants import UTC_NOW41from lp.services.database.constants import UTC_NOW
45from lp.services.features.testing import FeatureFixture42from lp.services.features.testing import FeatureFixture
@@ -985,6 +982,23 @@
985 self.assertShownTypes(982 self.assertShownTypes(
986 [InformationType.PUBLIC, InformationType.PROPRIETARY], branch)983 [InformationType.PUBLIC, InformationType.PROPRIETARY], branch)
987984
985 def test_stacked_on_private(self):
986 # A branch stacked on a private branch has its choices limited
987 # to the current type and the stacked-on type.
988 product = self.factory.makeProduct()
989 stacked_on_branch = self.factory.makeBranch(
990 product=product, information_type=InformationType.USERDATA)
991 branch = self.factory.makeBranch(
992 product=product, stacked_on=stacked_on_branch,
993 owner=product.owner,
994 information_type=InformationType.EMBARGOEDSECURITY)
995 with admin_logged_in():
996 branch.product.setBranchVisibilityTeamPolicy(
997 branch.owner, BranchVisibilityRule.PRIVATE)
998 self.assertShownTypes(
999 [InformationType.EMBARGOEDSECURITY, InformationType.USERDATA],
1000 branch)
1001
988 def test_private_branch(self):1002 def test_private_branch(self):
989 # Branches on projects with a private policy can be set to1003 # Branches on projects with a private policy can be set to
990 # User Data (aka. Private)1004 # User Data (aka. Private)