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.

185 lines
7.0 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 openerp.modules.module import load_information_from_description_file,\
  9. get_module_path, MANIFEST
  10. from openerp.tests.common import TransactionCase
  11. from ..hooks import _handle_rdepends_if_installed, _installed_modules
  12. MOCK_PATH = 'openerp.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. with open(os.path.join(module_path, MANIFEST), 'w') as manifest:
  38. manifest.write(repr({
  39. 'depends_if_installed': [
  40. 'base_manifest_extension',
  41. 'not installed',
  42. ],
  43. }))
  44. # parse it
  45. parsed = load_information_from_description_file(
  46. # this name won't really be used, but avoids a warning
  47. 'base', mod_path=module_path,
  48. )
  49. self.assertIn('base_manifest_extension', parsed['depends'])
  50. self.assertNotIn('not installed', parsed['depends'])
  51. self.assertNotIn('depends_if_installed', parsed)
  52. def test_installed_modules_correct_result(self):
  53. """It should return only installed modules in list"""
  54. result = _installed_modules(self.test_cr, self.test_rdepends)
  55. expected = self.test_rdepends[:2]
  56. self.assertItemsEqual(result, expected)
  57. def test_installed_modules_empty_starting_list(self):
  58. """It should safely handle being passed an empty module list"""
  59. result = _installed_modules(self.test_cr, [])
  60. self.assertEqual(result, [])
  61. @patch(MOCK_PATH + '._get_graph')
  62. def test_handle_rdepends_if_installed_graph_call(self, graph_mock):
  63. """It should call graph helper and return early if graph not found"""
  64. graph_mock.return_value = None
  65. graph_mock.reset_mock()
  66. self.test_cr = Mock()
  67. self.test_cr.reset_mock()
  68. _handle_rdepends_if_installed(*self.test_call)
  69. graph_mock.assert_called_once()
  70. self.test_cr.assert_not_called()
  71. @patch(MOCK_PATH + '._get_graph')
  72. def test_handle_rdepends_if_installed_clean_manifest(self, graph_mock):
  73. """It should remove rdepends key from manifest"""
  74. _handle_rdepends_if_installed(*self.test_call)
  75. self.assertEqual(self.test_manifest, {'depends': []})
  76. @patch(MOCK_PATH + '.local.rdepends_to_process', new_callable=dict)
  77. @patch(MOCK_PATH + '._get_graph')
  78. def test_handle_rdepends_if_installed_list(self, graph_mock, dict_mock):
  79. """It should correctly add all installed rdepends to processing dict"""
  80. _handle_rdepends_if_installed(*self.test_call)
  81. expected_result = {
  82. 'base': set([self.test_module_name]),
  83. 'base_manifest_extension': set([self.test_module_name]),
  84. }
  85. self.assertEqual(dict_mock, expected_result)
  86. @patch(MOCK_PATH + '.local.rdepends_to_process', new_callable=dict)
  87. @patch(MOCK_PATH + '._get_graph')
  88. def test_handle_rdepends_if_installed_dupes(self, graph_mock, dict_mock):
  89. """It should correctly handle multiple calls with same rdepends"""
  90. for __ in range(2):
  91. _handle_rdepends_if_installed(*self.test_call)
  92. self.test_manifest['rdepends_if_installed'] = self.test_rdepends
  93. test_module_name_2 = 'test_module_name_2'
  94. _handle_rdepends_if_installed(
  95. self.test_cr,
  96. self.test_manifest,
  97. test_module_name_2,
  98. )
  99. expected_set = set([self.test_module_name, test_module_name_2])
  100. expected_result = {
  101. 'base': expected_set,
  102. 'base_manifest_extension': expected_set,
  103. }
  104. self.assertEqual(dict_mock, expected_result)
  105. @patch(MOCK_PATH + '._get_graph')
  106. def test_handle_rdepends_if_installed_graph_reload(self, graph_mock):
  107. """It should reload installed rdepends already in module graph"""
  108. class TestGraph(dict):
  109. pass
  110. test_graph = TestGraph(base='Test Value')
  111. test_graph.add_module = Mock()
  112. graph_mock.return_value = test_graph
  113. _handle_rdepends_if_installed(*self.test_call)
  114. self.assertEqual(test_graph, {})
  115. test_graph.add_module.assert_called_once_with(self.cr, 'base')
  116. @patch(MOCK_PATH + '._handle_rdepends_if_installed')
  117. @patch(MOCK_PATH + '._get_cr')
  118. @patch(MOCK_PATH + '.original')
  119. def test_load_information_from_description_file_rdepends_key(
  120. self, super_mock, cr_mock, helper_mock
  121. ):
  122. """It should correctly call rdepends helper if key present"""
  123. super_mock.return_value = self.test_manifest
  124. cr_mock.return_value = self.cr
  125. helper_mock.reset_mock()
  126. load_information_from_description_file(self.test_module_name)
  127. helper_mock.assert_called_once_with(*self.test_call)
  128. @patch(MOCK_PATH + '._handle_rdepends_if_installed')
  129. @patch(MOCK_PATH + '._get_cr')
  130. @patch(MOCK_PATH + '.original')
  131. def test_load_information_from_description_file_no_rdepends_key(
  132. self, super_mock, cr_mock, helper_mock
  133. ):
  134. """It should not call rdepends helper if key not present"""
  135. del self.test_manifest['rdepends_if_installed']
  136. super_mock.return_value = self.test_manifest
  137. cr_mock.return_value = self.cr
  138. helper_mock.reset_mock()
  139. load_information_from_description_file(self.test_module_name)
  140. helper_mock.assert_not_called()
  141. @patch(MOCK_PATH + '._get_cr')
  142. @patch(MOCK_PATH + '.original')
  143. def test_load_information_from_description_file_rdepends_to_process(
  144. self, super_mock, cr_mock
  145. ):
  146. """It should correctly add pending rdepends to manifest"""
  147. del self.test_manifest['rdepends_if_installed']
  148. super_mock.return_value = self.test_manifest
  149. cr_mock.return_value = self.cr
  150. test_depends = set(['Test Depend 1', 'Test Depend 2'])
  151. test_rdepend_dict = {
  152. self.test_module_name: test_depends,
  153. 'Other Module': set(['Other Depend']),
  154. }
  155. dict_path = MOCK_PATH + '.local.rdepends_to_process'
  156. with patch.dict(dict_path, test_rdepend_dict, clear=True):
  157. load_information_from_description_file(self.test_module_name)
  158. self.assertEqual(self.test_manifest['depends'], list(test_depends))