From cf691c653885c1405e027427e2356efe92118216 Mon Sep 17 00:00:00 2001 From: Yann Date: Tue, 29 Dec 2015 11:35:07 +0100 Subject: [PATCH] Add a test on LeCrud.select() method (test order, groups, limit and offset arguments) + small bugfixes --- leapi/leclass.py | 4 +- leapi/lecrud.py | 30 ++++++++---- leapi/leobject.py | 5 +- leapi/letype.py | 4 +- leapi/test/test_lecrud.py | 92 ++++++++++++++++++++++++++++++++++- leapi/test/test_lerelation.py | 13 +++-- 6 files changed, 122 insertions(+), 26 deletions(-) diff --git a/leapi/leclass.py b/leapi/leclass.py index 6b759ee..9d3a3a6 100644 --- a/leapi/leclass.py +++ b/leapi/leclass.py @@ -37,6 +37,6 @@ class _LeClass(_LeObject): return cls.fieldtypes().keys() @classmethod - def get(cls, query_filters, field_list=None, order=None, group=None, limit=None, offset=0): + def get(cls, query_filters, field_list=None, order=None, groups=None, limit=None, offset=0): query_filters.append(('class_id', '=', cls._class_id)) - return super().get(query_filters, field_list, order=order, group=group, limit=limit, offset=offset) + return super().get(query_filters, field_list, order=order, groups=groups, limit=limit, offset=offset) diff --git a/leapi/lecrud.py b/leapi/lecrud.py index edb90b7..0344ea9 100644 --- a/leapi/lecrud.py +++ b/leapi/lecrud.py @@ -8,6 +8,9 @@ import warnings import importlib import re +REL_SUP = 0 +REL_SUB = 1 + class LeApiErrors(Exception): ## @brief Instanciate a new exceptions handling multiple exceptions # @param exptexptions dict : A list of data check Exception with concerned field (or stuff) as key @@ -257,7 +260,7 @@ class _LeCrud(object): # @return A list of lodel editorial components instance # @todo think about LeObject and LeClass instanciation (partial instanciation, etc) @classmethod - def get(cls, query_filters, field_list=None, order=None, group=None, limit=None, offset=0): + def get(cls, query_filters, field_list=None, order=None, groups=None, limit=None, offset=0): if field_list is None or len(field_list) == 0: #default field_list field_list = cls.fieldlist() @@ -273,11 +276,11 @@ class _LeCrud(object): if isinstance(order, Exception): raise order #can be buffered and raised later, but _prepare_filters raise when fails - #preparing group - if group: - group = cls._prepare_order_fields(group) - if isinstance(group, Exception): - raise group # can also be buffered and raised later + #preparing groups + if groups: + groups = cls._prepare_order_fields(groups) + if isinstance(groups, Exception): + raise groups # can also be buffered and raised later #checking limit and offset values if not (limit is None): @@ -288,7 +291,16 @@ class _LeCrud(object): raise ValueError("Invalid offset given : %d"%offset) #Fetching editorial components from datasource - results = cls._datasource.select(cls, field_list, filters, relational_filters, order=order, group=group, limit=limit, offset=offset) + results = cls._datasource.select( + target_cls = cls, + field_list = field_list, + filters = filters, + rel_filters = relational_filters, + order=order, + groups=groups, + limit=limit, + offset=offset + ) return results @@ -553,7 +565,7 @@ class _LeCrud(object): # ( RELATION, NATURE ) where NATURE is a string ( see EditorialModel.classtypes ) and RELATION is one of # the defined constant : # -# - leapi.leapi.REL_SUB for "subordinates" -# - leapi.leapi.REL_SUP for "superiors" +# - leapi.lecrud.REL_SUB for "subordinates" +# - leapi.lecrud.REL_SUP for "superiors" # # @note The filters translation process also check if given field are valids compared to the concerned letype and/or the leclass diff --git a/leapi/leobject.py b/leapi/leobject.py index cb18788..0a20e91 100644 --- a/leapi/leobject.py +++ b/leapi/leobject.py @@ -15,14 +15,11 @@ import copy import warnings import leapi -from leapi.lecrud import _LeCrud +from leapi.lecrud import _LeCrud, REL_SUP, REL_SUB from leapi.lefactory import LeFactory import EditorialModel from EditorialModel.types import EmType -REL_SUP = 0 -REL_SUB = 1 - ## @brief Main class to handle objects defined by the types of an Editorial Model class _LeObject(_LeCrud): diff --git a/leapi/letype.py b/leapi/letype.py index 21b62cf..7ba38cc 100644 --- a/leapi/letype.py +++ b/leapi/letype.py @@ -65,9 +65,9 @@ class _LeType(_LeClass): return cls._fields @classmethod - def get(cls, query_filters, field_list = None): + def get(cls, query_filters, field_list = None, order = None, groups = None, limit = None, offset = 0): query_filters.append(('type_id', '=', cls._type_id)) - return super().get(query_filters, field_list) + return super().get(query_filters, field_list, order, groups, limit, offset) @classmethod def fieldtypes(cls): diff --git a/leapi/test/test_lecrud.py b/leapi/test/test_lecrud.py index fcd9358..0350427 100644 --- a/leapi/test/test_lecrud.py +++ b/leapi/test/test_lecrud.py @@ -235,7 +235,7 @@ class LeCrudTestCase(TestCase): ## @todo test invalid get @patch('DataSource.dummy.leapidatasource.DummyDatasource.select') def test_get(self, dsmock): - """ Test the get method without group, limit, sort or offset """ + """ Test the select method without group, limit, sort or offset """ from dyncode import Publication, Numero, LeObject, Textes args = [ @@ -299,9 +299,97 @@ class LeCrudTestCase(TestCase): for callcls, field_list, filters, fl_ds, filters_ds, rfilters_ds in args: callcls.get(filters, field_list) - dsmock.assert_called_with(callcls, fl_ds, filters_ds, rfilters_ds, order=None, group=None, limit=None, offset=0) + dsmock.assert_called_with( + target_cls = callcls, + field_list = fl_ds, + filters = filters_ds, + rel_filters = rfilters_ds, + order=None, + groups=None, + limit=None, + offset=0 + ) dsmock.reset_mock() + @patch('DataSource.dummy.leapidatasource.DummyDatasource.select') + def test_get_complete(self, dsmock): + """ Test the select method with group limit sort and offset arguments """ + from dyncode import Numero + + args = [ + ( + Numero, + { + 'query_filters': [], + 'field_list': ['lodel_id'], + 'groups': ['titre'], + 'limit': 10, + + }, + { + 'target_cls': Numero, + 'field_list': ['lodel_id'], + 'filters': [], + 'rel_filters': [], + 'groups': [('titre', 'ASC')], + 'order': None, + 'limit': 10, + 'offset': 0, + }, + ), + ( + Numero, + { + 'query_filters': ['superior.parent = 20'], + 'field_list': ['lodel_id'], + 'offset': 1024, + 'order': ['titre', ('lodel_id', 'desc')] + + }, + { + 'target_cls': Numero, + 'field_list': ['lodel_id'], + 'filters': [], + 'rel_filters': [((leapi.lecrud.REL_SUP, 'parent'), '=', '20')], + 'groups': None, + 'order': [('titre', 'ASC'), ('lodel_id', 'DESC')], + 'limit': None, + 'offset': 1024, + }, + ), + ( + Numero, + { + 'query_filters': ['superior.parent = 20'], + 'field_list': ['lodel_id'], + 'offset': 1024, + 'limit': 2, + 'order': ['titre', ('lodel_id', 'desc')], + 'groups': ['titre'], + + }, + { + 'target_cls': Numero, + 'field_list': ['lodel_id'], + 'filters': [], + 'rel_filters': [((leapi.lecrud.REL_SUP, 'parent'), '=', '20')], + 'groups': [('titre', 'ASC')], + 'order': [('titre', 'ASC'), ('lodel_id', 'DESC')], + 'limit': 2, + 'offset': 1024, + }, + ), + ] + + for callcls, getargs, exptargs in args: + if callcls.implements_letype: + exptargs['filters'].append( ('type_id', '=', callcls._type_id) ) + if callcls.implements_leclass: + exptargs['filters'].append( ('class_id', '=', callcls._class_id) ) + callcls.get(**getargs) + dsmock.assert_called_once_with(**exptargs) + dsmock.reset_mock() + # # Utils methods check # diff --git a/leapi/test/test_lerelation.py b/leapi/test/test_lerelation.py index b7a7ca8..c0dd480 100644 --- a/leapi/test/test_lerelation.py +++ b/leapi/test/test_lerelation.py @@ -82,7 +82,7 @@ class LeHierarch(LeRelationTestCase): @patch('DataSource.dummy.leapidatasource.DummyDatasource.select') def test_get(self, dsmock): - """ Tests the LeHierarch.get() method """ + """ Tests the LeHierarch.get() method without limit group order etc.""" from dyncode import LeCrud, Publication, Numero, Personnes, LeObject, Rubrique, LeHierarch, LeRelation queries = [ @@ -114,12 +114,11 @@ class LeHierarch(LeRelationTestCase): cargs = dsmock.call_args self.assertEqual(len(cargs), 2) - cargs=cargs[0] - - self.assertEqual(cargs[0], target, "%s != %s"%(cargs, eargs)) - self.assertEqual(set(cargs[1]), set(field_ds), "%s != %s"%(cargs, eargs)) - self.assertEqual(cargs[2], filters_ds, "%s != %s"%(cargs, eargs)) - self.assertEqual(cargs[3], rfilters_ds, "%s != %s"%(cargs, eargs)) + cargs=cargs[1] + self.assertEqual(cargs['target_cls'], target, "%s != %s"%(cargs, eargs)) + self.assertEqual(set(cargs['field_list']), set(field_ds), "%s != %s"%(cargs, eargs)) + self.assertEqual(cargs['filters'], filters_ds, "%s != %s"%(cargs, eargs)) + self.assertEqual(cargs['rel_filters'], rfilters_ds, "%s != %s"%(cargs, eargs)) dsmock.reset_mock()