test/unittest_schema.py
changeset 0 b97547f5f1fa
child 13 bae30087db21
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/unittest_schema.py	Wed Nov 05 15:52:50 2008 +0100
@@ -0,0 +1,258 @@
+"""unit tests for module cubicweb.schema"""
+
+import sys
+from os.path import join, isabs, basename, dirname
+
+from logilab.common.testlib import TestCase, unittest_main
+
+from rql import RQLSyntaxError
+
+from yams import BadSchemaDefinition
+from yams.constraints import SizeConstraint, StaticVocabularyConstraint
+from yams.buildobjs import RelationDefinition, EntityType, RelationType
+
+from cubicweb.schema import CubicWebSchema, CubicWebEntitySchema, \
+     RQLConstraint, CubicWebSchemaLoader, ERQLExpression, RRQLExpression, \
+     normalize_expression
+from cubicweb.devtools import TestServerConfiguration as TestConfiguration
+
+DATADIR = join(dirname(__file__), 'data')
+
+# build a dummy schema ########################################################
+
+
+PERSONNE_PERMISSIONS =  {
+    'read':   ('managers', 'users', 'guests'),
+    'update': ('managers', 'owners'),
+    'add':    ('managers', ERQLExpression('X travaille S, S owned_by U')),
+    'delete': ('managers', 'owners',),
+    }
+
+CONCERNE_PERMISSIONS = {
+    'read':   ('managers', 'users', 'guests'),
+    'add':    ('managers', RRQLExpression('U has_update_permission S')),
+    'delete': ('managers', RRQLExpression('O owned_by U')),
+    }
+
+schema = CubicWebSchema('Test Schema')
+enote = schema.add_entity_type(EntityType('Note'))
+eaffaire = schema.add_entity_type(EntityType('Affaire'))
+eperson = schema.add_entity_type(EntityType('Personne', permissions=PERSONNE_PERMISSIONS))
+esociete = schema.add_entity_type(EntityType('Societe'))
+
+RELS = (
+    # attribute relations
+    ('Note date String'),
+    ('Note type String'),
+    ('Affaire sujet String'),
+    ('Affaire ref String'),
+    ('Personne nom String'),
+    ('Personne prenom String'),
+    ('Personne sexe String'),
+    ('Personne tel Int'),
+    ('Personne fax Int'),
+    ('Personne datenaiss Date'),
+    ('Personne TEST Boolean'),
+    ('Personne promo String'),
+    # real relations
+    ('Personne  travaille Societe'),
+    ('Personne  evaluee   Note'),
+    ('Societe evaluee   Note'),
+    ('Personne  concerne  Affaire'),
+    ('Personne  concerne  Societe'),
+    ('Affaire Concerne  Societe'),
+    )
+done = {}
+for rel in RELS:
+    _from, _type, _to = rel.split()
+    if not _type.lower() in done:
+        if _type == 'concerne':
+            schema.add_relation_type(RelationType(_type, permissions=CONCERNE_PERMISSIONS))
+        else:
+            schema.add_relation_type(RelationType(_type))
+        done[_type.lower()] = True
+    schema.add_relation_def(RelationDefinition(_from, _type, _to))
+
+class CubicWebSchemaTC(TestCase):
+
+    def test_normalize(self):
+        """test that entities, relations and attributes name are normalized
+        """
+        self.assertEqual(esociete.type, 'Societe')
+        self.assertEqual(schema.has_relation('TEST'), 0)
+        self.assertEqual(schema.has_relation('test'), 1)
+        self.assertEqual(eperson.subject_relation('test').type, 'test')
+        self.assertEqual(schema.has_relation('Concerne'), 0)
+        self.assertEqual(schema.has_relation('concerne'), 1)
+        self.assertEqual(schema.rschema('concerne').type, 'concerne')
+
+    def test_entity_perms(self):
+        eperson.set_default_groups()
+        self.assertEqual(eperson.get_groups('read'), set(('managers', 'users', 'guests')))
+        self.assertEqual(eperson.get_groups('update'), set(('managers', 'owners',)))
+        self.assertEqual(eperson.get_groups('delete'), set(('managers', 'owners')))
+        self.assertEqual(eperson.get_groups('add'), set(('managers',)))
+        self.assertEqual([str(e) for e in eperson.get_rqlexprs('add')],
+                         ['Any X WHERE X travaille S, S owned_by U, X eid %(x)s, U eid %(u)s'])
+        eperson.set_groups('read', ('managers',))
+        self.assertEqual(eperson.get_groups('read'), set(('managers',)))
+        
+    def test_relation_perms(self):
+        rconcerne = schema.rschema('concerne')
+        rconcerne.set_default_groups()
+        self.assertEqual(rconcerne.get_groups('read'), set(('managers', 'users', 'guests')))
+        self.assertEqual(rconcerne.get_groups('delete'), set(('managers',)))
+        self.assertEqual(rconcerne.get_groups('add'), set(('managers', )))
+        rconcerne.set_groups('read', ('managers',))
+        self.assertEqual(rconcerne.get_groups('read'), set(('managers',)))
+        self.assertEqual([str(e) for e in rconcerne.get_rqlexprs('add')],
+                         ['Any S WHERE U has_update_permission S, S eid %(s)s, U eid %(u)s'])
+
+    def test_erqlexpression(self):
+        self.assertRaises(RQLSyntaxError, ERQLExpression, '1')
+        expr = ERQLExpression('X travaille S, S owned_by U')
+        self.assertEquals(str(expr), 'Any X WHERE X travaille S, S owned_by U, X eid %(x)s, U eid %(u)s')
+        
+    def test_rrqlexpression(self):
+        self.assertRaises(Exception, RRQLExpression, '1')
+        self.assertRaises(RQLSyntaxError, RRQLExpression, 'O X Y')
+        expr = RRQLExpression('U has_update_permission O')
+        self.assertEquals(str(expr), 'Any O WHERE U has_update_permission O, O eid %(o)s, U eid %(u)s')
+        
+
+loader = CubicWebSchemaLoader()
+config = TestConfiguration('data')
+config.bootstrap_cubes()
+loader.lib_directory = config.schemas_lib_dir()
+    
+class SQLSchemaReaderClassTest(TestCase):
+
+    def test_knownValues_include_schema_files(self):
+        schema_files = loader.include_schema_files('Bookmark')
+        for file in schema_files:
+            self.assert_(isabs(file))
+        self.assertListEquals([basename(f) for f in schema_files], ['Bookmark.py'])
+
+    def test_knownValues_load_schema(self):
+        """read an url and return a Schema instance"""
+        schema = loader.load(config)
+        self.assert_(isinstance(schema, CubicWebSchema))
+        self.assertEquals(schema.name, 'data')
+        entities = [str(e) for e in schema.entities()]
+        entities.sort()
+        expected_entities = ['Bookmark', 'Boolean', 'Bytes', 'Card', 
+                             'Date', 'Datetime', 'Decimal',
+                             'EConstraint', 'EConstraintType', 'EEType',
+                             'EFRDef', 'EGroup', 'EmailAddress', 'ENFRDef',
+                             'EPermission', 'EProperty', 'ERType', 'EUser',
+                             'Float', 'Int', 'Interval', 
+                             'Password', 
+                             'RQLExpression', 
+                             'State', 'String', 'Time', 
+                             'Transition', 'TrInfo']
+        self.assertListEquals(entities, sorted(expected_entities))
+        relations = [str(r) for r in schema.relations()]
+        relations.sort()
+        expected_relations = ['add_permission', 'address', 'alias',
+                              'allowed_transition', 'bookmarked_by', 'canonical',
+
+                              'cardinality', 'comment', 'comment_format', 
+                              'composite', 'condition', 'constrained_by', 'content',
+                              'content_format', 'created_by', 'creation_date', 'cstrtype',
+
+                              'defaultval', 'delete_permission', 'description',
+                              'description_format', 'destination_state',
+
+                              'eid', 'expression', 'exprtype',
+
+                              'final', 'firstname', 'for_user',
+                              'from_entity', 'from_state', 'fulltext_container', 'fulltextindexed',
+
+                              'has_text', 
+                              'identical_to', 'identity', 'in_group', 'in_state', 'indexed',
+                              'initial_state', 'inlined', 'internationalizable', 'is', 'is_instance_of',
+
+                              'label', 'last_login_time', 'login',
+
+                              'mainvars', 'meta', 'modification_date',
+
+                              'name', 
+
+                              'ordernum', 'owned_by',
+
+                              'path', 'pkey', 'primary_email', 
+
+                              'read_permission', 'relation_type', 'require_group',
+                              
+                              'specializes', 'state_of', 'surname', 'symetric', 'synopsis',
+
+                              'title', 'to_entity', 'to_state', 'transition_of',
+
+                              'upassword', 'update_permission', 'use_email',
+
+                              'value', 
+
+                              'wf_info_for', 'wikiid']
+    
+        self.assertListEquals(relations, expected_relations)
+
+        eschema = schema.eschema('EUser')
+        rels = sorted(str(r) for r in eschema.subject_relations())
+        self.assertListEquals(rels, ['created_by', 'creation_date', 'eid',
+                                     'firstname', 'has_text', 'identity',
+                                     'in_group', 'in_state', 'is',
+                                     'is_instance_of', 'last_login_time',
+                                     'login', 'modification_date', 'owned_by',
+                                     'primary_email', 'surname', 'upassword',
+                                     'use_email'])
+        rels = sorted(r.type for r in eschema.object_relations())
+        self.assertListEquals(rels, ['bookmarked_by', 'created_by', 'for_user',
+                                     'identity', 'owned_by', 'wf_info_for'])
+        rschema = schema.rschema('relation_type')
+        properties = rschema.rproperties('EFRDef', 'ERType')
+        self.assertEquals(properties['cardinality'], '1*')
+        constraints = properties['constraints']
+        self.failUnlessEqual(len(constraints), 1, constraints)
+        constraint = constraints[0]
+        self.failUnless(isinstance(constraint, RQLConstraint))
+        self.failUnlessEqual(constraint.restriction, 'O final TRUE')
+
+    def test_fulltext_container(self):
+        schema = loader.load(config)
+        self.failUnless('has_text' in schema['EUser'].subject_relations())
+        self.failIf('has_text' in schema['EmailAddress'].subject_relations())
+
+
+class BadSchemaRQLExprTC(TestCase):
+    def setUp(self):
+        self.loader = CubicWebSchemaLoader()
+        self.loader.defined = {}
+        self.loader._instantiate_handlers()
+
+    def _test(self, schemafile, msg):
+        self.loader.handle_file(join(DATADIR, schemafile))
+        ex = self.assertRaises(BadSchemaDefinition,
+                               self.loader._build_schema, 'toto', False)
+        self.assertEquals(str(ex), msg)
+        
+    def test_rrqlexpr_on_etype(self):
+        self._test('rrqlexpr_on_eetype.py', "can't use RRQLExpression on an entity type, use an ERQLExpression (ToTo)")
+        
+    def test_erqlexpr_on_rtype(self):
+        self._test('erqlexpr_on_ertype.py', "can't use ERQLExpression on a relation type, use a RRQLExpression (toto)")
+        
+    def test_rqlexpr_on_rtype_read(self):
+        self._test('rqlexpr_on_ertype_read.py', "can't use rql expression for read permission of a relation type (toto)")
+        
+    def test_rrqlexpr_on_attr(self):
+        self._test('rrqlexpr_on_attr.py', "can't use RRQLExpression on a final relation type (eg attribute relation), use an ERQLExpression (attr)")
+
+
+class NormalizeExpressionTC(TestCase):
+
+    def test(self):
+        self.assertEquals(normalize_expression('X  bla Y,Y blur Z  ,  Z zigoulou   X '),
+                                               'X bla Y, Y blur Z, Z zigoulou X')
+
+if __name__ == '__main__':
+    unittest_main()