Merge lp:~edwin-grubbs/launchpad/bug-567065-empty-branch into lp:launchpad

Proposed by Edwin Grubbs
Status: Merged
Approved by: Edwin Grubbs
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~edwin-grubbs/launchpad/bug-567065-empty-branch
Merge into: lp:launchpad
Diff against target: 183 lines (+80/-16)
3 files modified
lib/lp/registry/browser/productseries.py (+13/-4)
lib/lp/registry/browser/tests/productseries-setbranch-view.txt (+32/-0)
lib/lp/registry/browser/tests/productseries-views.txt (+35/-12)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-567065-empty-branch
Reviewer Review Type Date Requested Status
Francis J. Lacoste (community) release-critical Approve
Abel Deuring (community) code Approve
Review via email: mp+24497@code.launchpad.net

Description of the change

Summary
-------

The "Submit Code" link in the involvement portlet on a product series
should be active after the user sets a branch for the series.

If you try to create a new branch with the same name as an existing
branch, you should get a warning.

Tests
-----

./bin/test -vv -t 'productseries-setbranch-view.txt|productseries-views.txt'

Demo and Q/A
------------

* Open http://launchpad.dev/firefox
  * Create a new series.
  * The "Submit code" link should be disabled.
  * Use "Configure series branch" link to add a new branch.
  * The "Submit code" link should now be enabled.
* Click on "Configure series branch".
  * Try to add a branch with the same name as the one you just created.
  * You should get an error message next to the form field.

