Merge lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests into lp:launchpad/db-devel
- bug-495067-move-windmill-tests
- Merge into db-devel
Proposed by
Edwin Grubbs
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
1455 lines (+699/-452) 18 files modified
database/schema/security.cfg (+3/-0) lib/canonical/launchpad/javascript/lp/comment.js (+0/-1) lib/canonical/launchpad/windmill/testing/widgets.py (+5/-3) lib/lp/code/browser/codereviewcomment.py (+4/-3) lib/lp/code/templates/branchmergeproposal-index.pt (+62/-27) lib/lp/registry/browser/product.py (+1/-1) lib/lp/registry/browser/team.py (+4/-2) lib/lp/registry/templates/milestone-index.pt (+2/-2) lib/lp/registry/templates/product-new.pt (+1/-1) lib/lp/registry/windmill/tests/test_add_milestone.py (+86/-87) lib/lp/registry/windmill/tests/test_datetime_picker.py (+70/-52) lib/lp/registry/windmill/tests/test_plusnew_step1.py (+65/-41) lib/lp/registry/windmill/tests/test_plusnew_step2.py (+90/-61) lib/lp/registry/windmill/tests/test_product.py (+43/-21) lib/lp/registry/windmill/tests/test_product_edit_people.py (+38/-17) lib/lp/registry/windmill/tests/test_project_licenses.py (+144/-124) lib/lp/registry/windmill/tests/test_timeline_graph.py (+6/-0) lib/lp/translations/tests/test_translationimportqueue.py (+75/-9) |
To merge this branch: | bzr merge lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | code | Approve | |
Review via email: mp+16057@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote : | # |
Revision history for this message
Curtis Hovey (sinzui) wrote : | # |
This must have been to most boring diff I have ever read.
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 20:25:26 +0000 |
4 | @@ -1216,6 +1216,9 @@ |
5 | public.libraryfilecontent = SELECT, INSERT |
6 | |
7 | # rosetta auto imports |
8 | +public.pofile = SELECT |
9 | +public.potemplate = SELECT |
10 | +public.translationgroup = SELECT |
11 | public.translationimportqueueentry = SELECT, INSERT, UPDATE |
12 | |
13 | # Closing bugs. |
14 | |
15 | === modified file 'lib/canonical/launchpad/javascript/lp/comment.js' |
16 | --- lib/canonical/launchpad/javascript/lp/comment.js 2009-11-26 19:54:52 +0000 |
17 | +++ lib/canonical/launchpad/javascript/lp/comment.js 2009-12-11 20:25:26 +0000 |
18 | @@ -361,7 +361,6 @@ |
19 | }, |
20 | renderUI: function() { |
21 | CodeReviewComment.superclass.renderUI.apply(this); |
22 | - Y.one('#inline-add-comment').setStyle('display', 'block'); |
23 | }, |
24 | /** |
25 | * Implementation of Widget.bindUI: Bind events to methods. |
26 | |
27 | === modified file 'lib/canonical/launchpad/windmill/testing/widgets.py' |
28 | --- lib/canonical/launchpad/windmill/testing/widgets.py 2009-10-29 14:23:16 +0000 |
29 | +++ lib/canonical/launchpad/windmill/testing/widgets.py 2009-12-11 20:25:26 +0000 |
30 | @@ -60,10 +60,10 @@ |
31 | * reloads and verifies that the new value sticked. |
32 | """ |
33 | client = WindmillTestClient(self.suite) |
34 | + client.open(url=self.url) |
35 | |
36 | self.user.ensure_login(client) |
37 | |
38 | - client.open(url=self.url) |
39 | client.waits.forPageLoad(timeout=constants.PAGE_LOAD) |
40 | widget_base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id) |
41 | client.waits.forElement( |
42 | @@ -298,13 +298,15 @@ |
43 | |
44 | def __call__(self): |
45 | client = WindmillTestClient(self.suite) |
46 | - self.user.ensure_login(client) |
47 | |
48 | # Load page. |
49 | client.open(url=self.url) |
50 | - client.waits.forPageLoad(timeout=constants.PAGE_LOAD) |
51 | + |
52 | + self.user.ensure_login(client) |
53 | |
54 | # Click on "Choose" link to show picker for the given field. |
55 | + client.waits.forElement( |
56 | + id=self.choose_link_id, timeout=constants.PAGE_LOAD) |
57 | client.click(id=self.choose_link_id) |
58 | |
59 | # Search picker. |
60 | |
61 | === removed directory 'lib/canonical/launchpad/windmill/tests' |
62 | === removed file 'lib/canonical/launchpad/windmill/tests/__init__.py' |
63 | === removed directory 'lib/canonical/launchpad/windmill/tests/test_registry' |
64 | === removed file 'lib/canonical/launchpad/windmill/tests/test_registry/__init__.py' |
65 | === modified file 'lib/lp/code/browser/codereviewcomment.py' |
66 | --- lib/lp/code/browser/codereviewcomment.py 2009-10-29 23:51:08 +0000 |
67 | +++ lib/lp/code/browser/codereviewcomment.py 2009-12-11 20:25:26 +0000 |
68 | @@ -204,7 +204,7 @@ |
69 | |
70 | class MyDropWidget(DropdownWidget): |
71 | "Override the default no-value display name to -Select-." |
72 | - _messageNoValue = '-Select-' |
73 | + _messageNoValue = 'Comment only' |
74 | |
75 | schema = IEditCodeReviewComment |
76 | |
77 | @@ -251,10 +251,11 @@ |
78 | @action('Save Comment', name='add') |
79 | def add_action(self, action, data): |
80 | """Create the comment...""" |
81 | + vote = data.get('vote') |
82 | + review_type = data.get('review_type') |
83 | comment = self.branch_merge_proposal.createComment( |
84 | self.user, subject=None, content=data['comment'], |
85 | - parent=self.reply_to, vote=data['vote'], |
86 | - review_type=data['review_type']) |
87 | + parent=self.reply_to, vote=vote, review_type=review_type) |
88 | |
89 | @property |
90 | def next_url(self): |
91 | |
92 | === modified file 'lib/lp/code/templates/branchmergeproposal-index.pt' |
93 | --- lib/lp/code/templates/branchmergeproposal-index.pt 2009-11-26 23:36:50 +0000 |
94 | +++ lib/lp/code/templates/branchmergeproposal-index.pt 2009-12-11 20:25:26 +0000 |
95 | @@ -21,6 +21,24 @@ |
96 | #commit-message, #edit-commit-message { |
97 | margin: 1em 0 0 0; |
98 | } |
99 | + #add-comment-form { |
100 | + max-width: 60em; |
101 | + padding-bottom: 3em; |
102 | + } |
103 | + #add-comment-form textarea{ |
104 | + width: 100%; |
105 | + max-width: inherit; |
106 | + } |
107 | + #add-comment-form .actions { |
108 | + float: right; |
109 | + margin: 0 -0.5em; |
110 | + } |
111 | + #add-comment-review-fields { |
112 | + margin-top: 1em; |
113 | + } |
114 | + #add-comment-review-fields div { |
115 | + display: inline; |
116 | + } |
117 | /* A page-specific fix for inline text are editing to line up box. */ |
118 | #edit-commit-message .yui-ieditor-input { top: 0; } |
119 | </style> |
120 | @@ -92,6 +110,12 @@ |
121 | </div> |
122 | |
123 | <div class="yui-g"> |
124 | + <tal:not-logged-in condition="not: view/user"> |
125 | + <div align="center" id="add-comment-login-first"> |
126 | + To post a comment you must <a href="+login">log in</a>. |
127 | + </div> |
128 | + </tal:not-logged-in> |
129 | + |
130 | <div tal:define="link menu/add_comment" |
131 | tal:condition="link/enabled" |
132 | tal:content="structure link/render"> |
133 | @@ -101,20 +125,27 @@ |
134 | <div id="conversation" |
135 | tal:content="structure view/conversation/@@+render"/> |
136 | </div> |
137 | - <!-- Hide inline commenting if YUI isn't used. --> |
138 | - <div id="inline-add-comment" style="display: none"> |
139 | - <tal:comment replace="structure context/@@+comment/++form++" /> |
140 | - <div class="actions" id="launchpad-form-actions"> |
141 | - <input type="submit" id="field.actions.add" name="field.actions.add" value="Save Comment" class="button" /> |
142 | - </div> |
143 | - </div> |
144 | - |
145 | - <script type="text/javascript"> |
146 | - LPS.use('lp.comment', function(Y) { |
147 | - var comment = new Y.lp.CodeReviewComment(); |
148 | - comment.render(); |
149 | - }) |
150 | - </script> |
151 | + |
152 | + <tal:logged-in condition="view/user"> |
153 | + <div tal:define="comment_form nocall:context/@@+comment; |
154 | + dummy comment_form/initialize"> |
155 | + <h2 id="add-comment">Add comment</h2> |
156 | + <form action="+comment" |
157 | + method="post" |
158 | + enctype="multipart/form-data" |
159 | + accept-charset="UTF-8" |
160 | + id="add-comment-form"> |
161 | + <tal:comment-input replace="structure comment_form/widgets/comment"/> |
162 | + <div id="add-comment-review-fields"> |
163 | + Review: <tal:review replace="structure comment_form/widgets/vote"/> |
164 | + Review type: <tal:review replace="structure comment_form/widgets/review_type"/> |
165 | + <div class="actions" |
166 | + tal:content="structure comment_form/actions/field.actions.add/render" /> |
167 | + </div> |
168 | + </form> |
169 | + </div> |
170 | + </tal:logged-in> |
171 | + |
172 | <div class="yui-g"> |
173 | <div class="yui-u first"> |
174 | <div id="source-revisions" |
175 | @@ -159,21 +190,25 @@ |
176 | string:<script id='codereview-script' type='text/javascript'>" /> |
177 | conf = <tal:status-config replace="view/status_config" /> |
178 | <!-- |
179 | - LPS.use('io-base', 'code.codereview', 'code.branchmergeproposal', |
180 | + LPS.use('io-base', 'code.codereview', 'code.branchmergeproposal', 'lp.comment', |
181 | function(Y) { |
182 | |
183 | - |
184 | - if(Y.UA.ie) { |
185 | - return; |
186 | - } |
187 | - |
188 | - Y.on('domready', function() { |
189 | - Y.code.codereview.connect_links(); |
190 | - Y.code.branchmergeproposal.connect_status(conf); |
191 | - }); |
192 | - |
193 | - (new Y.codereview.NumberToggle()).render(); |
194 | - |
195 | + Y.on('load', function() { |
196 | + var logged_in = LP.client.links['me'] !== undefined; |
197 | + |
198 | + if (logged_in) { |
199 | + var comment = new Y.lp.CodeReviewComment(); |
200 | + comment.render(); |
201 | + |
202 | + if(Y.UA.ie) { |
203 | + return; |
204 | + } |
205 | + |
206 | + Y.code.codereview.connect_links(); |
207 | + Y.code.branchmergeproposal.connect_status(conf); |
208 | + } |
209 | + (new Y.codereview.NumberToggle()).render(); |
210 | + }, window); |
211 | }); |
212 | --> |
213 | <tal:script replace="structure string:</script>" /> |
214 | |
215 | === modified file 'lib/lp/registry/browser/product.py' |
216 | --- lib/lp/registry/browser/product.py 2009-12-05 18:37:28 +0000 |
217 | +++ lib/lp/registry/browser/product.py 2009-12-11 20:25:26 +0000 |
218 | @@ -778,7 +778,7 @@ |
219 | **additional_arguments) |
220 | self.show_programming_languages = bool( |
221 | self.context.programminglang or |
222 | - self.user == self.context.owner) |
223 | + check_permission('launchpad.Edit', self.context)) |
224 | |
225 | @property |
226 | def show_license_status(self): |
227 | |
228 | === modified file 'lib/lp/registry/browser/team.py' |
229 | --- lib/lp/registry/browser/team.py 2009-12-01 22:09:05 +0000 |
230 | +++ lib/lp/registry/browser/team.py 2009-12-11 20:25:26 +0000 |
231 | @@ -901,7 +901,6 @@ |
232 | return None |
233 | |
234 | |
235 | - |
236 | class ProposedTeamMembersEditView(LaunchpadFormView): |
237 | schema = Interface |
238 | label = 'Proposed team members' |
239 | @@ -915,7 +914,10 @@ |
240 | status = TeamMembershipStatus.APPROVED |
241 | elif action == "decline": |
242 | status = TeamMembershipStatus.DECLINED |
243 | - elif action == "hold": |
244 | + else: |
245 | + # The action is "hold" or no action was specified for this |
246 | + # person, which could happen if the set of proposed members |
247 | + # changed while the form was being processed. |
248 | continue |
249 | |
250 | self.context.setMembershipData( |
251 | |
252 | === modified file 'lib/lp/registry/templates/milestone-index.pt' |
253 | --- lib/lp/registry/templates/milestone-index.pt 2009-11-15 19:37:56 +0000 |
254 | +++ lib/lp/registry/templates/milestone-index.pt 2009-12-11 20:25:26 +0000 |
255 | @@ -53,12 +53,12 @@ |
256 | tal:condition="view/milestone/series_target" /></dd> |
257 | </dl> |
258 | |
259 | - <dl> |
260 | + <dl id="version"> |
261 | <dt>Version:</dt> |
262 | <dd><tal:version replace="context/name" /></dd> |
263 | </dl> |
264 | |
265 | - <dl> |
266 | + <dl id="code-name"> |
267 | <dt>Code name:</dt> |
268 | <dd> |
269 | <tal:code-name replace="view/milestone/code_name" /> |
270 | |
271 | === modified file 'lib/lp/registry/templates/product-new.pt' |
272 | --- lib/lp/registry/templates/product-new.pt 2009-12-03 18:33:22 +0000 |
273 | +++ lib/lp/registry/templates/product-new.pt 2009-12-11 20:25:26 +0000 |
274 | @@ -100,7 +100,7 @@ |
275 | url_field.on('keyup', function(e) { |
276 | if (url_field.get('value') == '') { |
277 | /* The user cleared the URL field; turn on autofill. */ |
278 | - name_field.attach('keyup', autofill); |
279 | + name_field.on('keyup', autofill); |
280 | } |
281 | else { |
282 | /* Honor the user's URL; turn off autofill. */ |
283 | |
284 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_add_milestone.py' => 'lib/lp/registry/windmill/tests/test_add_milestone.py' |
285 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_add_milestone.py 2009-06-25 05:30:52 +0000 |
286 | +++ lib/lp/registry/windmill/tests/test_add_milestone.py 2009-12-11 20:25:26 +0000 |
287 | @@ -7,95 +7,94 @@ |
288 | __all__ = [] |
289 | |
290 | import time |
291 | +import unittest |
292 | |
293 | from canonical.launchpad.windmill.testing import lpuser |
294 | |
295 | from windmill.authoring import WindmillTestClient |
296 | |
297 | - |
298 | -class InlineAddMilestoneForReleaseTest: |
299 | - """Test adding a milestone inline.""" |
300 | - |
301 | - def __init__(self, name=None, |
302 | - url='http://launchpad.dev:8085/bzr/trunk/+addrelease', |
303 | - suite='milestone', user=lpuser.FOO_BAR): |
304 | - """Create a new InlineAddMilestoneForReleaseTest. |
305 | - |
306 | - :param name: Name of the test. |
307 | - :param url: Starting url. |
308 | - :param suite: The suite in which this test is part of. |
309 | - :param user: The user who should be logged in. |
310 | - """ |
311 | - self.url = url |
312 | - if name is None: |
313 | - self.__name__ = 'test_%s_add_milestone' % suite |
314 | - else: |
315 | - self.__name__ = name |
316 | - self.suite = suite |
317 | - self.user = user |
318 | - self.client = None |
319 | - |
320 | - def __call__(self): |
321 | - """Tests creating new milestone for a release.""" |
322 | - # Ensure that the milestone name doesn't conflict with previous |
323 | - # test runs, and test that it correctly lowercases the name. |
324 | - milestone_name = u'FOObar%x' % int(time.time()) |
325 | - code_name = u'code-%s' % milestone_name |
326 | - |
327 | - self.client = WindmillTestClient(self.suite) |
328 | - |
329 | - self.user.ensure_login(self.client) |
330 | - self.client.open(url=self.url) |
331 | - self.client.waits.forPageLoad(timeout=u'20000') |
332 | - |
333 | - self.client.waits.forElement(id=u'field.milestone_for_release', |
334 | - timeout=u'8000') |
335 | - |
336 | - # Click the "Create milestone" link. |
337 | - self.client.click(id=u'create-milestone-link') |
338 | - |
339 | - # Submit milestone form. |
340 | - self.client.waits.forElement(id=u'field.name', timeout=u'8000') |
341 | - self.client.type(id='field.name', text=milestone_name) |
342 | - self.client.type(id='field.code_name', text=code_name) |
343 | - self.client.type(id='field.dateexpected', text=u"2004-01-05") |
344 | - self.client.type(id='field.summary', text=u"foo bar") |
345 | - self.client.click(id=u'formoverlay-add-milestone') |
346 | - |
347 | - # Verify that the milestone was added to the SELECT input, |
348 | - # and that it is now selected. |
349 | - self.client.waits.sleep(milliseconds='1000') |
350 | - self.client.asserts.assertSelected(id="field.milestone_for_release", |
351 | - validator=milestone_name.lower()) |
352 | - |
353 | - # Verify error message when trying to create a milestone with a |
354 | - # conflicting name. |
355 | - self.client.click(id=u'create-milestone-link') |
356 | - self.client.waits.forElement(id=u'field.name', timeout=u'8000') |
357 | - self.client.type(id='field.name', text=milestone_name) |
358 | - self.client.click(id=u'formoverlay-add-milestone') |
359 | - self.client.asserts.assertText( |
360 | - id='milestone-error', |
361 | - validator='The name %s is already used' % milestone_name.lower()) |
362 | - self.client.click(classname='close-button') |
363 | - |
364 | - # Submit product release form. |
365 | - self.client.select(id='field.milestone_for_release', |
366 | - val=milestone_name.lower()) |
367 | - self.client.type(id='field.datereleased', text=u"2004-02-22") |
368 | - self.client.click(id=u'field.actions.create') |
369 | - self.client.waits.forPageLoad(timeout=u'20000') |
370 | - |
371 | - # Verify that the release was created. |
372 | - milestone_xpath = ( |
373 | - "//table[@id='series_trunk']//a[@href='/bzr/+milestone/%s']" |
374 | - % milestone_name.lower()) |
375 | - self.client.waits.forElement(xpath=milestone_xpath, timeout=u'8000') |
376 | - self.client.asserts.assertText( |
377 | - xpath=milestone_xpath, validator=milestone_name.lower()) |
378 | - self.client.asserts.assertText( |
379 | - xpath=milestone_xpath, validator=code_name) |
380 | - |
381 | - |
382 | -test_inline_add_milestone_for_release = InlineAddMilestoneForReleaseTest( |
383 | - name='test_inline_add_milestone_for_release') |
384 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
385 | +from lp.testing import TestCaseWithFactory |
386 | + |
387 | + |
388 | +def test_inline_add_milestone(client, url, name=None, suite='milestone', |
389 | + user=lpuser.FOO_BAR): |
390 | + """Test the form overlay for adding a milestone. |
391 | + |
392 | + :param name: Name of the test. |
393 | + :param url: Starting url. |
394 | + :param suite: The suite in which this test is part of. |
395 | + :param user: The user who should be logged in. |
396 | + """ |
397 | + # Ensure that the milestone name doesn't conflict with previous |
398 | + # test runs, and test that it correctly lowercases the name. |
399 | + milestone_name = u'FOObar%x' % int(time.time()) |
400 | + code_name = u'code-%s' % milestone_name |
401 | + |
402 | + user.ensure_login(client) |
403 | + client.open(url=url) |
404 | + client.waits.forPageLoad(timeout=u'20000') |
405 | + |
406 | + client.waits.forElement( |
407 | + id=u'field.milestone_for_release', timeout=u'8000') |
408 | + |
409 | + # Click the "Create milestone" link. |
410 | + client.click(id=u'create-milestone-link') |
411 | + |
412 | + # Submit milestone form. |
413 | + client.waits.forElement(id=u'field.name', timeout=u'8000') |
414 | + client.type(id='field.name', text=milestone_name) |
415 | + client.type(id='field.code_name', text=code_name) |
416 | + client.type(id='field.dateexpected', text=u"2004-01-05") |
417 | + client.type(id='field.summary', text=u"foo bar") |
418 | + client.click(id=u'formoverlay-add-milestone') |
419 | + |
420 | + # Verify that the milestone was added to the SELECT input, |
421 | + # and that it is now selected. |
422 | + client.waits.sleep(milliseconds='1000') |
423 | + client.asserts.assertSelected(id="field.milestone_for_release", |
424 | + validator=milestone_name.lower()) |
425 | + |
426 | + # Verify error message when trying to create a milestone with a |
427 | + # conflicting name. |
428 | + client.click(id=u'create-milestone-link') |
429 | + client.waits.forElement(id=u'field.name', timeout=u'8000') |
430 | + client.type(id='field.name', text=milestone_name) |
431 | + client.click(id=u'formoverlay-add-milestone') |
432 | + client.asserts.assertTextIn( |
433 | + classname='yui-lazr-formoverlay-errors', |
434 | + validator='The name %s is already used' % milestone_name.lower()) |
435 | + client.click(classname='close-button') |
436 | + |
437 | + # Submit product release form. |
438 | + client.select(id='field.milestone_for_release', |
439 | + val=milestone_name.lower()) |
440 | + client.type(id='field.datereleased', text=u"2004-02-22") |
441 | + client.click(id=u'field.actions.create') |
442 | + client.waits.forPageLoad(timeout=u'20000') |
443 | + |
444 | + # Verify that the release was created. |
445 | + client.waits.forElement(id="version") |
446 | + client.asserts.assertText( |
447 | + xpath="//*[@id='version']/dd", validator=milestone_name.lower()) |
448 | + client.asserts.assertText( |
449 | + xpath="//*[@id='code-name']/dd", validator=code_name) |
450 | + |
451 | + |
452 | +class TestAddMilestone(TestCaseWithFactory): |
453 | + """Test form overlay widget for adding a milestone.""" |
454 | + |
455 | + layer = RegistryWindmillLayer |
456 | + |
457 | + def setUp(self): |
458 | + self.client = WindmillTestClient('AddMilestone') |
459 | + |
460 | + def test_adding_milestone_on_addrelease_page(self): |
461 | + test_inline_add_milestone( |
462 | + self.client, |
463 | + url='http://launchpad.dev:8085/bzr/trunk/+addrelease', |
464 | + name='test_inline_add_milestone_for_release') |
465 | + |
466 | + |
467 | +def test_suite(): |
468 | + return unittest.TestLoader().loadTestsFromName(__name__) |
469 | |
470 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_datetime_picker.py' => 'lib/lp/registry/windmill/tests/test_datetime_picker.py' |
471 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_datetime_picker.py 2009-06-25 05:30:52 +0000 |
472 | +++ lib/lp/registry/windmill/tests/test_datetime_picker.py 2009-12-11 20:25:26 +0000 |
473 | @@ -6,57 +6,75 @@ |
474 | __metaclass__ = type |
475 | __all__ = [] |
476 | |
477 | +import unittest |
478 | + |
479 | +from windmill.authoring import WindmillTestClient |
480 | + |
481 | from canonical.launchpad.windmill.testing import lpuser |
482 | |
483 | -from windmill.authoring import WindmillTestClient |
484 | - |
485 | -def test_datetime_calendar_widget(): |
486 | - """Test the calendar widget's general functionality. |
487 | - |
488 | - This test ensures that, with Javascript enabled, an input field |
489 | - with the 'yui-calendar' class will get an extra 'choose...' link |
490 | - which opens up a calendar widget. The extra class 'withtime' is |
491 | - used to optionally include time fields. |
492 | - """ |
493 | - client = WindmillTestClient("Datetime calendar widget test") |
494 | - lpuser.SAMPLE_PERSON.ensure_login(client) |
495 | - |
496 | - # Open a new sprint page and wait for it to finish loading. |
497 | - client.open(url=u'http://blueprints.launchpad.dev:8085/sprints/+new') |
498 | - client.waits.forPageLoad(timeout=u'20000') |
499 | - client.waits.forElement(link=u'Choose...', timeout=u'8000') |
500 | - |
501 | - # Enter a date directly in the field first (which will ensure |
502 | - # the calendar widget opens with this date.) |
503 | - client.click(id=u'field.time_starts') |
504 | - client.type(text=u'2009-05-08 10:04', id=u'field.time_starts') |
505 | - |
506 | - # Open the calendar widget |
507 | - client.click(link=u'Choose...') |
508 | - |
509 | - # Initially choose the 21st of May 2009 and verify that the input |
510 | - # field's value has changed. |
511 | - client.click(link=u'21') |
512 | - client.asserts.assertValue(validator=u'2009-05-21 10:04', |
513 | - id=u'field.time_starts') |
514 | - |
515 | - # Navigate to the next month, select the 9th, enter a time of 10:30 |
516 | - # and click the close/confirm button, then verify the correct value |
517 | - # is in the field. |
518 | - client.click(link=u'Next Month (June 2009)') |
519 | - client.click(link=u'9') |
520 | - client.type( |
521 | - xpath=(u"//div[@id='calendar_container-field.time_starts']" |
522 | - u"/div[2]/input"), |
523 | - text=u'10') |
524 | - |
525 | - client.type( |
526 | - xpath=(u"//div[@id='calendar_container-field.time_starts']" |
527 | - u"/div[2]/input[2]"), |
528 | - text=u'30') |
529 | - |
530 | - client.click(xpath=(u"//div[@id='calendar_container-field.time_starts']" |
531 | - u"/div[2]/button")) |
532 | - client.asserts.assertValue(validator=u'2009-06-09 10:30', |
533 | - id=u'field.time_starts') |
534 | - |
535 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
536 | +from lp.testing import TestCaseWithFactory |
537 | + |
538 | + |
539 | +class TestDateTimeCalendarWidget(TestCaseWithFactory): |
540 | + """Test datetime calendar widget.""" |
541 | + |
542 | + layer = RegistryWindmillLayer |
543 | + |
544 | + def setUp(self): |
545 | + self.client = WindmillTestClient('DateTimeCalendarWidget') |
546 | + |
547 | + def test_datetime_calendar_widget(self): |
548 | + """Test the calendar widget's general functionality. |
549 | + |
550 | + This test ensures that, with Javascript enabled, an input field |
551 | + with the 'yui-calendar' class will get an extra 'choose...' link |
552 | + which opens up a calendar widget. The extra class 'withtime' is |
553 | + used to optionally include time fields. |
554 | + """ |
555 | + lpuser.SAMPLE_PERSON.ensure_login(self.client) |
556 | + |
557 | + # Open a new sprint page and wait for it to finish loading. |
558 | + self.client.open( |
559 | + url=u'http://blueprints.launchpad.dev:8085/sprints/+new') |
560 | + self.client.waits.forPageLoad(timeout=u'20000') |
561 | + self.client.waits.forElement(link=u'Choose...', timeout=u'8000') |
562 | + |
563 | + # Enter a date directly in the field first (which will ensure |
564 | + # the calendar widget opens with this date.) |
565 | + self.client.click(id=u'field.time_starts') |
566 | + self.client.type(text=u'2009-05-08 10:04', id=u'field.time_starts') |
567 | + |
568 | + # Open the calendar widget |
569 | + self.client.click(link=u'Choose...') |
570 | + |
571 | + # Initially choose the 21st of May 2009 and verify that the input |
572 | + # field's value has changed. |
573 | + self.client.click(link=u'21') |
574 | + self.client.asserts.assertValue( |
575 | + validator=u'2009-05-21 10:04', id=u'field.time_starts') |
576 | + |
577 | + # Navigate to the next month, select the 9th, enter a time of 10:30 |
578 | + # and click the close/confirm button, then verify the correct value |
579 | + # is in the field. |
580 | + self.client.click(link=u'Next Month (June 2009)') |
581 | + self.client.click(link=u'9') |
582 | + self.client.type( |
583 | + xpath=(u"//div[@id='calendar_container-field.time_starts']" |
584 | + u"/div[2]/input"), |
585 | + text=u'10') |
586 | + |
587 | + self.client.type( |
588 | + xpath=(u"//div[@id='calendar_container-field.time_starts']" |
589 | + u"/div[2]/input[2]"), |
590 | + text=u'30') |
591 | + |
592 | + self.client.click( |
593 | + xpath=(u"//div[@id='calendar_container-field.time_starts']" |
594 | + u"/div[2]/button")) |
595 | + self.client.asserts.assertValue( |
596 | + validator=u'2009-06-09 10:30', id=u'field.time_starts') |
597 | + |
598 | + |
599 | +def test_suite(): |
600 | + return unittest.TestLoader().loadTestsFromName(__name__) |
601 | |
602 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step1.py' => 'lib/lp/registry/windmill/tests/test_plusnew_step1.py' |
603 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step1.py 2009-06-25 05:30:52 +0000 |
604 | +++ lib/lp/registry/windmill/tests/test_plusnew_step1.py 2009-12-11 20:25:26 +0000 |
605 | @@ -1,48 +1,72 @@ |
606 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
607 | # GNU Affero General Public License version 3 (see the file LICENSE). |
608 | |
609 | +"""Test form for creating a new project.""" |
610 | + |
611 | +__metaclass__ = type |
612 | +__all__ = [] |
613 | + |
614 | +import unittest |
615 | + |
616 | from windmill.authoring import WindmillTestClient |
617 | |
618 | from canonical.launchpad.windmill.testing import lpuser |
619 | |
620 | - |
621 | -def test_projects_plusnew_text_fields(): |
622 | - """Test the text fields on step 1 of projects/+new page. |
623 | - |
624 | - On step 1 of the wizard, the URL field gets autofilled from the Name |
625 | - field. Also, the URL field will not accept invalid characters. |
626 | - """ |
627 | - client = WindmillTestClient('projects/+new step one dynamism') |
628 | - lpuser.SAMPLE_PERSON.ensure_login(client) |
629 | - |
630 | - # Perform step 1 of the project registration, using information that will |
631 | - # yield search results. |
632 | - client.open(url=u'http://launchpad.dev:8085/projects/+new') |
633 | - client.waits.forPageLoad(timeout=u'20000') |
634 | - |
635 | - client.type(text=u'dolphin', id='field.displayname') |
636 | - # The field is forced to lower case by a CSS text-transform, but that's |
637 | - # presentation and not testable. However, the field /is/ autofilled from |
638 | - # the displayname field, and this we can test. |
639 | - client.asserts.assertValue( |
640 | - id=u'field.name', |
641 | - validator=u'dolphin') |
642 | - # If we type into the Name field something that contains some trailing |
643 | - # invalid characters, they don't end up in the URL field. |
644 | - client.type(text=u'dol@phin', id='field.displayname') |
645 | - client.asserts.assertValue( |
646 | - id=u'field.name', |
647 | - validator=u'dol') |
648 | - # Typing directly into the URL field prevents the autofilling. |
649 | - client.type(text=u'mongoose', id='field.name') |
650 | - client.type(text=u'dingo', id='field.displayname') |
651 | - client.asserts.assertValue( |
652 | - id=u'field.name', |
653 | - validator=u'mongoose') |
654 | - # But once we clear the URL field, autofilling is re-enabled. Type a |
655 | - # backspace character to trigger this. |
656 | - client.type(text=u'\x08', id='field.name') |
657 | - client.type(text='hyena', id='field.displayname') |
658 | - client.asserts.assertValue( |
659 | - id=u'field.name', |
660 | - validator=u'hyena') |
661 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
662 | +from lp.testing import TestCaseWithFactory |
663 | + |
664 | +BACKSPACE = u'\x08' |
665 | + |
666 | + |
667 | +class TestNewProjectStep1(TestCaseWithFactory): |
668 | + """Test form for creating a new project.""" |
669 | + |
670 | + layer = RegistryWindmillLayer |
671 | + |
672 | + def setUp(self): |
673 | + self.client = WindmillTestClient('TestNewProjectStep1') |
674 | + |
675 | + def test_projects_plusnew_text_fields(self): |
676 | + """Test the text fields on step 1 of projects/+new page. |
677 | + |
678 | + On step 1 of the wizard, the URL field gets autofilled from the Name |
679 | + field. Also, the URL field will not accept invalid characters. |
680 | + """ |
681 | + # Perform step 1 of the project registration, using information |
682 | + # that will yield search results. |
683 | + self.client.open(url=u'http://launchpad.dev:8085/projects/+new') |
684 | + |
685 | + lpuser.SAMPLE_PERSON.ensure_login(self.client) |
686 | + |
687 | + self.client.waits.forElement(id='field.displayname') |
688 | + self.client.type(text=u'dolphin', id='field.displayname') |
689 | + |
690 | + # The field is forced to lower case by a CSS text-transform, but |
691 | + # that's presentation and not testable. However, the field /is/ |
692 | + # autofilled from the displayname field, and this we can test. |
693 | + self.client.asserts.assertValue( |
694 | + id=u'field.name', |
695 | + validator=u'dolphin') |
696 | + # If we type into the Name field something that contains some trailing |
697 | + # invalid characters, they don't end up in the URL field. |
698 | + self.client.type(text=u'dol@phin', id='field.displayname') |
699 | + self.client.asserts.assertValue( |
700 | + id=u'field.name', |
701 | + validator=u'dol') |
702 | + # Typing directly into the URL field prevents the autofilling. |
703 | + self.client.type(text=u'mongoose', id='field.name') |
704 | + self.client.type(text=u'dingo', id='field.displayname') |
705 | + self.client.asserts.assertValue( |
706 | + id=u'field.name', |
707 | + validator=u'mongoose') |
708 | + # But once we clear the URL field, autofilling is re-enabled. Type a |
709 | + # backspace character to trigger this. |
710 | + self.client.type(text=BACKSPACE, id='field.name') |
711 | + self.client.type(text='hyena', id='field.displayname') |
712 | + self.client.asserts.assertValue( |
713 | + id=u'field.name', |
714 | + validator=u'hyena') |
715 | + |
716 | + |
717 | +def test_suite(): |
718 | + return unittest.TestLoader().loadTestsFromName(__name__) |
719 | |
720 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step2.py' => 'lib/lp/registry/windmill/tests/test_plusnew_step2.py' |
721 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_plusnew_step2.py 2009-07-21 17:14:29 +0000 |
722 | +++ lib/lp/registry/windmill/tests/test_plusnew_step2.py 2009-12-11 20:25:26 +0000 |
723 | @@ -1,68 +1,97 @@ |
724 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
725 | # GNU Affero General Public License version 3 (see the file LICENSE). |
726 | |
727 | +"""Test for form for creating a project.""" |
728 | + |
729 | +__metaclass__ = type |
730 | +__all__ = [] |
731 | + |
732 | +import unittest |
733 | + |
734 | from windmill.authoring import WindmillTestClient |
735 | |
736 | from canonical.launchpad.windmill.testing import lpuser |
737 | |
738 | - |
739 | -def test_projects_plusnew_step_two(): |
740 | - """Test the dynamic aspects of step 2 of projects/+new page. |
741 | - |
742 | - When the project being registered matches existing projects, the step two |
743 | - page has some extra javascript-y goodness. At the start, there's a 'No' |
744 | - button that hides the search results and reveals the rest of the project |
745 | - registration form. After that, there's a href that toggles between |
746 | - revealing the search results and hiding them. |
747 | - """ |
748 | - client = WindmillTestClient('projects/+new step two dynamism') |
749 | - lpuser.SAMPLE_PERSON.ensure_login(client) |
750 | - |
751 | - # Perform step 1 of the project registration, using information that will |
752 | - # yield search results. |
753 | - client.open(url=u'http://launchpad.dev:8085/projects/+new') |
754 | - client.waits.forPageLoad(timeout=u'20000') |
755 | - |
756 | - client.type(text=u'Badgers', id='field.displayname') |
757 | - client.type(text=u'badgers', id='field.name') |
758 | - client.type(text=u"There's the Badger", id='field.title') |
759 | - client.type(text=u'Badgers ate my firefox', id='field.summary') |
760 | - client.click(id=u'field.actions.continue') |
761 | - client.waits.forPageLoad(timeout=u'20000') |
762 | - # The h2 heading indicates that a search was performed. |
763 | - client.asserts.assertText( |
764 | - id=u'step-title', |
765 | - validator=u'Check for duplicate projects') |
766 | - # Clicking on the "No" button hides the button and search results, reveals |
767 | - # the form widgets, and reveals an href link for toggling the search |
768 | - # results. It also changes the h2 title to something more appropriate. |
769 | - client.click(id=u'registration-details-buttons') |
770 | - client.asserts.assertText( |
771 | - id=u'step-title', |
772 | - validator=u'Registration details') |
773 | - # The className for hidden elements is lazr-closed because it's set by |
774 | - # the slide-in effect. For slide-out elements, it's lazr-opened. |
775 | - client.asserts.assertProperty( |
776 | - id='search-results', validator='className|lazr-closed') |
777 | - client.asserts.assertProperty( |
778 | - id=u'launchpad-form-widgets', |
779 | - validator='className|lazr-opened') |
780 | - client.asserts.assertNotProperty( |
781 | - id=u'search-results-expander', |
782 | - validator='className|unseen') |
783 | - # Clicking on the href expands the search results. |
784 | - client.click(id='search-results-expander') |
785 | - client.waits.forElement( |
786 | - xpath='//*[@id="search-results" and contains(@class, "lazr-opened")]', |
787 | - milliseconds=u'1000') |
788 | - client.asserts.assertProperty( |
789 | - id=u'search-results', |
790 | - validator='className|lazr-opened') |
791 | - # Clicking it again hides the results. |
792 | - client.click(id='search-results-expander') |
793 | - client.waits.forElement( |
794 | - xpath='//*[@id="search-results" and contains(@class, "lazr-closed")]', |
795 | - milliseconds=u'1000') |
796 | - client.asserts.assertProperty( |
797 | - id=u'search-results', |
798 | - validator='className|lazr-closed') |
799 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
800 | +from lp.testing import TestCaseWithFactory |
801 | + |
802 | + |
803 | +class TestNewProjectStep2(TestCaseWithFactory): |
804 | + """Test form for creating a new project.""" |
805 | + |
806 | + layer = RegistryWindmillLayer |
807 | + |
808 | + def setUp(self): |
809 | + self.client = WindmillTestClient('TestNewProjectStep2') |
810 | + |
811 | + def test_projects_plusnew_step_two(self): |
812 | + """Test the dynamic aspects of step 2 of projects/+new page. |
813 | + |
814 | + When the project being registered matches existing projects, the |
815 | + step two page has some extra javascript-y goodness. At the |
816 | + start, there's a 'No' button that hides the search results and |
817 | + reveals the rest of the project registration form. After that, |
818 | + there's a href that toggles between revealing the search results |
819 | + and hiding them. |
820 | + """ |
821 | + |
822 | + # Perform step 1 of the project registration, using information |
823 | + # that will yield search results. |
824 | + self.client.open(url=u'http://launchpad.dev:8085/projects/+new') |
825 | + |
826 | + lpuser.SAMPLE_PERSON.ensure_login(self.client) |
827 | + |
828 | + self.client.waits.forElement(id='field.displayname', timeout=u'20000') |
829 | + self.client.type(text=u'Badgers', id='field.displayname') |
830 | + self.client.type(text=u'badgers', id='field.name') |
831 | + self.client.type(text=u"There's the Badger", id='field.title') |
832 | + self.client.type(text=u'Badgers ate my firefox', id='field.summary') |
833 | + self.client.click(id=u'field.actions.continue') |
834 | + self.client.waits.forPageLoad(timeout=u'20000') |
835 | + # The h2 heading indicates that a search was performed. |
836 | + self.client.asserts.assertTextIn( |
837 | + id=u'step-title', |
838 | + validator=u'Check for duplicate projects') |
839 | + |
840 | + # Clicking on the "No" button hides the button and search |
841 | + # results, reveals the form widgets, and reveals an href link |
842 | + # for toggling the search results. It also changes the h2 title |
843 | + # to something more appropriate. |
844 | + self.client.click(id=u'registration-details-buttons') |
845 | + self.client.asserts.assertTextIn( |
846 | + id=u'step-title', |
847 | + validator=u'Registration details') |
848 | + |
849 | + # The className for hidden elements is lazr-closed because it's |
850 | + # set by the slide-in effect. For slide-out elements, it's |
851 | + # lazr-opened. |
852 | + self.client.asserts.assertProperty( |
853 | + id='search-results', validator='className|lazr-closed') |
854 | + self.client.asserts.assertProperty( |
855 | + id=u'launchpad-form-widgets', |
856 | + validator='className|lazr-opened') |
857 | + self.client.asserts.assertNotProperty( |
858 | + id=u'search-results-expander', |
859 | + validator='className|unseen') |
860 | + # Clicking on the href expands the search results. |
861 | + self.client.click(id='search-results-expander') |
862 | + self.client.waits.forElement( |
863 | + xpath='//*[@id="search-results" ' |
864 | + 'and contains(@class, "lazr-opened")]', |
865 | + milliseconds=u'1000') |
866 | + self.client.asserts.assertProperty( |
867 | + id=u'search-results', |
868 | + validator='className|lazr-opened') |
869 | + # Clicking it again hides the results. |
870 | + self.client.click(id='search-results-expander') |
871 | + self.client.waits.forElement( |
872 | + xpath='//*[@id="search-results" ' |
873 | + 'and contains(@class, "lazr-closed")]', |
874 | + milliseconds=u'1000') |
875 | + self.client.asserts.assertProperty( |
876 | + id=u'search-results', |
877 | + validator='className|lazr-closed') |
878 | + |
879 | + |
880 | +def test_suite(): |
881 | + return unittest.TestLoader().loadTestsFromName(__name__) |
882 | |
883 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_product.py' => 'lib/lp/registry/windmill/tests/test_product.py' |
884 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_product.py 2009-07-17 00:26:05 +0000 |
885 | +++ lib/lp/registry/windmill/tests/test_product.py 2009-12-11 20:25:26 +0000 |
886 | @@ -1,24 +1,46 @@ |
887 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
888 | # GNU Affero General Public License version 3 (see the file LICENSE). |
889 | |
890 | -from canonical.launchpad.windmill.testing import lpuser |
891 | -from canonical.launchpad.windmill.testing import widgets |
892 | - |
893 | -test_title_inline_edit = widgets.InlineEditorWidgetTest( |
894 | - url='http://launchpad.dev:8085/firefox', |
895 | - widget_id='product-title', |
896 | - expected_value='Mozilla Firefox', |
897 | - new_value='The awesome Mozilla Firefox', |
898 | - name='test_title_inline_edit', |
899 | - suite=__name__, |
900 | - user=lpuser.SAMPLE_PERSON) |
901 | - |
902 | -test_programming_languages_edit = widgets.InlineEditorWidgetTest( |
903 | - url='http://launchpad.dev:8085/firefox', |
904 | - widget_id='programminglang', |
905 | - widget_tag='span', |
906 | - expected_value='Not yet specified', |
907 | - new_value='C++', |
908 | - name='test_proglang_inline_edit', |
909 | - suite=__name__, |
910 | - user=lpuser.SAMPLE_PERSON) |
911 | +"""Test product index page.""" |
912 | + |
913 | +__metaclass__ = type |
914 | +__all__ = [] |
915 | + |
916 | +import unittest |
917 | + |
918 | +from canonical.launchpad.windmill.testing import lpuser, widgets |
919 | + |
920 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
921 | +from lp.testing import TestCaseWithFactory |
922 | + |
923 | +class TestProductIndexPage(TestCaseWithFactory): |
924 | + """Test product index page.""" |
925 | + |
926 | + layer = RegistryWindmillLayer |
927 | + |
928 | + def test_title_inline_edit(self): |
929 | + test = widgets.InlineEditorWidgetTest( |
930 | + url='http://launchpad.dev:8085/firefox', |
931 | + widget_id='product-title', |
932 | + expected_value='Mozilla Firefox', |
933 | + new_value='The awesome Mozilla Firefox', |
934 | + name='test_title_inline_edit', |
935 | + suite=__name__, |
936 | + user=lpuser.SAMPLE_PERSON) |
937 | + test() |
938 | + |
939 | + def test_programming_languages_edit(self): |
940 | + test = widgets.InlineEditorWidgetTest( |
941 | + url='http://launchpad.dev:8085/firefox', |
942 | + widget_id='programminglang', |
943 | + widget_tag='span', |
944 | + expected_value='Not yet specified', |
945 | + new_value='C++', |
946 | + name='test_proglang_inline_edit', |
947 | + suite=__name__, |
948 | + user=lpuser.SAMPLE_PERSON) |
949 | + test() |
950 | + |
951 | + |
952 | +def test_suite(): |
953 | + return unittest.TestLoader().loadTestsFromName(__name__) |
954 | |
955 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_product_edit_people.py' => 'lib/lp/registry/windmill/tests/test_product_edit_people.py' |
956 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_product_edit_people.py 2009-07-17 00:26:05 +0000 |
957 | +++ lib/lp/registry/windmill/tests/test_product_edit_people.py 2009-12-11 20:25:26 +0000 |
958 | @@ -1,23 +1,44 @@ |
959 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
960 | # GNU Affero General Public License version 3 (see the file LICENSE). |
961 | |
962 | +"""Test picker on +edit-people page.""" |
963 | + |
964 | +__metaclass__ = type |
965 | +__all__ = [] |
966 | + |
967 | +import unittest |
968 | + |
969 | from canonical.launchpad.windmill.testing.widgets import ( |
970 | FormPickerWidgetTest) |
971 | |
972 | - |
973 | -test_product_edit_people_driver = FormPickerWidgetTest( |
974 | - name='test_product_edit_people_driver', |
975 | - url='http://launchpad.dev:8085/firefox/+edit-people', |
976 | - short_field_name='driver', |
977 | - search_text='Perell\xc3\xb3', |
978 | - result_index=1, |
979 | - new_value='carlos') |
980 | - |
981 | -test_product_edit_people_owner = FormPickerWidgetTest( |
982 | - name='test_product_edit_people_owner', |
983 | - url='http://launchpad.dev:8085/firefox/+edit-people', |
984 | - short_field_name='owner', |
985 | - search_text='guadamen', |
986 | - result_index=1, |
987 | - new_value='guadamen') |
988 | - |
989 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
990 | +from lp.testing import TestCaseWithFactory |
991 | + |
992 | +class TestProductEditPeople(TestCaseWithFactory): |
993 | + """Test picker +edit-people page.""" |
994 | + |
995 | + layer = RegistryWindmillLayer |
996 | + |
997 | + def test_product_edit_people_driver(self): |
998 | + test = FormPickerWidgetTest( |
999 | + name='test_product_edit_people_driver', |
1000 | + url='http://launchpad.dev:8085/firefox/+edit-people', |
1001 | + short_field_name='driver', |
1002 | + search_text='Perell\xc3\xb3', |
1003 | + result_index=1, |
1004 | + new_value='carlos') |
1005 | + test() |
1006 | + |
1007 | + def test_product_edit_people_owner(self): |
1008 | + test = FormPickerWidgetTest( |
1009 | + name='test_product_edit_people_owner', |
1010 | + url='http://launchpad.dev:8085/firefox/+edit-people', |
1011 | + short_field_name='owner', |
1012 | + search_text='guadamen', |
1013 | + result_index=1, |
1014 | + new_value='guadamen') |
1015 | + test() |
1016 | + |
1017 | + |
1018 | +def test_suite(): |
1019 | + return unittest.TestLoader().loadTestsFromName(__name__) |
1020 | |
1021 | === renamed file 'lib/canonical/launchpad/windmill/tests/test_registry/test_project_licenses.py' => 'lib/lp/registry/windmill/tests/test_project_licenses.py' |
1022 | --- lib/canonical/launchpad/windmill/tests/test_registry/test_project_licenses.py 2009-07-17 02:25:09 +0000 |
1023 | +++ lib/lp/registry/windmill/tests/test_project_licenses.py 2009-12-11 20:25:26 +0000 |
1024 | @@ -1,131 +1,151 @@ |
1025 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
1026 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1027 | |
1028 | +"""Test project licenses picker.""" |
1029 | + |
1030 | +__metaclass__ = type |
1031 | +__all__ = [] |
1032 | + |
1033 | +import unittest |
1034 | + |
1035 | from windmill.authoring import WindmillTestClient |
1036 | |
1037 | from canonical.launchpad.windmill.testing import lpuser |
1038 | |
1039 | - |
1040 | -def test_project_licenses(): |
1041 | - """Test the dynamic aspects of the project license picker.""" |
1042 | - client = WindmillTestClient('firefox/+edit license picking') |
1043 | - lpuser.SAMPLE_PERSON.ensure_login(client) |
1044 | - |
1045 | - # The firefox project is as good as any. |
1046 | - client.open(url=u'http://launchpad.dev:8085/firefox/+edit') |
1047 | - client.waits.forPageLoad(timeout=u'20000') |
1048 | - |
1049 | - # The Recommended table is visible. |
1050 | - client.asserts.assertProperty( |
1051 | - id=u'recommended', |
1052 | - validator='className|lazr-opened') |
1053 | - # But the More table is not. |
1054 | - client.asserts.assertProperty( |
1055 | - id=u'more', |
1056 | - validator='className|lazr-closed') |
1057 | - # Neither is the Other choices. |
1058 | - client.asserts.assertProperty( |
1059 | - id=u'special', |
1060 | - validator='className|lazr-closed') |
1061 | - |
1062 | - # Clicking on the link exposes the More section though. |
1063 | - client.click(id='more-expand') |
1064 | - client.waits.sleep(milliseconds=u'1000') |
1065 | - client.asserts.assertProperty( |
1066 | - id=u'more', |
1067 | - validator='className|lazr-opened') |
1068 | - |
1069 | - # As does clicking on the Other choices section. |
1070 | - client.click(id='special-expand') |
1071 | - client.waits.sleep(milliseconds=u'1000') |
1072 | - client.asserts.assertProperty( |
1073 | - id=u'special', |
1074 | - validator='className|lazr-opened') |
1075 | - |
1076 | - # Clicking on any opened link closes the section. |
1077 | - client.click(id='recommended-expand') |
1078 | - client.asserts.assertProperty( |
1079 | - id=u'recommended', |
1080 | - validator='className|lazr-closed') |
1081 | - |
1082 | - # The license details box starts out hidden. |
1083 | - client.asserts.assertProperty( |
1084 | - id=u'license-details', |
1085 | - validator='className|lazr-closed') |
1086 | - |
1087 | - # But clicking on one of the Other/* licenses exposes it. |
1088 | - client.click(id='field.licenses.26') |
1089 | - client.asserts.assertProperty( |
1090 | - id=u'license-details', |
1091 | - validator='className|lazr-opened') |
1092 | - |
1093 | - # Clicking on Other/Proprietary exposes the additional commercial |
1094 | - # licensing details. |
1095 | - client.asserts.assertProperty( |
1096 | - id=u'proprietary', |
1097 | - validator='className|lazr-closed') |
1098 | - |
1099 | - client.click(id='field.licenses.25') |
1100 | - client.asserts.assertProperty( |
1101 | - id=u'license-details', |
1102 | - validator='className|lazr-opened') |
1103 | - client.asserts.assertProperty( |
1104 | - id=u'proprietary', |
1105 | - validator='className|lazr-opened') |
1106 | - |
1107 | - # Only when all Other/* items are unchecked does the details box get |
1108 | - # hidden. |
1109 | - client.click(id='field.licenses.26') |
1110 | - client.asserts.assertProperty( |
1111 | - id=u'license-details', |
1112 | - validator='className|lazr-opened') |
1113 | - |
1114 | - client.click(id='field.licenses.25') |
1115 | - client.asserts.assertProperty( |
1116 | - id=u'license-details', |
1117 | - validator='className|lazr-closed') |
1118 | - client.asserts.assertProperty( |
1119 | - id=u'proprietary', |
1120 | - validator='className|lazr-closed') |
1121 | - |
1122 | - # Clicking on "I haven't specified..." unchecks everything and closes the |
1123 | - # details box, but leaves the sections opened. |
1124 | - client.click(id='field.licenses.25') |
1125 | - client.asserts.assertProperty( |
1126 | - id=u'license-details', |
1127 | - validator='className|lazr-opened') |
1128 | - |
1129 | - client.asserts.assertChecked( |
1130 | - id=u'field.licenses.25') |
1131 | - |
1132 | - client.click(id='license_pending') |
1133 | - client.asserts.assertNotChecked( |
1134 | - id=u'field.licenses.25') |
1135 | - |
1136 | - client.asserts.assertProperty( |
1137 | - id=u'license-details', |
1138 | - validator='className|lazr-closed') |
1139 | - |
1140 | - # Submitting the form with items checked ensures that the next time the |
1141 | - # page is visited, those sections will be open. The Recommended section |
1142 | - # is always open. |
1143 | - |
1144 | - client.click(id='field.licenses.25') |
1145 | - client.type(id='field.license_info', text='Foo bar') |
1146 | - client.click(id='field.licenses.3') |
1147 | - client.click(id='field.actions.change') |
1148 | - client.waits.forPageLoad(timeout=u'20000') |
1149 | - |
1150 | - client.open(url=u'http://launchpad.dev:8085/firefox/+edit') |
1151 | - client.waits.forPageLoad(timeout=u'20000') |
1152 | - |
1153 | - client.asserts.assertProperty( |
1154 | - id=u'more', |
1155 | - validator='className|lazr-opened') |
1156 | - # Neither is the Other choices. |
1157 | - client.asserts.assertProperty( |
1158 | - id=u'special', |
1159 | - validator='className|lazr-opened') |
1160 | - client.asserts.assertProperty( |
1161 | - id=u'license-details', |
1162 | - validator='className|lazr-opened') |
1163 | +from lp.registry.windmill.testing import RegistryWindmillLayer |
1164 | +from lp.testing import TestCaseWithFactory |
1165 | + |
1166 | + |
1167 | +class TestProjectLicenses(TestCaseWithFactory): |
1168 | + """Test project licenses picker.""" |
1169 | + |
1170 | + layer = RegistryWindmillLayer |
1171 | + |
1172 | + def setUp(self): |
1173 | + self.client = WindmillTestClient('TestProjectLicenses') |
1174 | + |
1175 | + def test_project_licenses(self): |
1176 | + """Test the dynamic aspects of the project license picker.""" |
1177 | + # The firefox project is as good as any. |
1178 | + self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit') |
1179 | + self.client.waits.forPageLoad(timeout=u'20000') |
1180 | + |
1181 | + lpuser.SAMPLE_PERSON.ensure_login(self.client) |
1182 | + |
1183 | + # The Recommended table is visible. |
1184 | + self.client.waits.forElementProperty( |
1185 | + id=u'recommended', |
1186 | + option='className|lazr-opened') |
1187 | + # But the More table is not. |
1188 | + self.client.asserts.assertProperty( |
1189 | + id=u'more', |
1190 | + validator='className|lazr-closed') |
1191 | + # Neither is the Other choices. |
1192 | + self.client.asserts.assertProperty( |
1193 | + id=u'special', |
1194 | + validator='className|lazr-closed') |
1195 | + |
1196 | + # Clicking on the link exposes the More section though. |
1197 | + self.client.click(id='more-expand') |
1198 | + self.client.waits.forElementProperty( |
1199 | + id=u'more', |
1200 | + option='className|lazr-opened') |
1201 | + |
1202 | + # As does clicking on the Other choices section. |
1203 | + self.client.click(id='special-expand') |
1204 | + self.client.waits.forElementProperty( |
1205 | + id=u'special', |
1206 | + option='className|lazr-opened') |
1207 | + |
1208 | + # Clicking on any opened link closes the section. |
1209 | + self.client.click(id='recommended-expand') |
1210 | + self.client.waits.forElementProperty( |
1211 | + id=u'recommended', |
1212 | + option='className|lazr-closed') |
1213 | + |
1214 | + # The license details box starts out hidden. |
1215 | + self.client.asserts.assertProperty( |
1216 | + id=u'license-details', |
1217 | + validator='className|lazr-closed') |
1218 | + |
1219 | + # But clicking on one of the Other/* licenses exposes it. |
1220 | + self.client.click(id='field.licenses.26') |
1221 | + self.client.asserts.assertProperty( |
1222 | + id=u'license-details', |
1223 | + validator='className|lazr-opened') |
1224 | + |
1225 | + # Clicking on Other/Proprietary exposes the additional commercial |
1226 | + # licensing details. |
1227 | + self.client.asserts.assertProperty( |
1228 | + id=u'proprietary', |
1229 | + validator='className|lazr-closed') |
1230 | + |
1231 | + self.client.click(id='field.licenses.25') |
1232 | + self.client.asserts.assertProperty( |
1233 | + id=u'license-details', |
1234 | + validator='className|lazr-opened') |
1235 | + self.client.asserts.assertProperty( |
1236 | + id=u'proprietary', |
1237 | + validator='className|lazr-opened') |
1238 | + |
1239 | + # Only when all Other/* items are unchecked does the details box get |
1240 | + # hidden. |
1241 | + self.client.click(id='field.licenses.26') |
1242 | + self.client.asserts.assertProperty( |
1243 | + id=u'license-details', |
1244 | + validator='className|lazr-opened') |
1245 | + |
1246 | + self.client.click(id='field.licenses.25') |
1247 | + self.client.waits.forElementProperty( |
1248 | + id=u'license-details', |
1249 | + option='className|lazr-closed') |
1250 | + self.client.asserts.assertProperty( |
1251 | + id=u'proprietary', |
1252 | + validator='className|lazr-closed') |
1253 | + |
1254 | + # Clicking on "I haven't specified..." unchecks everything and |
1255 | + # closes the details box, but leaves the sections opened. |
1256 | + |
1257 | + self.client.click(id='field.licenses.25') |
1258 | + self.client.waits.forElementProperty( |
1259 | + id=u'license-details', |
1260 | + option='className|lazr-opened') |
1261 | + |
1262 | + self.client.asserts.assertChecked( |
1263 | + id=u'field.licenses.25') |
1264 | + |
1265 | + self.client.click(id='license_pending') |
1266 | + self.client.asserts.assertNotChecked( |
1267 | + id=u'field.licenses.25') |
1268 | + |
1269 | + self.client.asserts.assertProperty( |
1270 | + id=u'license-details', |
1271 | + validator='className|lazr-closed') |
1272 | + |
1273 | + # Submitting the form with items checked ensures that the next |
1274 | + # time the page is visited, those sections will be open. The |
1275 | + # Recommended section is always open. |
1276 | + |
1277 | + self.client.click(id='field.licenses.25') |
1278 | + self.client.type(id='field.license_info', text='Foo bar') |
1279 | + self.client.click(id='field.licenses.3') |
1280 | + self.client.click(id='field.actions.change') |
1281 | + self.client.waits.forPageLoad(timeout=u'20000') |
1282 | + |
1283 | + self.client.open(url=u'http://launchpad.dev:8085/firefox/+edit') |
1284 | + self.client.waits.forPageLoad(timeout=u'20000') |
1285 | + |
1286 | + self.client.asserts.assertProperty( |
1287 | + id=u'more', |
1288 | + validator='className|lazr-opened') |
1289 | + # Neither is the Other choices. |
1290 | + self.client.asserts.assertProperty( |
1291 | + id=u'special', |
1292 | + validator='className|lazr-opened') |
1293 | + self.client.asserts.assertProperty( |
1294 | + id=u'license-details', |
1295 | + validator='className|lazr-opened') |
1296 | + |
1297 | + |
1298 | +def test_suite(): |
1299 | + return unittest.TestLoader().loadTestsFromName(__name__) |
1300 | |
1301 | === modified file 'lib/lp/registry/windmill/tests/test_timeline_graph.py' |
1302 | --- lib/lp/registry/windmill/tests/test_timeline_graph.py 2009-10-29 13:40:37 +0000 |
1303 | +++ lib/lp/registry/windmill/tests/test_timeline_graph.py 2009-12-11 20:25:26 +0000 |
1304 | @@ -1,6 +1,11 @@ |
1305 | # Copyright 2009 Canonical Ltd. This software is licensed under the |
1306 | # GNU Affero General Public License version 3 (see the file LICENSE). |
1307 | |
1308 | +"""Test for timeline graph widget.""" |
1309 | + |
1310 | +__metaclass__ = type |
1311 | +__all__ = [] |
1312 | + |
1313 | import unittest |
1314 | |
1315 | from windmill.authoring import WindmillTestClient |
1316 | @@ -9,6 +14,7 @@ |
1317 | from lp.testing import TestCaseWithFactory |
1318 | |
1319 | class TestTimelineGraph(TestCaseWithFactory): |
1320 | + """Test timeline graph widget.""" |
1321 | |
1322 | layer = RegistryWindmillLayer |
1323 | |
1324 | |
1325 | === modified file 'lib/lp/translations/tests/test_translationimportqueue.py' |
1326 | --- lib/lp/translations/tests/test_translationimportqueue.py 2009-11-19 11:24:43 +0000 |
1327 | +++ lib/lp/translations/tests/test_translationimportqueue.py 2009-12-11 20:25:26 +0000 |
1328 | @@ -5,6 +5,7 @@ |
1329 | |
1330 | __metaclass__ = type |
1331 | |
1332 | +import transaction |
1333 | import unittest |
1334 | |
1335 | from zope.component import getUtility |
1336 | @@ -17,25 +18,27 @@ |
1337 | from canonical.testing import LaunchpadZopelessLayer |
1338 | |
1339 | |
1340 | -class TestTranslationImportQueueEntryStatus(TestCaseWithFactory): |
1341 | - """Test handling of the status of a queue entry.""" |
1342 | +class TestCanSetStatusBase(TestCaseWithFactory): |
1343 | + """Base for tests that check that canSetStatus works .""" |
1344 | |
1345 | layer = LaunchpadZopelessLayer |
1346 | + dbuser = None |
1347 | + entry = None |
1348 | |
1349 | def setUp(self): |
1350 | """Set up context to test in.""" |
1351 | - super(TestTranslationImportQueueEntryStatus, self).setUp() |
1352 | + super(TestCanSetStatusBase, self).setUp() |
1353 | |
1354 | self.queue = getUtility(ITranslationImportQueue) |
1355 | self.rosetta_experts = ( |
1356 | getUtility(ILaunchpadCelebrities).rosetta_experts) |
1357 | self.productseries = self.factory.makeProductSeries() |
1358 | self.uploaderperson = self.factory.makePerson() |
1359 | - self.potemplate = self.factory.makePOTemplate( |
1360 | - productseries=self.productseries) |
1361 | - self.entry = self.queue.addOrUpdateEntry( |
1362 | - 'demo.pot', '#demo', False, self.uploaderperson, |
1363 | - productseries=self.productseries, potemplate=self.potemplate) |
1364 | + |
1365 | + def _switch_dbuser(self): |
1366 | + if self.dbuser != None: |
1367 | + transaction.commit() |
1368 | + self.layer.switchDbUser(self.dbuser) |
1369 | |
1370 | def _assertCanSetStatus(self, user, entry, expected_list): |
1371 | # Helper to check for all statuses. |
1372 | @@ -49,6 +52,7 @@ |
1373 | RosettaImportStatus.IMPORTED, |
1374 | RosettaImportStatus.NEEDS_REVIEW, |
1375 | ] |
1376 | + self._switch_dbuser() |
1377 | # Do *not* use assertContentEqual here, as the order matters. |
1378 | self.assertEqual(expected_list, |
1379 | [entry.canSetStatus(status, user) |
1380 | @@ -71,6 +75,7 @@ |
1381 | # If the entry has no import target set, even Rosetta experts |
1382 | # cannot set it to approved. |
1383 | self.entry.potemplate = None |
1384 | + self.entry.pofile = None |
1385 | self._assertCanSetStatus(self.rosetta_experts, self.entry, |
1386 | # A B D F I NR |
1387 | [False, True, True, True, True, True]) |
1388 | @@ -115,5 +120,66 @@ |
1389 | [False, False, False, False, False, False]) |
1390 | |
1391 | |
1392 | +class TestCanSetStatusPOTemplate(TestCanSetStatusBase): |
1393 | + """Test canStatus applied to an entry with a POTemplate.""" |
1394 | + |
1395 | + def setUp(self): |
1396 | + """Create the entry to test on.""" |
1397 | + super(TestCanSetStatusPOTemplate, self).setUp() |
1398 | + |
1399 | + self.potemplate = self.factory.makePOTemplate( |
1400 | + productseries=self.productseries) |
1401 | + self.entry = self.queue.addOrUpdateEntry( |
1402 | + 'demo.pot', '#demo', False, self.uploaderperson, |
1403 | + productseries=self.productseries, potemplate=self.potemplate) |
1404 | + |
1405 | + |
1406 | +class TestCanSetStatusPOFile(TestCanSetStatusBase): |
1407 | + """Test canStatus applied to an entry with a POFile.""" |
1408 | + |
1409 | + def setUp(self): |
1410 | + """Create the entry to test on.""" |
1411 | + super(TestCanSetStatusPOFile, self).setUp() |
1412 | + |
1413 | + self.potemplate = self.factory.makePOTemplate( |
1414 | + productseries=self.productseries) |
1415 | + self.pofile = self.factory.makePOFile('eo', potemplate=self.potemplate) |
1416 | + self.entry = self.queue.addOrUpdateEntry( |
1417 | + 'demo.po', '#demo', False, self.uploaderperson, |
1418 | + productseries=self.productseries, pofile=self.pofile) |
1419 | + |
1420 | + |
1421 | +class TestCanSetStatusPOTemplateWithQueuedUser(TestCanSetStatusPOTemplate): |
1422 | + """Test handling of the status of a queue entry with 'queued' db user. |
1423 | + |
1424 | + The archive uploader needs to set (and therefore check) the status of a |
1425 | + queue entry. It connects as a different database user and therefore we |
1426 | + need to make sure that setStatus stays within this user's permissions. |
1427 | + This is the version for POTemplate entries. |
1428 | + """ |
1429 | + |
1430 | + dbuser = 'queued' |
1431 | + |
1432 | + |
1433 | +class TestCanSetStatusPOFileWithQueuedUser(TestCanSetStatusPOFile): |
1434 | + """Test handling of the status of a queue entry with 'queued' db user. |
1435 | + |
1436 | + The archive uploader needs to set (and therefore check) the status of a |
1437 | + queue entry. It connects as a different database user and therefore we |
1438 | + need to make sure that setStatus stays within this user's permissions. |
1439 | + This is the version for POFile entries. |
1440 | + """ |
1441 | + |
1442 | + dbuser = 'queued' |
1443 | + |
1444 | + |
1445 | def test_suite(): |
1446 | - return unittest.TestLoader().loadTestsFromName(__name__) |
1447 | + """Add only specific test cases and leave out the base case.""" |
1448 | + suite = unittest.TestSuite() |
1449 | + suite.addTest(unittest.makeSuite(TestCanSetStatusPOTemplate)) |
1450 | + suite.addTest(unittest.makeSuite(TestCanSetStatusPOFile)) |
1451 | + suite.addTest( |
1452 | + unittest.makeSuite(TestCanSetStatusPOTemplateWithQueuedUser)) |
1453 | + suite.addTest(unittest.makeSuite(TestCanSetStatusPOFileWithQueuedUser)) |
1454 | + return suite |
1455 | + |
Summary
-------
Moved the remaining registry windmill tests from launchpad/ windmill/ tests to lib/lp/ registry/ windmill/ tests.
lib/canonical/
Implementation details ------- ------- -
-------
Most of the changes just involve boilerplate to convert the tests
to unittests, indenting functions that became methods, and replacing
client with self.client.
I've included a smaller diff below of the changes that were made to fix
regressions since these tests had not been automatically run. I also
encountered authentication problems with the lpuser module's
ensure_login() method. Some of the tests use helper functions from a
different module that creates a new windmill client each time the
function is called. I assume there is something in the initialization of
the new client that invalidates the cookie from the last client,
therefore, I have to load a page in the new client before calling
ensure_login() so that it can find the "Login" link, otherwise it
assumes it is still logged in just fine.
lib/lp/ registry/ browser/ product. py
The windmill test was using foo.bar instead of the owner of the
project, so it seemed better to fix this by allowing anyone with
launchpad.Edit access to be able to see the programming language
fields inline editing icon.
lib/lp/ registry/ templates/ milestone- index.pt registry/ windmill/ tests/test_ add_milestone. py
lib/lp/
Creating a release now takes you to the milestone/release index
page instead of the series index page. The ids were added to
simplify the tests.
lib/lp/ registry/ templates/ product- new.pt
node.attach() was replaced with node.on(), so this functionality
was actually broken in production.
lib/lp/ registry/ windmill/ tests/test_ plusnew_ step1.py registry/ windmill/ tests/test_ plusnew_ step2.py registry/ windmill/ tests/test_ product. py registry/ windmill/ tests/test_ project_ licenses. py
lib/lp/
lib/lp/
lib/lp/
Tests
-----
./bin/test -vv --layer= RegistryWindmil lLayer
{{{
=== modified file 'lib/canonical/ launchpad/ windmill/ testing/ widgets. py' launchpad/ windmill/ testing/ widgets. py 2009-10-29 14:23:16 +0000 launchpad/ windmill/ testing/ widgets. py 2009-12-11 00:22:50 +0000 ent(self. suite) open(url= self.url)
--- lib/canonical/
+++ lib/canonical/
@@ -60,10 +60,10 @@
* reloads and verifies that the new value sticked.
"""
client = WindmillTestCli
+ client.
- client. open(url= self.url)
client. waits.forPageLo ad(timeout= constants. PAGE_LOAD)
widget_ base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id)
client. waits.forElemen t(
@@ -298,13 +298,15 @@
def __call__(self): ent(self. suite) ensure_ login(client)
client = WindmillTestCli
- self.user.
# Load page.
client. open(url= self.url) waits.forPageLo ad(timeout= constants. PAGE_LOAD) ensure_ login(client)
- client.
+
+ self.user.
# Click on "Choose" link to show picker for the given field. waits.forElemen t( choose_ link_id, timeout= constants. PAGE_LOAD)
client. click(id= self.choose_ link_id)
+ client.
+ id=self.
# Search picker.
=== modified file 'lib/lp/regis...