Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

test_datasource.py 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import copy
  2. import datetime
  3. import unittest
  4. from unittest import mock
  5. from unittest.mock import patch
  6. import tests.loader_utils
  7. from tests.leapi.query.utils import dyncode_module as dyncode
  8. from lodel.leapi.query import LeDeleteQuery, LeUpdateQuery, LeGetQuery, \
  9. LeInsertQuery
  10. from lodel.leapi.exceptions import *
  11. class LeQueryDatasourceTestCase(unittest.TestCase):
  12. """ Testing LeQuery objects connection with datasource """
  13. mockread = mock.MagicMock()
  14. mockwrite = mock.MagicMock()
  15. dyncode = None
  16. @classmethod
  17. def setUpClass(cls):
  18. """ Mocking read & write datasource of dyncode """
  19. cls.dyncode = dict()
  20. for dyncls in dyncode.dynclasses:
  21. dyncls._ro_datasource = cls.mockread
  22. dyncls._rw_datasource = cls.mockwrite
  23. cls.dyncode[dyncls.__name__] = dyncls
  24. def setUp(self):
  25. """ Reseting all mock calls before test """
  26. self.mockread.reset_mock()
  27. self.mockwrite.reset_mock()
  28. def check_nocall(self, read = True, exclude = None):
  29. """ Utility function to check if a datasource mock method has been
  30. called during test """
  31. exclude = [] if exclude is None else exclude
  32. if read:
  33. mockds = self.mockread
  34. else:
  35. mockds = self.mockwrite
  36. if 'select' not in exclude:
  37. self.assertFalse(
  38. mockds.select.called,
  39. "select method was not expected to be called")
  40. if 'delete' not in exclude:
  41. self.assertFalse(
  42. mockds.delete.called,
  43. "delete method was not expected to be called")
  44. if 'update' not in exclude:
  45. self.assertFalse(
  46. mockds.update.called,
  47. "update method was not expected to be called")
  48. if 'insert' not in exclude:
  49. self.assertFalse(
  50. mockds.insert.called,
  51. "insert method was not expected to be called")
  52. def test_delete_simple_filter(self):
  53. """ Testing delete query mocking datasource using simple query
  54. filters """
  55. cls = self.dyncode['Person']
  56. query = LeDeleteQuery(
  57. target_class = cls,
  58. query_filter = ['lodel_id = 1', 'alias.lodel_id = 2'])
  59. query.execute()
  60. # Cannot check with assert_called_once_with because of the array
  61. # that is not in a deterministic order
  62. call_args = self.mockwrite.delete.call_args[0]
  63. self.assertEqual(call_args[0], cls)
  64. self.assertEqual(
  65. sorted(call_args[1]),
  66. sorted([('lodel_id', '=', 1), ('alias', '=', '2')]))
  67. self.assertEqual(call_args[2], [])
  68. self.check_nocall(read = False, exclude = ['delete'])
  69. self.check_nocall(read = True)
  70. def test_delete_simple_rel_filters(self):
  71. """ Testing delete query mocking datasource using simple filters
  72. and relationnal filters"""
  73. cls = self.dyncode['Person']
  74. query = LeDeleteQuery(
  75. target_class = cls,
  76. query_filter = ['lodel_id = 1', 'alias.firstname = foo'])
  77. query.execute()
  78. self.mockwrite.delete.assert_called_once_with(
  79. cls,
  80. [('lodel_id', '=', 1)],
  81. [(('alias', {cls: 'firstname'}), '=', 'foo')])
  82. self.check_nocall(read = False, exclude = ['delete'])
  83. self.check_nocall(read = True)
  84. def test_delete_rel_filters(self):
  85. """ Testing delete query mocking datasource """
  86. cls = self.dyncode['Person']
  87. query = LeDeleteQuery(
  88. target_class = cls,
  89. query_filter = ['alias.firstname = foo'])
  90. query.execute()
  91. self.mockwrite.delete.assert_called_once_with(
  92. cls,
  93. [],
  94. [(('alias', {cls: 'firstname'}), '=', 'foo')])
  95. self.check_nocall(read = False, exclude = ['delete'])
  96. self.check_nocall(read = True)
  97. @unittest.skip("Waiting references checks stack implementation")
  98. def test_insert(self):
  99. """ Testing LeInsertQuery mocking datasource """
  100. cls = self.dyncode['Person']
  101. query = LeInsertQuery(
  102. target_class = cls)
  103. self.mockwrite.insert.return_value = 1
  104. datas = {
  105. 'firstname': 'foo',
  106. 'lastname': 'bar',
  107. 'alias': None}
  108. query.execute(datas)
  109. self.assertEqual(self.mockwrite.insert.call_count, 1)
  110. cargs , _ = self.mockwrite.insert.call_args
  111. pdatas = cls.prepare_datas(datas, True, False)
  112. self.assertEqual(cargs[0], cls)
  113. cargs = cargs[1]
  114. self.assertEqual(set(pdatas.keys()), set(cargs.keys()))
  115. for dname in pdatas:
  116. if isinstance(pdatas[dname], datetime.datetime):
  117. d1 = pdatas[dname]
  118. d2 = cargs[dname]
  119. for vname in ('year', 'month', 'day', 'hour', 'minute'):
  120. self.assertEqual(
  121. getattr(d1, vname), getattr(d2, vname))
  122. pass
  123. else:
  124. self.assertEqual(pdatas[dname], cargs[dname])
  125. self.check_nocall(read = False, exclude = ['insert'])
  126. self.check_nocall(read = True)
  127. def test_update_instance(self):
  128. """ Testing LeUpdateQuery with an instance mocking datasource """
  129. cls = self.dyncode['Person']
  130. inst = cls(lodel_id = 1, firstname = 'foo', lastname = 'bar',
  131. alias = None, linked_texts = None)
  132. query = LeUpdateQuery(inst)
  133. with self.assertRaises(LeApiQueryError):
  134. # Bad call, giving data while an instance was given to __init__
  135. query.execute(data = {'firstname': 'ooba'})
  136. query.execute()
  137. self.mockwrite.update.assert_called_once_with(
  138. cls,
  139. [('lodel_id', '=', '1')],
  140. [],
  141. inst.datas(True))
  142. self.check_nocall(read=False, exclude = ['update'])
  143. self.check_nocall(read=True)
  144. def test_update_filter(self):
  145. """ Testing LeUpdateQuery with filter mocking datasource """
  146. cls = self.dyncode['Person']
  147. fake_db_datas = [{
  148. 'lodel_id': 1,
  149. 'firstname': 'barfoo',
  150. 'lastname': 'foobar',
  151. 'fullname': 'barfoo foobar',
  152. 'alias': None,
  153. 'linked_texts': None,
  154. 'help_text': None,
  155. 'classname': 'Person',
  156. 'date_create': None,
  157. 'date_update': None}]
  158. q_datas = {'firstname': 'foobar', 'lastname': 'barfoo'}
  159. expt_datas = copy.copy(fake_db_datas[0])
  160. expt_datas.update(q_datas)
  161. expt_datas = cls.prepare_datas(expt_datas, True, True)
  162. query = LeUpdateQuery(cls, [('lodel_id', '=', 1)])
  163. with self.assertRaises(LeApiQueryError):
  164. # Bad call, no datas given while a class and a filters were given
  165. # to __init__
  166. query.execute()
  167. self.mockread.select.return_value = fake_db_datas
  168. query.execute(q_datas)
  169. self.mockwrite.update.asser_called_once_with(
  170. cls,
  171. [('lodel_id', '=', '1')],
  172. [],
  173. expt_datas)