PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/xivo_dird/plugins/tests/test_phonebook_plugin.py

https://gitlab.com/xivo.solutions/xivo-dird
Python | 348 lines | 240 code | 92 blank | 16 comment | 0 complexity | 5d6c24a7d0176409294dc6e3be88d62e MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2015 Avencall
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>
  17. import unittest
  18. from hamcrest import assert_that, contains_inanyorder
  19. from mock import Mock, ANY, sentinel, patch
  20. from xivo_dird.plugins.base_plugins import BaseSourcePlugin
  21. from xivo_dird.plugins.phonebook_plugin import _PhonebookConfig, \
  22. _PhonebookResultConverter, _PhonebookClient, PhonebookPlugin, _PhonebookFactory
  23. from xivo_dird.plugins.source_result import make_result_class
  24. class TestPhonebookPlugin(unittest.TestCase):
  25. def setUp(self):
  26. self.config = {'config': sentinel}
  27. self.pbook_config = Mock(_PhonebookConfig)
  28. self.pbook_result_converter = Mock(_PhonebookResultConverter)
  29. self.pbook_client = Mock(_PhonebookClient)
  30. self.pbook_factory = Mock(_PhonebookFactory)
  31. self.pbook_factory.new_phonebook_config.return_value = self.pbook_config
  32. self.pbook_factory.new_phonebook_result_converter.return_value = self.pbook_result_converter
  33. self.pbook_factory.new_phonebook_client.return_value = self.pbook_client
  34. self.pbook_plugin = PhonebookPlugin()
  35. self.pbook_plugin.pbook_factory = self.pbook_factory
  36. def test_load(self):
  37. self.pbook_plugin.load(self.config)
  38. self.pbook_factory.new_phonebook_config.assert_called_once_with(self.config['config'])
  39. self.pbook_factory.new_phonebook_result_converter.assert_called_once_with(self.pbook_config)
  40. self.pbook_factory.new_phonebook_client.assert_called_once_with(self.pbook_config)
  41. def test_search(self):
  42. term = 'foobar'
  43. self.pbook_client.search.return_value = sentinel.search_result
  44. self.pbook_result_converter.convert_all.return_value = sentinel.convert_all_result
  45. self.pbook_plugin.load(self.config)
  46. result = self.pbook_plugin.search(term)
  47. self.pbook_client.search.assert_called_once_with(term)
  48. self.pbook_result_converter.convert_all.assert_called_once_with(sentinel.search_result)
  49. self.assertIs(result, sentinel.convert_all_result)
  50. def test_first_match(self):
  51. exten = '123456'
  52. self.pbook_client.first_match.return_value = sentinel.first_match_result
  53. self.pbook_result_converter.convert.return_value = sentinel.convert_result
  54. self.pbook_plugin.load(self.config)
  55. result = self.pbook_plugin.first_match(exten)
  56. self.pbook_client.first_match.assert_called_once_with(exten)
  57. self.pbook_result_converter.convert.assert_called_once_with(sentinel.first_match_result)
  58. self.assertIs(result, sentinel.convert_result)
  59. class _TestPhonebookFactory(unittest.TestCase):
  60. def setUp(self):
  61. self.pbook_factory = _PhonebookFactory()
  62. def test_phonebook_config(self):
  63. phonebook_config = self.pbook_factory.new_phonebook_config({})
  64. self.assertIsInstance(phonebook_config, _PhonebookConfig)
  65. def test_phonebook_client(self):
  66. phonebook_client = self.pbook_factory.new_phonebook_client(sentinel.pbook_config)
  67. self.assertIsInstance(phonebook_client, _PhonebookClient)
  68. def test_phonebook_result_converter(self):
  69. phonebook_result_converter = self.pbook_factory.new_phonebook_result_converter(sentinel.pbook_config)
  70. self.assertIsInstance(phonebook_result_converter, _PhonebookResultConverter)
  71. class TestPhonebookConfig(unittest.TestCase):
  72. def test_name(self):
  73. value = 'foo'
  74. phonebook_config = _PhonebookConfig({'name': value})
  75. self.assertEqual(value, phonebook_config.name())
  76. def test_name_when_absent(self):
  77. phonebook_config = _PhonebookConfig({})
  78. self.assertRaises(Exception, phonebook_config.name)
  79. def test_format_columns(self):
  80. value = {'firstname': '{phonebook.firstname}'}
  81. phonebook_config = _PhonebookConfig({
  82. BaseSourcePlugin.FORMAT_COLUMNS: value,
  83. })
  84. self.assertEqual(value, phonebook_config.format_columns())
  85. def test_format_columns_when_absent(self):
  86. phonebook_config = _PhonebookConfig({})
  87. self.assertRaises(Exception, phonebook_config.format_columns)
  88. def test_first_matched_columns(self):
  89. value = ['phonebook.exten']
  90. phonebook_config = _PhonebookConfig({
  91. BaseSourcePlugin.FIRST_MATCHED_COLUMNS: value,
  92. })
  93. self.assertEqual(value, phonebook_config.first_matched_columns())
  94. def test_looked_up_keys(self):
  95. value = {'firstname': '{phonebook.firstname}',
  96. 'name': '{phonebook.firstname} {phonebook.lastname}'}
  97. phonebook_config = _PhonebookConfig({
  98. BaseSourcePlugin.FORMAT_COLUMNS: value,
  99. })
  100. assert_that(phonebook_config.looked_up_keys(),
  101. contains_inanyorder('phonebook.firstname', 'phonebook.lastname'))
  102. def test_phonebook_url(self):
  103. value = 'http://example.org/foobar'
  104. phonebook_config = _PhonebookConfig({'phonebook_url': value})
  105. self.assertEqual(value, phonebook_config.phonebook_url())
  106. def test_phonebook_url_when_absent(self):
  107. phonebook_config = _PhonebookConfig({})
  108. self.assertEqual(_PhonebookConfig.DEFAULT_PHONEBOOK_URL, phonebook_config.phonebook_url())
  109. def test_phonebook_username(self):
  110. value = 'john'
  111. phonebook_config = _PhonebookConfig({'phonebook_username': value})
  112. self.assertEqual(value, phonebook_config.phonebook_username())
  113. def test_phonebook_password(self):
  114. value = 'foobar'
  115. phonebook_config = _PhonebookConfig({'phonebook_password': value})
  116. self.assertEqual(value, phonebook_config.phonebook_password())
  117. def test_phonebook_timeout(self):
  118. value = 4.0
  119. phonebook_config = _PhonebookConfig({'phonebook_timeout': value})
  120. self.assertEqual(value, phonebook_config.phonebook_timeout())
  121. class TestPhonebookClient(unittest.TestCase):
  122. def setUp(self):
  123. self.url = 'http://example.org'
  124. self.username = 'admin'
  125. self.password = 'foobar'
  126. self.timeout = 1.1
  127. self.first_matched_columns = ['phonebook.exten', 'phonebook.office']
  128. self.pbook_config = Mock(_PhonebookConfig)
  129. self.pbook_config.phonebook_url.return_value = self.url
  130. self.pbook_config.phonebook_username.return_value = self.username
  131. self.pbook_config.phonebook_password.return_value = self.password
  132. self.pbook_config.phonebook_timeout.return_value = self.timeout
  133. self.pbook_config.first_matched_columns.return_value = self.first_matched_columns
  134. self.pbook_client = _PhonebookClient(self.pbook_config)
  135. @patch('xivo_dird.plugins.phonebook_plugin.requests')
  136. def test_search(self, mock_requests):
  137. response = Mock()
  138. response.status_code = 200
  139. response.json.return_value = sentinel.json
  140. mock_requests.get.return_value = response
  141. result = self.pbook_client.search('foo')
  142. mock_requests.get.assert_called_once_with(self.url,
  143. auth=ANY,
  144. params={'act': 'search', 'search': 'foo'},
  145. timeout=self.timeout, verify=False)
  146. response.json.assert_called_once_with()
  147. self.assertIs(result, sentinel.json)
  148. @patch('xivo_dird.plugins.phonebook_plugin.requests')
  149. def test_search_on_http_204(self, mock_requests):
  150. response = Mock()
  151. response.status_code = 204
  152. mock_requests.get.return_value = response
  153. result = self.pbook_client.search('foo')
  154. self.assertFalse(response.json.called)
  155. self.assertEqual(result, [])
  156. @patch('xivo_dird.plugins.phonebook_plugin.requests')
  157. def test_search_on_http_401(self, mock_requests):
  158. response = Mock()
  159. response.status_code = 401
  160. mock_requests.get.return_value = response
  161. result = self.pbook_client.search('foo')
  162. self.assertFalse(response.json.called)
  163. self.assertEqual(result, [])
  164. @patch('xivo_dird.plugins.phonebook_plugin.requests')
  165. def test_search_on_requests_exception(self, mock_requests):
  166. mock_requests.exceptions.TimeoutError = TimeoutError('test')
  167. result = self.pbook_client.search('foo')
  168. self.assertEqual(result, [])
  169. def test_first_match_return_None_if_no_match(self):
  170. self.pbook_client.search = Mock()
  171. self.pbook_client.search.return_value = []
  172. result = self.pbook_client.first_match('123456')
  173. self.assertIs(result, None)
  174. def test_new_auth(self):
  175. auth = self.pbook_client._new_auth(self.pbook_config)
  176. self.assertIsNotNone(auth)
  177. def test_new_auth_when_no_username(self):
  178. self.pbook_config.phonebook_username.return_value = None
  179. self.pbook_config.phonebook_password.return_value = None
  180. auth = self.pbook_client._new_auth(self.pbook_config)
  181. self.assertIsNone(auth)
  182. class TestPhonebookResultConverter(unittest.TestCase):
  183. def setUp(self):
  184. self.name = 'foo'
  185. self.format_columns = {
  186. 'name': '{phonebook.firstname} {phonebook.lastname}',
  187. 'firstname': '{phonebook.firstname}',
  188. 'lastname': '{phonebook.lastname}',
  189. 'number': '{phonebooknumber.office.number}',
  190. }
  191. self.pbook_config = Mock(_PhonebookConfig)
  192. self.pbook_config.name.return_value = self.name
  193. self.pbook_config.format_columns.return_value = self.format_columns
  194. self.pbook_config.looked_up_keys.return_value = ['phonebook.firstname',
  195. 'phonebook.lastname',
  196. 'phonebooknumber.office.number']
  197. self.pbook_result_converter = _PhonebookResultConverter(self.pbook_config)
  198. self.SourceResult = make_result_class(self.name, None, None)
  199. def test_convert(self):
  200. raw_result = {
  201. 'phonebook': {
  202. 'firstname': 'Alice',
  203. 'lastname': 'Wonder',
  204. 'displayname': 'Alice Wonder',
  205. },
  206. 'phonebooknumber': {
  207. 'office': {
  208. 'number': '111',
  209. }
  210. },
  211. }
  212. expected_result = self.SourceResult({'firstname': 'Alice',
  213. 'lastname': 'Wonder',
  214. 'name': 'Alice Wonder',
  215. 'number': '111'})
  216. result = self.pbook_result_converter.convert(raw_result)
  217. self.assertEqual(expected_result, result)
  218. def test_convert_value_false_doesnt_raise(self):
  219. raw_result = {
  220. 'phonebook': {
  221. 'firstname': 'Éric',
  222. 'lastname': 'Wonder',
  223. },
  224. 'phonebooknumber': False,
  225. }
  226. expected_result = self.SourceResult({'firstname': 'Éric',
  227. 'lastname': 'Wonder',
  228. 'name': 'Éric Wonder',
  229. 'number': None})
  230. result = self.pbook_result_converter.convert(raw_result)
  231. self.assertEqual(expected_result, result)
  232. def test_convert_missing_key_doesnt_raise(self):
  233. raw_result = {
  234. 'phonebook': {
  235. 'firstname': 'Alice',
  236. },
  237. }
  238. expected_result = self.SourceResult({'firstname': 'Alice',
  239. 'lastname': None,
  240. 'name': 'Alice',
  241. 'number': None})
  242. result = self.pbook_result_converter.convert(raw_result)
  243. self.assertEqual(expected_result, result)
  244. def test_convert_all(self):
  245. raw_results = [{
  246. 'phonebook': {
  247. 'firstname': 'Alice',
  248. 'lastname': 'Wonder',
  249. },
  250. }]
  251. expected_results = [self.SourceResult({'firstname': 'Alice',
  252. 'lastname': 'Wonder',
  253. 'name': 'Alice Wonder',
  254. 'number': None})]
  255. results = self.pbook_result_converter.convert_all(raw_results)
  256. self.assertEqual(expected_results, results)