From bf879a833cde3b30dae87e4913252affca151f28 Mon Sep 17 00:00:00 2001 From: Yann Date: Wed, 25 May 2016 14:16:32 +0200 Subject: [PATCH] Adds tests for LeGetQuery + bugfixes - separates LeGetQuery tests and LeFilteredQuery tests - small bugfixes associated to tests --- lodel/leapi/query.py | 30 +++++++--- tests/leapi/query/test_filtered.py | 30 ---------- tests/leapi/query/test_get.py | 94 ++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 37 deletions(-) create mode 100644 tests/leapi/query/test_get.py diff --git a/lodel/leapi/query.py b/lodel/leapi/query.py index 3225744..2490448 100644 --- a/lodel/leapi/query.py +++ b/lodel/leapi/query.py @@ -195,7 +195,7 @@ class LeFilteredQuery(LeQuery): field name" % fieldname) continue # Checking field against target_class - ret = self.__check_field(self._target_class, field) + ret = self._check_field(self._target_class, field) if isinstance(ret, Exception): err_l[field] = ret continue @@ -292,7 +292,7 @@ a relational field, but %s.%s was present in the filter" pass @classmethod - def __check_field(cls, target_class, fieldname): + def _check_field(cls, target_class, fieldname): try: target_class.field(fieldname) except NameError: @@ -463,15 +463,14 @@ class LeGetQuery(LeFilteredQuery): # Checking kwargs and assigning default values if there is some for argname in kwargs: - if argname not in ('order', 'group', 'limit', 'offset'): + if argname not in ('field_list', 'order', 'group', 'limit', 'offset'): raise TypeError("Unexpected argument '%s'" % argname) if 'field_list' not in kwargs: - #field_list = target_class.get_field_list - self.__field_list = target_class.fieldnames(include_ro = True) + self.set_field_list(target_class.fieldnames(include_ro = True)) else: - #target_class.check_fields(kwargs['field_list']) - self.__field_list = kwargs['field_list'] + self.set_field_list(kwargs['field_list']) + if 'order' in kwargs: #check kwargs['order'] self.__order = kwargs['order'] @@ -493,6 +492,23 @@ class LeGetQuery(LeFilteredQuery): except ValueError: raise ValueError("offset argument expected to be an integer >= 0") + ##@brief Set the field list + # @param field_list list | None : If None use all fields + # @return None + # @throw LeQueryError if unknown field given + def set_field_list(self, field_list): + err_l = dict() + for fieldname in field_list: + ret = self._check_field(self._target_class, fieldname) + if isinstance(ret, Exception): + expt = NameError( "No field named '%s' in %s" % ( fieldname, + self._target_class.__name__)) + err_l[fieldname] = expt + if len(err_l) > 0: + raise LeQueryError( msg = "Error while setting field_list in a get query", + exceptions = err_l) + self.__field_list = list(set(field_list)) + ##@brief Execute the get query def execute(self, datasource): super().execute(datasource) diff --git a/tests/leapi/query/test_filtered.py b/tests/leapi/query/test_filtered.py index 1811e78..2953afa 100644 --- a/tests/leapi/query/test_filtered.py +++ b/tests/leapi/query/test_filtered.py @@ -6,36 +6,6 @@ from tests.leapi.query.utils import dyncode_module as dyncode from lodel.leapi.leobject import LeApiDataCheckError from lodel.leapi.query import LeDeleteQuery, LeUpdateQuery, LeGetQuery -class LeGetQueryTestCase(unittest.TestCase): - - def test_init_default(self): - """ Testing GetQuery instanciation default values""" - tclass_list = [ dyncode.Object, - dyncode.Entry, - dyncode.Person, - dyncode.Text, - dyncode.Section, - dyncode.Publication, - dyncode.Text_Person, - ] - for tclass in tclass_list: - get_q = LeGetQuery(tclass, []) - qinfos = get_q.dump_infos() - self.assertEqual( set(qinfos['field_list']), - set(tclass.fieldnames(True))) - self.assertEqual( qinfos['limit'], - None) - self.assertEqual( qinfos['offset'], - 0) - self.assertEqual( qinfos['group'], - None) - self.assertEqual( qinfos['order'], - None) - self.assertEqual( qinfos['query_filter'], - ([],[])) - self.assertEqual( qinfos['target_class'], - tclass) - class LeFilteredQueryTestCase(unittest.TestCase): q_classes = [ LeDeleteQuery, LeUpdateQuery, LeGetQuery ] diff --git a/tests/leapi/query/test_get.py b/tests/leapi/query/test_get.py new file mode 100644 index 0000000..02b007d --- /dev/null +++ b/tests/leapi/query/test_get.py @@ -0,0 +1,94 @@ +import unittest + +import itertools + +import tests.loader_utils +from tests.leapi.query.utils import dyncode_module as dyncode + +from lodel.leapi.leobject import LeApiDataCheckError +from lodel.leapi.query import LeDeleteQuery, LeUpdateQuery, LeGetQuery, LeQueryError + +class LeGetQueryTestCase(unittest.TestCase): + + def test_init_default(self): + """ Testing GetQuery instanciation arguments default value """ + tclass_list = [ dyncode.Object, + dyncode.Entry, + dyncode.Person, + dyncode.Text, + dyncode.Section, + dyncode.Publication, + dyncode.Text_Person ] + + for tclass in tclass_list: + get_q = LeGetQuery(tclass, []) + qinfos = get_q.dump_infos() + self.assertEqual( set(qinfos['field_list']), + set(tclass.fieldnames(True))) + self.assertEqual( qinfos['limit'], + None) + self.assertEqual( qinfos['offset'], + 0) + self.assertEqual( qinfos['group'], + None) + self.assertEqual( qinfos['order'], + None) + self.assertEqual( qinfos['query_filter'], + ([],[])) + self.assertEqual( qinfos['target_class'], + tclass) + + def test_field_list(self): + """ Testing GetQuery field list argument processing """ + tclass_list = [ dyncode.Object, + dyncode.Entry, + dyncode.Person, + dyncode.Text, + dyncode.Section, + dyncode.Publication, + dyncode.Text_Person ] + + for tclass in tclass_list: + # testing all field list possible combinations + field_list = tclass.fieldnames(True) + for r in range(1, len(field_list) + 1): + combinations = [ list(c) for c in itertools.combinations(field_list, r)] + for test_flist in combinations: + expected = set(test_flist) + get_q = LeGetQuery(tclass, [], field_list = test_flist) + qinfos = get_q.dump_infos() + self.assertEqual( sorted(qinfos['field_list']), + sorted(test_flist)) + + def test_field_list_duplicated(self): + """ Testing GetQuery field list argument deduplication """ + tclass_list = [ dyncode.Object, + dyncode.Text, + dyncode.Section, + dyncode.Publication, + dyncode.Text_Person ] + for tclass in tclass_list: + fl = [ 'lodel_id', + 'lodel_id', + 'help_text', + 'help_text', + 'help_text'] + get_q = LeGetQuery(tclass, [], field_list = fl) + self.assertEqual( sorted(list(set(fl))), + sorted(get_q.dump_infos()['field_list'])) + + def test_field_list_invalid(self): + """ Testing GetQuery invalid field name detection in field list """ + bad_field_lists = ( ('non-existing',), + (1,), + (True,), + (None,), + ('lodel_id', 'non-existing',), + ('lodel_id', 1,), + ('lodel_id', True,), + ('lodel_id', None,) ) + + for bad_field_list in bad_field_lists: + with self.assertRaises(LeQueryError): + LeGetQuery(dyncode.Object, [], field_list = bad_field_list) +