Merge lp:~edwin-grubbs/launchpad/bug-495067-move-windmill-tests into lp:launchpad/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
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+16057@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :
Download full text (13.1 KiB)

Summary
-------

Moved the remaining registry windmill tests from
lib/canonical/launchpad/windmill/tests to lib/lp/registry/windmill/tests.

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
lib/lp/registry/windmill/tests/test_add_milestone.py
    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
lib/lp/registry/windmill/tests/test_plusnew_step2.py
lib/lp/registry/windmill/tests/test_product.py
lib/lp/registry/windmill/tests/test_project_licenses.py

Tests
-----

./bin/test -vv --layer=RegistryWindmillLayer

{{{

=== modified file 'lib/canonical/launchpad/windmill/testing/widgets.py'
--- lib/canonical/launchpad/windmill/testing/widgets.py 2009-10-29 14:23:16 +0000
+++ lib/canonical/launchpad/windmill/testing/widgets.py 2009-12-11 00:22:50 +0000
@@ -60,10 +60,10 @@
         * reloads and verifies that the new value sticked.
         """
         client = WindmillTestClient(self.suite)
+ client.open(url=self.url)

         self.user.ensure_login(client)

- client.open(url=self.url)
         client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
         widget_base = u"//%s[@id='%s']" % (self.widget_tag, self.widget_id)
         client.waits.forElement(
@@ -298,13 +298,15 @@

     def __call__(self):
         client = WindmillTestClient(self.suite)
- self.user.ensure_login(client)

         # Load page.
         client.open(url=self.url)
- client.waits.forPageLoad(timeout=constants.PAGE_LOAD)
+
+ self.user.ensure_login(client)

         # Click on "Choose" link to show picker for the given field.
+ client.waits.forElement(
+ id=self.choose_link_id, timeout=constants.PAGE_LOAD)
         client.click(id=self.choose_link_id)

         # Search picker.

=== modified file 'lib/lp/regis...

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:&lt;script id='codereview-script' type='text/javascript'&gt;" />
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:&lt;/script&gt;" />
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+

Subscribers

People subscribed via source and target branches

to status/vote changes: