Merge lp:~thumper/launchpad/claim-review-into-model-attempt2 into lp:launchpad/db-devel
- claim-review-into-model-attempt2
- Merge into db-devel
Proposed by
Tim Penhey
Status: | Merged |
---|---|
Merged at revision: | 8763 |
Proposed branch: | lp:~thumper/launchpad/claim-review-into-model-attempt2 |
Merge into: | lp:launchpad/db-devel |
Prerequisite: | lp:~thumper/launchpad/lp-code-errors |
Diff against target: |
342 lines (+177/-26) 7 files modified
lib/lp/code/configure.zcml (+7/-4) lib/lp/code/errors.py (+5/-2) lib/lp/code/interfaces/codereviewvote.py (+41/-11) lib/lp/code/model/codereviewvote.py (+29/-0) lib/lp/code/model/tests/test_branchmergeproposals.py (+1/-0) lib/lp/code/model/tests/test_codereviewvote.py (+91/-9) lib/lp/code/stories/webservice/xx-branchmergeproposal.txt (+3/-0) |
To merge this branch: | bzr merge lp:~thumper/launchpad/claim-review-into-model-attempt2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paul Hummer (community) | Approve | ||
Review via email: mp+15728@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) 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/lp/code/configure.zcml' | |||
2 | --- lib/lp/code/configure.zcml 2009-11-16 22:53:42 +0000 | |||
3 | +++ lib/lp/code/configure.zcml 2009-12-07 04:01:14 +0000 | |||
4 | @@ -28,9 +28,13 @@ | |||
5 | 28 | provides="lp.code.interfaces.branchmergequeue.IBranchMergeQueueSet"> | 28 | provides="lp.code.interfaces.branchmergequeue.IBranchMergeQueueSet"> |
6 | 29 | <allow interface="lp.code.interfaces.branchmergequeue.IBranchMergeQueueSet"/> | 29 | <allow interface="lp.code.interfaces.branchmergequeue.IBranchMergeQueueSet"/> |
7 | 30 | </securedutility> | 30 | </securedutility> |
8 | 31 | |||
9 | 31 | <class class="lp.code.model.codereviewvote.CodeReviewVoteReference"> | 32 | <class class="lp.code.model.codereviewvote.CodeReviewVoteReference"> |
12 | 32 | <allow interface="lp.code.interfaces.codereviewvote.ICodeReviewVoteReference"/> | 33 | <allow interface="lp.code.interfaces.codereviewvote.ICodeReviewVoteReferencePublic"/> |
13 | 33 | <require permission="launchpad.Edit" set_attributes="reviewer" /> | 34 | <require |
14 | 35 | permission="launchpad.Edit" | ||
15 | 36 | interface="lp.code.interfaces.codereviewvote.ICodeReviewVoteReferenceEdit" | ||
16 | 37 | set_attributes="reviewer" /> | ||
17 | 34 | </class> | 38 | </class> |
18 | 35 | <subscriber | 39 | <subscriber |
19 | 36 | for="lp.code.interfaces.codereviewvote.ICodeReviewVoteReference | 40 | for="lp.code.interfaces.codereviewvote.ICodeReviewVoteReference |
20 | @@ -257,8 +261,7 @@ | |||
21 | 257 | updatePreviewDiff"/> | 261 | updatePreviewDiff"/> |
22 | 258 | <require | 262 | <require |
23 | 259 | permission="launchpad.AnyPerson" | 263 | permission="launchpad.AnyPerson" |
26 | 260 | attributes=" | 264 | attributes="createComment |
25 | 261 | createComment | ||
27 | 262 | createCommentFromMessage"/> | 265 | createCommentFromMessage"/> |
28 | 263 | </class> | 266 | </class> |
29 | 264 | <adapter | 267 | <adapter |
30 | 265 | 268 | ||
31 | === modified file 'lib/lp/code/errors.py' | |||
32 | --- lib/lp/code/errors.py 2009-12-07 04:01:13 +0000 | |||
33 | +++ lib/lp/code/errors.py 2009-12-07 04:01:14 +0000 | |||
34 | @@ -8,6 +8,7 @@ | |||
35 | 8 | 'BadBranchMergeProposalSearchContext', | 8 | 'BadBranchMergeProposalSearchContext', |
36 | 9 | 'BadStateTransition', | 9 | 'BadStateTransition', |
37 | 10 | 'BranchMergeProposalExists', | 10 | 'BranchMergeProposalExists', |
38 | 11 | 'ClaimReviewFailed', | ||
39 | 11 | 'InvalidBranchMergeProposal', | 12 | 'InvalidBranchMergeProposal', |
40 | 12 | 'UserNotBranchReviewer', | 13 | 'UserNotBranchReviewer', |
41 | 13 | 'WrongBranchMergeProposal', | 14 | 'WrongBranchMergeProposal', |
42 | @@ -22,6 +23,10 @@ | |||
43 | 22 | """The user requested a state transition that is not possible.""" | 23 | """The user requested a state transition that is not possible.""" |
44 | 23 | 24 | ||
45 | 24 | 25 | ||
46 | 26 | class ClaimReviewFailed(Exception): | ||
47 | 27 | """The user cannot claim the pending review.""" | ||
48 | 28 | |||
49 | 29 | |||
50 | 25 | class InvalidBranchMergeProposal(Exception): | 30 | class InvalidBranchMergeProposal(Exception): |
51 | 26 | """Raised during the creation of a new branch merge proposal. | 31 | """Raised during the creation of a new branch merge proposal. |
52 | 27 | 32 | ||
53 | @@ -44,5 +49,3 @@ | |||
54 | 44 | 49 | ||
55 | 45 | class WrongBranchMergeProposal(Exception): | 50 | class WrongBranchMergeProposal(Exception): |
56 | 46 | """The comment requested is not associated with this merge proposal.""" | 51 | """The comment requested is not associated with this merge proposal.""" |
57 | 47 | |||
58 | 48 | |||
59 | 49 | 52 | ||
60 | === modified file 'lib/lp/code/interfaces/codereviewvote.py' | |||
61 | --- lib/lp/code/interfaces/codereviewvote.py 2009-10-09 04:15:55 +0000 | |||
62 | +++ lib/lp/code/interfaces/codereviewvote.py 2009-12-07 04:01:14 +0000 | |||
63 | @@ -9,7 +9,7 @@ | |||
64 | 9 | ] | 9 | ] |
65 | 10 | 10 | ||
66 | 11 | from zope.interface import Interface | 11 | from zope.interface import Interface |
68 | 12 | from zope.schema import Datetime, Int, TextLine | 12 | from zope.schema import Bool, Datetime, Int, TextLine |
69 | 13 | 13 | ||
70 | 14 | from canonical.launchpad import _ | 14 | from canonical.launchpad import _ |
71 | 15 | from canonical.launchpad.fields import PublicPersonChoice | 15 | from canonical.launchpad.fields import PublicPersonChoice |
72 | @@ -19,16 +19,12 @@ | |||
73 | 19 | ICodeReviewComment) | 19 | ICodeReviewComment) |
74 | 20 | from lazr.restful.fields import Reference | 20 | from lazr.restful.fields import Reference |
75 | 21 | from lazr.restful.declarations import ( | 21 | from lazr.restful.declarations import ( |
86 | 22 | export_as_webservice_entry, exported) | 22 | call_with, export_as_webservice_entry, export_write_operation, exported, |
87 | 23 | 23 | REQUEST_USER) | |
88 | 24 | 24 | ||
89 | 25 | class ICodeReviewVoteReference(Interface): | 25 | |
90 | 26 | """A reference to a vote on a IBranchMergeProposal. | 26 | class ICodeReviewVoteReferencePublic(Interface): |
91 | 27 | 27 | """The public attributes for code review vote references.""" | |
82 | 28 | There is at most one reference to a vote for each reviewer on a given | ||
83 | 29 | branch merge proposal. | ||
84 | 30 | """ | ||
85 | 31 | export_as_webservice_entry() | ||
92 | 32 | 28 | ||
93 | 33 | id = Int( | 29 | id = Int( |
94 | 34 | title=_("The ID of the vote reference")) | 30 | title=_("The ID of the vote reference")) |
95 | @@ -66,3 +62,37 @@ | |||
96 | 66 | "The code review comment that contains the most recent vote." | 62 | "The code review comment that contains the most recent vote." |
97 | 67 | ), | 63 | ), |
98 | 68 | required=True, schema=ICodeReviewComment)) | 64 | required=True, schema=ICodeReviewComment)) |
99 | 65 | |||
100 | 66 | is_pending = exported( | ||
101 | 67 | Bool(title=_("Is the pending?"), required=True, readonly=True)) | ||
102 | 68 | |||
103 | 69 | |||
104 | 70 | class ICodeReviewVoteReferenceEdit(Interface): | ||
105 | 71 | """Method that require edit permissions.""" | ||
106 | 72 | |||
107 | 73 | @call_with(claimant=REQUEST_USER) | ||
108 | 74 | @export_write_operation() | ||
109 | 75 | def claimReview(claimant): | ||
110 | 76 | """Change a pending review into a review for claimant. | ||
111 | 77 | |||
112 | 78 | Pending team reviews can be claimed by members of that team. This | ||
113 | 79 | allows reviews to be moved of the general team todo list, and onto a | ||
114 | 80 | personal todo list. | ||
115 | 81 | |||
116 | 82 | :param claimant: The person claiming the team review. | ||
117 | 83 | :raises ClaimReviewFailed: If the claimant already has a | ||
118 | 84 | personal review, if the reviewer is not a team, if the | ||
119 | 85 | claimant is not in the reviewer team, or if the review is | ||
120 | 86 | not pending. | ||
121 | 87 | """ | ||
122 | 88 | |||
123 | 89 | |||
124 | 90 | class ICodeReviewVoteReference(ICodeReviewVoteReferencePublic, | ||
125 | 91 | ICodeReviewVoteReferenceEdit): | ||
126 | 92 | """A reference to a vote on a IBranchMergeProposal. | ||
127 | 93 | |||
128 | 94 | There is at most one reference to a vote for each reviewer on a given | ||
129 | 95 | branch merge proposal. | ||
130 | 96 | """ | ||
131 | 97 | |||
132 | 98 | export_as_webservice_entry() | ||
133 | 69 | 99 | ||
134 | === modified file 'lib/lp/code/model/codereviewvote.py' | |||
135 | --- lib/lp/code/model/codereviewvote.py 2009-06-25 04:06:00 +0000 | |||
136 | +++ lib/lp/code/model/codereviewvote.py 2009-12-07 04:01:14 +0000 | |||
137 | @@ -15,6 +15,7 @@ | |||
138 | 15 | from canonical.database.constants import DEFAULT | 15 | from canonical.database.constants import DEFAULT |
139 | 16 | from canonical.database.datetimecol import UtcDateTimeCol | 16 | from canonical.database.datetimecol import UtcDateTimeCol |
140 | 17 | from canonical.database.sqlbase import SQLBase | 17 | from canonical.database.sqlbase import SQLBase |
141 | 18 | from lp.code.errors import ClaimReviewFailed | ||
142 | 18 | from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference | 19 | from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference |
143 | 19 | 20 | ||
144 | 20 | 21 | ||
145 | @@ -36,3 +37,31 @@ | |||
146 | 36 | review_type = StringCol(default=None) | 37 | review_type = StringCol(default=None) |
147 | 37 | comment = ForeignKey( | 38 | comment = ForeignKey( |
148 | 38 | dbName='vote_message', foreignKey='CodeReviewComment', default=None) | 39 | dbName='vote_message', foreignKey='CodeReviewComment', default=None) |
149 | 40 | |||
150 | 41 | @property | ||
151 | 42 | def is_pending(self): | ||
152 | 43 | """See `ICodeReviewVote`""" | ||
153 | 44 | # Reviews are pending if there is no associated comment. | ||
154 | 45 | return self.comment is None | ||
155 | 46 | |||
156 | 47 | def claimReview(self, claimant): | ||
157 | 48 | """See `ICodeReviewVote`""" | ||
158 | 49 | if not self.is_pending: | ||
159 | 50 | raise ClaimReviewFailed('The review is not pending.') | ||
160 | 51 | if not self.reviewer.is_team: | ||
161 | 52 | raise ClaimReviewFailed('Cannot claim non-team reviews.') | ||
162 | 53 | if not claimant.inTeam(self.reviewer): | ||
163 | 54 | raise ClaimReviewFailed( | ||
164 | 55 | '%s is not a member of %s' % | ||
165 | 56 | (claimant.unique_displayname, | ||
166 | 57 | self.reviewer.unique_displayname)) | ||
167 | 58 | claimant_review = ( | ||
168 | 59 | self.branch_merge_proposal.getUsersVoteReference(claimant)) | ||
169 | 60 | if claimant_review is not None: | ||
170 | 61 | if claimant_review.is_pending: | ||
171 | 62 | error_str = '%s has an existing pending review' | ||
172 | 63 | else: | ||
173 | 64 | error_str = '%s has an existing personal review' | ||
174 | 65 | raise ClaimReviewFailed( | ||
175 | 66 | error_str % claimant.unique_displayname) | ||
176 | 67 | self.reviewer = claimant | ||
177 | 39 | 68 | ||
178 | === modified file 'lib/lp/code/model/tests/test_branchmergeproposals.py' | |||
179 | --- lib/lp/code/model/tests/test_branchmergeproposals.py 2009-12-07 04:01:13 +0000 | |||
180 | +++ lib/lp/code/model/tests/test_branchmergeproposals.py 2009-12-07 04:01:14 +0000 | |||
181 | @@ -1683,6 +1683,7 @@ | |||
182 | 1683 | # Still only one vote. | 1683 | # Still only one vote. |
183 | 1684 | self.assertEqual(1, len(list(merge_proposal.votes))) | 1684 | self.assertEqual(1, len(list(merge_proposal.votes))) |
184 | 1685 | 1685 | ||
185 | 1686 | |||
186 | 1686 | class TestBranchMergeProposalResubmit(TestCaseWithFactory): | 1687 | class TestBranchMergeProposalResubmit(TestCaseWithFactory): |
187 | 1687 | 1688 | ||
188 | 1688 | layer = DatabaseFunctionalLayer | 1689 | layer = DatabaseFunctionalLayer |
189 | 1689 | 1690 | ||
190 | === modified file 'lib/lp/code/model/tests/test_codereviewvote.py' | |||
191 | --- lib/lp/code/model/tests/test_codereviewvote.py 2009-06-25 04:06:00 +0000 | |||
192 | +++ lib/lp/code/model/tests/test_codereviewvote.py 2009-12-07 04:01:14 +0000 | |||
193 | @@ -3,30 +3,112 @@ | |||
194 | 3 | 3 | ||
195 | 4 | from unittest import TestLoader | 4 | from unittest import TestLoader |
196 | 5 | 5 | ||
197 | 6 | from zope.security.interfaces import Unauthorized | ||
198 | 7 | |||
199 | 6 | from canonical.database.constants import UTC_NOW | 8 | from canonical.database.constants import UTC_NOW |
200 | 9 | from canonical.testing import DatabaseFunctionalLayer | ||
201 | 10 | |||
202 | 11 | from lp.code.enums import CodeReviewVote | ||
203 | 12 | from lp.code.errors import ClaimReviewFailed | ||
204 | 7 | from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference | 13 | from lp.code.interfaces.codereviewvote import ICodeReviewVoteReference |
208 | 8 | from lp.testing import TestCaseWithFactory | 14 | from lp.testing import login_person, TestCaseWithFactory |
209 | 9 | from canonical.launchpad.webapp.testing import verifyObject | 15 | |
207 | 10 | from canonical.testing import LaunchpadZopelessLayer | ||
210 | 11 | 16 | ||
211 | 12 | class TestCodeReviewVote(TestCaseWithFactory): | 17 | class TestCodeReviewVote(TestCaseWithFactory): |
212 | 13 | 18 | ||
214 | 14 | layer = LaunchpadZopelessLayer | 19 | layer = DatabaseFunctionalLayer |
215 | 15 | 20 | ||
216 | 16 | def test_create_vote(self): | 21 | def test_create_vote(self): |
217 | 17 | """CodeReviewVotes can be created""" | 22 | """CodeReviewVotes can be created""" |
218 | 18 | merge_proposal = self.factory.makeBranchMergeProposal() | 23 | merge_proposal = self.factory.makeBranchMergeProposal() |
219 | 19 | reviewer = self.factory.makePerson() | 24 | reviewer = self.factory.makePerson() |
222 | 20 | registrant = self.factory.makePerson() | 25 | login_person(merge_proposal.registrant) |
223 | 21 | vote = merge_proposal.nominateReviewer(reviewer, registrant) | 26 | vote = merge_proposal.nominateReviewer( |
224 | 27 | reviewer, merge_proposal.registrant) | ||
225 | 22 | self.assertEqual(reviewer, vote.reviewer) | 28 | self.assertEqual(reviewer, vote.reviewer) |
227 | 23 | self.assertEqual(registrant, vote.registrant) | 29 | self.assertEqual(merge_proposal.registrant, vote.registrant) |
228 | 24 | self.assertEqual(merge_proposal, vote.branch_merge_proposal) | 30 | self.assertEqual(merge_proposal, vote.branch_merge_proposal) |
229 | 25 | self.assertEqual([vote], list(merge_proposal.votes)) | 31 | self.assertEqual([vote], list(merge_proposal.votes)) |
230 | 26 | self.assertSqlAttributeEqualsDate( | 32 | self.assertSqlAttributeEqualsDate( |
231 | 27 | vote, 'date_created', UTC_NOW) | 33 | vote, 'date_created', UTC_NOW) |
234 | 28 | assert verifyObject(ICodeReviewVoteReference, vote), ('Implements the' | 34 | self.assertProvides(vote, ICodeReviewVoteReference) |
235 | 29 | ' expected interface.') | 35 | |
236 | 36 | |||
237 | 37 | class TestCodeReviewVoteReferenceClaimReview(TestCaseWithFactory): | ||
238 | 38 | """Tests for CodeReviewVoteReference.claimReview.""" | ||
239 | 39 | |||
240 | 40 | layer = DatabaseFunctionalLayer | ||
241 | 41 | |||
242 | 42 | def setUp(self): | ||
243 | 43 | TestCaseWithFactory.setUp(self) | ||
244 | 44 | # Setup the proposal, claimant and team reviewer. | ||
245 | 45 | self.bmp = self.factory.makeBranchMergeProposal() | ||
246 | 46 | self.claimant = self.factory.makePerson() | ||
247 | 47 | self.review_team = self.factory.makeTeam() | ||
248 | 48 | |||
249 | 49 | def _addPendingReview(self): | ||
250 | 50 | """Add a pending review for the review_team.""" | ||
251 | 51 | login_person(self.bmp.registrant) | ||
252 | 52 | return self.bmp.nominateReviewer( | ||
253 | 53 | reviewer=self.review_team, | ||
254 | 54 | registrant=self.bmp.registrant) | ||
255 | 55 | |||
256 | 56 | def _addClaimantToReviewTeam(self): | ||
257 | 57 | """Add the claimant to the review team.""" | ||
258 | 58 | login_person(self.review_team.teamowner) | ||
259 | 59 | self.review_team.addMember( | ||
260 | 60 | person=self.claimant, reviewer=self.review_team.teamowner) | ||
261 | 61 | |||
262 | 62 | def test_personal_completed_review(self): | ||
263 | 63 | # If the claimant has a personal review already, then they can't claim | ||
264 | 64 | # a pending team review. | ||
265 | 65 | login_person(self.claimant) | ||
266 | 66 | # Make sure that the personal review is done before the pending team | ||
267 | 67 | # review, otherwise the pending team review will be claimed by this | ||
268 | 68 | # one. | ||
269 | 69 | self.bmp.createComment( | ||
270 | 70 | self.claimant, 'Message subject', 'Message content', | ||
271 | 71 | vote=CodeReviewVote.APPROVE) | ||
272 | 72 | review = self._addPendingReview() | ||
273 | 73 | self._addClaimantToReviewTeam() | ||
274 | 74 | self.assertRaises( | ||
275 | 75 | ClaimReviewFailed, review.claimReview, self.claimant) | ||
276 | 76 | |||
277 | 77 | def test_personal_pending_review(self): | ||
278 | 78 | # If the claimant has a pending review already, then they can't claim | ||
279 | 79 | # a pending team review. | ||
280 | 80 | review = self._addPendingReview() | ||
281 | 81 | self._addClaimantToReviewTeam() | ||
282 | 82 | login_person(self.bmp.registrant) | ||
283 | 83 | self.bmp.nominateReviewer( | ||
284 | 84 | reviewer=self.claimant, registrant=self.bmp.registrant) | ||
285 | 85 | login_person(self.claimant) | ||
286 | 86 | self.assertRaises( | ||
287 | 87 | ClaimReviewFailed, review.claimReview, self.claimant) | ||
288 | 88 | |||
289 | 89 | def test_personal_not_in_review_team(self): | ||
290 | 90 | # If the claimant is not in the review team, an error is raised. | ||
291 | 91 | review = self._addPendingReview() | ||
292 | 92 | # Since the claimant isn't in the review team, they don't have | ||
293 | 93 | # launchpad.Edit on the review itself, hence Unauthorized. | ||
294 | 94 | login_person(self.claimant) | ||
295 | 95 | # Actually accessing claimReview triggers the security proxy. | ||
296 | 96 | self.assertRaises( | ||
297 | 97 | Unauthorized, getattr, review, 'claimReview') | ||
298 | 98 | # The merge proposal registrant however does have edit permissions, | ||
299 | 99 | # but isn't in the team, so they get ClaimReviewFailed. | ||
300 | 100 | login_person(self.bmp.registrant) | ||
301 | 101 | self.assertRaises( | ||
302 | 102 | ClaimReviewFailed, review.claimReview, self.bmp.registrant) | ||
303 | 103 | |||
304 | 104 | def test_success(self): | ||
305 | 105 | # If the claimant is in the review team, and does not have a personal | ||
306 | 106 | # review, pending or completed, then they can claim the team review. | ||
307 | 107 | review = self._addPendingReview() | ||
308 | 108 | self._addClaimantToReviewTeam() | ||
309 | 109 | login_person(self.claimant) | ||
310 | 110 | review.claimReview(self.claimant) | ||
311 | 111 | self.assertEqual(self.claimant, review.reviewer) | ||
312 | 30 | 112 | ||
313 | 31 | 113 | ||
314 | 32 | def test_suite(): | 114 | def test_suite(): |
315 | 33 | 115 | ||
316 | === modified file 'lib/lp/code/stories/webservice/xx-branchmergeproposal.txt' | |||
317 | --- lib/lp/code/stories/webservice/xx-branchmergeproposal.txt 2009-11-05 21:36:14 +0000 | |||
318 | +++ lib/lp/code/stories/webservice/xx-branchmergeproposal.txt 2009-12-07 04:01:14 +0000 | |||
319 | @@ -79,6 +79,7 @@ | |||
320 | 79 | branch_merge_proposal_link: u'http://api.launchpad.dev/beta/~.../+merge/...' | 79 | branch_merge_proposal_link: u'http://api.launchpad.dev/beta/~.../+merge/...' |
321 | 80 | comment_link: None | 80 | comment_link: None |
322 | 81 | date_created: u'...' | 81 | date_created: u'...' |
323 | 82 | is_pending: True | ||
324 | 82 | registrant_link: u'http://api.launchpad.dev/beta/~person-name...' | 83 | registrant_link: u'http://api.launchpad.dev/beta/~person-name...' |
325 | 83 | resource_type_link: u'http://api.launchpad.dev/beta/#code_review_vote_reference' | 84 | resource_type_link: u'http://api.launchpad.dev/beta/#code_review_vote_reference' |
326 | 84 | review_type: u'green' | 85 | review_type: u'green' |
327 | @@ -194,6 +195,7 @@ | |||
328 | 194 | branch_merge_proposal_link: u'http://.../~source/fooix/fix-it/+merge/...' | 195 | branch_merge_proposal_link: u'http://.../~source/fooix/fix-it/+merge/...' |
329 | 195 | comment_link: u'http://.../~source/fooix/fix-it/+merge/.../comments/...' | 196 | comment_link: u'http://.../~source/fooix/fix-it/+merge/.../comments/...' |
330 | 196 | date_created: u'...' | 197 | date_created: u'...' |
331 | 198 | is_pending: False | ||
332 | 197 | registrant_link: u'http://.../~person-name...' | 199 | registrant_link: u'http://.../~person-name...' |
333 | 198 | resource_type_link: u'http://.../#code_review_vote_reference' | 200 | resource_type_link: u'http://.../#code_review_vote_reference' |
334 | 199 | review_type: u'code' | 201 | review_type: u'code' |
335 | @@ -221,6 +223,7 @@ | |||
336 | 221 | branch_merge_proposal_link: u'http://.../~source/fooix/fix-it/+merge/...' | 223 | branch_merge_proposal_link: u'http://.../~source/fooix/fix-it/+merge/...' |
337 | 222 | comment_link: None | 224 | comment_link: None |
338 | 223 | date_created: u'...' | 225 | date_created: u'...' |
339 | 226 | is_pending: True | ||
340 | 224 | registrant_link: u'http://.../~target' | 227 | registrant_link: u'http://.../~target' |
341 | 225 | resource_type_link: u'http://.../#code_review_vote_reference' | 228 | resource_type_link: u'http://.../#code_review_vote_reference' |
342 | 226 | review_type: u'code' | 229 | review_type: u'code' |
Moves the logic of actually claiming a review into the model code itself and exposes it over the api.
tests: tests.test_ codereviewvote
model.
and for the is_pending bit: xx-branchmergep roposal
webservice/