comparison test/test_actions.py @ 5121:894aa07be6cb

issue2550785: Using login from search (or logout) fails. when logging in from a search page or after a logout it fails with an error. The fix also keeps the user on the same page they started from (e.g. search results) before the login. There are two parts to this: 1) changes to the templates to properly define the __came_from form element. 2) code changes to the LoginAction code in roundup/cgi/actions.py. New test code added. Needed some additional functions from urllib so urllib_.py got a change.
author John Rouillard <rouilj@ieee.org>
date Sun, 03 Jul 2016 12:32:35 -0400
parents 748ba87e1aca
children 114d9628fd77
comparison
equal deleted inserted replaced
5120:722394a48d7b 5121:894aa07be6cb
235 235
236 # unless explicitly overridden, we should never get here 236 # unless explicitly overridden, we should never get here
237 self.client.opendb = lambda a: self.fail( 237 self.client.opendb = lambda a: self.fail(
238 "Logged in, but we shouldn't be.") 238 "Logged in, but we shouldn't be.")
239 239
240 def assertRaisesMessage(self, exception, callable, message, *args,
241 **kwargs):
242 """An extension of assertRaises, which also checks the exception
243 message. We need this because we rely on exception messages when
244 redirecting.
245 """
246 try:
247 callable(*args, **kwargs)
248 except exception, msg:
249 self.assertEqual(str(msg), message)
250 else:
251 if hasattr(exception, '__name__'):
252 excName = exception.__name__
253 else:
254 excName = str(exception)
255 raise self.failureException, excName
256
240 def assertLoginLeavesMessages(self, messages, username=None, password=None): 257 def assertLoginLeavesMessages(self, messages, username=None, password=None):
241 if username is not None: 258 if username is not None:
242 self.form.value.append(MiniFieldStorage('__login_name', username)) 259 self.form.value.append(MiniFieldStorage('__login_name', username))
243 if password is not None: 260 if password is not None:
244 self.form.value.append( 261 self.form.value.append(
245 MiniFieldStorage('__login_password', password)) 262 MiniFieldStorage('__login_password', password))
246 263
247 LoginAction(self.client).handle() 264 LoginAction(self.client).handle()
248 self.assertEqual(self.client._error_message, messages) 265 self.assertEqual(self.client._error_message, messages)
249 266
267 def assertLoginRaisesRedirect(self, message, username=None, password=None, came_from=None):
268 if username is not None:
269 self.form.value.append(MiniFieldStorage('__login_name', username))
270 if password is not None:
271 self.form.value.append(
272 MiniFieldStorage('__login_password', password))
273 if came_from is not None:
274 self.form.value.append(
275 MiniFieldStorage('__came_from', came_from))
276
277 self.assertRaisesMessage(Redirect, LoginAction(self.client).handle, message)
278
250 def testNoUsername(self): 279 def testNoUsername(self):
251 self.assertLoginLeavesMessages(['Username required']) 280 self.assertLoginLeavesMessages(['Username required'])
252 281
253 def testInvalidUsername(self): 282 def testInvalidUsername(self):
254 def raiseKeyError(a): 283 def raiseKeyError(a):
269 def opendb(username): 298 def opendb(username):
270 self.assertEqual(username, 'foo') 299 self.assertEqual(username, 'foo')
271 self.client.opendb = opendb 300 self.client.opendb = opendb
272 301
273 self.assertLoginLeavesMessages([], 'foo', 'right') 302 self.assertLoginLeavesMessages([], 'foo', 'right')
303
304 def testCorrectLoginRedirect(self):
305 self.client.db.security.hasPermission = lambda *args, **kwargs: True
306 def opendb(username):
307 self.assertEqual(username, 'foo')
308 self.client.opendb = opendb
309
310 # basic test with query
311 self.assertLoginRaisesRedirect("http://whoami.com/path/issue?%40action=search",
312 'foo', 'right', "http://whoami.com/path/issue?@action=search")
313
314 # test that old messages are removed
315 self.form.value[:] = [] # clear out last test's setup values
316 self.assertLoginRaisesRedirect("http://whoami.com/path/issue?%40action=search",
317 'foo', 'right', "http://whoami.com/path/issue?@action=search&@ok_messagehurrah+we+win&@error_message=blam")
318
319 # test when there is no query
320 self.form.value[:] = [] # clear out last test's setup values
321 self.assertLoginRaisesRedirect("http://whoami.com/path/issue255",
322 'foo', 'right', "http://whoami.com/path/issue255")
323
324 # test if we are logged out; should kill the @action=logout
325 self.form.value[:] = [] # clear out last test's setup values
326 self.assertLoginRaisesRedirect("http://localhost:9017/demo/issue39?%40startwith=0&%40pagesize=50",
327 'foo', 'right', "http://localhost:9017/demo/issue39?@action=logout&@pagesize=50&@startwith=0")
328
329 def testInvalidLoginRedirect(self):
330 self.client.db.security.hasPermission = lambda *args, **kwargs: True
331
332 def opendb(username):
333 self.assertEqual(username, 'foo')
334 self.client.opendb = opendb
335
336 # basic test with query
337 self.assertLoginRaisesRedirect("http://whoami.com/path/issue?%40error_message=Invalid+login&%40action=search",
338 'foo', 'wrong', "http://whoami.com/path/issue?@action=search")
339
340 # test that old messages are removed
341 self.form.value[:] = [] # clear out last test's setup values
342 self.assertLoginRaisesRedirect("http://whoami.com/path/issue?%40error_message=Invalid+login&%40action=search",
343 'foo', 'wrong', "http://whoami.com/path/issue?@action=search&@ok_messagehurrah+we+win&@error_message=blam")
344
345 # test when there is no __came_from specified
346 self.form.value[:] = [] # clear out last test's setup values
347 # I am not sure why this produces three copies of the same error.
348 # only one copy of the error is displayed to the user in the web interface.
349 self.assertLoginLeavesMessages(['Invalid login', 'Invalid login', 'Invalid login'], 'foo', 'wrong')
350
351 # test when there is no query
352 self.form.value[:] = [] # clear out last test's setup values
353 self.assertLoginRaisesRedirect("http://whoami.com/path/issue255?%40error_message=Invalid+login",
354 'foo', 'wrong', "http://whoami.com/path/issue255")
274 355
275 class EditItemActionTestCase(ActionTestCase): 356 class EditItemActionTestCase(ActionTestCase):
276 def setUp(self): 357 def setUp(self):
277 ActionTestCase.setUp(self) 358 ActionTestCase.setUp(self)
278 self.result = [] 359 self.result = []

Roundup Issue Tracker: http://roundup-tracker.org/