No Description
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.

test_leobject.py 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. #
  2. # This file is part of Lodel 2 (https://github.com/OpenEdition)
  3. #
  4. # Copyright (C) 2015-2017 Cléo UMS-3287
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU Affero General Public License as published
  8. # by the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU Affero General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Affero General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import unittest
  20. from unittest import mock
  21. from unittest.mock import patch
  22. import tests.loader_utils
  23. import leapi_dyncode as dyncode
  24. from lodel.leapi.leobject import LeObject
  25. from lodel.leapi.query import LeDeleteQuery, LeUpdateQuery, LeGetQuery, \
  26. LeInsertQuery
  27. from lodel.leapi.exceptions import *
  28. class LeObjectDummyTestCase(unittest.TestCase):
  29. """ Testing LeObject method with a dummy datasource """
  30. def test_init(self):
  31. """ Testing LeObject child class __init__ """
  32. dyncode.Person(
  33. lodel_id = '1',
  34. lastname = "Foo",
  35. firstname = "Bar",
  36. alias = "Foobar")
  37. def test_init_abstract(self):
  38. """ Testing init abstract LeObject childs """
  39. abstract_classes = [
  40. dyncode.Entitie, dyncode.Indexabs]
  41. for cls in abstract_classes:
  42. with self.assertRaises(NotImplementedError):
  43. cls(lodel_id = 1)
  44. def test_init_bad_fields(self):
  45. """ Testing init with bad arguments """
  46. with self.assertRaises(LeApiErrors):
  47. dyncode.Person(
  48. lodel_id = 1,
  49. foobar = "barfoo")
  50. with self.assertRaises(LeApiError):
  51. dyncode.Person(lastname = "foo", firstname = "bar")
  52. def test_data_accessor(self):
  53. """ Testing data accessor method """
  54. inst = dyncode.Person(lodel_id = 1, lastname = "foo")
  55. self.assertEqual(inst.data('lodel_id'), 1)
  56. self.assertEqual(inst.data('lastname'), 'foo')
  57. def test_data_accessor_fails(self):
  58. """ Testing that data accessor detects unitialized fields """
  59. inst = dyncode.Person(lodel_id = 1, lastname = "foo")
  60. with self.assertRaises(RuntimeError):
  61. inst.data('firstname')
  62. def test_name2class(self):
  63. """ Testing the class method that returns a dynamic object given it's
  64. name """
  65. self.assertEqual(dyncode.Object.name2class('Person'), dyncode.Person)
  66. self.assertEqual(dyncode.Object.name2class('Object'), dyncode.Object)
  67. def test_bad_name2class(self):
  68. """ Testing failures of the class method that returns a dynamic object
  69. given it's name """
  70. badnames = ['foobar', 'str', str, None, 42]
  71. callers = [dyncode.Object, dyncode.Person, dyncode.Entitie]
  72. for caller in callers:
  73. for badname in badnames:
  74. with self.assertRaises(LeApiError, msg="LeApiError not raised \
  75. but invalid name %s was given" % badname):
  76. caller.name2class(badname)
  77. def test_abstract_name2class(self):
  78. with self.assertRaises(NotImplementedError):
  79. LeObject.name2class('Person')
  80. with self.assertRaises(NotImplementedError):
  81. LeObject.name2class(42)
  82. def test_initilized(self):
  83. """ Testing initialized method """
  84. inst = dyncode.Person(
  85. lodel_id = 1, lastname="foo")
  86. self.assertFalse(inst.initialized)
  87. def test_uid_fieldname(self):
  88. self.assertEqual(dyncode.Person.uid_fieldname(), ["lodel_id"])
  89. def test_fieldnames_accessor(self):
  90. """ Testing fieldnames() accessor method """
  91. fnames = dyncode.Person.fieldnames(False)
  92. self.assertEqual(set(fnames),
  93. {'lastname', 'linked_texts', 'firstname', 'alias'})
  94. def test_bad_insert(self):
  95. """ Insert with bad arguments """
  96. badargs = [
  97. {},
  98. {'lodel_id': 1,'lastname': 'foo', 'firstname': 'bar'}]
  99. for arg in badargs:
  100. with self.assertRaises(LeApiDataCheckErrors):
  101. dyncode.Person.insert(arg)
  102. def test_delete_instance(self):
  103. """ Testing instance method delete """
  104. inst = dyncode.Person(
  105. lodel_id = 1, firstname = "foo", lastname = "bar")
  106. inst.delete()
  107. class LeObjectQueryMockTestCase(unittest.TestCase):
  108. """ Testing LeObject mocking LeQuery objects """
  109. def test_insert(self):
  110. """ Checking that LeObject insert method calls LeInsertQuery
  111. correctly """
  112. datas = {'lastname': 'foo', 'firstname': 'bar'}
  113. with patch.object(
  114. LeInsertQuery, '__init__', return_value = None) as mock_init:
  115. try:
  116. dyncode.Person.insert(datas)
  117. except AttributeError:
  118. pass #Because of mock
  119. mock_init.assert_called_once_with(dyncode.Person)
  120. with patch.object(
  121. LeInsertQuery, 'execute', return_value = 42) as mock_insert:
  122. ret = dyncode.Person.insert(datas)
  123. self.assertEqual(ret, 42, 'Bad return value forwarding')
  124. mock_insert.assert_called_once_with(datas)
  125. def test_delete(self):
  126. """ Checking that LeObject delete method calls LeDeleteQuery
  127. correctly """
  128. with patch.object(
  129. LeDeleteQuery, '__init__', return_value = None) as mock_init:
  130. inst = dyncode.Person(
  131. lodel_id = 1, firstname = "foo", lastname = "bar")
  132. try:
  133. inst.delete()
  134. except AttributeError:
  135. pass
  136. mock_init.assert_called_once_with(
  137. dyncode.Person, [('lodel_id', '=', 1)])
  138. with patch.object(
  139. LeDeleteQuery, 'execute', return_value = 1) as mock_execute:
  140. inst = dyncode.Person(
  141. lodel_id = 1, firstname = "foo", lastname = "bar")
  142. ret = inst.delete()
  143. self.assertEqual(ret, 1, 'Bad return value forwarding')
  144. mock_execute.assert_called_once_with()
  145. def test_delete_bundle(self):
  146. """ Checking that LeObject delete_bundle method calls LeDeleteQuery
  147. correctly """
  148. with patch.object(
  149. LeDeleteQuery, '__init__', return_value = None) as mock_init:
  150. try:
  151. dyncode.Person.delete_bundle(['lodel_id > 1'])
  152. except AttributeError:
  153. pass
  154. mock_init.assert_called_once_with(
  155. dyncode.Person, ['lodel_id > 1'])
  156. with patch.object(
  157. LeDeleteQuery, 'execute', return_value = 1) as mock_execute:
  158. dyncode.Person.delete_bundle(['lodel_id > 1'])
  159. mock_execute.assert_called_once_with()
  160. def test_update_instance(self):
  161. """ Checking that LeObject update method calls LeUpdateQuery
  162. correctly """
  163. with patch.object(
  164. LeUpdateQuery, '__init__', return_value = None) as mock_init:
  165. with patch.object(
  166. LeObject, 'datas', return_value = {
  167. 'lodel_id': 1, 'firstname': 'foo', 'lastname': 'bar',
  168. 'fullname': 'Foo Bar', 'alias': None }) as mock_datas:
  169. inst = dyncode.Person(
  170. lodel_id = 1, firstname = "foo", lastname = "bar")
  171. try:
  172. inst.update()
  173. except AttributeError:
  174. pass
  175. mock_init.assert_called_once_with(
  176. dyncode.Person, [('lodel_id', '=', 1)])
  177. with patch.object(
  178. LeUpdateQuery, 'execute', return_value = None) as mock_update:
  179. with patch.object(
  180. LeObject, 'datas', return_value = {
  181. 'lodel_id': 1, 'firstname': 'foo', 'lastname': 'bar',
  182. 'fullname': 'Foo Bar', 'alias': None }) as mock_datas:
  183. inst = dyncode.Person(
  184. lodel_id = 1, firstname = "foo", lastname = "bar")
  185. inst.update()
  186. mock_update.assert_called_once_with({
  187. 'lodel_id': 1, 'firstname': 'foo', 'lastname': 'bar',
  188. 'fullname': 'Foo Bar', 'alias': None })
  189. def test_get(self):
  190. """ Checking that LeObject.get method calls LeGetQuery
  191. correctly """
  192. get_args = {
  193. 'query_filters': ['lodel_id = 1'],
  194. 'field_list': ['firstname'],
  195. 'order': ['firstname'],
  196. 'group': ['alias'],
  197. 'limit': 42,
  198. 'offset': 24}
  199. with patch.object(
  200. LeGetQuery, '__init__', return_value = None) as mock_init:
  201. try:
  202. dyncode.Person.get(**get_args)
  203. except AttributeError:
  204. pass
  205. mock_init.assert_called_once_with(
  206. dyncode.Person,
  207. **get_args)
  208. ret_val = [{
  209. 'lodel_id': 1,
  210. 'firstname': 'foo',
  211. 'lastname': 'bar',
  212. 'fullname': 'foo bar',
  213. 'alias': None,
  214. 'classname': 'Person'}]
  215. with patch.object(
  216. LeGetQuery, 'execute', return_value = ret_val) as mock_execute:
  217. results = dyncode.Person.get(**get_args)
  218. mock_execute.assert_called_once_with()
  219. res = results[0]
  220. self.assertEqual(res.d.lodel_id, 1)
  221. self.assertEqual(res.d.firstname, 'foo')
  222. self.assertEqual(res.d.lastname, 'bar')
  223. def test_get_mini(self):
  224. """ Checking that LeObject.get method calls LeGetQuery correctly
  225. when called with minimum args """
  226. with patch.object(
  227. LeGetQuery, '__init__', return_value = None) as mock_init:
  228. try:
  229. dyncode.Person.get(['lodel_id = 1'])
  230. except AttributeError:
  231. pass
  232. mock_init.assert_called_once_with(
  233. dyncode.Person,
  234. query_filters = ['lodel_id = 1'],
  235. field_list = None,
  236. order = None, group = None, limit = None, offset = 0)
  237. with patch.object(
  238. LeGetQuery, 'execute', return_value = []) as mock_exec:
  239. dyncode.Person.get(['lodel_id = 1'])
  240. mock_exec.assert_called_once_with()