test/unittest_schema.py
brancholdstable
changeset 7074 e4580e5f0703
parent 6910 bab54e22f94d
child 6944 0cf10429ad39
equal deleted inserted replaced
6749:48f468f33704 7074:e4580e5f0703
    15 #
    15 #
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """unit tests for module cubicweb.schema"""
    18 """unit tests for module cubicweb.schema"""
    19 
    19 
       
    20 from __future__ import with_statement
       
    21 
    20 import sys
    22 import sys
    21 from os.path import join, isabs, basename, dirname
    23 from os.path import join, isabs, basename, dirname
    22 
    24 
    23 from logilab.common.testlib import TestCase, unittest_main
    25 from logilab.common.testlib import TestCase, unittest_main
    24 
    26 
    70     ('Personne prenom String'),
    72     ('Personne prenom String'),
    71     ('Personne sexe String'),
    73     ('Personne sexe String'),
    72     ('Personne tel Int'),
    74     ('Personne tel Int'),
    73     ('Personne fax Int'),
    75     ('Personne fax Int'),
    74     ('Personne datenaiss Date'),
    76     ('Personne datenaiss Date'),
    75     ('Personne TEST Boolean'),
       
    76     ('Personne promo String'),
    77     ('Personne promo String'),
    77     # real relations
    78     # real relations
    78     ('Personne  travaille Societe'),
    79     ('Personne  travaille Societe'),
    79     ('Personne  evaluee   Note'),
    80     ('Personne  evaluee   Note'),
    80     ('Societe evaluee   Note'),
    81     ('Societe evaluee   Note'),
    81     ('Personne  concerne  Affaire'),
    82     ('Personne  concerne  Affaire'),
    82     ('Personne  concerne  Societe'),
    83     ('Personne  concerne  Societe'),
    83     ('Affaire Concerne  Societe'),
    84     ('Affaire concerne  Societe'),
    84     )
    85     )
    85 done = {}
    86 done = {}
    86 for rel in RELS:
    87 for rel in RELS:
    87     _from, _type, _to = rel.split()
    88     _from, _type, _to = rel.split()
    88     if not _type.lower() in done:
    89     if not _type.lower() in done:
   106         #    RRQLVocabularyConstraint and QLUniqueConstraint
   107         #    RRQLVocabularyConstraint and QLUniqueConstraint
   107         self.failIf(issubclass(RQLUniqueConstraint, RQLVocabularyConstraint))
   108         self.failIf(issubclass(RQLUniqueConstraint, RQLVocabularyConstraint))
   108         self.failIf(issubclass(RQLUniqueConstraint, RQLConstraint))
   109         self.failIf(issubclass(RQLUniqueConstraint, RQLConstraint))
   109         self.failUnless(issubclass(RQLConstraint, RQLVocabularyConstraint))
   110         self.failUnless(issubclass(RQLConstraint, RQLVocabularyConstraint))
   110 
   111 
   111     def test_normalize(self):
       
   112         """test that entities, relations and attributes name are normalized
       
   113         """
       
   114         self.assertEqual(esociete.type, 'Societe')
       
   115         self.assertEqual(schema.has_relation('TEST'), 0)
       
   116         self.assertEqual(schema.has_relation('test'), 1)
       
   117         self.assertEqual(eperson.subjrels['test'].type, 'test')
       
   118         self.assertEqual(schema.has_relation('Concerne'), 0)
       
   119         self.assertEqual(schema.has_relation('concerne'), 1)
       
   120         self.assertEqual(schema.rschema('concerne').type, 'concerne')
       
   121 
       
   122     def test_entity_perms(self):
   112     def test_entity_perms(self):
   123         self.assertEqual(eperson.get_groups('read'), set(('managers', 'users', 'guests')))
   113         self.assertEqual(eperson.get_groups('read'), set(('managers', 'users', 'guests')))
   124         self.assertEqual(eperson.get_groups('update'), set(('managers', 'owners',)))
   114         self.assertEqual(eperson.get_groups('update'), set(('managers', 'owners',)))
   125         self.assertEqual(eperson.get_groups('delete'), set(('managers', 'owners')))
   115         self.assertEqual(eperson.get_groups('delete'), set(('managers', 'owners')))
   126         self.assertEqual(eperson.get_groups('add'), set(('managers',)))
   116         self.assertEqual(eperson.get_groups('add'), set(('managers',)))
   149         self.assertRaises(RQLSyntaxError, RRQLExpression, 'O X Y')
   139         self.assertRaises(RQLSyntaxError, RRQLExpression, 'O X Y')
   150         expr = RRQLExpression('U has_update_permission O')
   140         expr = RRQLExpression('U has_update_permission O')
   151         self.assertEqual(str(expr), 'Any O,U WHERE U has_update_permission O, O eid %(o)s, U eid %(u)s')
   141         self.assertEqual(str(expr), 'Any O,U WHERE U has_update_permission O, O eid %(o)s, U eid %(u)s')
   152 
   142 
   153 loader = CubicWebSchemaLoader()
   143 loader = CubicWebSchemaLoader()
   154 config = TestConfiguration('data')
   144 config = TestConfiguration('data', apphome=DATADIR)
   155 config.bootstrap_cubes()
   145 config.bootstrap_cubes()
   156 
   146 
   157 class SchemaReaderClassTest(TestCase):
   147 class SchemaReaderClassTest(TestCase):
   158 
   148 
   159     def test_order_eschemas(self):
   149     def test_order_eschemas(self):
   165 
   155 
   166     def test_knownValues_load_schema(self):
   156     def test_knownValues_load_schema(self):
   167         schema = loader.load(config)
   157         schema = loader.load(config)
   168         self.assert_(isinstance(schema, CubicWebSchema))
   158         self.assert_(isinstance(schema, CubicWebSchema))
   169         self.assertEqual(schema.name, 'data')
   159         self.assertEqual(schema.name, 'data')
   170         entities = [str(e) for e in schema.entities()]
   160         entities = sorted([str(e) for e in schema.entities()])
   171         entities.sort()
       
   172         expected_entities = ['BaseTransition', 'Bookmark', 'Boolean', 'Bytes', 'Card',
   161         expected_entities = ['BaseTransition', 'Bookmark', 'Boolean', 'Bytes', 'Card',
   173                              'Date', 'Datetime', 'Decimal',
   162                              'Date', 'Datetime', 'Decimal',
   174                              'CWCache', 'CWConstraint', 'CWConstraintType', 'CWEType',
   163                              'CWCache', 'CWConstraint', 'CWConstraintType', 'CWEType',
   175                              'CWAttribute', 'CWGroup', 'EmailAddress', 'CWRelation',
   164                              'CWAttribute', 'CWGroup', 'EmailAddress', 'CWRelation',
   176                              'CWPermission', 'CWProperty', 'CWRType',
   165                              'CWPermission', 'CWProperty', 'CWRType',
       
   166                              'CWSource', 'CWSourceHostConfig',
   177                              'CWUniqueTogetherConstraint', 'CWUser',
   167                              'CWUniqueTogetherConstraint', 'CWUser',
   178                              'ExternalUri', 'File', 'Float', 'Int', 'Interval', 'Note',
   168                              'ExternalUri', 'File', 'Float', 'Int', 'Interval', 'Note',
   179                              'Password', 'Personne',
   169                              'Password', 'Personne',
   180                              'RQLExpression',
   170                              'RQLExpression',
   181                              'Societe', 'State', 'String', 'SubNote', 'SubWorkflowExitPoint',
   171                              'Societe', 'State', 'StateFull', 'String', 'SubNote', 'SubWorkflowExitPoint',
   182                              'Tag', 'Time', 'Transition', 'TrInfo',
   172                              'Tag', 'Time', 'Transition', 'TrInfo',
   183                              'Workflow', 'WorkflowTransition']
   173                              'Workflow', 'WorkflowTransition']
   184         self.assertListEqual(entities, sorted(expected_entities))
   174         self.assertListEqual(entities, sorted(expected_entities))
   185         relations = [str(r) for r in schema.relations()]
   175         relations = sorted([str(r) for r in schema.relations()])
   186         relations.sort()
       
   187         expected_relations = ['add_permission', 'address', 'alias', 'allowed_transition',
   176         expected_relations = ['add_permission', 'address', 'alias', 'allowed_transition',
   188                               'bookmarked_by', 'by_transition',
   177                               'bookmarked_by', 'by_transition',
   189 
   178 
   190                               'cardinality', 'comment', 'comment_format',
   179                               'cardinality', 'comment', 'comment_format',
   191                               'composite', 'condition', 'connait',
   180                               'composite', 'condition', 'config', 'connait',
   192                               'constrained_by', 'constraint_of',
   181                               'constrained_by', 'constraint_of',
   193                               'content', 'content_format',
   182                               'content', 'content_format',
   194                               'created_by', 'creation_date', 'cstrtype', 'custom_workflow', 'cwuri',
   183                               'created_by', 'creation_date', 'cstrtype', 'custom_workflow',
       
   184                               'cwuri', 'cw_source', 'cw_host_config_of',
       
   185                               'cw_support', 'cw_dont_cross', 'cw_may_cross',
   195 
   186 
   196                               'data', 'data_encoding', 'data_format', 'data_name', 'default_workflow', 'defaultval', 'delete_permission',
   187                               'data', 'data_encoding', 'data_format', 'data_name', 'default_workflow', 'defaultval', 'delete_permission',
   197                               'description', 'description_format', 'destination_state',
   188                               'description', 'description_format', 'destination_state',
   198 
   189 
   199                               'ecrit_par', 'eid', 'evaluee', 'expression', 'exprtype',
   190                               'ecrit_par', 'eid', 'evaluee', 'expression', 'exprtype',
   205                               'identity', 'in_group', 'in_state', 'indexed',
   196                               'identity', 'in_group', 'in_state', 'indexed',
   206                               'initial_state', 'inlined', 'internationalizable', 'is', 'is_instance_of',
   197                               'initial_state', 'inlined', 'internationalizable', 'is', 'is_instance_of',
   207 
   198 
   208                               'label', 'last_login_time', 'login',
   199                               'label', 'last_login_time', 'login',
   209 
   200 
   210                               'mainvars', 'modification_date',
   201                               'mainvars', 'match_host', 'modification_date',
   211 
   202 
   212                               'name', 'nom',
   203                               'name', 'nom',
   213 
   204 
   214                               'ordernum', 'owned_by',
   205                               'ordernum', 'owned_by',
   215 
   206 
   223 
   214 
   224                               'upassword', 'update_permission', 'uri', 'use_email',
   215                               'upassword', 'update_permission', 'uri', 'use_email',
   225 
   216 
   226                               'value',
   217                               'value',
   227 
   218 
   228                               'wf_info_for', 'wikiid', 'workflow_of']
   219                               'wf_info_for', 'wikiid', 'workflow_of', 'tr_count']
   229 
   220 
   230         self.assertListEqual(relations, expected_relations)
   221         self.assertListEqual(relations, sorted(expected_relations))
   231 
   222 
   232         eschema = schema.eschema('CWUser')
   223         eschema = schema.eschema('CWUser')
   233         rels = sorted(str(r) for r in eschema.subject_relations())
   224         rels = sorted(str(r) for r in eschema.subject_relations())
   234         self.assertListEqual(rels, ['created_by', 'creation_date', 'custom_workflow', 'cwuri', 'eid',
   225         self.assertListEqual(rels, ['created_by', 'creation_date', 'custom_workflow',
       
   226                                     'cw_source', 'cwuri', 'eid',
   235                                      'evaluee', 'firstname', 'has_text', 'identity',
   227                                      'evaluee', 'firstname', 'has_text', 'identity',
   236                                      'in_group', 'in_state', 'is',
   228                                      'in_group', 'in_state', 'is',
   237                                      'is_instance_of', 'last_login_time',
   229                                      'is_instance_of', 'last_login_time',
   238                                      'login', 'modification_date', 'owned_by',
   230                                      'login', 'modification_date', 'owned_by',
   239                                      'primary_email', 'surname', 'upassword',
   231                                      'primary_email', 'surname', 'upassword',
   265         self.assertEqual(aschema.get_groups('update'),
   257         self.assertEqual(aschema.get_groups('update'),
   266                           set(('managers',)))
   258                           set(('managers',)))
   267         self.assertEqual([x.expression for x in aschema.get_rqlexprs('update')],
   259         self.assertEqual([x.expression for x in aschema.get_rqlexprs('update')],
   268                           ['U has_update_permission X'])
   260                           ['U has_update_permission X'])
   269 
   261 
   270 class BadSchemaRQLExprTC(TestCase):
   262 class BadSchemaTC(TestCase):
   271     def setUp(self):
   263     def setUp(self):
   272         self.loader = CubicWebSchemaLoader()
   264         self.loader = CubicWebSchemaLoader()
   273         self.loader.defined = {}
   265         self.loader.defined = {}
   274         self.loader.loaded_files = []
   266         self.loader.loaded_files = []
   275         self.loader.post_build_callbacks = []
   267         self.loader.post_build_callbacks = []
   276         self.loader._pyreader = PyFileReader(self.loader)
   268         self.loader._pyreader = PyFileReader(self.loader)
   277 
   269 
   278     def _test(self, schemafile, msg):
   270     def _test(self, schemafile, msg):
   279         self.loader.handle_file(join(DATADIR, schemafile))
   271         self.loader.handle_file(join(DATADIR, schemafile))
   280         ex = self.assertRaises(BadSchemaDefinition,
   272         with self.assertRaises(BadSchemaDefinition) as cm:
   281                                self.loader._build_schema, 'toto', False)
   273             self.loader._build_schema('toto', False)
   282         self.assertEqual(str(ex), msg)
   274         self.assertEqual(str(cm.exception), msg)
       
   275 
       
   276     def test_lowered_etype(self):
       
   277         self._test('lowered_etype.py',
       
   278                    "'my_etype' is not a valid name for an entity type. It should "
       
   279                    "start with an upper cased letter and be followed by at least "
       
   280                    "a lower cased letter")
       
   281 
       
   282     def test_uppered_rtype(self):
       
   283         self._test('uppered_rtype.py',
       
   284                    "'ARelation' is not a valid name for a relation type. It should be lower cased")
   283 
   285 
   284     def test_rrqlexpr_on_etype(self):
   286     def test_rrqlexpr_on_etype(self):
   285         self._test('rrqlexpr_on_eetype.py',
   287         self._test('rrqlexpr_on_eetype.py',
   286                    "can't use RRQLExpression on ToTo, use an ERQLExpression")
   288                    "can't use RRQLExpression on ToTo, use an ERQLExpression")
   287 
   289 
   306 
   308 
   307 class RQLExpressionTC(TestCase):
   309 class RQLExpressionTC(TestCase):
   308     def test_comparison(self):
   310     def test_comparison(self):
   309         self.assertEqual(ERQLExpression('X is CWUser', 'X', 0),
   311         self.assertEqual(ERQLExpression('X is CWUser', 'X', 0),
   310                           ERQLExpression('X is CWUser', 'X', 0))
   312                           ERQLExpression('X is CWUser', 'X', 0))
   311         self.assertNotEquals(ERQLExpression('X is CWUser', 'X', 0),
   313         self.assertNotEqual(ERQLExpression('X is CWUser', 'X', 0),
   312                              ERQLExpression('X is CWGroup', 'X', 0))
   314                              ERQLExpression('X is CWGroup', 'X', 0))
   313 
   315 
   314 class GuessRrqlExprMainVarsTC(TestCase):
   316 class GuessRrqlExprMainVarsTC(TestCase):
   315     def test_exists(self):
   317     def test_exists(self):
   316         mainvars = guess_rrqlexpr_mainvars(normalize_expression('NOT EXISTS(O team_competition C, C level < 3)'))
   318         mainvars = guess_rrqlexpr_mainvars(normalize_expression('NOT EXISTS(O team_competition C, C level < 3)'))