OLD | NEW |
| (Empty) |
1 # Copyright (C) 2011 Google Inc. All rights reserved. | |
2 # | |
3 # Redistribution and use in source and binary forms, with or without | |
4 # modification, are permitted provided that the following conditions are | |
5 # met: | |
6 # | |
7 # * Redistributions of source code must retain the above copyright | |
8 # notice, this list of conditions and the following disclaimer. | |
9 # * Redistributions in binary form must reproduce the above | |
10 # copyright notice, this list of conditions and the following disclaimer | |
11 # in the documentation and/or other materials provided with the | |
12 # distribution. | |
13 # * Neither the name of Google Inc. nor the names of its | |
14 # contributors may be used to endorse or promote products derived from | |
15 # this software without specific prior written permission. | |
16 # | |
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | |
29 import unittest2 as unittest | |
30 import datetime | |
31 import StringIO | |
32 | |
33 from .bugzilla import Bugzilla, BugzillaQueries, EditUsersParser | |
34 | |
35 from webkitpy.common.config import urls | |
36 from webkitpy.common.config.committers import Reviewer, Committer, Contributor,
CommitterList | |
37 from webkitpy.common.system.outputcapture import OutputCapture | |
38 from webkitpy.common.net.web_mock import MockBrowser | |
39 from webkitpy.thirdparty.mock import Mock | |
40 from webkitpy.thirdparty.BeautifulSoup import BeautifulSoup | |
41 | |
42 | |
43 class BugzillaTest(unittest.TestCase): | |
44 _example_attachment = ''' | |
45 <attachment | |
46 isobsolete="1" | |
47 ispatch="1" | |
48 isprivate="0" | |
49 > | |
50 <attachid>33721</attachid> | |
51 <date>2009-07-29 10:23 PDT</date> | |
52 <desc>Fixed whitespace issue</desc> | |
53 <filename>patch</filename> | |
54 <type>text/plain</type> | |
55 <size>9719</size> | |
56 <attacher>christian.plesner.hansen@gmail.com</attacher> | |
57 <flag name="review" | |
58 id="17931" | |
59 status="+" | |
60 setter="one@test.com" | |
61 /> | |
62 <flag name="commit-queue" | |
63 id="17932" | |
64 status="+" | |
65 setter="two@test.com" | |
66 /> | |
67 </attachment> | |
68 ''' | |
69 _expected_example_attachment_parsing = { | |
70 'attach_date': datetime.datetime(2009, 07, 29, 10, 23), | |
71 'bug_id' : 100, | |
72 'is_obsolete' : True, | |
73 'is_patch' : True, | |
74 'id' : 33721, | |
75 'url' : "https://bugs.webkit.org/attachment.cgi?id=33721", | |
76 'name' : "Fixed whitespace issue", | |
77 'type' : "text/plain", | |
78 'review' : '+', | |
79 'reviewer_email' : 'one@test.com', | |
80 'commit-queue' : '+', | |
81 'committer_email' : 'two@test.com', | |
82 'attacher_email' : 'christian.plesner.hansen@gmail.com', | |
83 } | |
84 | |
85 def test_url_creation(self): | |
86 # FIXME: These would be all better as doctests | |
87 bugs = Bugzilla() | |
88 self.assertIsNone(bugs.bug_url_for_bug_id(None)) | |
89 self.assertIsNone(bugs.short_bug_url_for_bug_id(None)) | |
90 self.assertIsNone(bugs.attachment_url_for_id(None)) | |
91 | |
92 def test_parse_bug_id(self): | |
93 # Test that we can parse the urls we produce. | |
94 bugs = Bugzilla() | |
95 self.assertEqual(12345, urls.parse_bug_id(bugs.short_bug_url_for_bug_id(
12345))) | |
96 self.assertEqual(12345, urls.parse_bug_id(bugs.bug_url_for_bug_id(12345)
)) | |
97 self.assertEqual(12345, urls.parse_bug_id(bugs.bug_url_for_bug_id(12345,
xml=True))) | |
98 | |
99 _bug_xml = """ | |
100 <bug> | |
101 <bug_id>32585</bug_id> | |
102 <creation_ts>2009-12-15 15:17 PST</creation_ts> | |
103 <short_desc>bug to test webkit-patch's and commit-queue's fa
ilures</short_desc> | |
104 <delta_ts>2009-12-27 21:04:50 PST</delta_ts> | |
105 <reporter_accessible>1</reporter_accessible> | |
106 <cclist_accessible>1</cclist_accessible> | |
107 <classification_id>1</classification_id> | |
108 <classification>Unclassified</classification> | |
109 <product>WebKit</product> | |
110 <component>Tools / Tests</component> | |
111 <version>528+ (Nightly build)</version> | |
112 <rep_platform>PC</rep_platform> | |
113 <op_sys>Mac OS X 10.5</op_sys> | |
114 <bug_status>NEW</bug_status> | |
115 <priority>P2</priority> | |
116 <bug_severity>Normal</bug_severity> | |
117 <target_milestone>---</target_milestone> | |
118 <everconfirmed>1</everconfirmed> | |
119 <reporter name="Eric Seidel">eric@webkit.org</reporter> | |
120 <assigned_to name="Nobody">webkit-unassigned@lists.webkit.org</assigne
d_to> | |
121 <cc>foo@bar.com</cc> | |
122 <cc>example@example.com</cc> | |
123 <long_desc isprivate="0"> | |
124 <who name="Eric Seidel">eric@webkit.org</who> | |
125 <bug_when>2009-12-15 15:17:28 PST</bug_when> | |
126 <thetext>bug to test webkit-patch and commit-queue failures | |
127 | |
128 Ignore this bug. Just for testing failure modes of webkit-patch and the commit-
queue.</thetext> | |
129 </long_desc> | |
130 <attachment | |
131 isobsolete="0" | |
132 ispatch="1" | |
133 isprivate="0" | |
134 > | |
135 <attachid>45548</attachid> | |
136 <date>2009-12-27 23:51 PST</date> | |
137 <desc>Patch</desc> | |
138 <filename>bug-32585-20091228005112.patch</filename> | |
139 <type>text/plain</type> | |
140 <size>10882</size> | |
141 <attacher>mjs@apple.com</attacher> | |
142 | |
143 <token>1261988248-dc51409e9c421a4358f365fa8bec8357</token> | |
144 <data encoding="base64">SW5kZXg6IFdlYktpdC9tYWMvQ2hhbmdlTG9nCj09PT
09PT09PT09PT09PT09PT09PT09PT09PT09 | |
145 removed-because-it-was-really-long | |
146 ZEZpbmlzaExvYWRXaXRoUmVhc29uOnJlYXNvbl07Cit9CisKIEBlbmQKIAogI2VuZGlmCg== | |
147 </data> | |
148 | |
149 <flag name="review" | |
150 id="27602" | |
151 status="?" | |
152 setter="mjs@apple.com" | |
153 /> | |
154 </attachment> | |
155 </bug> | |
156 """ | |
157 | |
158 _single_bug_xml = """ | |
159 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | |
160 <!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/bugzilla.dtd"> | |
161 <bugzilla version="3.2.3" | |
162 urlbase="https://bugs.webkit.org/" | |
163 maintainer="admin@webkit.org" | |
164 exporter="eric@webkit.org" | |
165 > | |
166 %s | |
167 </bugzilla> | |
168 """ % _bug_xml | |
169 | |
170 _expected_example_bug_parsing = { | |
171 "id" : 32585, | |
172 "title" : u"bug to test webkit-patch's and commit-queue's failures", | |
173 "cc_emails" : ["foo@bar.com", "example@example.com"], | |
174 "reporter_email" : "eric@webkit.org", | |
175 "assigned_to_email" : "webkit-unassigned@lists.webkit.org", | |
176 "bug_status": "NEW", | |
177 "attachments" : [{ | |
178 "attach_date": datetime.datetime(2009, 12, 27, 23, 51), | |
179 'name': u'Patch', | |
180 'url' : "https://bugs.webkit.org/attachment.cgi?id=45548", | |
181 'is_obsolete': False, | |
182 'review': '?', | |
183 'is_patch': True, | |
184 'attacher_email': 'mjs@apple.com', | |
185 'bug_id': 32585, | |
186 'type': 'text/plain', | |
187 'id': 45548 | |
188 }], | |
189 "comments" : [{ | |
190 'comment_date': datetime.datetime(2009, 12, 15, 15, 17, 28), | |
191 'comment_email': 'eric@webkit.org', | |
192 'text': """bug to test webkit-patch and commit-queue failures | |
193 | |
194 Ignore this bug. Just for testing failure modes of webkit-patch and the commit-
queue.""", | |
195 }] | |
196 } | |
197 | |
198 # FIXME: This should move to a central location and be shared by more unit t
ests. | |
199 def _assert_dictionaries_equal(self, actual, expected): | |
200 # Make sure we aren't parsing more or less than we expect | |
201 self.assertItemsEqual(actual.keys(), expected.keys()) | |
202 | |
203 for key, expected_value in expected.items(): | |
204 self.assertEqual(actual[key], expected_value, ("Failure for key: %s:
Actual='%s' Expected='%s'" % (key, actual[key], expected_value))) | |
205 | |
206 def test_parse_bug_dictionary_from_xml(self): | |
207 bug = Bugzilla()._parse_bug_dictionary_from_xml(self._single_bug_xml) | |
208 self._assert_dictionaries_equal(bug, self._expected_example_bug_parsing) | |
209 | |
210 _sample_multi_bug_xml = """ | |
211 <bugzilla version="3.2.3" urlbase="https://bugs.webkit.org/" maintainer="admin@w
ebkit.org" exporter="eric@webkit.org"> | |
212 %s | |
213 %s | |
214 </bugzilla> | |
215 """ % (_bug_xml, _bug_xml) | |
216 | |
217 def test_parse_bugs_from_xml(self): | |
218 bugzilla = Bugzilla() | |
219 bugs = bugzilla._parse_bugs_from_xml(self._sample_multi_bug_xml) | |
220 self.assertEqual(len(bugs), 2) | |
221 self.assertEqual(bugs[0].id(), self._expected_example_bug_parsing['id']) | |
222 bugs = bugzilla._parse_bugs_from_xml("") | |
223 self.assertEqual(len(bugs), 0) | |
224 | |
225 # This could be combined into test_bug_parsing later if desired. | |
226 def test_attachment_parsing(self): | |
227 bugzilla = Bugzilla() | |
228 soup = BeautifulSoup(self._example_attachment) | |
229 attachment_element = soup.find("attachment") | |
230 attachment = bugzilla._parse_attachment_element(attachment_element, self
._expected_example_attachment_parsing['bug_id']) | |
231 self.assertTrue(attachment) | |
232 self._assert_dictionaries_equal(attachment, self._expected_example_attac
hment_parsing) | |
233 | |
234 _sample_attachment_detail_page = """ | |
235 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
236 "http://www.w3.org/TR/html4/loose.dtd"> | |
237 <html> | |
238 <head> | |
239 <title> | |
240 Attachment 41073 Details for Bug 27314</title> | |
241 <link rel="Top" href="https://bugs.webkit.org/"> | |
242 <link rel="Up" href="show_bug.cgi?id=27314"> | |
243 """ | |
244 | |
245 def test_attachment_detail_bug_parsing(self): | |
246 bugzilla = Bugzilla() | |
247 self.assertEqual(27314, bugzilla._parse_bug_id_from_attachment_page(self
._sample_attachment_detail_page)) | |
248 | |
249 def test_add_cc_to_bug(self): | |
250 bugzilla = Bugzilla() | |
251 bugzilla.browser = MockBrowser() | |
252 bugzilla.authenticate = lambda: None | |
253 expected_logs = "Adding ['adam@example.com'] to the CC list for bug 42\n
" | |
254 OutputCapture().assert_outputs(self, bugzilla.add_cc_to_bug, [42, ["adam
@example.com"]], expected_logs=expected_logs) | |
255 | |
256 def _mock_control_item(self, name): | |
257 mock_item = Mock() | |
258 mock_item.name = name | |
259 return mock_item | |
260 | |
261 def _mock_find_control(self, item_names=[], selected_index=0): | |
262 mock_control = Mock() | |
263 mock_control.items = [self._mock_control_item(name) for name in item_nam
es] | |
264 mock_control.value = [item_names[selected_index]] if item_names else Non
e | |
265 return lambda name, type: mock_control | |
266 | |
267 def _assert_reopen(self, item_names=None, selected_index=None, extra_logs=No
ne): | |
268 bugzilla = Bugzilla() | |
269 bugzilla.browser = MockBrowser() | |
270 bugzilla.authenticate = lambda: None | |
271 | |
272 mock_find_control = self._mock_find_control(item_names, selected_index) | |
273 bugzilla.browser.find_control = mock_find_control | |
274 expected_logs = "Re-opening bug 42\n['comment']\n" | |
275 if extra_logs: | |
276 expected_logs += extra_logs | |
277 OutputCapture().assert_outputs(self, bugzilla.reopen_bug, [42, ["comment
"]], expected_logs=expected_logs) | |
278 | |
279 def test_reopen_bug(self): | |
280 self._assert_reopen(item_names=["REOPENED", "RESOLVED", "CLOSED"], selec
ted_index=1) | |
281 self._assert_reopen(item_names=["UNCONFIRMED", "RESOLVED", "CLOSED"], se
lected_index=1) | |
282 extra_logs = "Did not reopen bug 42, it appears to already be open with
status ['NEW'].\n" | |
283 self._assert_reopen(item_names=["NEW", "RESOLVED"], selected_index=0, ex
tra_logs=extra_logs) | |
284 | |
285 def test_file_object_for_upload(self): | |
286 bugzilla = Bugzilla() | |
287 file_object = StringIO.StringIO() | |
288 unicode_tor = u"WebKit \u2661 Tor Arne Vestb\u00F8!" | |
289 utf8_tor = unicode_tor.encode("utf-8") | |
290 self.assertEqual(bugzilla._file_object_for_upload(file_object), file_obj
ect) | |
291 self.assertEqual(bugzilla._file_object_for_upload(utf8_tor).read(), utf8
_tor) | |
292 self.assertEqual(bugzilla._file_object_for_upload(unicode_tor).read(), u
tf8_tor) | |
293 | |
294 def test_filename_for_upload(self): | |
295 bugzilla = Bugzilla() | |
296 mock_file = Mock() | |
297 mock_file.name = "foo" | |
298 self.assertEqual(bugzilla._filename_for_upload(mock_file, 1234), 'foo') | |
299 mock_timestamp = lambda: "now" | |
300 filename = bugzilla._filename_for_upload(StringIO.StringIO(), 1234, exte
nsion="patch", timestamp=mock_timestamp) | |
301 self.assertEqual(filename, "bug-1234-now.patch") | |
302 | |
303 def test_commit_queue_flag(self): | |
304 bugzilla = Bugzilla() | |
305 | |
306 bugzilla.committers = CommitterList(reviewers=[Reviewer("WebKit Reviewer
", "reviewer@webkit.org")], | |
307 committers=[Committer("WebKit Committer", "committer@webkit.org")], | |
308 contributors=[Contributor("WebKit Contributor", "contributor@webkit.
org")], | |
309 watchers=[]) | |
310 | |
311 def assert_commit_queue_flag(mark_for_landing, mark_for_commit_queue, ex
pected, username=None): | |
312 bugzilla.username = username | |
313 capture = OutputCapture() | |
314 capture.capture_output() | |
315 try: | |
316 self.assertEqual(bugzilla._commit_queue_flag(mark_for_landing=ma
rk_for_landing, mark_for_commit_queue=mark_for_commit_queue), expected) | |
317 finally: | |
318 capture.restore_output() | |
319 | |
320 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=F
alse, expected='X', username='unknown@webkit.org') | |
321 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=T
rue, expected='?', username='unknown@webkit.org') | |
322 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=T
rue, expected='?', username='unknown@webkit.org') | |
323 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Tr
ue, expected='?', username='unknown@webkit.org') | |
324 | |
325 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=F
alse, expected='X', username='contributor@webkit.org') | |
326 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=T
rue, expected='?', username='contributor@webkit.org') | |
327 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Fa
lse, expected='?', username='contributor@webkit.org') | |
328 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Tr
ue, expected='?', username='contributor@webkit.org') | |
329 | |
330 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=F
alse, expected='X', username='committer@webkit.org') | |
331 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=T
rue, expected='?', username='committer@webkit.org') | |
332 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Fa
lse, expected='+', username='committer@webkit.org') | |
333 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Tr
ue, expected='+', username='committer@webkit.org') | |
334 | |
335 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=F
alse, expected='X', username='reviewer@webkit.org') | |
336 assert_commit_queue_flag(mark_for_landing=False, mark_for_commit_queue=T
rue, expected='?', username='reviewer@webkit.org') | |
337 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Fa
lse, expected='+', username='reviewer@webkit.org') | |
338 assert_commit_queue_flag(mark_for_landing=True, mark_for_commit_queue=Tr
ue, expected='+', username='reviewer@webkit.org') | |
339 | |
340 | |
341 class BugzillaQueriesTest(unittest.TestCase): | |
342 _sample_request_page = """ | |
343 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
344 "http://www.w3.org/TR/html4/loose.dtd"> | |
345 <html> | |
346 <head> | |
347 <title>Request Queue</title> | |
348 </head> | |
349 <body> | |
350 | |
351 <h3>Flag: review</h3> | |
352 <table class="requests" cellspacing="0" cellpadding="4" border="1"> | |
353 <tr> | |
354 <th>Requester</th> | |
355 <th>Requestee</th> | |
356 <th>Bug</th> | |
357 <th>Attachment</th> | |
358 <th>Created</th> | |
359 </tr> | |
360 <tr> | |
361 <td>Shinichiro Hamaji <hamaji@chromium.org></td> | |
362 <td></td> | |
363 <td><a href="show_bug.cgi?id=30015">30015: text-transform:capitalize is
failing in CSS2.1 test suite</a></td> | |
364 <td><a href="attachment.cgi?id=40511&action=review"> | |
365 40511: Patch v0</a></td> | |
366 <td>2009-10-02 04:58 PST</td> | |
367 </tr> | |
368 <tr> | |
369 <td>Zan Dobersek <zandobersek@gmail.com></td> | |
370 <td></td> | |
371 <td><a href="show_bug.cgi?id=26304">26304: [GTK] Add controls for playin
g html5 video.</a></td> | |
372 <td><a href="attachment.cgi?id=40722&action=review"> | |
373 40722: Media controls, the simple approach</a></td> | |
374 <td>2009-10-06 09:13 PST</td> | |
375 </tr> | |
376 <tr> | |
377 <td>Zan Dobersek <zandobersek@gmail.com></td> | |
378 <td></td> | |
379 <td><a href="show_bug.cgi?id=26304">26304: [GTK] Add controls for playin
g html5 video.</a></td> | |
380 <td><a href="attachment.cgi?id=40723&action=review"> | |
381 40723: Adjust the media slider thumb size</a></td> | |
382 <td>2009-10-06 09:15 PST</td> | |
383 </tr> | |
384 </table> | |
385 </body> | |
386 </html> | |
387 """ | |
388 _sample_quip_page = u""" | |
389 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
390 "http://www.w3.org/TR/html4/loose.dtd"> | |
391 <html> | |
392 <head> | |
393 <title>Bugzilla Quip System</title> | |
394 </head> | |
395 <body> | |
396 <h2> | |
397 | |
398 Existing quips: | |
399 </h2> | |
400 <ul> | |
401 <li>Everything should be made as simple as possible, but not simpler. -
Albert Einstein</li> | |
402 <li>Good artists copy. Great artists steal. - Pablo Picasso</li> | |
403 <li>\u00e7gua mole em pedra dura, tanto bate at\u008e que fura.</li> | |
404 | |
405 </ul> | |
406 </body> | |
407 </html> | |
408 """ | |
409 | |
410 def _assert_result_count(self, queries, html, count): | |
411 self.assertEqual(queries._parse_result_count(html), count) | |
412 | |
413 def test_parse_result_count(self): | |
414 queries = BugzillaQueries(None) | |
415 # Pages with results, always list the count at least twice. | |
416 self._assert_result_count(queries, '<span class="bz_result_count">314 bu
gs found.</span><span class="bz_result_count">314 bugs found.</span>', 314) | |
417 self._assert_result_count(queries, '<span class="bz_result_count">Zarro
Boogs found.</span>', 0) | |
418 self._assert_result_count(queries, '<span class="bz_result_count">\n \nO
ne bug found.</span>', 1) | |
419 self.assertRaises(Exception, queries._parse_result_count, ['Invalid']) | |
420 | |
421 def test_request_page_parsing(self): | |
422 queries = BugzillaQueries(None) | |
423 self.assertEqual([40511, 40722, 40723], queries._parse_attachment_ids_re
quest_query(self._sample_request_page)) | |
424 | |
425 def test_quip_page_parsing(self): | |
426 queries = BugzillaQueries(None) | |
427 expected_quips = ["Everything should be made as simple as possible, but
not simpler. - Albert Einstein", "Good artists copy. Great artists steal. - Pabl
o Picasso", u"\u00e7gua mole em pedra dura, tanto bate at\u008e que fura."] | |
428 self.assertEqual(expected_quips, queries._parse_quips(self._sample_quip_
page)) | |
429 | |
430 def test_load_query(self): | |
431 queries = BugzillaQueries(Mock()) | |
432 queries._load_query("request.cgi?action=queue&type=review&group=type") | |
433 | |
434 | |
435 class EditUsersParserTest(unittest.TestCase): | |
436 _example_user_results = """ | |
437 <div id="bugzilla-body"> | |
438 <p>1 user found.</p> | |
439 <table id="admin_table" border="1" cellpadding="4" cellspacing="0"> | |
440 <tr bgcolor="#6666FF"> | |
441 <th align="left">Edit user... | |
442 </th> | |
443 <th align="left">Real name | |
444 </th> | |
445 <th align="left">Account History | |
446 </th> | |
447 </tr> | |
448 <tr> | |
449 <td > | |
450 <a href="editusers.cgi?action=edit&userid=1234&matchva
lue=login_name&groupid=&grouprestrict=&matchtype=substr&matchstr
=abarth%40webkit.org"> | |
451 abarth@webkit.org | |
452 </a> | |
453 </td> | |
454 <td > | |
455 Adam Barth | |
456 </td> | |
457 <td > | |
458 <a href="editusers.cgi?action=activity&userid=1234&mat
chvalue=login_name&groupid=&grouprestrict=&matchtype=substr&matc
hstr=abarth%40webkit.org"> | |
459 View | |
460 </a> | |
461 </td> | |
462 </tr> | |
463 </table> | |
464 """ | |
465 | |
466 _example_empty_user_results = """ | |
467 <div id="bugzilla-body"> | |
468 <p>0 users found.</p> | |
469 <table id="admin_table" border="1" cellpadding="4" cellspacing="0"> | |
470 <tr bgcolor="#6666FF"> | |
471 <th align="left">Edit user... | |
472 </th> | |
473 <th align="left">Real name | |
474 </th> | |
475 <th align="left">Account History | |
476 </th> | |
477 </tr> | |
478 <tr><td colspan="3" align="center"><i><none></i></td></tr> | |
479 </table> | |
480 """ | |
481 | |
482 def _assert_login_userid_pairs(self, results_page, expected_logins): | |
483 parser = EditUsersParser() | |
484 logins = parser.login_userid_pairs_from_edit_user_results(results_page) | |
485 self.assertEqual(logins, expected_logins) | |
486 | |
487 def test_logins_from_editusers_results(self): | |
488 self._assert_login_userid_pairs(self._example_user_results, [("abarth@we
bkit.org", 1234)]) | |
489 self._assert_login_userid_pairs(self._example_empty_user_results, []) | |
490 | |
491 _example_user_page = """<table class="main"><tr> | |
492 <th><label for="login">Login name:</label></th> | |
493 <td>eric@webkit.org | |
494 </td> | |
495 </tr> | |
496 <tr> | |
497 <th><label for="name">Real name:</label></th> | |
498 <td>Eric Seidel | |
499 </td> | |
500 </tr> | |
501 <tr> | |
502 <th>Group access:</th> | |
503 <td> | |
504 <table class="groups"> | |
505 <tr> | |
506 </tr> | |
507 <tr> | |
508 <th colspan="2">User is a member of these groups</th> | |
509 </tr> | |
510 <tr class="direct"> | |
511 <td class="checkbox"><input type="checkbox" | |
512 id="group_7" | |
513 name="group_7" | |
514 value="1" checked="checked" /></td> | |
515 <td class="groupname"> | |
516 <label for="group_7"> | |
517 <strong>canconfirm:</strong> | |
518 Can confirm a bug. | |
519 </label> | |
520 </td> | |
521 </tr> | |
522 <tr class="direct"> | |
523 <td class="checkbox"><input type="checkbox" | |
524 id="group_6" | |
525 name="group_6" | |
526 value="1" /></td> | |
527 <td class="groupname"> | |
528 <label for="group_6"> | |
529 <strong>editbugs:</strong> | |
530 Can edit all aspects of any bug. | |
531 /label> | |
532 </td> | |
533 </tr> | |
534 </table> | |
535 </td> | |
536 </tr> | |
537 | |
538 <tr> | |
539 <th>Product responsibilities:</th> | |
540 <td> | |
541 <em>none</em> | |
542 </td> | |
543 </tr> | |
544 </table>""" | |
545 | |
546 def test_user_dict_from_edit_user_page(self): | |
547 parser = EditUsersParser() | |
548 user_dict = parser.user_dict_from_edit_user_page(self._example_user_page
) | |
549 expected_user_dict = {u'login': u'eric@webkit.org', u'groups': set(['can
confirm']), u'name': u'Eric Seidel'} | |
550 self.assertEqual(expected_user_dict, user_dict) | |
OLD | NEW |