You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
4.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2016-2017 LasLabs Inc.
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. import mock
  5. from contextlib import contextmanager
  6. from odoo.tools.misc import mute_logger
  7. from odoo.tests.common import TransactionCase
  8. class EndTestException(Exception):
  9. """ It stops tests from continuing """
  10. pass
  11. class TestResUsers(TransactionCase):
  12. def setUp(self):
  13. super(TestResUsers, self).setUp()
  14. self.ResUsers = self.env['res.users']
  15. @contextmanager
  16. def _mock_assets(self, assets=None):
  17. """ It provides mocked imports from res_users.py
  18. :param assets: (list) Name of imports to mock. Mocks `http` if None
  19. :return: (dict) Dictionary of mocks, keyed by module name
  20. """
  21. if assets is None:
  22. assets = ['http']
  23. patches = {name: mock.DEFAULT for name in assets}
  24. with mock.patch.multiple(
  25. 'odoo.addons.auth_session_timeout.models.res_users', **patches
  26. ) as mocks:
  27. yield mocks
  28. def _auth_timeout_check(self, http_mock):
  29. """ It wraps ``_auth_timeout_check`` for easier calling """
  30. self.db = mock.MagicMock()
  31. self.uid = mock.MagicMock()
  32. self.passwd = mock.MagicMock()
  33. self.path = '/this/is/a/test/path'
  34. get_filename = http_mock.root.session_store.get_session_filename
  35. get_filename.return_value = self.path
  36. return self.ResUsers._auth_timeout_check()
  37. def test_session_validity_no_request(self):
  38. """ It should return immediately if no request """
  39. with self._mock_assets() as assets:
  40. assets['http'].request = False
  41. res = self._auth_timeout_check(assets['http'])
  42. self.assertFalse(res)
  43. def test_session_validity_gets_session_file(self):
  44. """ It should call get the session file for the session id """
  45. with self._mock_assets() as assets:
  46. get_params = assets['http'].request.env[''].get_session_parameters
  47. get_params.return_value = 0, []
  48. store = assets['http'].root.session_store
  49. store.get_session_filename.side_effect = EndTestException
  50. with self.assertRaises(EndTestException):
  51. self._auth_timeout_check(assets['http'])
  52. store.get_session_filename.assert_called_once_with(
  53. assets['http'].request.session.sid,
  54. )
  55. def test_session_validity_logout(self):
  56. """ It should log out of session if past deadline """
  57. with self._mock_assets(['http', 'getmtime', 'utime']) as assets:
  58. get_params = assets['http'].request.env[''].get_session_parameters
  59. get_params.return_value = -9999, []
  60. assets['getmtime'].return_value = 0
  61. self._auth_timeout_check(assets['http'])
  62. assets['http'].request.session.logout.assert_called_once_with(
  63. keep_db=True,
  64. )
  65. def test_session_validity_updates_utime(self):
  66. """ It should update utime of session file if not expired """
  67. with self._mock_assets(['http', 'getmtime', 'utime']) as assets:
  68. get_params = assets['http'].request.env[''].get_session_parameters
  69. get_params.return_value = 9999, []
  70. self._auth_timeout_check(assets['http'])
  71. assets['utime'].assert_called_once_with(
  72. assets['http'].root.session_store.get_session_filename(),
  73. None,
  74. )
  75. @mute_logger('odoo.addons.auth_session_timeout.models.res_users')
  76. def test_session_validity_os_error_guard(self):
  77. """ It should properly guard from OSError & return """
  78. with self._mock_assets(['http', 'utime', 'getmtime']) as assets:
  79. get_params = assets['http'].request.env[''].get_session_parameters
  80. get_params.return_value = 0, []
  81. assets['getmtime'].side_effect = OSError
  82. res = self._auth_timeout_check(assets['http'])
  83. self.assertFalse(res)
  84. def test_on_timeout_session_loggedout(self):
  85. with self._mock_assets(['http', 'getmtime']) as assets:
  86. assets['getmtime'].return_value = 0
  87. assets['http'].request.session.uid = self.env.uid
  88. assets['http'].request.session.dbname = self.env.cr.dbname
  89. assets['http'].request.session.sid = 123
  90. assets['http'].request.session.logout = mock.Mock()
  91. self.ResUsers._auth_timeout_check()
  92. self.assertTrue(assets['http'].request.session.logout.called)