Merge lp:~mars/launchpad/fix-js-unittests into lp:launchpad/db-devel
- fix-js-unittests
- Merge into db-devel
Status: | Rejected |
---|---|
Rejected by: | Māris Fogels |
Proposed branch: | lp:~mars/launchpad/fix-js-unittests |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
524 lines (+218/-52) 12 files modified
database/schema/security.cfg (+3/-0) lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js (+5/-0) lib/canonical/launchpad/javascript/client/client.js (+2/-2) lib/canonical/launchpad/javascript/lp/comment.js (+0/-1) lib/canonical/launchpad/javascript/lp/lp.js (+2/-3) lib/canonical/launchpad/javascript/soyuz/lp_dynamic_dom_updater.js (+5/-5) lib/lp/code/browser/branch.py (+5/-0) lib/lp/code/browser/codereviewcomment.py (+4/-3) lib/lp/code/errors.py (+51/-0) lib/lp/code/templates/branchmergeproposal-index.pt (+62/-27) lib/lp/registry/browser/team.py (+4/-2) lib/lp/translations/tests/test_translationimportqueue.py (+75/-9) |
To merge this branch: | bzr merge lp:~mars/launchpad/fix-js-unittests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gavin Panella (community) | Approve | ||
Review via email: mp+15546@code.launchpad.net |
Commit message
Description of the change
Māris Fogels (mars) wrote : | # |
Gavin Panella (allenap) wrote : | # |
Has Y.fail() been renamed as Y.error(), or is it a deprecated synonym? If neither, then I'd be inclined to leave it alone; "fail" more closely matches the terminology used in the Python testing world. Y.error() sounds like it should be used when test set-up fails, not when an assertion fails.
I'm very happy to see that the 'click' simulation has been fixed (re. test_me_too.js). Figuring that one out caused me a very sweary afternoon of pain.
Thanks for doing this :)
Māris Fogels (mars) wrote : | # |
On Wed, Dec 2, 2009 at 8:54 AM, Gavin Panella <email address hidden> wrote:
> Review: Approve
> Has Y.fail() been renamed as Y.error(), or is it a deprecated synonym? If neither, then I'd be inclined to leave it alone; "fail" more closely matches the terminology used in the Python testing world. Y.error() sounds like it should be used when test set-up fails, not when an assertion fails.
Yes, Y.fail() became Y.error(). Y.fail() is now only in the 'test' module, and has become the standard xUnit "fail()" call.
This caused a subtle bug: my tests were failing when they should have been raising errors. Turns out the code under test was calling Y.fail() itself, so it raised a failure exception instead of a real error.
>
> I'm very happy to see that the 'click' simulation has been fixed (re. test_me_too.js). Figuring that one out caused me a very sweary afternoon of pain.
It took me a while, too. I remembered a comment Bjorn made during the lazr-js sprint about using click because mousedown was unreliable. Turns out it was true!
>
> Thanks for doing this :)
>
My pleasure! Thank you for the review.
Mars
- 8737. By Māris Fogels
-
Merge from db-devel
- 8738. By Māris Fogels
-
Merged trunk instead of db-devel so we can land on the mainline.
- 8739. By Māris Fogels
-
Merge from RF. Fixed one conflict.
Māris Fogels (mars) wrote : | # |
Rejecting my own branch, as it has become stale (because PQM refuses to land it, argh!)
Unmerged revisions
- 8739. By Māris Fogels
-
Merge from RF. Fixed one conflict.
- 8738. By Māris Fogels
-
Merged trunk instead of db-devel so we can land on the mainline.
- 8737. By Māris Fogels
-
Merge from db-devel
- 8736. By Māris Fogels
-
Fixed a number of JS unit tests that broke during the YUI 3.0.0 upgrade.
Preview Diff
1 | === modified file 'database/schema/security.cfg' | |||
2 | --- database/schema/security.cfg 2009-12-02 13:08:18 +0000 | |||
3 | +++ database/schema/security.cfg 2009-12-11 13:41:18 +0000 | |||
4 | @@ -1216,6 +1216,9 @@ | |||
5 | 1216 | public.libraryfilecontent = SELECT, INSERT | 1216 | public.libraryfilecontent = SELECT, INSERT |
6 | 1217 | 1217 | ||
7 | 1218 | # rosetta auto imports | 1218 | # rosetta auto imports |
8 | 1219 | public.pofile = SELECT | ||
9 | 1220 | public.potemplate = SELECT | ||
10 | 1221 | public.translationgroup = SELECT | ||
11 | 1219 | public.translationimportqueueentry = SELECT, INSERT, UPDATE | 1222 | public.translationimportqueueentry = SELECT, INSERT, UPDATE |
12 | 1220 | 1223 | ||
13 | 1221 | # Closing bugs. | 1224 | # Closing bugs. |
14 | 1222 | 1225 | ||
15 | === modified file 'lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js' | |||
16 | --- lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js 2009-12-10 13:45:40 +0000 | |||
17 | +++ lib/canonical/launchpad/javascript/bugs/filebug-dupefinder.js 2009-12-11 13:41:18 +0000 | |||
18 | @@ -56,8 +56,13 @@ | |||
19 | 56 | 56 | ||
20 | 57 | // Check that the details_div actually exists and raise an error if | 57 | // Check that the details_div actually exists and raise an error if |
21 | 58 | // we can't find it. | 58 | // we can't find it. |
22 | 59 | <<<<<<< TREE | ||
23 | 59 | if (!Y.Lang.isValue(details_div)) { | 60 | if (!Y.Lang.isValue(details_div)) { |
24 | 60 | Y.fail( | 61 | Y.fail( |
25 | 62 | ======= | ||
26 | 63 | if (!Y.Lang.isValue(details_div)) { | ||
27 | 64 | Y.error( | ||
28 | 65 | >>>>>>> MERGE-SOURCE | ||
29 | 61 | "Unable to find details div for expander " + expander.get('id')); | 66 | "Unable to find details div for expander " + expander.get('id')); |
30 | 62 | } else { | 67 | } else { |
31 | 63 | return details_div; | 68 | return details_div; |
32 | 64 | 69 | ||
33 | === modified file 'lib/canonical/launchpad/javascript/client/client.js' | |||
34 | --- lib/canonical/launchpad/javascript/client/client.js 2009-12-07 12:26:37 +0000 | |||
35 | +++ lib/canonical/launchpad/javascript/client/client.js 2009-12-11 13:41:18 +0000 | |||
36 | @@ -694,11 +694,11 @@ | |||
37 | 694 | */ | 694 | */ |
38 | 695 | initializer: function(config) { | 695 | initializer: function(config) { |
39 | 696 | if (!Y.Lang.isString(config.patch)) { | 696 | if (!Y.Lang.isString(config.patch)) { |
41 | 697 | Y.fail("missing config: 'patch' containing the attribute name"); | 697 | Y.error("missing config: 'patch' containing the attribute name"); |
42 | 698 | } | 698 | } |
43 | 699 | 699 | ||
44 | 700 | if (!Y.Lang.isString(config.resource)) { | 700 | if (!Y.Lang.isString(config.resource)) { |
46 | 701 | Y.fail("missing config: 'resource' containing the URL to patch"); | 701 | Y.error("missing config: 'resource' containing the URL to patch"); |
47 | 702 | } | 702 | } |
48 | 703 | 703 | ||
49 | 704 | // Save the config object that the user passed in so that we can pass | 704 | // Save the config object that the user passed in so that we can pass |
50 | 705 | 705 | ||
51 | === modified file 'lib/canonical/launchpad/javascript/lp/comment.js' | |||
52 | --- lib/canonical/launchpad/javascript/lp/comment.js 2009-11-26 19:54:52 +0000 | |||
53 | +++ lib/canonical/launchpad/javascript/lp/comment.js 2009-12-11 13:41:18 +0000 | |||
54 | @@ -361,7 +361,6 @@ | |||
55 | 361 | }, | 361 | }, |
56 | 362 | renderUI: function() { | 362 | renderUI: function() { |
57 | 363 | CodeReviewComment.superclass.renderUI.apply(this); | 363 | CodeReviewComment.superclass.renderUI.apply(this); |
58 | 364 | Y.one('#inline-add-comment').setStyle('display', 'block'); | ||
59 | 365 | }, | 364 | }, |
60 | 366 | /** | 365 | /** |
61 | 367 | * Implementation of Widget.bindUI: Bind events to methods. | 366 | * Implementation of Widget.bindUI: Bind events to methods. |
62 | 368 | 367 | ||
63 | === modified file 'lib/canonical/launchpad/javascript/lp/lp.js' | |||
64 | --- lib/canonical/launchpad/javascript/lp/lp.js 2009-12-07 12:26:37 +0000 | |||
65 | +++ lib/canonical/launchpad/javascript/lp/lp.js 2009-12-11 13:41:18 +0000 | |||
66 | @@ -66,10 +66,10 @@ | |||
67 | 66 | 66 | ||
68 | 67 | // If either the wrapper or the icon is null, raise an error. | 67 | // If either the wrapper or the icon is null, raise an error. |
69 | 68 | if (wrapper_div === null) { | 68 | if (wrapper_div === null) { |
71 | 69 | Y.fail("Collapsible has no wrapper div."); | 69 | Y.error("Collapsible has no wrapper div."); |
72 | 70 | } | 70 | } |
73 | 71 | if (icon === null) { | 71 | if (icon === null) { |
75 | 72 | Y.fail("Collapsible has no icon."); | 72 | Y.error("Collapsible has no icon."); |
76 | 73 | } | 73 | } |
77 | 74 | 74 | ||
78 | 75 | // Work out the target icon and animation based on the state of | 75 | // Work out the target icon and animation based on the state of |
79 | @@ -791,4 +791,3 @@ | |||
80 | 791 | tag2.style.display = display; | 791 | tag2.style.display = display; |
81 | 792 | return false; | 792 | return false; |
82 | 793 | } | 793 | } |
83 | 794 | |||
84 | 795 | 794 | ||
85 | === modified file 'lib/canonical/launchpad/javascript/soyuz/lp_dynamic_dom_updater.js' | |||
86 | --- lib/canonical/launchpad/javascript/soyuz/lp_dynamic_dom_updater.js 2009-11-24 16:11:43 +0000 | |||
87 | +++ lib/canonical/launchpad/javascript/soyuz/lp_dynamic_dom_updater.js 2009-12-11 13:41:18 +0000 | |||
88 | @@ -14,7 +14,7 @@ | |||
89 | 14 | var lp = Y.namespace('lp'); | 14 | var lp = Y.namespace('lp'); |
90 | 15 | 15 | ||
91 | 16 | /** | 16 | /** |
93 | 17 | * The DomUpdater class provides the ability to plugin functionality | 17 | * The DomUpdater class provides the ability to plugin functionality |
94 | 18 | * to a DOM subtree so that it can update itself when given data in an | 18 | * to a DOM subtree so that it can update itself when given data in an |
95 | 19 | * expected format. | 19 | * expected format. |
96 | 20 | * | 20 | * |
97 | @@ -79,7 +79,7 @@ | |||
98 | 79 | Y.lp.DomUpdater = DomUpdater; | 79 | Y.lp.DomUpdater = DomUpdater; |
99 | 80 | 80 | ||
100 | 81 | /** | 81 | /** |
102 | 82 | * The DynamicDomUpdater class provides the ability to plug functionality | 82 | * The DynamicDomUpdater class provides the ability to plug functionality |
103 | 83 | * into a DOM subtree so that it can update itself using an LP api method. | 83 | * into a DOM subtree so that it can update itself using an LP api method. |
104 | 84 | * | 84 | * |
105 | 85 | * For example: | 85 | * For example: |
106 | @@ -94,7 +94,7 @@ | |||
107 | 94 | * Once configured, the 'table' dom subtree will now update itself | 94 | * Once configured, the 'table' dom subtree will now update itself |
108 | 95 | * by calling the user defined domUpdateFunction (with a default interval | 95 | * by calling the user defined domUpdateFunction (with a default interval |
109 | 96 | * of 6000ms) with the result of the LPs api call. | 96 | * of 6000ms) with the result of the LPs api call. |
111 | 97 | * | 97 | * |
112 | 98 | * @class DynamicDomUpdater | 98 | * @class DynamicDomUpdater |
113 | 99 | * @extends DomUpdater | 99 | * @extends DomUpdater |
114 | 100 | * @constructor | 100 | * @constructor |
115 | @@ -326,7 +326,7 @@ | |||
116 | 326 | } | 326 | } |
117 | 327 | 327 | ||
118 | 328 | if (actual_interval_updated) { | 328 | if (actual_interval_updated) { |
120 | 329 | Y.log("Actual poll interval updated to " + | 329 | Y.log("Actual poll interval updated to " + |
121 | 330 | this._actual_interval + "ms."); | 330 | this._actual_interval + "ms."); |
122 | 331 | } | 331 | } |
123 | 332 | 332 | ||
124 | @@ -344,7 +344,7 @@ | |||
125 | 344 | * @private | 344 | * @private |
126 | 345 | */ | 345 | */ |
127 | 346 | _handleFailure: function(id, request) { | 346 | _handleFailure: function(id, request) { |
129 | 347 | Y.fail("LP.DynamicDomUpdater for " + this.get("host") + | 347 | Y.error("LP.DynamicDomUpdater for " + this.get("host") + |
130 | 348 | " failed to get dynamic data."); | 348 | " failed to get dynamic data."); |
131 | 349 | } | 349 | } |
132 | 350 | }); | 350 | }); |
133 | 351 | 351 | ||
134 | === modified file 'lib/lp/code/browser/branch.py' | |||
135 | --- lib/lp/code/browser/branch.py 2009-12-11 00:56:16 +0000 | |||
136 | +++ lib/lp/code/browser/branch.py 2009-12-11 13:41:18 +0000 | |||
137 | @@ -79,9 +79,14 @@ | |||
138 | 79 | from lp.code.browser.branchmergeproposal import ( | 79 | from lp.code.browser.branchmergeproposal import ( |
139 | 80 | latest_proposals_for_each_branch) | 80 | latest_proposals_for_each_branch) |
140 | 81 | from lp.code.enums import ( | 81 | from lp.code.enums import ( |
141 | 82 | <<<<<<< TREE | ||
142 | 82 | BranchLifecycleStatus, BranchType, RevisionControlSystems, | 83 | BranchLifecycleStatus, BranchType, RevisionControlSystems, |
143 | 83 | UICreatableBranchType) | 84 | UICreatableBranchType) |
144 | 84 | from lp.code.errors import InvalidBranchMergeProposal | 85 | from lp.code.errors import InvalidBranchMergeProposal |
145 | 86 | ======= | ||
146 | 87 | BranchLifecycleStatus, BranchType, UICreatableBranchType) | ||
147 | 88 | from lp.code.errors import InvalidBranchMergeProposal | ||
148 | 89 | >>>>>>> MERGE-SOURCE | ||
149 | 85 | from lp.code.interfaces.branch import ( | 90 | from lp.code.interfaces.branch import ( |
150 | 86 | BranchCreationForbidden, BranchExists, IBranch, | 91 | BranchCreationForbidden, BranchExists, IBranch, |
151 | 87 | user_has_special_branch_access) | 92 | user_has_special_branch_access) |
152 | 88 | 93 | ||
153 | === modified file 'lib/lp/code/browser/branchmergeproposal.py' | |||
154 | === modified file 'lib/lp/code/browser/codereviewcomment.py' | |||
155 | --- lib/lp/code/browser/codereviewcomment.py 2009-10-29 23:51:08 +0000 | |||
156 | +++ lib/lp/code/browser/codereviewcomment.py 2009-12-11 13:41:18 +0000 | |||
157 | @@ -204,7 +204,7 @@ | |||
158 | 204 | 204 | ||
159 | 205 | class MyDropWidget(DropdownWidget): | 205 | class MyDropWidget(DropdownWidget): |
160 | 206 | "Override the default no-value display name to -Select-." | 206 | "Override the default no-value display name to -Select-." |
162 | 207 | _messageNoValue = '-Select-' | 207 | _messageNoValue = 'Comment only' |
163 | 208 | 208 | ||
164 | 209 | schema = IEditCodeReviewComment | 209 | schema = IEditCodeReviewComment |
165 | 210 | 210 | ||
166 | @@ -251,10 +251,11 @@ | |||
167 | 251 | @action('Save Comment', name='add') | 251 | @action('Save Comment', name='add') |
168 | 252 | def add_action(self, action, data): | 252 | def add_action(self, action, data): |
169 | 253 | """Create the comment...""" | 253 | """Create the comment...""" |
170 | 254 | vote = data.get('vote') | ||
171 | 255 | review_type = data.get('review_type') | ||
172 | 254 | comment = self.branch_merge_proposal.createComment( | 256 | comment = self.branch_merge_proposal.createComment( |
173 | 255 | self.user, subject=None, content=data['comment'], | 257 | self.user, subject=None, content=data['comment'], |
176 | 256 | parent=self.reply_to, vote=data['vote'], | 258 | parent=self.reply_to, vote=vote, review_type=review_type) |
175 | 257 | review_type=data['review_type']) | ||
177 | 258 | 259 | ||
178 | 259 | @property | 260 | @property |
179 | 260 | def next_url(self): | 261 | def next_url(self): |
180 | 261 | 262 | ||
181 | === modified file 'lib/lp/code/configure.zcml' | |||
182 | === modified file 'lib/lp/code/errors.py' | |||
183 | --- lib/lp/code/errors.py 2009-12-07 06:51:42 +0000 | |||
184 | +++ lib/lp/code/errors.py 2009-12-11 13:41:18 +0000 | |||
185 | @@ -1,3 +1,4 @@ | |||
186 | 1 | <<<<<<< TREE | ||
187 | 1 | # Copyright 2009 Canonical Ltd. This software is licensed under the | 2 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
188 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 3 | # GNU Affero General Public License version 3 (see the file LICENSE). |
189 | 3 | 4 | ||
190 | @@ -54,3 +55,53 @@ | |||
191 | 54 | 55 | ||
192 | 55 | class WrongBranchMergeProposal(Exception): | 56 | class WrongBranchMergeProposal(Exception): |
193 | 56 | """The comment requested is not associated with this merge proposal.""" | 57 | """The comment requested is not associated with this merge proposal.""" |
194 | 58 | ======= | ||
195 | 59 | # Copyright 2009 Canonical Ltd. This software is licensed under the | ||
196 | 60 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
197 | 61 | |||
198 | 62 | """Errors used in the lp/code modules.""" | ||
199 | 63 | |||
200 | 64 | __metaclass__ = type | ||
201 | 65 | __all__ = [ | ||
202 | 66 | 'BadBranchMergeProposalSearchContext', | ||
203 | 67 | 'BadStateTransition', | ||
204 | 68 | 'BranchMergeProposalExists', | ||
205 | 69 | 'InvalidBranchMergeProposal', | ||
206 | 70 | 'UserNotBranchReviewer', | ||
207 | 71 | 'WrongBranchMergeProposal', | ||
208 | 72 | ] | ||
209 | 73 | |||
210 | 74 | |||
211 | 75 | class BadBranchMergeProposalSearchContext(Exception): | ||
212 | 76 | """The context is not valid for a branch merge proposal search.""" | ||
213 | 77 | |||
214 | 78 | |||
215 | 79 | class BadStateTransition(Exception): | ||
216 | 80 | """The user requested a state transition that is not possible.""" | ||
217 | 81 | |||
218 | 82 | |||
219 | 83 | class InvalidBranchMergeProposal(Exception): | ||
220 | 84 | """Raised during the creation of a new branch merge proposal. | ||
221 | 85 | |||
222 | 86 | The text of the exception is the rule violation. | ||
223 | 87 | """ | ||
224 | 88 | |||
225 | 89 | |||
226 | 90 | class BranchMergeProposalExists(InvalidBranchMergeProposal): | ||
227 | 91 | """Raised if there is already a matching BranchMergeProposal.""" | ||
228 | 92 | |||
229 | 93 | |||
230 | 94 | class UserNotBranchReviewer(Exception): | ||
231 | 95 | """The user who attempted to review the merge proposal isn't a reviewer. | ||
232 | 96 | |||
233 | 97 | A specific reviewer may be set on a branch. If a specific reviewer | ||
234 | 98 | isn't set then any user in the team of the owner of the branch is | ||
235 | 99 | considered a reviewer. | ||
236 | 100 | """ | ||
237 | 101 | |||
238 | 102 | |||
239 | 103 | class WrongBranchMergeProposal(Exception): | ||
240 | 104 | """The comment requested is not associated with this merge proposal.""" | ||
241 | 105 | |||
242 | 106 | |||
243 | 107 | >>>>>>> MERGE-SOURCE | ||
244 | 57 | 108 | ||
245 | === modified file 'lib/lp/code/model/tests/test_branchmergeproposals.py' | |||
246 | === modified file 'lib/lp/code/templates/branch-import-details.pt' | |||
247 | === modified file 'lib/lp/code/templates/branchmergeproposal-index.pt' | |||
248 | --- lib/lp/code/templates/branchmergeproposal-index.pt 2009-11-26 23:36:50 +0000 | |||
249 | +++ lib/lp/code/templates/branchmergeproposal-index.pt 2009-12-11 13:41:18 +0000 | |||
250 | @@ -21,6 +21,24 @@ | |||
251 | 21 | #commit-message, #edit-commit-message { | 21 | #commit-message, #edit-commit-message { |
252 | 22 | margin: 1em 0 0 0; | 22 | margin: 1em 0 0 0; |
253 | 23 | } | 23 | } |
254 | 24 | #add-comment-form { | ||
255 | 25 | max-width: 60em; | ||
256 | 26 | padding-bottom: 3em; | ||
257 | 27 | } | ||
258 | 28 | #add-comment-form textarea{ | ||
259 | 29 | width: 100%; | ||
260 | 30 | max-width: inherit; | ||
261 | 31 | } | ||
262 | 32 | #add-comment-form .actions { | ||
263 | 33 | float: right; | ||
264 | 34 | margin: 0 -0.5em; | ||
265 | 35 | } | ||
266 | 36 | #add-comment-review-fields { | ||
267 | 37 | margin-top: 1em; | ||
268 | 38 | } | ||
269 | 39 | #add-comment-review-fields div { | ||
270 | 40 | display: inline; | ||
271 | 41 | } | ||
272 | 24 | /* A page-specific fix for inline text are editing to line up box. */ | 42 | /* A page-specific fix for inline text are editing to line up box. */ |
273 | 25 | #edit-commit-message .yui-ieditor-input { top: 0; } | 43 | #edit-commit-message .yui-ieditor-input { top: 0; } |
274 | 26 | </style> | 44 | </style> |
275 | @@ -92,6 +110,12 @@ | |||
276 | 92 | </div> | 110 | </div> |
277 | 93 | 111 | ||
278 | 94 | <div class="yui-g"> | 112 | <div class="yui-g"> |
279 | 113 | <tal:not-logged-in condition="not: view/user"> | ||
280 | 114 | <div align="center" id="add-comment-login-first"> | ||
281 | 115 | To post a comment you must <a href="+login">log in</a>. | ||
282 | 116 | </div> | ||
283 | 117 | </tal:not-logged-in> | ||
284 | 118 | |||
285 | 95 | <div tal:define="link menu/add_comment" | 119 | <div tal:define="link menu/add_comment" |
286 | 96 | tal:condition="link/enabled" | 120 | tal:condition="link/enabled" |
287 | 97 | tal:content="structure link/render"> | 121 | tal:content="structure link/render"> |
288 | @@ -101,20 +125,27 @@ | |||
289 | 101 | <div id="conversation" | 125 | <div id="conversation" |
290 | 102 | tal:content="structure view/conversation/@@+render"/> | 126 | tal:content="structure view/conversation/@@+render"/> |
291 | 103 | </div> | 127 | </div> |
306 | 104 | <!-- Hide inline commenting if YUI isn't used. --> | 128 | |
307 | 105 | <div id="inline-add-comment" style="display: none"> | 129 | <tal:logged-in condition="view/user"> |
308 | 106 | <tal:comment replace="structure context/@@+comment/++form++" /> | 130 | <div tal:define="comment_form nocall:context/@@+comment; |
309 | 107 | <div class="actions" id="launchpad-form-actions"> | 131 | dummy comment_form/initialize"> |
310 | 108 | <input type="submit" id="field.actions.add" name="field.actions.add" value="Save Comment" class="button" /> | 132 | <h2 id="add-comment">Add comment</h2> |
311 | 109 | </div> | 133 | <form action="+comment" |
312 | 110 | </div> | 134 | method="post" |
313 | 111 | 135 | enctype="multipart/form-data" | |
314 | 112 | <script type="text/javascript"> | 136 | accept-charset="UTF-8" |
315 | 113 | LPS.use('lp.comment', function(Y) { | 137 | id="add-comment-form"> |
316 | 114 | var comment = new Y.lp.CodeReviewComment(); | 138 | <tal:comment-input replace="structure comment_form/widgets/comment"/> |
317 | 115 | comment.render(); | 139 | <div id="add-comment-review-fields"> |
318 | 116 | }) | 140 | Review: <tal:review replace="structure comment_form/widgets/vote"/> |
319 | 117 | </script> | 141 | Review type: <tal:review replace="structure comment_form/widgets/review_type"/> |
320 | 142 | <div class="actions" | ||
321 | 143 | tal:content="structure comment_form/actions/field.actions.add/render" /> | ||
322 | 144 | </div> | ||
323 | 145 | </form> | ||
324 | 146 | </div> | ||
325 | 147 | </tal:logged-in> | ||
326 | 148 | |||
327 | 118 | <div class="yui-g"> | 149 | <div class="yui-g"> |
328 | 119 | <div class="yui-u first"> | 150 | <div class="yui-u first"> |
329 | 120 | <div id="source-revisions" | 151 | <div id="source-revisions" |
330 | @@ -159,21 +190,25 @@ | |||
331 | 159 | string:<script id='codereview-script' type='text/javascript'>" /> | 190 | string:<script id='codereview-script' type='text/javascript'>" /> |
332 | 160 | conf = <tal:status-config replace="view/status_config" /> | 191 | conf = <tal:status-config replace="view/status_config" /> |
333 | 161 | <!-- | 192 | <!-- |
335 | 162 | LPS.use('io-base', 'code.codereview', 'code.branchmergeproposal', | 193 | LPS.use('io-base', 'code.codereview', 'code.branchmergeproposal', 'lp.comment', |
336 | 163 | function(Y) { | 194 | function(Y) { |
337 | 164 | 195 | ||
350 | 165 | 196 | Y.on('load', function() { | |
351 | 166 | if(Y.UA.ie) { | 197 | var logged_in = LP.client.links['me'] !== undefined; |
352 | 167 | return; | 198 | |
353 | 168 | } | 199 | if (logged_in) { |
354 | 169 | 200 | var comment = new Y.lp.CodeReviewComment(); | |
355 | 170 | Y.on('domready', function() { | 201 | comment.render(); |
356 | 171 | Y.code.codereview.connect_links(); | 202 | |
357 | 172 | Y.code.branchmergeproposal.connect_status(conf); | 203 | if(Y.UA.ie) { |
358 | 173 | }); | 204 | return; |
359 | 174 | 205 | } | |
360 | 175 | (new Y.codereview.NumberToggle()).render(); | 206 | |
361 | 176 | 207 | Y.code.codereview.connect_links(); | |
362 | 208 | Y.code.branchmergeproposal.connect_status(conf); | ||
363 | 209 | } | ||
364 | 210 | (new Y.codereview.NumberToggle()).render(); | ||
365 | 211 | }, window); | ||
366 | 177 | }); | 212 | }); |
367 | 178 | --> | 213 | --> |
368 | 179 | <tal:script replace="structure string:</script>" /> | 214 | <tal:script replace="structure string:</script>" /> |
369 | 180 | 215 | ||
370 | === modified file 'lib/lp/registry/browser/team.py' | |||
371 | --- lib/lp/registry/browser/team.py 2009-12-01 22:09:05 +0000 | |||
372 | +++ lib/lp/registry/browser/team.py 2009-12-11 13:41:18 +0000 | |||
373 | @@ -901,7 +901,6 @@ | |||
374 | 901 | return None | 901 | return None |
375 | 902 | 902 | ||
376 | 903 | 903 | ||
377 | 904 | |||
378 | 905 | class ProposedTeamMembersEditView(LaunchpadFormView): | 904 | class ProposedTeamMembersEditView(LaunchpadFormView): |
379 | 906 | schema = Interface | 905 | schema = Interface |
380 | 907 | label = 'Proposed team members' | 906 | label = 'Proposed team members' |
381 | @@ -915,7 +914,10 @@ | |||
382 | 915 | status = TeamMembershipStatus.APPROVED | 914 | status = TeamMembershipStatus.APPROVED |
383 | 916 | elif action == "decline": | 915 | elif action == "decline": |
384 | 917 | status = TeamMembershipStatus.DECLINED | 916 | status = TeamMembershipStatus.DECLINED |
386 | 918 | elif action == "hold": | 917 | else: |
387 | 918 | # The action is "hold" or no action was specified for this | ||
388 | 919 | # person, which could happen if the set of proposed members | ||
389 | 920 | # changed while the form was being processed. | ||
390 | 919 | continue | 921 | continue |
391 | 920 | 922 | ||
392 | 921 | self.context.setMembershipData( | 923 | self.context.setMembershipData( |
393 | 922 | 924 | ||
394 | === modified file 'lib/lp/translations/tests/test_translationimportqueue.py' | |||
395 | --- lib/lp/translations/tests/test_translationimportqueue.py 2009-11-19 11:24:43 +0000 | |||
396 | +++ lib/lp/translations/tests/test_translationimportqueue.py 2009-12-11 13:41:18 +0000 | |||
397 | @@ -5,6 +5,7 @@ | |||
398 | 5 | 5 | ||
399 | 6 | __metaclass__ = type | 6 | __metaclass__ = type |
400 | 7 | 7 | ||
401 | 8 | import transaction | ||
402 | 8 | import unittest | 9 | import unittest |
403 | 9 | 10 | ||
404 | 10 | from zope.component import getUtility | 11 | from zope.component import getUtility |
405 | @@ -17,25 +18,27 @@ | |||
406 | 17 | from canonical.testing import LaunchpadZopelessLayer | 18 | from canonical.testing import LaunchpadZopelessLayer |
407 | 18 | 19 | ||
408 | 19 | 20 | ||
411 | 20 | class TestTranslationImportQueueEntryStatus(TestCaseWithFactory): | 21 | class TestCanSetStatusBase(TestCaseWithFactory): |
412 | 21 | """Test handling of the status of a queue entry.""" | 22 | """Base for tests that check that canSetStatus works .""" |
413 | 22 | 23 | ||
414 | 23 | layer = LaunchpadZopelessLayer | 24 | layer = LaunchpadZopelessLayer |
415 | 25 | dbuser = None | ||
416 | 26 | entry = None | ||
417 | 24 | 27 | ||
418 | 25 | def setUp(self): | 28 | def setUp(self): |
419 | 26 | """Set up context to test in.""" | 29 | """Set up context to test in.""" |
421 | 27 | super(TestTranslationImportQueueEntryStatus, self).setUp() | 30 | super(TestCanSetStatusBase, self).setUp() |
422 | 28 | 31 | ||
423 | 29 | self.queue = getUtility(ITranslationImportQueue) | 32 | self.queue = getUtility(ITranslationImportQueue) |
424 | 30 | self.rosetta_experts = ( | 33 | self.rosetta_experts = ( |
425 | 31 | getUtility(ILaunchpadCelebrities).rosetta_experts) | 34 | getUtility(ILaunchpadCelebrities).rosetta_experts) |
426 | 32 | self.productseries = self.factory.makeProductSeries() | 35 | self.productseries = self.factory.makeProductSeries() |
427 | 33 | self.uploaderperson = self.factory.makePerson() | 36 | self.uploaderperson = self.factory.makePerson() |
433 | 34 | self.potemplate = self.factory.makePOTemplate( | 37 | |
434 | 35 | productseries=self.productseries) | 38 | def _switch_dbuser(self): |
435 | 36 | self.entry = self.queue.addOrUpdateEntry( | 39 | if self.dbuser != None: |
436 | 37 | 'demo.pot', '#demo', False, self.uploaderperson, | 40 | transaction.commit() |
437 | 38 | productseries=self.productseries, potemplate=self.potemplate) | 41 | self.layer.switchDbUser(self.dbuser) |
438 | 39 | 42 | ||
439 | 40 | def _assertCanSetStatus(self, user, entry, expected_list): | 43 | def _assertCanSetStatus(self, user, entry, expected_list): |
440 | 41 | # Helper to check for all statuses. | 44 | # Helper to check for all statuses. |
441 | @@ -49,6 +52,7 @@ | |||
442 | 49 | RosettaImportStatus.IMPORTED, | 52 | RosettaImportStatus.IMPORTED, |
443 | 50 | RosettaImportStatus.NEEDS_REVIEW, | 53 | RosettaImportStatus.NEEDS_REVIEW, |
444 | 51 | ] | 54 | ] |
445 | 55 | self._switch_dbuser() | ||
446 | 52 | # Do *not* use assertContentEqual here, as the order matters. | 56 | # Do *not* use assertContentEqual here, as the order matters. |
447 | 53 | self.assertEqual(expected_list, | 57 | self.assertEqual(expected_list, |
448 | 54 | [entry.canSetStatus(status, user) | 58 | [entry.canSetStatus(status, user) |
449 | @@ -71,6 +75,7 @@ | |||
450 | 71 | # If the entry has no import target set, even Rosetta experts | 75 | # If the entry has no import target set, even Rosetta experts |
451 | 72 | # cannot set it to approved. | 76 | # cannot set it to approved. |
452 | 73 | self.entry.potemplate = None | 77 | self.entry.potemplate = None |
453 | 78 | self.entry.pofile = None | ||
454 | 74 | self._assertCanSetStatus(self.rosetta_experts, self.entry, | 79 | self._assertCanSetStatus(self.rosetta_experts, self.entry, |
455 | 75 | # A B D F I NR | 80 | # A B D F I NR |
456 | 76 | [False, True, True, True, True, True]) | 81 | [False, True, True, True, True, True]) |
457 | @@ -115,5 +120,66 @@ | |||
458 | 115 | [False, False, False, False, False, False]) | 120 | [False, False, False, False, False, False]) |
459 | 116 | 121 | ||
460 | 117 | 122 | ||
461 | 123 | class TestCanSetStatusPOTemplate(TestCanSetStatusBase): | ||
462 | 124 | """Test canStatus applied to an entry with a POTemplate.""" | ||
463 | 125 | |||
464 | 126 | def setUp(self): | ||
465 | 127 | """Create the entry to test on.""" | ||
466 | 128 | super(TestCanSetStatusPOTemplate, self).setUp() | ||
467 | 129 | |||
468 | 130 | self.potemplate = self.factory.makePOTemplate( | ||
469 | 131 | productseries=self.productseries) | ||
470 | 132 | self.entry = self.queue.addOrUpdateEntry( | ||
471 | 133 | 'demo.pot', '#demo', False, self.uploaderperson, | ||
472 | 134 | productseries=self.productseries, potemplate=self.potemplate) | ||
473 | 135 | |||
474 | 136 | |||
475 | 137 | class TestCanSetStatusPOFile(TestCanSetStatusBase): | ||
476 | 138 | """Test canStatus applied to an entry with a POFile.""" | ||
477 | 139 | |||
478 | 140 | def setUp(self): | ||
479 | 141 | """Create the entry to test on.""" | ||
480 | 142 | super(TestCanSetStatusPOFile, self).setUp() | ||
481 | 143 | |||
482 | 144 | self.potemplate = self.factory.makePOTemplate( | ||
483 | 145 | productseries=self.productseries) | ||
484 | 146 | self.pofile = self.factory.makePOFile('eo', potemplate=self.potemplate) | ||
485 | 147 | self.entry = self.queue.addOrUpdateEntry( | ||
486 | 148 | 'demo.po', '#demo', False, self.uploaderperson, | ||
487 | 149 | productseries=self.productseries, pofile=self.pofile) | ||
488 | 150 | |||
489 | 151 | |||
490 | 152 | class TestCanSetStatusPOTemplateWithQueuedUser(TestCanSetStatusPOTemplate): | ||
491 | 153 | """Test handling of the status of a queue entry with 'queued' db user. | ||
492 | 154 | |||
493 | 155 | The archive uploader needs to set (and therefore check) the status of a | ||
494 | 156 | queue entry. It connects as a different database user and therefore we | ||
495 | 157 | need to make sure that setStatus stays within this user's permissions. | ||
496 | 158 | This is the version for POTemplate entries. | ||
497 | 159 | """ | ||
498 | 160 | |||
499 | 161 | dbuser = 'queued' | ||
500 | 162 | |||
501 | 163 | |||
502 | 164 | class TestCanSetStatusPOFileWithQueuedUser(TestCanSetStatusPOFile): | ||
503 | 165 | """Test handling of the status of a queue entry with 'queued' db user. | ||
504 | 166 | |||
505 | 167 | The archive uploader needs to set (and therefore check) the status of a | ||
506 | 168 | queue entry. It connects as a different database user and therefore we | ||
507 | 169 | need to make sure that setStatus stays within this user's permissions. | ||
508 | 170 | This is the version for POFile entries. | ||
509 | 171 | """ | ||
510 | 172 | |||
511 | 173 | dbuser = 'queued' | ||
512 | 174 | |||
513 | 175 | |||
514 | 118 | def test_suite(): | 176 | def test_suite(): |
516 | 119 | return unittest.TestLoader().loadTestsFromName(__name__) | 177 | """Add only specific test cases and leave out the base case.""" |
517 | 178 | suite = unittest.TestSuite() | ||
518 | 179 | suite.addTest(unittest.makeSuite(TestCanSetStatusPOTemplate)) | ||
519 | 180 | suite.addTest(unittest.makeSuite(TestCanSetStatusPOFile)) | ||
520 | 181 | suite.addTest( | ||
521 | 182 | unittest.makeSuite(TestCanSetStatusPOTemplateWithQueuedUser)) | ||
522 | 183 | suite.addTest(unittest.makeSuite(TestCanSetStatusPOFileWithQueuedUser)) | ||
523 | 184 | return suite | ||
524 | 185 |
Hi,
This branch fixes a number of failures in the JavaScript unit test suite that
resulted from the YUI 3.0.0 upgrade.
I manually ran all of the unit tests under lib/canonical/ launchpad/ javascript/
to ensure that the features under test still work.
My changes are free of lint. There is one spurious lint error in lp.js.
Maris