Merge lp:~stevenk/launchpad/branch-use-information_type-redux into lp:launchpad
- branch-use-information_type-redux
- Merge into devel
Proposed by
Steve Kowalik
Status: | Merged |
---|---|
Approved by: | Steve Kowalik |
Approved revision: | no longer in the source branch. |
Merged at revision: | 15307 |
Proposed branch: | lp:~stevenk/launchpad/branch-use-information_type-redux |
Merge into: | lp:launchpad |
Diff against target: |
603 lines (+135/-100) 18 files modified
lib/lp/app/browser/tests/test_launchpad.py (+6/-3) lib/lp/code/browser/tests/test_branch.py (+6/-3) lib/lp/code/browser/tests/test_branchmergeproposal.py (+2/-1) lib/lp/code/errors.py (+5/-0) lib/lp/code/interfaces/branch.py (+7/-4) lib/lp/code/model/branch.py (+35/-12) lib/lp/code/model/tests/test_branch.py (+29/-3) lib/lp/code/model/tests/test_branchlookup.py (+2/-1) lib/lp/code/model/tests/test_branchmergeproposal.py (+4/-3) lib/lp/code/model/tests/test_branchvisibility.py (+4/-7) lib/lp/code/model/tests/test_sourcepackagerecipe.py (+3/-1) lib/lp/code/model/tests/test_sourcepackagerecipebuild.py (+4/-2) lib/lp/code/stories/branches/xx-branch-edit-privacy.txt (+0/-33) lib/lp/code/stories/branches/xx-branch-index.txt (+0/-15) lib/lp/code/xmlrpc/tests/test_branch.py (+4/-2) lib/lp/registry/stories/product/xx-product-development-focus.txt (+6/-2) lib/lp/testing/factory.py (+14/-6) lib/lp/translations/tests/test_translationtemplatesbuildjob.py (+4/-2) |
To merge this branch: | bzr merge lp:~stevenk/launchpad/branch-use-information_type-redux |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code | Approve | |
Review via email: mp+107150@code.launchpad.net |
Commit message
Switch Branch to using information_type to check privacy by default.
Description of the change
Building on https:/
I have fixed the test failures, and have changed transitionToInf
To post a comment you must log in.
Revision history for this message
William Grant (wgrant) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/app/browser/tests/test_launchpad.py' |
2 | --- lib/lp/app/browser/tests/test_launchpad.py 2012-02-23 23:44:00 +0000 |
3 | +++ lib/lp/app/browser/tests/test_launchpad.py 2012-05-25 01:57:19 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the |
6 | +# Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
7 | # GNU Affero General Public License version 3 (see the file LICENSE). |
8 | |
9 | """Tests for traversal from the root branch object.""" |
10 | @@ -20,6 +20,7 @@ |
11 | from lp.app.errors import GoneError |
12 | from lp.app.interfaces.launchpad import ILaunchpadCelebrities |
13 | from lp.code.interfaces.linkedbranch import ICanHasLinkedBranch |
14 | +from lp.registry.enums import InformationType |
15 | from lp.registry.interfaces.person import ( |
16 | IPersonSet, |
17 | PersonVisibility, |
18 | @@ -192,7 +193,8 @@ |
19 | branch = self.factory.makeProductBranch() |
20 | naked_product = removeSecurityProxy(branch.product) |
21 | ICanHasLinkedBranch(naked_product).setBranch(branch) |
22 | - removeSecurityProxy(branch).explicitly_private = True |
23 | + removeSecurityProxy(branch).information_type = ( |
24 | + InformationType.USERDATA) |
25 | login(ANONYMOUS) |
26 | requiredMessage = ( |
27 | u"The target %s does not have a linked branch." % |
28 | @@ -218,7 +220,8 @@ |
29 | branch = self.factory.makeProductBranch() |
30 | naked_product = removeSecurityProxy(branch.product) |
31 | ICanHasLinkedBranch(naked_product).setBranch(branch) |
32 | - removeSecurityProxy(branch).explicitly_private = True |
33 | + removeSecurityProxy(branch).information_type = ( |
34 | + InformationType.USERDATA) |
35 | login(ANONYMOUS) |
36 | self.assertNotFound(naked_product.name, use_default_referer=False) |
37 | |
38 | |
39 | === modified file 'lib/lp/code/browser/tests/test_branch.py' |
40 | --- lib/lp/code/browser/tests/test_branch.py 2012-05-23 22:27:56 +0000 |
41 | +++ lib/lp/code/browser/tests/test_branch.py 2012-05-25 01:57:19 +0000 |
42 | @@ -758,7 +758,8 @@ |
43 | # If the target is private, the landing targets should not include it. |
44 | bmp = self.factory.makeBranchMergeProposal() |
45 | branch = bmp.source_branch |
46 | - removeSecurityProxy(bmp.target_branch).explicitly_private = True |
47 | + removeSecurityProxy(bmp.target_branch).information_type = ( |
48 | + InformationType.USERDATA) |
49 | view = BranchView(branch, LaunchpadTestRequest()) |
50 | self.assertTrue(view.no_merges) |
51 | self.assertEqual([], view.landing_targets) |
52 | @@ -779,7 +780,8 @@ |
53 | # it. |
54 | bmp = self.factory.makeBranchMergeProposal() |
55 | branch = bmp.target_branch |
56 | - removeSecurityProxy(bmp.source_branch).explicitly_private = True |
57 | + removeSecurityProxy(bmp.source_branch).information_type = ( |
58 | + InformationType.USERDATA) |
59 | view = BranchView(branch, LaunchpadTestRequest()) |
60 | self.assertTrue(view.no_merges) |
61 | self.assertEqual([], view.landing_candidates) |
62 | @@ -799,7 +801,8 @@ |
63 | # the target is private, then the dependent_branches are not shown. |
64 | branch = self.factory.makeProductBranch() |
65 | bmp = self.factory.makeBranchMergeProposal(prerequisite_branch=branch) |
66 | - removeSecurityProxy(bmp.source_branch).explicitly_private = True |
67 | + removeSecurityProxy(bmp.source_branch).information_type = ( |
68 | + InformationType.USERDATA) |
69 | view = BranchView(branch, LaunchpadTestRequest()) |
70 | self.assertTrue(view.no_merges) |
71 | self.assertEqual([], view.dependent_branches) |
72 | |
73 | === modified file 'lib/lp/code/browser/tests/test_branchmergeproposal.py' |
74 | --- lib/lp/code/browser/tests/test_branchmergeproposal.py 2012-05-23 22:27:56 +0000 |
75 | +++ lib/lp/code/browser/tests/test_branchmergeproposal.py 2012-05-25 01:57:19 +0000 |
76 | @@ -1290,7 +1290,8 @@ |
77 | bmp2 = self.factory.makeBranchMergeProposal( |
78 | date_created=( |
79 | datetime(year=2008, month=10, day=10, tzinfo=pytz.UTC))) |
80 | - removeSecurityProxy(bmp2.source_branch).explicitly_private = True |
81 | + removeSecurityProxy(bmp2.source_branch).information_type = ( |
82 | + InformationType.USERDATA) |
83 | self.assertEqual( |
84 | [bmp1], latest_proposals_for_each_branch([bmp1, bmp2])) |
85 | |
86 | |
87 | === modified file 'lib/lp/code/errors.py' |
88 | --- lib/lp/code/errors.py 2012-05-23 22:27:56 +0000 |
89 | +++ lib/lp/code/errors.py 2012-05-25 01:57:19 +0000 |
90 | @@ -10,6 +10,7 @@ |
91 | 'BadStateTransition', |
92 | 'BranchCannotBePrivate', |
93 | 'BranchCannotBePublic', |
94 | + 'BranchCannotChangeInformationType', |
95 | 'BranchCreationException', |
96 | 'BranchCreationForbidden', |
97 | 'BranchCreatorNotMemberOfOwnerTeam', |
98 | @@ -155,6 +156,10 @@ |
99 | """The branch cannot be made private.""" |
100 | |
101 | |
102 | +class BranchCannotChangeInformationType(Exception): |
103 | + """The information type of this branch cannot be changed.""" |
104 | + |
105 | + |
106 | class InvalidBranchException(Exception): |
107 | """Base exception for an error resolving a branch for a component. |
108 | |
109 | |
110 | === modified file 'lib/lp/code/interfaces/branch.py' |
111 | --- lib/lp/code/interfaces/branch.py 2012-05-18 04:14:08 +0000 |
112 | +++ lib/lp/code/interfaces/branch.py 2012-05-25 01:57:19 +0000 |
113 | @@ -1120,11 +1120,14 @@ |
114 | :raise: CannotDeleteBranch if the branch cannot be deleted. |
115 | """ |
116 | |
117 | - def transitionToInformationType(information_type, who): |
118 | - """Set the information type for this branch. |
119 | + def transitionToInformationType(information_type, who, |
120 | + verify_policy=True): |
121 | + """Set the information type for this branch. |
122 | |
123 | - :information_type: The `InformationType` to transition to. |
124 | - :who: The `IPerson` who is making the change. |
125 | + :param information_type: The `InformationType` to transition to. |
126 | + :param who: The `IPerson` who is making the change. |
127 | + :param verify_policy: Check if the new information type complies |
128 | + with the `IBranchNamespacePolicy`. |
129 | """ |
130 | |
131 | |
132 | |
133 | === modified file 'lib/lp/code/model/branch.py' |
134 | --- lib/lp/code/model/branch.py 2012-05-23 22:27:56 +0000 |
135 | +++ lib/lp/code/model/branch.py 2012-05-25 01:57:19 +0000 |
136 | @@ -77,6 +77,7 @@ |
137 | AlreadyLatestFormat, |
138 | BranchCannotBePrivate, |
139 | BranchCannotBePublic, |
140 | + BranchCannotChangeInformationType, |
141 | BranchMergeProposalExists, |
142 | BranchTargetError, |
143 | BranchTypeError, |
144 | @@ -128,7 +129,11 @@ |
145 | ) |
146 | from lp.code.model.seriessourcepackagebranch import SeriesSourcePackageBranch |
147 | from lp.codehosting.safe_open import safe_open |
148 | -from lp.registry.enums import InformationType |
149 | +from lp.registry.enums import ( |
150 | + InformationType, |
151 | + PRIVATE_INFORMATION_TYPES, |
152 | + PUBLIC_INFORMATION_TYPES, |
153 | + ) |
154 | from lp.registry.interfaces.person import ( |
155 | validate_person, |
156 | validate_public_person, |
157 | @@ -187,33 +192,42 @@ |
158 | |
159 | @property |
160 | def private(self): |
161 | - return self.transitively_private |
162 | + return self.information_type in PRIVATE_INFORMATION_TYPES |
163 | |
164 | def setPrivate(self, private, user): |
165 | """See `IBranch`.""" |
166 | - if private == self.explicitly_private: |
167 | + if private: |
168 | + information_type = InformationType.USERDATA |
169 | + else: |
170 | + information_type = InformationType.PUBLIC |
171 | + return self.transitionToInformationType(information_type, user) |
172 | + |
173 | + def transitionToInformationType(self, information_type, who, |
174 | + verify_policy=True): |
175 | + """See `IBranch`.""" |
176 | + if self.information_type == information_type: |
177 | return |
178 | + if (self.stacked_on |
179 | + and self.stacked_on.information_type in PRIVATE_INFORMATION_TYPES |
180 | + and information_type in PUBLIC_INFORMATION_TYPES): |
181 | + raise BranchCannotChangeInformationType() |
182 | + private = information_type in PRIVATE_INFORMATION_TYPES |
183 | # Only check the privacy policy if the user is not special. |
184 | - if (not user_has_special_branch_access(user)): |
185 | + if verify_policy and not user_has_special_branch_access(who): |
186 | policy = IBranchNamespacePolicy(self.namespace) |
187 | - |
188 | if private and not policy.canBranchesBePrivate(): |
189 | raise BranchCannotBePrivate() |
190 | if not private and not policy.canBranchesBePublic(): |
191 | raise BranchCannotBePublic() |
192 | + self.information_type = information_type |
193 | + # Set the legacy values for now. |
194 | self.explicitly_private = private |
195 | # If this branch is private, then it is also transitively_private |
196 | # otherwise we need to reload the value. |
197 | if private: |
198 | self.transitively_private = True |
199 | - self.information_type = InformationType.USERDATA |
200 | else: |
201 | self.transitively_private = AutoReload |
202 | - self.information_type = InformationType.PUBLIC |
203 | - |
204 | - def transitionToInformationType(self, information_type, who): |
205 | - """See `IBranch`.""" |
206 | - self.information_type = information_type |
207 | |
208 | registrant = ForeignKey( |
209 | dbName='registrant', foreignKey='Person', |
210 | @@ -1052,6 +1066,15 @@ |
211 | self.mirror_status_message = ( |
212 | 'Invalid stacked on location: ' + stacked_on_url) |
213 | self.stacked_on = stacked_on_branch |
214 | + # If the branch we are stacking on is not public, and we are, |
215 | + # set our information_type to the stacked on's, since having a |
216 | + # public branch stacked on a private branch does not make sense. |
217 | + if (self.stacked_on |
218 | + and self.stacked_on.information_type in PRIVATE_INFORMATION_TYPES |
219 | + and self.information_type in PUBLIC_INFORMATION_TYPES): |
220 | + self.transitionToInformationType( |
221 | + self.stacked_on.information_type, self.owner, |
222 | + verify_policy=False) |
223 | if self.branch_type == BranchType.HOSTED: |
224 | self.last_mirrored = UTC_NOW |
225 | else: |
226 | @@ -1207,7 +1230,7 @@ |
227 | This method doesn't check the stacked upon branch. That is handled by |
228 | the `visibleByUser` method. |
229 | """ |
230 | - if not self.explicitly_private: |
231 | + if self.information_type in PUBLIC_INFORMATION_TYPES: |
232 | return True |
233 | if user is None: |
234 | return False |
235 | |
236 | === modified file 'lib/lp/code/model/tests/test_branch.py' |
237 | --- lib/lp/code/model/tests/test_branch.py 2012-05-23 22:27:56 +0000 |
238 | +++ lib/lp/code/model/tests/test_branch.py 2012-05-25 01:57:19 +0000 |
239 | @@ -56,6 +56,7 @@ |
240 | AlreadyLatestFormat, |
241 | BranchCannotBePrivate, |
242 | BranchCannotBePublic, |
243 | + BranchCannotChangeInformationType, |
244 | BranchCreatorNotMemberOfOwnerTeam, |
245 | BranchCreatorNotOwner, |
246 | BranchTargetError, |
247 | @@ -2334,16 +2335,21 @@ |
248 | def test_public_stacked_on_private_is_private(self): |
249 | # A public branch stacked on a private branch is private. |
250 | stacked_on = self.factory.makeBranch(private=True) |
251 | - branch = self.factory.makeBranch(stacked_on=stacked_on, private=False) |
252 | + branch = self.factory.makeBranch( |
253 | + stacked_on=stacked_on, private=False) |
254 | self.assertTrue(branch.private) |
255 | + self.assertEqual( |
256 | + stacked_on.information_type, branch.information_type) |
257 | self.assertTrue(removeSecurityProxy(branch).transitively_private) |
258 | - self.assertFalse(branch.explicitly_private) |
259 | + self.assertTrue(branch.explicitly_private) |
260 | |
261 | def test_private_stacked_on_public_is_private(self): |
262 | - # A public branch stacked on a private branch is private. |
263 | + # A private branch stacked on a public branch is private. |
264 | stacked_on = self.factory.makeBranch(private=False) |
265 | branch = self.factory.makeBranch(stacked_on=stacked_on, private=True) |
266 | self.assertTrue(branch.private) |
267 | + self.assertNotEqual( |
268 | + stacked_on.information_type, branch.information_type) |
269 | self.assertTrue(removeSecurityProxy(branch).transitively_private) |
270 | self.assertTrue(branch.explicitly_private) |
271 | |
272 | @@ -2436,6 +2442,26 @@ |
273 | branch.setPrivate, |
274 | False, branch.owner) |
275 | |
276 | + def test_cannot_transition_with_private_stacked_on(self): |
277 | + # If a public branch is stacked on a private branch, it can not |
278 | + # change its information_type to public. |
279 | + stacked_on = self.factory.makeBranch(private=True) |
280 | + branch = self.factory.makeBranch(stacked_on=stacked_on) |
281 | + self.assertRaises( |
282 | + BranchCannotChangeInformationType, |
283 | + branch.transitionToInformationType, InformationType.PUBLIC, |
284 | + branch.owner) |
285 | + |
286 | + def test_can_transition_with_public_stacked_on(self): |
287 | + # If a private branch is stacked on a public branch, it can change |
288 | + # its information_type. |
289 | + stacked_on = self.factory.makeBranch() |
290 | + branch = self.factory.makeBranch(stacked_on=stacked_on, private=True) |
291 | + branch.transitionToInformationType( |
292 | + InformationType.UNEMBARGOEDSECURITY, branch.owner) |
293 | + self.assertEqual( |
294 | + InformationType.UNEMBARGOEDSECURITY, branch.information_type) |
295 | + |
296 | |
297 | class TestBranchCommitsForDays(TestCaseWithFactory): |
298 | """Tests for `Branch.commitsForDays`.""" |
299 | |
300 | === modified file 'lib/lp/code/model/tests/test_branchlookup.py' |
301 | --- lib/lp/code/model/tests/test_branchlookup.py 2012-01-01 02:58:52 +0000 |
302 | +++ lib/lp/code/model/tests/test_branchlookup.py 2012-05-25 01:57:19 +0000 |
303 | @@ -147,7 +147,8 @@ |
304 | owner = self.factory.makePerson() |
305 | private_branch = self.factory.makeAnyBranch( |
306 | owner=owner, private=True) |
307 | - branch = self.factory.makeAnyBranch(stacked_on=private_branch) |
308 | + branch = self.factory.makeAnyBranch( |
309 | + stacked_on=private_branch, owner=owner) |
310 | with person_logged_in(owner): |
311 | path = branch_id_alias(branch) |
312 | result = self.branch_set.getIdAndTrailingPath(path) |
313 | |
314 | === modified file 'lib/lp/code/model/tests/test_branchmergeproposal.py' |
315 | --- lib/lp/code/model/tests/test_branchmergeproposal.py 2012-05-23 22:27:56 +0000 |
316 | +++ lib/lp/code/model/tests/test_branchmergeproposal.py 2012-05-25 01:57:19 +0000 |
317 | @@ -929,8 +929,9 @@ |
318 | charlie, BranchSubscriptionNotificationLevel.NOEMAIL, None, |
319 | CodeReviewNotificationLevel.FULL, charlie) |
320 | # Make both branches private. |
321 | - removeSecurityProxy(bmp.source_branch).explicitly_private = True |
322 | - removeSecurityProxy(bmp.target_branch).explicitly_private = True |
323 | + for branch in (bmp.source_branch, bmp.target_branch): |
324 | + removeSecurityProxy(branch).information_type = ( |
325 | + InformationType.USERDATA) |
326 | recipients = bmp.getNotificationRecipients( |
327 | CodeReviewNotificationLevel.FULL) |
328 | self.assertFalse(bob in recipients) |
329 | @@ -1505,7 +1506,7 @@ |
330 | base_branch = self.factory.makeBranch( |
331 | owner=owner, private=True, product=product) |
332 | source_branch = self.factory.makeBranch( |
333 | - stacked_on=base_branch, product=product) |
334 | + stacked_on=base_branch, product=product, owner=owner) |
335 | target_branch = self.factory.makeBranch(owner=owner, product=product) |
336 | target_branch.product.setBranchVisibilityTeamPolicy( |
337 | owner, BranchVisibilityRule.PRIVATE) |
338 | |
339 | === modified file 'lib/lp/code/model/tests/test_branchvisibility.py' |
340 | --- lib/lp/code/model/tests/test_branchvisibility.py 2012-05-23 22:27:56 +0000 |
341 | +++ lib/lp/code/model/tests/test_branchvisibility.py 2012-05-25 01:57:19 +0000 |
342 | @@ -1,4 +1,4 @@ |
343 | -# Copyright 2011 Canonical Ltd. This software is licensed under the |
344 | +# Copyright 2011-2012 Canonical Ltd. This software is licensed under the |
345 | # GNU Affero General Public License version 3 (see the file LICENSE). |
346 | |
347 | """Tests for visibility of branches. |
348 | @@ -134,14 +134,11 @@ |
349 | private_owner = self.factory.makePerson() |
350 | test_branches = [] |
351 | for x in range(5): |
352 | - # We want the first 3 public and the last 3 private |
353 | - branch = self.factory.makeBranch(name='branch_%s' % x) |
354 | - # The 3rd, 4th and 5th will be explicitly private. |
355 | - branch.explicitly_private = x > 2 |
356 | + # We want the first 3 public and the last 3 private. |
357 | + branch = self.factory.makeBranch(private=x > 2) |
358 | test_branches.append(branch) |
359 | test_branches.append( |
360 | - self.factory.makeBranch( |
361 | - name='branch_5', private=True, owner=private_owner)) |
362 | + self.factory.makeBranch(private=True, owner=private_owner)) |
363 | |
364 | # Anonymous users see just the public branches. |
365 | branch_info = [(branch, branch.private) |
366 | |
367 | === modified file 'lib/lp/code/model/tests/test_sourcepackagerecipe.py' |
368 | --- lib/lp/code/model/tests/test_sourcepackagerecipe.py 2012-02-28 11:14:44 +0000 |
369 | +++ lib/lp/code/model/tests/test_sourcepackagerecipe.py 2012-05-25 01:57:19 +0000 |
370 | @@ -50,6 +50,7 @@ |
371 | ) |
372 | from lp.code.model.sourcepackagerecipedata import SourcePackageRecipeData |
373 | from lp.code.tests.helpers import recipe_parser_newest_version |
374 | +from lp.registry.enums import InformationType |
375 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
376 | from lp.services.database.bulk import load_referencing |
377 | from lp.services.database.constants import UTC_NOW |
378 | @@ -529,7 +530,8 @@ |
379 | with person_logged_in(owner): |
380 | recipe = self.factory.makeSourcePackageRecipe(branches=[branch]) |
381 | self.assertTrue(check_permission('launchpad.View', recipe)) |
382 | - removeSecurityProxy(branch).explicitly_private = True |
383 | + removeSecurityProxy(branch).information_type = ( |
384 | + InformationType.USERDATA) |
385 | with person_logged_in(self.factory.makePerson()): |
386 | self.assertFalse(check_permission('launchpad.View', recipe)) |
387 | self.assertFalse(check_permission('launchpad.View', recipe)) |
388 | |
389 | === modified file 'lib/lp/code/model/tests/test_sourcepackagerecipebuild.py' |
390 | --- lib/lp/code/model/tests/test_sourcepackagerecipebuild.py 2012-04-24 06:44:30 +0000 |
391 | +++ lib/lp/code/model/tests/test_sourcepackagerecipebuild.py 2012-05-25 01:57:19 +0000 |
392 | @@ -1,4 +1,4 @@ |
393 | -# Copyright 2010-2011 Canonical Ltd. This software is licensed under the |
394 | +# Copyright 2010-2012 Canonical Ltd. This software is licensed under the |
395 | # GNU Affero General Public License version 3 (see the file LICENSE). |
396 | |
397 | """Tests for source package builds.""" |
398 | @@ -38,6 +38,7 @@ |
399 | SourcePackageRecipeBuildMailer, |
400 | ) |
401 | from lp.code.model.sourcepackagerecipebuild import SourcePackageRecipeBuild |
402 | +from lp.registry.enums import InformationType |
403 | from lp.registry.interfaces.pocket import PackagePublishingPocket |
404 | from lp.registry.interfaces.series import SeriesStatus |
405 | from lp.services.database.lpstorm import IStore |
406 | @@ -176,7 +177,8 @@ |
407 | job = build.makeJob() |
408 | self.assertTrue(check_permission('launchpad.View', build)) |
409 | self.assertTrue(check_permission('launchpad.View', job)) |
410 | - removeSecurityProxy(branch).explicitly_private = True |
411 | + removeSecurityProxy(branch).information_type = ( |
412 | + InformationType.USERDATA) |
413 | with person_logged_in(self.factory.makePerson()): |
414 | self.assertFalse(check_permission('launchpad.View', build)) |
415 | self.assertFalse(check_permission('launchpad.View', job)) |
416 | |
417 | === modified file 'lib/lp/code/stories/branches/xx-branch-edit-privacy.txt' |
418 | --- lib/lp/code/stories/branches/xx-branch-edit-privacy.txt 2012-01-15 13:32:27 +0000 |
419 | +++ lib/lp/code/stories/branches/xx-branch-edit-privacy.txt 2012-05-25 01:57:19 +0000 |
420 | @@ -129,36 +129,3 @@ |
421 | Traceback (most recent call last): |
422 | ... |
423 | LookupError: label 'Keep branch confidential' |
424 | - |
425 | - |
426 | -Branches stacked on private branches |
427 | ------------------------------------- |
428 | - |
429 | -A public branch is private if it is stacked on a private branch. When the |
430 | -branch is edited, it is shown as private but the checkbox widget is disabled |
431 | -and the title and hint text is updated to inform the user. |
432 | - |
433 | - >>> login('admin@canonical.com') |
434 | - >>> stacked_on_branch = factory.makeAnyBranch(private=True) |
435 | - >>> stacked_branch = factory.makeAnyBranch(stacked_on=stacked_on_branch) |
436 | - >>> url = canonical_url(stacked_branch) |
437 | - >>> logout() |
438 | - |
439 | - >>> admin_browser.open(url) |
440 | - >>> admin_browser.getLink('Change branch details').click() |
441 | - >>> privacy_checkbox = admin_browser.getControl('Branch is confidential') |
442 | - >>> print privacy_checkbox.selected |
443 | - True |
444 | - >>> print privacy_checkbox.disabled |
445 | - True |
446 | - >>> ('branch is confidential because it is stacked on a private branch' |
447 | - ... in admin_browser.contents) |
448 | - True |
449 | - |
450 | -If the branch is edited and saved, there is no user message displayed since |
451 | -the transitive privacy status hasn't changed. |
452 | - |
453 | - >>> admin_browser.getControl('Description').value = "New changes" |
454 | - >>> admin_browser.getControl('Change Branch').click() |
455 | - >>> print_feedback_messages(browser.contents) |
456 | - ... |
457 | |
458 | === modified file 'lib/lp/code/stories/branches/xx-branch-index.txt' |
459 | --- lib/lp/code/stories/branches/xx-branch-index.txt 2012-02-22 21:51:33 +0000 |
460 | +++ lib/lp/code/stories/branches/xx-branch-index.txt 2012-05-25 01:57:19 +0000 |
461 | @@ -409,21 +409,6 @@ |
462 | >>> print extract_text(find_tag_by_id(content, 'privacy')) |
463 | This branch is public |
464 | |
465 | -We mark the stacked-on branch as private: |
466 | - |
467 | - >>> admin_browser.open(stacked_on_url) |
468 | - >>> admin_browser.getLink('Change branch details').click() |
469 | - >>> admin_browser.getControl('Keep branch confidential').selected = True |
470 | - >>> admin_browser.getControl('Change Branch').click() |
471 | - |
472 | -Now the stacked branch is private: |
473 | - |
474 | - >>> admin_browser.open(url) |
475 | - >>> content = find_tag_by_id(admin_browser.contents, 'document') |
476 | - >>> print extract_text(find_tag_by_id(content, 'privacy')) |
477 | - This branch is private because it is stacked on a private branch. |
478 | - |
479 | - |
480 | Navigation Context |
481 | .................. |
482 | |
483 | |
484 | === modified file 'lib/lp/code/xmlrpc/tests/test_branch.py' |
485 | --- lib/lp/code/xmlrpc/tests/test_branch.py 2012-05-23 22:27:56 +0000 |
486 | +++ lib/lp/code/xmlrpc/tests/test_branch.py 2012-05-25 01:57:19 +0000 |
487 | @@ -1,4 +1,4 @@ |
488 | -# Copyright 2009-2011 Canonical Ltd. This software is licensed under the |
489 | +# Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
490 | # GNU Affero General Public License version 3 (see the file LICENSE). |
491 | |
492 | """Unit tests for the public codehosting API.""" |
493 | @@ -16,6 +16,7 @@ |
494 | from lp.code.interfaces.codehosting import BRANCH_ALIAS_PREFIX |
495 | from lp.code.interfaces.linkedbranch import ICanHasLinkedBranch |
496 | from lp.code.xmlrpc.branch import PublicCodehostingAPI |
497 | +from lp.registry.enums import InformationType |
498 | from lp.services.xmlrpc import LaunchpadFault |
499 | from lp.testing import ( |
500 | person_logged_in, |
501 | @@ -323,7 +324,8 @@ |
502 | def test_private_branch_as_development_focus(self): |
503 | # We resolve private linked branches using the writable alias. |
504 | product, trunk = self.makeProdutWithTrunk() |
505 | - removeSecurityProxy(trunk).explicitly_private = True |
506 | + removeSecurityProxy(trunk).information_type = ( |
507 | + InformationType.USERDATA) |
508 | self.assertOnlyWritableResolves(product.name) |
509 | |
510 | def test_private_branch_as_user(self): |
511 | |
512 | === modified file 'lib/lp/registry/stories/product/xx-product-development-focus.txt' |
513 | --- lib/lp/registry/stories/product/xx-product-development-focus.txt 2012-01-15 13:32:27 +0000 |
514 | +++ lib/lp/registry/stories/product/xx-product-development-focus.txt 2012-05-25 01:57:19 +0000 |
515 | @@ -14,7 +14,9 @@ |
516 | >>> eric = factory.makePerson(name='eric', email='eric@example.com') |
517 | >>> fooix = factory.makeProduct(name='fooix', owner=eric) |
518 | >>> branch = factory.makeBranch(owner=eric, product=fooix, name='trunk') |
519 | - >>> # Make revisions for the branch so it has a codebrowse link. |
520 | + |
521 | +Make revisions for the branch so it has a codebrowse link. |
522 | + |
523 | >>> factory.makeRevisionsForBranch(branch) |
524 | >>> logout() |
525 | |
526 | @@ -145,7 +147,9 @@ |
527 | |
528 | >>> login('admin@canonical.com') |
529 | >>> from zope.security.proxy import removeSecurityProxy |
530 | - >>> removeSecurityProxy(branch).explicitly_private = True |
531 | + >>> from lp.registry.enums import InformationType |
532 | + >>> removeSecurityProxy(branch).information_type = ( |
533 | + ... InformationType.USERDATA) |
534 | >>> logout() |
535 | |
536 | >>> anon_browser.open('http://launchpad.dev/fooix') |
537 | |
538 | === modified file 'lib/lp/testing/factory.py' |
539 | --- lib/lp/testing/factory.py 2012-05-23 22:27:56 +0000 |
540 | +++ lib/lp/testing/factory.py 2012-05-25 01:57:19 +0000 |
541 | @@ -1072,8 +1072,8 @@ |
542 | |
543 | def makeBranch(self, branch_type=None, owner=None, |
544 | name=None, product=_DEFAULT, url=_DEFAULT, registrant=None, |
545 | - private=False, stacked_on=None, sourcepackage=None, |
546 | - reviewer=None, **optional_branch_args): |
547 | + private=None, information_type=None, stacked_on=None, |
548 | + sourcepackage=None, reviewer=None, **optional_branch_args): |
549 | """Create and return a new, arbitrary Branch of the given type. |
550 | |
551 | Any parameters for `IBranchNamespace.createBranch` can be specified to |
552 | @@ -1119,11 +1119,19 @@ |
553 | branch = namespace.createBranch( |
554 | branch_type=branch_type, name=name, registrant=registrant, |
555 | url=url, **optional_branch_args) |
556 | - if private: |
557 | - removeSecurityProxy(branch).explicitly_private = True |
558 | - removeSecurityProxy(branch).transitively_private = True |
559 | + assert information_type is None or private is None, ( |
560 | + "Can not specify both information_type and private") |
561 | + if private is not None: |
562 | + information_type = ( |
563 | + InformationType.USERDATA if private else |
564 | + InformationType.PUBLIC) |
565 | + if information_type is not None: |
566 | + removeSecurityProxy(branch).transitionToInformationType( |
567 | + information_type, registrant, verify_policy=False) |
568 | if stacked_on is not None: |
569 | - removeSecurityProxy(branch).stacked_on = stacked_on |
570 | + removeSecurityProxy(branch).branchChanged( |
571 | + removeSecurityProxy(stacked_on).unique_name, 'rev1', None, |
572 | + None, None) |
573 | if reviewer is not None: |
574 | removeSecurityProxy(branch).reviewer = reviewer |
575 | return branch |
576 | |
577 | === modified file 'lib/lp/translations/tests/test_translationtemplatesbuildjob.py' |
578 | --- lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2012-01-01 02:58:52 +0000 |
579 | +++ lib/lp/translations/tests/test_translationtemplatesbuildjob.py 2012-05-25 01:57:19 +0000 |
580 | @@ -1,4 +1,4 @@ |
581 | -# Copyright 2010 Canonical Ltd. This software is licensed under the |
582 | +# Copyright 2010-2012 Canonical Ltd. This software is licensed under the |
583 | # GNU Affero General Public License version 3 (see the file LICENSE). |
584 | |
585 | __metaclass__ = type |
586 | @@ -17,6 +17,7 @@ |
587 | from lp.code.model.branchjob import BranchJob |
588 | from lp.code.model.directbranchcommit import DirectBranchCommit |
589 | from lp.codehosting.scanner import events |
590 | +from lp.registry.enums import InformationType |
591 | from lp.services.job.model.job import Job |
592 | from lp.services.webapp.interfaces import ( |
593 | DEFAULT_FLAVOR, |
594 | @@ -249,7 +250,8 @@ |
595 | def test_private_branch(self): |
596 | # We don't generate templates for private branches. |
597 | branch = self._makeTranslationBranch(fake_pottery_compatible=True) |
598 | - removeSecurityProxy(branch).explicitly_private = True |
599 | + removeSecurityProxy(branch).information_type = ( |
600 | + InformationType.USERDATA) |
601 | self.assertFalse(self.jobsource.generatesTemplates(branch)) |
602 | |
603 | def test_scheduleTranslationTemplatesBuild_subscribed(self): |