To post a comment you must log in.
Revision history for this message
Abel Deuring (adeuring) :
review: Approve (code)
Revision history for this message
Francis J. Lacoste (flacoste) :
review: Approve (release-critical)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/browser/productseries.py'
2--- lib/lp/registry/browser/productseries.py 2010-04-17 00:36:18 +0000
3+++ lib/lp/registry/browser/productseries.py 2010-04-30 13:56:27 +0000
4@@ -182,10 +182,11 @@
5 'report_bug', 'help_translate', 'submit_code', 'register_blueprint']
6
7 def submit_code(self):
8- product = self.context.context.product
9+ view = self.context
10+ product_series = view.context
11 target = canonical_url(
12- product, view_name='+addbranch', rootsite='code')
13- enabled = product.official_codehosting
14+ product_series, view_name='+addbranch', rootsite='code')
15+ enabled = view.official_codehosting
16 return Link(
17 target, 'Submit code', icon='code', enabled=enabled)
18
19@@ -1029,7 +1030,6 @@
20 BranchType.MIRRORED, branch_name, branch_owner,
21 data['repo_url'])
22 if branch is None:
23- self.errors_in_action = True
24 return
25
26 self.context.branch = branch
27@@ -1060,6 +1060,10 @@
28 self._setBranchExists(e.existing_branch,
29 'branch_name')
30 self.errors_in_action = True
31+ # Abort transaction. This is normally handled
32+ # by LaunchpadFormView, but we are already in
33+ # the success handler.
34+ self._abort()
35 return
36 self.context.branch = code_import.branch
37 self.request.response.addInfoNotification(
38@@ -1089,6 +1093,11 @@
39 self.context.displayname)
40 except BranchExists, e:
41 self._setBranchExists(e.existing_branch, 'branch_name')
42+ if branch is None:
43+ self.errors_in_action = True
44+ # Abort transaction. This is normally handled by
45+ # LaunchpadFormView, but we are already in the success handler.
46+ self._abort()
47 return branch
48
49
50
51=== modified file 'lib/lp/registry/browser/tests/productseries-setbranch-view.txt'
52--- lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2010-04-16 17:37:34 +0000
53+++ lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2010-04-30 13:56:27 +0000
54@@ -113,6 +113,10 @@
55 ... }
56
57 >>> view = create_initialized_view(series, name='+setbranch', principal=product.owner, form=form)
58+ >>> print view.errors_in_action
59+ False
60+ >>> print view.next_url
61+ http://launchpad.dev/chevy/camaro
62 >>> for error in view.errors:
63 ... print error
64 >>> for notification in view.request.response.notifications:
65@@ -121,6 +125,26 @@
66 >>> print series.branch.name
67 camaro-branch
68
69+Using a branch name that already exists results in an error.
70+
71+ >>> form = {
72+ ... 'field.branch_type': 'create-new',
73+ ... 'field.branch_name': 'camaro-branch',
74+ ... 'field.branch_owner': product.owner.name,
75+ ... 'field.actions.update': 'Update',
76+ ... }
77+
78+ >>> view = create_initialized_view(series, name='+setbranch', principal=product.owner, form=form)
79+ >>> print view.errors_in_action
80+ True
81+ >>> print view.next_url
82+ None
83+ >>> for error in view.errors:
84+ ... print error
85+ You already have a branch for <em>Chevy</em> called <em>camaro-branch</em>.
86+ >>> for notification in view.request.response.notifications:
87+ ... print notification.message
88+
89
90 Import a branch hosted elsewhere
91 --------------------------------
92@@ -362,6 +386,10 @@
93 >>> for error in view.errors:
94 ... print error
95 You already have a branch for <em>Chevy</em> called <em>chevette-branch</em>.
96+ >>> print view.errors_in_action
97+ True
98+ >>> print view.next_url
99+ None
100
101 >>> for notification in view.request.response.notifications:
102 ... print notification.message
103@@ -381,5 +409,9 @@
104 >>> for error in view.errors:
105 ... print error
106 You already have a branch for <em>Chevy</em> called <em>blazer-branch</em>.
107+ >>> print view.errors_in_action
108+ True
109+ >>> print view.next_url
110+ None
111 >>> for notification in view.request.response.notifications:
112 ... print notification.message
113
114=== modified file 'lib/lp/registry/browser/tests/productseries-views.txt'
115--- lib/lp/registry/browser/tests/productseries-views.txt 2010-04-12 15:33:19 +0000
116+++ lib/lp/registry/browser/tests/productseries-views.txt 2010-04-30 13:56:27 +0000
117@@ -23,23 +23,47 @@
118 The ProductSeries involvement view uses the ProductSeriesInvolvedMenu when
119 rendering links:
120
121- >>> from operator import attrgetter
122- >>> from canonical.launchpad.webapp.tales import MenuAPI
123-
124 >>> login_person(product.owner)
125 >>> product.official_answers = True
126 >>> product.official_blueprints = True
127 >>> product.official_malone = True
128 >>> product.official_rosetta = True
129 >>> view = create_view(series, '+get-involved')
130- >>> menuapi = MenuAPI(view)
131- >>> for link in sorted(
132- ... menuapi.navigation.values(), key=attrgetter('sort_key')):
133- ... print link.url
134- http://bugs.launchpad.dev/app/simple/+filebug
135- http://translations.launchpad.dev/app/simple
136- http://code.launchpad.dev/app/+addbranch
137- http://blueprints.launchpad.dev/app/simple/+addspec
138+
139+ # official_answers is always false for product series.
140+ >>> print view.official_answers
141+ False
142+ >>> print view.official_blueprints
143+ True
144+ >>> print view.official_malone
145+ True
146+ >>> print view.official_rosetta
147+ True
148+ >>> print view.official_codehosting
149+ False
150+ >>> for link in view.enabled_links:
151+ ... print link.url
152+ http://bugs.launchpad.dev/app/simple/+filebug
153+ http://translations.launchpad.dev/app/simple
154+ http://blueprints.launchpad.dev/app/simple/+addspec
155+ >>> for link in view.visible_disabled_links:
156+ ... print link.url
157+ http://code.launchpad.dev/app/simple/+addbranch
158+
159+Setting a branch for the series should enable the +addbranch link.
160+
161+ >>> series.branch = factory.makeBranch()
162+ >>> view = create_view(series, '+get-involved')
163+ >>> print view.official_codehosting
164+ True
165+ >>> for link in view.enabled_links:
166+ ... print link.url
167+ http://bugs.launchpad.dev/app/simple/+filebug
168+ http://translations.launchpad.dev/app/simple
169+ http://code.launchpad.dev/app/simple/+addbranch
170+ http://blueprints.launchpad.dev/app/simple/+addspec
171+ >>> for link in view.visible_disabled_links:
172+ ... print link.url
173
174
175 ProductSeries view
176@@ -360,7 +384,6 @@
177 The delete action will not delete a series that is the active focus of
178 development.
179
180- >>> transaction.commit()
181 >>> form = {
182 ... 'field.actions.delete': 'Delete this Series',
183 ... }