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.

186 lines
7.1 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017 Therp BV <http://therp.nl>
  3. # Copyright 2017 LasLabs Inc.
  4. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
  5. from mock import Mock, patch
  6. import os
  7. import tempfile
  8. from odoo.modules.module import load_information_from_description_file,\
  9. get_module_path
  10. from odoo.tests.common import TransactionCase
  11. from ..hooks import _handle_rdepends_if_installed, _installed_modules
  12. MOCK_PATH = 'odoo.addons.base_manifest_extension.hooks'
  13. class TestHooks(TransactionCase):
  14. def setUp(self):
  15. super(TestHooks, self).setUp()
  16. self.test_cr = self.env.cr
  17. self.test_rdepends = [
  18. 'base',
  19. 'base_manifest_extension',
  20. 'not_installed',
  21. ]
  22. self.test_manifest = {
  23. 'rdepends_if_installed': self.test_rdepends,
  24. 'depends': [],
  25. }
  26. self.test_module_name = 'base_manifest_extension'
  27. self.test_call = (
  28. self.test_cr,
  29. self.test_manifest,
  30. self.test_module_name,
  31. )
  32. def test_base_manifest_extension(self):
  33. # write a test manifest
  34. module_path = tempfile.mkdtemp(dir=os.path.join(
  35. get_module_path('base_manifest_extension'), 'static'
  36. ))
  37. manifest_path = os.path.join(module_path, '__manifest__.py')
  38. with open(manifest_path, 'w') as manifest:
  39. manifest.write(repr({
  40. 'depends_if_installed': [
  41. 'base_manifest_extension',
  42. 'not installed',
  43. ],
  44. }))
  45. # parse it
  46. parsed = load_information_from_description_file(
  47. # this name won't really be used, but avoids a warning
  48. 'base', mod_path=module_path,
  49. )
  50. self.assertIn('base_manifest_extension', parsed['depends'])
  51. self.assertNotIn('not installed', parsed['depends'])
  52. self.assertNotIn('depends_if_installed', parsed)
  53. def test_installed_modules_correct_result(self):
  54. """It should return only installed modules in list"""
  55. result = _installed_modules(self.test_cr, self.test_rdepends)
  56. expected = self.test_rdepends[:2]
  57. self.assertItemsEqual(result, expected)
  58. def test_installed_modules_empty_starting_list(self):
  59. """It should safely handle being passed an empty module list"""
  60. result = _installed_modules(self.test_cr, [])
  61. self.assertEqual(result, [])
  62. @patch(MOCK_PATH + '._get_graph')
  63. def test_handle_rdepends_if_installed_graph_call(self, graph_mock):
  64. """It should call graph helper and return early if graph not found"""
  65. graph_mock.return_value = None
  66. graph_mock.reset_mock()
  67. self.test_cr = Mock()
  68. self.test_cr.reset_mock()
  69. _handle_rdepends_if_installed(*self.test_call)
  70. graph_mock.assert_called_once()
  71. self.test_cr.assert_not_called()
  72. @patch(MOCK_PATH + '._get_graph')
  73. def test_handle_rdepends_if_installed_clean_manifest(self, graph_mock):
  74. """It should remove rdepends key from manifest"""
  75. _handle_rdepends_if_installed(*self.test_call)
  76. self.assertEqual(self.test_manifest, {'depends': []})
  77. @patch(MOCK_PATH + '.local.rdepends_to_process', new_callable=dict)
  78. @patch(MOCK_PATH + '._get_graph')
  79. def test_handle_rdepends_if_installed_list(self, graph_mock, dict_mock):
  80. """It should correctly add all installed rdepends to processing dict"""
  81. _handle_rdepends_if_installed(*self.test_call)
  82. expected_result = {
  83. 'base': set([self.test_module_name]),
  84. 'base_manifest_extension': set([self.test_module_name]),
  85. }
  86. self.assertEqual(dict_mock, expected_result)
  87. @patch(MOCK_PATH + '.local.rdepends_to_process', new_callable=dict)
  88. @patch(MOCK_PATH + '._get_graph')
  89. def test_handle_rdepends_if_installed_dupes(self, graph_mock, dict_mock):
  90. """It should correctly handle multiple calls with same rdepends"""
  91. for __ in range(2):
  92. _handle_rdepends_if_installed(*self.test_call)
  93. self.test_manifest['rdepends_if_installed'] = self.test_rdepends
  94. test_module_name_2 = 'test_module_name_2'
  95. _handle_rdepends_if_installed(
  96. self.test_cr,
  97. self.test_manifest,
  98. test_module_name_2,
  99. )
  100. expected_set = set([self.test_module_name, test_module_name_2])
  101. expected_result = {
  102. 'base': expected_set,
  103. 'base_manifest_extension': expected_set,
  104. }
  105. self.assertEqual(dict_mock, expected_result)
  106. @patch(MOCK_PATH + '._get_graph')
  107. def test_handle_rdepends_if_installed_graph_reload(self, graph_mock):
  108. """It should reload installed rdepends already in module graph"""
  109. class TestGraph(dict):
  110. pass
  111. test_graph = TestGraph(base='Test Value')
  112. test_graph.add_module = Mock()
  113. graph_mock.return_value = test_graph
  114. _handle_rdepends_if_installed(*self.test_call)
  115. self.assertEqual(test_graph, {})
  116. test_graph.add_module.assert_called_once_with(self.cr, 'base')
  117. @patch(MOCK_PATH + '._handle_rdepends_if_installed')
  118. @patch(MOCK_PATH + '._get_cr')
  119. @patch(MOCK_PATH + '.original')
  120. def test_load_information_from_description_file_rdepends_key(
  121. self, super_mock, cr_mock, helper_mock
  122. ):
  123. """It should correctly call rdepends helper if key present"""
  124. super_mock.return_value = self.test_manifest
  125. cr_mock.return_value = self.cr
  126. helper_mock.reset_mock()
  127. load_information_from_description_file(self.test_module_name)
  128. helper_mock.assert_called_once_with(*self.test_call)
  129. @patch(MOCK_PATH + '._handle_rdepends_if_installed')
  130. @patch(MOCK_PATH + '._get_cr')
  131. @patch(MOCK_PATH + '.original')
  132. def test_load_information_from_description_file_no_rdepends_key(
  133. self, super_mock, cr_mock, helper_mock
  134. ):
  135. """It should not call rdepends helper if key not present"""
  136. del self.test_manifest['rdepends_if_installed']
  137. super_mock.return_value = self.test_manifest
  138. cr_mock.return_value = self.cr
  139. helper_mock.reset_mock()
  140. load_information_from_description_file(self.test_module_name)
  141. helper_mock.assert_not_called()
  142. @patch(MOCK_PATH + '._get_cr')
  143. @patch(MOCK_PATH + '.original')
  144. def test_load_information_from_description_file_rdepends_to_process(
  145. self, super_mock, cr_mock
  146. ):
  147. """It should correctly add pending rdepends to manifest"""
  148. del self.test_manifest['rdepends_if_installed']
  149. super_mock.return_value = self.test_manifest
  150. cr_mock.return_value = self.cr
  151. test_depends = set(['Test Depend 1', 'Test Depend 2'])
  152. test_rdepend_dict = {
  153. self.test_module_name: test_depends,
  154. 'Other Module': set(['Other Depend']),
  155. }
  156. dict_path = MOCK_PATH + '.local.rdepends_to_process'
  157. with patch.dict(dict_path, test_rdepend_dict, clear=True):
  158. load_information_from_description_file(self.test_module_name)
  159. self.assertEqual(self.test_manifest['depends'], list(test_depends))