Mercurial > p > roundup > code
comparison test/test_cgi.py @ 1438:13c42b803101
Better handling of the form variable labels.
It's done in one step rather than the split step of last week. This
means that "msg-1@link@files" will work now.
I had to change the password confirmation special var from "name:confirm"
to ":confirm:name" so it conformed with the pattern set by ":add:" etc.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 17 Feb 2003 06:44:01 +0000 |
| parents | c70068162e64 |
| children | 8ce33ce262a4 |
comparison
equal
deleted
inserted
replaced
| 1437:077235194ac2 | 1438:13c42b803101 |
|---|---|
| 6 # | 6 # |
| 7 # This module is distributed in the hope that it will be useful, | 7 # This module is distributed in the hope that it will be useful, |
| 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| 10 # | 10 # |
| 11 # $Id: test_cgi.py,v 1.9 2003-02-14 00:31:46 richard Exp $ | 11 # $Id: test_cgi.py,v 1.10 2003-02-17 06:44:01 richard Exp $ |
| 12 | 12 |
| 13 import unittest, os, shutil, errno, sys, difflib, cgi | 13 import unittest, os, shutil, errno, sys, difflib, cgi, re |
| 14 | 14 |
| 15 from roundup.cgi import client | 15 from roundup.cgi import client |
| 16 from roundup import init, instance, password, hyperdb, date | 16 from roundup import init, instance, password, hyperdb, date |
| 17 | 17 |
| 18 class FileUpload: | 18 class FileUpload: |
| 60 string=hyperdb.String(), | 60 string=hyperdb.String(), |
| 61 boolean=hyperdb.Boolean(), link=hyperdb.Link('test'), | 61 boolean=hyperdb.Boolean(), link=hyperdb.Link('test'), |
| 62 multilink=hyperdb.Multilink('test'), date=hyperdb.Date(), | 62 multilink=hyperdb.Multilink('test'), date=hyperdb.Date(), |
| 63 interval=hyperdb.Interval()) | 63 interval=hyperdb.Interval()) |
| 64 | 64 |
| 65 # compile the labels re | |
| 66 classes = '|'.join(self.db.classes.keys()) | |
| 67 self.FV_SPECIAL = re.compile(client.Client.FV_LABELS%classes, | |
| 68 re.VERBOSE) | |
| 69 | |
| 65 def parseForm(self, form, classname='test', nodeid=None): | 70 def parseForm(self, form, classname='test', nodeid=None): |
| 66 cl = client.Client(self.instance, None, {'PATH_INFO':'/'}, | 71 cl = client.Client(self.instance, None, {'PATH_INFO':'/'}, |
| 67 makeForm(form)) | 72 makeForm(form)) |
| 68 cl.classname = classname | 73 cl.classname = classname |
| 69 cl.nodeid = nodeid | 74 cl.nodeid = nodeid |
| 74 self.db.close() | 79 self.db.close() |
| 75 try: | 80 try: |
| 76 shutil.rmtree(self.dirname) | 81 shutil.rmtree(self.dirname) |
| 77 except OSError, error: | 82 except OSError, error: |
| 78 if error.errno not in (errno.ENOENT, errno.ESRCH): raise | 83 if error.errno not in (errno.ENOENT, errno.ESRCH): raise |
| 84 | |
| 85 # | |
| 86 # form label extraction | |
| 87 # | |
| 88 def tl(self, s, c, i, a, p): | |
| 89 m = self.FV_SPECIAL.match(s) | |
| 90 self.assertNotEqual(m, None) | |
| 91 d = m.groupdict() | |
| 92 self.assertEqual(d['classname'], c) | |
| 93 self.assertEqual(d['id'], i) | |
| 94 for action in 'required add remove link note file'.split(): | |
| 95 if a == action: | |
| 96 self.assertNotEqual(d[action], None) | |
| 97 else: | |
| 98 self.assertEqual(d[action], None) | |
| 99 self.assertEqual(d['propname'], p) | |
| 100 | |
| 101 def testLabelMatching(self): | |
| 102 self.tl('<propname>', None, None, None, '<propname>') | |
| 103 self.tl(':required', None, None, 'required', None) | |
| 104 self.tl(':confirm:<propname>', None, None, 'confirm', '<propname>') | |
| 105 self.tl(':add:<propname>', None, None, 'add', '<propname>') | |
| 106 self.tl(':remove:<propname>', None, None, 'remove', '<propname>') | |
| 107 self.tl(':link:<propname>', None, None, 'link', '<propname>') | |
| 108 self.tl('test1:<prop>', 'test', '1', None, '<prop>') | |
| 109 self.tl('test1:required', 'test', '1', 'required', None) | |
| 110 self.tl('test1:add:<prop>', 'test', '1', 'add', '<prop>') | |
| 111 self.tl('test1:remove:<prop>', 'test', '1', 'remove', '<prop>') | |
| 112 self.tl('test1:link:<prop>', 'test', '1', 'link', '<prop>') | |
| 113 self.tl('test1:confirm:<prop>', 'test', '1', 'confirm', '<prop>') | |
| 114 self.tl('test-1:<prop>', 'test', '-1', None, '<prop>') | |
| 115 self.tl('test-1:required', 'test', '-1', 'required', None) | |
| 116 self.tl('test-1:add:<prop>', 'test', '-1', 'add', '<prop>') | |
| 117 self.tl('test-1:remove:<prop>', 'test', '-1', 'remove', '<prop>') | |
| 118 self.tl('test-1:link:<prop>', 'test', '-1', 'link', '<prop>') | |
| 119 self.tl('test-1:confirm:<prop>', 'test', '-1', 'confirm', '<prop>') | |
| 120 self.tl(':note', None, None, 'note', None) | |
| 121 self.tl(':file', None, None, 'file', None) | |
| 79 | 122 |
| 80 # | 123 # |
| 81 # Empty form | 124 # Empty form |
| 82 # | 125 # |
| 83 def testNothing(self): | 126 def testNothing(self): |
| 275 self.assertEqual(self.parseForm({'password': ''}, 'user'), | 318 self.assertEqual(self.parseForm({'password': ''}, 'user'), |
| 276 ({('user', None): {}}, [])) | 319 ({('user', None): {}}, [])) |
| 277 self.assertRaises(ValueError, self.parseForm, {'password': ['', '']}, | 320 self.assertRaises(ValueError, self.parseForm, {'password': ['', '']}, |
| 278 'user') | 321 'user') |
| 279 self.assertRaises(ValueError, self.parseForm, {'password': 'foo', | 322 self.assertRaises(ValueError, self.parseForm, {'password': 'foo', |
| 280 'password:confirm': ['', '']}, 'user') | 323 ':confirm:password': ['', '']}, 'user') |
| 281 | 324 |
| 282 def testSetPassword(self): | 325 def testSetPassword(self): |
| 283 self.assertEqual(self.parseForm({'password': 'foo', | 326 self.assertEqual(self.parseForm({'password': 'foo', |
| 284 'password:confirm': 'foo'}, 'user'), | 327 ':confirm:password': 'foo'}, 'user'), |
| 285 ({('user', None): {'password': 'foo'}}, [])) | 328 ({('user', None): {'password': 'foo'}}, [])) |
| 286 | 329 |
| 287 def testSetPasswordConfirmBad(self): | 330 def testSetPasswordConfirmBad(self): |
| 288 self.assertRaises(ValueError, self.parseForm, {'password': 'foo'}, | 331 self.assertRaises(ValueError, self.parseForm, {'password': 'foo'}, |
| 289 'user') | 332 'user') |
| 290 self.assertRaises(ValueError, self.parseForm, {'password': 'foo', | 333 self.assertRaises(ValueError, self.parseForm, {'password': 'foo', |
| 291 'password:confirm': 'bar'}, 'user') | 334 ':confirm:password': 'bar'}, 'user') |
| 292 | 335 |
| 293 def testEmptyPasswordNotSet(self): | 336 def testEmptyPasswordNotSet(self): |
| 294 nodeid = self.db.user.create(username='1', | 337 nodeid = self.db.user.create(username='1', |
| 295 password=password.Password('foo')) | 338 password=password.Password('foo')) |
| 296 self.assertEqual(self.parseForm({'password': ''}, 'user', nodeid), | 339 self.assertEqual(self.parseForm({'password': ''}, 'user', nodeid), |
| 297 ({('user', nodeid): {}}, [])) | 340 ({('user', nodeid): {}}, [])) |
| 298 nodeid = self.db.user.create(username='2', | 341 nodeid = self.db.user.create(username='2', |
| 299 password=password.Password('foo')) | 342 password=password.Password('foo')) |
| 300 self.assertEqual(self.parseForm({'password': '', | 343 self.assertEqual(self.parseForm({'password': '', |
| 301 'password:confirm': ''}, 'user', nodeid), | 344 ':confirm:password': ''}, 'user', nodeid), |
| 302 ({('user', nodeid): {}}, [])) | 345 ({('user', nodeid): {}}, [])) |
| 303 | 346 |
| 304 # | 347 # |
| 305 # Boolean | 348 # Boolean |
| 306 # | 349 # |
| 359 # | 402 # |
| 360 # Test multiple items in form | 403 # Test multiple items in form |
| 361 # | 404 # |
| 362 def testMultiple(self): | 405 def testMultiple(self): |
| 363 self.assertEqual(self.parseForm({'string': 'a', 'issue-1@title': 'b'}), | 406 self.assertEqual(self.parseForm({'string': 'a', 'issue-1@title': 'b'}), |
| 364 ({('test', None): {'string': 'a'}, ('issue', '-1'): | 407 ({('test', None): {'string': 'a'}, |
| 365 {'title': 'b'}}, [])) | 408 ('issue', '-1'): {'title': 'b'} |
| 409 }, [])) | |
| 410 | |
| 411 def testMultipleExistingContext(self): | |
| 366 nodeid = self.db.test.create() | 412 nodeid = self.db.test.create() |
| 367 self.assertEqual(self.parseForm({'string': 'a', 'issue-1@title': 'b'}, | 413 self.assertEqual(self.parseForm({'string': 'a', 'issue-1@title': 'b'}, |
| 368 'test', nodeid), ({('test', nodeid): {'string': 'a'}, | 414 'test', nodeid),({('test', nodeid): {'string': 'a'}, |
| 369 ('issue', '-1'): {'title': 'b'}}, [])) | 415 ('issue', '-1'): {'title': 'b'}}, [])) |
| 416 | |
| 417 def testLinking(self): | |
| 370 self.assertEqual(self.parseForm({ | 418 self.assertEqual(self.parseForm({ |
| 371 'string': 'a', | 419 'string': 'a', |
| 372 'issue-1@:add:nosy': '1', | 420 'issue-1@add@nosy': '1', |
| 373 'issue-2@:link:superseder': 'issue-1', | 421 'issue-2@link@superseder': 'issue-1', |
| 374 }), | 422 }), |
| 375 ({('test', None): {'string': 'a'}, | 423 ({('test', None): {'string': 'a'}, |
| 376 ('issue', '-1'): {'nosy': ['1']}, | 424 ('issue', '-1'): {'nosy': ['1']}, |
| 377 ('issue', '-2'): {}}, | 425 ('issue', '-2'): {} |
| 378 [('issue', '-2', 'superseder', | 426 }, |
| 379 [(('issue', '-1'), ('issue', '-1'))]) | 427 [('issue', '-2', 'superseder', [('issue', '-1')]) |
| 380 ] | 428 ] |
| 381 ) | 429 ) |
| 382 ) | 430 ) |
| 383 | 431 |
| 384 def testLinkBadDesignator(self): | 432 def testLinkBadDesignator(self): |
| 385 self.assertRaises(ValueError, self.parseForm, | 433 self.assertRaises(ValueError, self.parseForm, |
| 386 {'test-1@:link:link': 'blah'}) | 434 {'test-1@link@link': 'blah'}) |
| 387 self.assertRaises(ValueError, self.parseForm, | 435 self.assertRaises(ValueError, self.parseForm, |
| 388 {'test-1@:link:link': 'issue'}) | 436 {'test-1@link@link': 'issue'}) |
| 389 | 437 |
| 390 def testBackwardsCompat(self): | 438 def testBackwardsCompat(self): |
| 391 res = self.parseForm({':note': 'spam'}, 'issue') | 439 res = self.parseForm({':note': 'spam'}, 'issue') |
| 392 date = res[0][('msg', '-1')]['date'] | 440 date = res[0][('msg', '-1')]['date'] |
| 393 self.assertEqual(res, ({('issue', None): {}, ('msg', '-1'): | 441 self.assertEqual(res, ({('issue', None): {}, ('msg', '-1'): |
