Merge lp:~abentley/launchpad/reassign into lp:launchpad
- reassign
- Merge into devel
Proposed by
Aaron Bentley
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~abentley/launchpad/reassign |
Merge into: | lp:launchpad |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~abentley/launchpad/reassign |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paul Hummer (community) | Approve | ||
Review via email: mp+9791@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote : | # |
Revision history for this message
Paul Hummer (rockstar) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/canonical/launchpad/pagetitles.py' |
2 | --- lib/canonical/launchpad/pagetitles.py 2009-07-29 02:38:44 +0000 |
3 | +++ lib/canonical/launchpad/pagetitles.py 2009-07-29 20:56:34 +0000 |
4 | @@ -1549,6 +1549,8 @@ |
5 | translationgroup_reassignment = ContextTitle(smartquote( |
6 | 'Change the owner of "%s" translation group')) |
7 | |
8 | +reviewrequest_reassign = 'Reassign review request' |
9 | + |
10 | translationgroups_index = 'Launchpad translation groups' |
11 | |
12 | translationimportqueueentry_index = 'Translation import queue entry' |
13 | |
14 | === modified file 'lib/lp/code/browser/branchmergeproposal.py' |
15 | --- lib/lp/code/browser/branchmergeproposal.py 2009-08-05 14:47:07 +0000 |
16 | +++ lib/lp/code/browser/branchmergeproposal.py 2009-08-06 18:09:19 +0000 |
17 | @@ -290,6 +290,18 @@ |
18 | |
19 | usedfor = IBranchMergeProposal |
20 | |
21 | + @stepthrough('reviews') |
22 | + def traverse_review(self, id): |
23 | + """Navigate to a CodeReviewVoteReference through its BMP.""" |
24 | + try: |
25 | + id = int(id) |
26 | + except ValueError: |
27 | + return None |
28 | + try: |
29 | + return self.context.getVoteReference(id) |
30 | + except WrongBranchMergeProposal: |
31 | + return None |
32 | + |
33 | @stepthrough('comments') |
34 | def traverse_comment(self, id): |
35 | try: |
36 | @@ -467,6 +479,10 @@ |
37 | self.user_can_claim = False |
38 | else: |
39 | self.user_can_claim = self.user_can_review |
40 | + if user in (context.reviewer, context.registrant): |
41 | + self.user_can_reassign = True |
42 | + else: |
43 | + self.user_can_reassign = False |
44 | |
45 | @property |
46 | def show_date_requested(self): |
47 | |
48 | === added file 'lib/lp/code/browser/codereviewvote.py' |
49 | --- lib/lp/code/browser/codereviewvote.py 1970-01-01 00:00:00 +0000 |
50 | +++ lib/lp/code/browser/codereviewvote.py 2009-08-06 18:09:19 +0000 |
51 | @@ -0,0 +1,36 @@ |
52 | +# Copyright 2009 Canonical Ltd. This software is licensed under the |
53 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
54 | + |
55 | + |
56 | +"""Views, navigation and actions for CodeReviewVotes.""" |
57 | + |
58 | + |
59 | +__metaclass__ = type |
60 | + |
61 | + |
62 | +from zope.interface import Interface |
63 | + |
64 | +from canonical.launchpad import _ |
65 | +from canonical.launchpad.fields import PublicPersonChoice |
66 | +from canonical.launchpad.webapp import ( |
67 | + action, canonical_url, LaunchpadFormView) |
68 | + |
69 | + |
70 | +class ReassignSchema(Interface): |
71 | + """Schema to use when reassigning the reviewer for a requested review.""" |
72 | + |
73 | + reviewer = PublicPersonChoice( title=_('Reviewer'), required=True, |
74 | + description=_('A person who you want to review this.'), |
75 | + vocabulary='ValidPersonOrTeam') |
76 | + |
77 | + |
78 | +class CodeReviewVoteReassign(LaunchpadFormView): |
79 | + """View for reassinging the reviewer for a requested review.""" |
80 | + |
81 | + schema = ReassignSchema |
82 | + |
83 | + @action('Reassign', name='reassign') |
84 | + def reassign_action(self, action, data): |
85 | + """Use the form data to change the review request reviewer.""" |
86 | + self.context.reviewer = data['reviewer'] |
87 | + self.next_url = canonical_url(self.context.branch_merge_proposal) |
88 | |
89 | === modified file 'lib/lp/code/browser/configure.zcml' |
90 | --- lib/lp/code/browser/configure.zcml 2009-07-29 02:38:44 +0000 |
91 | +++ lib/lp/code/browser/configure.zcml 2009-08-06 14:28:41 +0000 |
92 | @@ -61,6 +61,13 @@ |
93 | path_expression="string:+review/${id}" |
94 | attribute_to_parent="branch_merge_proposal" |
95 | rootsite="code"/> |
96 | + <browser:page |
97 | + for="lp.code.interfaces.codereviewvote.ICodeReviewVoteReference" |
98 | + name="+reassign" |
99 | + class="lp.code.browser.codereviewvote.CodeReviewVoteReassign" |
100 | + facet="branches" |
101 | + permission="launchpad.AnyPerson" |
102 | + template="../templates/reviewrequest-reassign.pt"/> |
103 | <facet |
104 | facet="branches"> |
105 | <browser:url |
106 | |
107 | === modified file 'lib/lp/code/browser/tests/test_branchmergeproposal.py' |
108 | --- lib/lp/code/browser/tests/test_branchmergeproposal.py 2009-08-06 17:51:02 +0000 |
109 | +++ lib/lp/code/browser/tests/test_branchmergeproposal.py 2009-08-06 18:09:19 +0000 |
110 | @@ -180,6 +180,34 @@ |
111 | view = BranchMergeProposalVoteView(self.bmp, LaunchpadTestRequest()) |
112 | self.assertFalse(view.requested_reviews[0].user_can_claim) |
113 | |
114 | + def makeReviewRequest(self, viewer=None, registrant=None): |
115 | + albert = self.factory.makePerson() |
116 | + if registrant is None: |
117 | + registrant = self.bmp.source_branch.owner |
118 | + self._nominateReviewer(albert, registrant) |
119 | + if viewer is None: |
120 | + viewer = albert |
121 | + login_person(viewer) |
122 | + view = BranchMergeProposalVoteView(self.bmp, LaunchpadTestRequest()) |
123 | + return view.requested_reviews[0] |
124 | + |
125 | + def test_user_can_reassign_assignee(self): |
126 | + """The user can reassign if they are the assignee.""" |
127 | + review_request = self.makeReviewRequest() |
128 | + self.assertTrue(review_request.user_can_reassign) |
129 | + |
130 | + def test_user_can_reassign_registrant(self): |
131 | + """The user can reassign if they are the registrant.""" |
132 | + registrant = self.factory.makePerson() |
133 | + review_request = self.makeReviewRequest(registrant, registrant) |
134 | + self.assertTrue(review_request.user_can_reassign) |
135 | + |
136 | + def test_user_cannot_reassign_random_person(self): |
137 | + """Random people cannot reassign reviews.""" |
138 | + viewer = self.factory.makePerson() |
139 | + review_request = self.makeReviewRequest(viewer) |
140 | + self.assertFalse(review_request.user_can_reassign) |
141 | + |
142 | def testCurrentReviewOrdering(self): |
143 | # Most recent first. |
144 | # Request three reviews. |
145 | |
146 | === added file 'lib/lp/code/browser/tests/test_codereviewvote.py' |
147 | --- lib/lp/code/browser/tests/test_codereviewvote.py 1970-01-01 00:00:00 +0000 |
148 | +++ lib/lp/code/browser/tests/test_codereviewvote.py 2009-08-06 18:09:19 +0000 |
149 | @@ -0,0 +1,40 @@ |
150 | +# Copyright 2009 Canonical Ltd. This software is licensed under the |
151 | +# GNU Affero General Public License version 3 (see the file LICENSE). |
152 | + |
153 | + |
154 | +"""Unit tests for CodeReviewVoteReferences.""" |
155 | + |
156 | + |
157 | +__metaclass__ = type |
158 | + |
159 | + |
160 | +import unittest |
161 | + |
162 | +from canonical.launchpad.webapp.servers import LaunchpadTestRequest |
163 | +from canonical.testing import DatabaseFunctionalLayer |
164 | +from lp.testing import ( |
165 | + login_person, TestCaseWithFactory) |
166 | +from lp.code.browser.codereviewvote import CodeReviewVoteReassign |
167 | + |
168 | + |
169 | +class TestReassignReviewer(TestCaseWithFactory): |
170 | + """Test functionality for changing the reviewer.""" |
171 | + |
172 | + layer = DatabaseFunctionalLayer |
173 | + |
174 | + def test_reassign(self): |
175 | + """A reviewer can reassign their vote to someone else.""" |
176 | + bmp = self.factory.makeBranchMergeProposal() |
177 | + reviewer = self.factory.makePerson() |
178 | + login_person(bmp.registrant) |
179 | + vote = bmp.nominateReviewer( |
180 | + reviewer=reviewer, registrant=bmp.registrant) |
181 | + new_reviewer = self.factory.makePerson() |
182 | + login_person(reviewer) |
183 | + view = CodeReviewVoteReassign(vote, LaunchpadTestRequest()) |
184 | + view.reassign_action.success({'reviewer': new_reviewer}) |
185 | + self.assertEqual(vote.reviewer, new_reviewer) |
186 | + |
187 | + |
188 | +def test_suite(): |
189 | + return unittest.TestLoader().loadTestsFromName(__name__) |
190 | |
191 | === modified file 'lib/lp/code/stories/branches/xx-branch-merge-proposals.txt' |
192 | --- lib/lp/code/stories/branches/xx-branch-merge-proposals.txt 2009-08-06 17:51:02 +0000 |
193 | +++ lib/lp/code/stories/branches/xx-branch-merge-proposals.txt 2009-08-06 17:53:03 +0000 |
194 | @@ -320,6 +320,22 @@ |
195 | Reviewer Review Type Date Requested Status... |
196 | Foo Bar claimable ... ago Pending ... |
197 | |
198 | +The claimant can reassign the review to someone else. |
199 | + |
200 | + >>> foobar_browser.getLink('Reassign').click() |
201 | + >>> foobar_browser.getControl('Reviewer').value = 'hwdb-team' |
202 | + >>> foobar_browser.getControl('Reassign').click() |
203 | + >>> foobar_browser.open('http://code.launchpad.dev/~name12/gnome-terminal' |
204 | + ... '/klingon/+merge/1') |
205 | + >>> pending = find_tag_by_id( |
206 | + ... foobar_browser.contents, 'code-review-votes') |
207 | + |
208 | +The review is now reassigned to the HWDB team. |
209 | + |
210 | + >>> print extract_text(pending) |
211 | + Reviewer Review Type Date Requested Status... |
212 | + HWDB Team claimable ... ago Pending ... |
213 | + |
214 | |
215 | == Marking as merged == |
216 | |
217 | |
218 | === modified file 'lib/lp/code/templates/branchmergeproposal-votes.pt' |
219 | --- lib/lp/code/templates/branchmergeproposal-votes.pt 2009-08-05 14:47:07 +0000 |
220 | +++ lib/lp/code/templates/branchmergeproposal-votes.pt 2009-08-05 20:16:34 +0000 |
221 | @@ -44,7 +44,13 @@ |
222 | <!-- Pending reviews --> |
223 | <tr tal:repeat="review view/requested_reviews" |
224 | tal:attributes="id string:review-${review/reviewer/name}"> |
225 | - <td tal:content="structure review/reviewer/fmt:link:mainsite" /> |
226 | + <td> |
227 | + <tal:reviewer |
228 | + tal:replace="structure review/reviewer/fmt:link:mainsite" /> |
229 | + <a tal:condition="review/user_can_reassign" |
230 | + tal:attributes="href string:reviews/${review/id}/+reassign"><img |
231 | + src="/@@/edit" title="Reassign reviewer" alt="Reassign" /></a> |
232 | + </td> |
233 | <td tal:content="review/review_type" /> |
234 | <td> |
235 | <tal:date-requested condition="review/show_date_requested"> |
236 | |
237 | === added file 'lib/lp/code/templates/reviewrequest-reassign.pt' |
238 | --- lib/lp/code/templates/reviewrequest-reassign.pt 1970-01-01 00:00:00 +0000 |
239 | +++ lib/lp/code/templates/reviewrequest-reassign.pt 2009-07-29 20:56:34 +0000 |
240 | @@ -0,0 +1,22 @@ |
241 | +<html |
242 | + xmlns="http://www.w3.org/1999/xhtml" |
243 | + xmlns:tal="http://xml.zope.org/namespaces/tal" |
244 | + xmlns:metal="http://xml.zope.org/namespaces/metal" |
245 | + xmlns:i18n="http://xml.zope.org/namespaces/i18n" |
246 | + xml:lang="en" |
247 | + lang="en" |
248 | + dir="ltr" |
249 | + metal:use-macro="view/macro:page/onecolumn" |
250 | + i18n:domain="launchpad" |
251 | +> |
252 | +<body> |
253 | +<div metal:fill-slot="main" |
254 | + tal:define="context_menu context/menu:context"> |
255 | + |
256 | + <h1>Reassign review request</h1> |
257 | + <div metal:use-macro="context/@@launchpad_form/form"> |
258 | + <div metal:fill-slot="extra_info" style="clear: both" /> |
259 | + </div> |
260 | +</div> |
261 | +</body> |
262 | +</html> |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
reviewer rockstar
= Summary =
This is a follow-up to my claim-review branch. Now that reviews can be
claimed, it must be possible to "un-claim" them, and being able to
reassign reviews is useful for delegation as well.
== Proposed fix ==
Provide an edit icon next to the name of the review that, when clicked,
allows the user to assign the review to someone else. Only the
registrant and the reviewer can see this icon. (But anyone who can
claim the review can claim it and then reassign it.)
== Pre-implementation notes == /code.edge. launchpad. net/~abentley/ launchpad/ reassign/ +merge/ 9463
Discussion with the Code team. ui approved by beuno:
https:/
== Implementation details ==
Can't think of anything unusual.
== Tests == eproposal -t test_codereviewvote -t merge-proposals .txt
bin/test -t test_branchmerg
xx-branch-
== Demo and Q/A ==
Create a branch merge proposal. Request a review. Reassign the review.
= Launchpad lint =
Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.
Linting changed files: code/browser/ configure. zcml /launchpad/ pagetitles. py code/browser/ tests/test_ branchmergeprop osal.py code/browser/ codereviewvote. py code/stories/ branches/ xx-branch- merge-proposals .txt code/browser/ tests/test_ codereviewvote. py code/browser/ branchmergeprop osal.py code/templates/ branchmergeprop osal-votes. pt code/templates/ reviewrequest- reassign. pt enigmail. mozdev. org
lib/lp/
lib/canonical
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
lib/lp/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAkp 7Hi4ACgkQ0F+ nu1YWqI2xSQCeL+ UTWZs872RynfCXm ieBAYU1 1D/BAXO0Z1fjP1h /8
ab0An3LZo43n6ua
=axSL
-----END PGP SIGNATURE-----