# HG changeset patch
# User Julien Cristau
# Date 1405697725 -7200
# Node ID fa44db7da2dc4cca37ec1e4f1197189d9dbb4269
# Parent 928732ec00dd5742987ef7bb5fc4682d9cf7c6c4# Parent 4900a937838b682e0d1e4dea4f9d9ab068b03fb0
merge 3.19.3 into 3.20 branch
diff -r 928732ec00dd -r fa44db7da2dc .hgtags
--- a/.hgtags Thu Jul 17 11:08:56 2014 +0200
+++ b/.hgtags Fri Jul 18 17:35:25 2014 +0200
@@ -332,6 +332,9 @@
ee413076752b3e606801ef55e48f7e7ccd1f7238 cubicweb-version-3.17.15
ee413076752b3e606801ef55e48f7e7ccd1f7238 cubicweb-debian-version-3.17.15-1
ee413076752b3e606801ef55e48f7e7ccd1f7238 cubicweb-centos-version-3.17.15-1
+a979d1594af6501a774fb32eb67cd32fea626655 cubicweb-version-3.17.16
+a979d1594af6501a774fb32eb67cd32fea626655 cubicweb-debian-version-3.17.16-1
+a979d1594af6501a774fb32eb67cd32fea626655 cubicweb-centos-version-3.17.16-1
db37bf35a1474843ded0a537f9cb4838f4a78cda cubicweb-version-3.18.0
db37bf35a1474843ded0a537f9cb4838f4a78cda cubicweb-debian-version-3.18.0-1
db37bf35a1474843ded0a537f9cb4838f4a78cda cubicweb-centos-version-3.18.0-1
@@ -356,3 +359,9 @@
1fe4bc4a8ac8831a379e9ebea08d75fbb6fc5c2a cubicweb-version-3.19.1
1fe4bc4a8ac8831a379e9ebea08d75fbb6fc5c2a cubicweb-debian-version-3.19.1-1
1fe4bc4a8ac8831a379e9ebea08d75fbb6fc5c2a cubicweb-centos-version-3.19.1-1
+8ac2202866e747444ce12778ff8789edd9c92eae cubicweb-version-3.19.2
+8ac2202866e747444ce12778ff8789edd9c92eae cubicweb-debian-version-3.19.2-1
+8ac2202866e747444ce12778ff8789edd9c92eae cubicweb-centos-version-3.19.2-1
+37f7c60f89f13dfcf326a4ea0a98ca20d959f7bd cubicweb-version-3.19.3
+37f7c60f89f13dfcf326a4ea0a98ca20d959f7bd cubicweb-debian-version-3.19.3-1
+37f7c60f89f13dfcf326a4ea0a98ca20d959f7bd cubicweb-centos-version-3.19.3-1
diff -r 928732ec00dd -r fa44db7da2dc __pkginfo__.py
--- a/__pkginfo__.py Thu Jul 17 11:08:56 2014 +0200
+++ b/__pkginfo__.py Fri Jul 18 17:35:25 2014 +0200
@@ -22,7 +22,7 @@
modname = distname = "cubicweb"
-numversion = (3, 19, 1)
+numversion = (3, 19, 3)
version = '.'.join(str(num) for num in numversion)
description = "a repository of entities / relations for knowledge management"
@@ -44,8 +44,7 @@
'rql': '>= 0.31.2',
'yams': '>= 0.39.1',
#gettext # for xgettext, msgcat, etc...
- # web dependancies
- 'simplejson': '>= 2.0.9',
+ # web dependencies
'lxml': '',
'Twisted': '',
# XXX graphviz
diff -r 928732ec00dd -r fa44db7da2dc cubicweb.spec
--- a/cubicweb.spec Thu Jul 17 11:08:56 2014 +0200
+++ b/cubicweb.spec Fri Jul 18 17:35:25 2014 +0200
@@ -7,7 +7,7 @@
%endif
Name: cubicweb
-Version: 3.19.1
+Version: 3.19.3
Release: logilab.1%{?dist}
Summary: CubicWeb is a semantic web application framework
Source0: http://download.logilab.org/pub/cubicweb/cubicweb-%{version}.tar.gz
diff -r 928732ec00dd -r fa44db7da2dc cwvreg.py
--- a/cwvreg.py Thu Jul 17 11:08:56 2014 +0200
+++ b/cwvreg.py Fri Jul 18 17:35:25 2014 +0200
@@ -241,7 +241,7 @@
class CWRegistry(Registry):
def __init__(self, vreg):
- super(CWRegistry, self).__init__(vreg.config)
+ super(CWRegistry, self).__init__(vreg.config.debugmode)
self.vreg = vreg
@property
diff -r 928732ec00dd -r fa44db7da2dc dataimport.py
--- a/dataimport.py Thu Jul 17 11:08:56 2014 +0200
+++ b/dataimport.py Fri Jul 18 17:35:25 2014 +0200
@@ -1114,7 +1114,6 @@
def _handle_insert_entity_sql(self, session, sql, attrs):
# We have to overwrite the source given in parameters
# as here, we directly use the system source
- attrs['source'] = 'system'
attrs['asource'] = self.system_source.uri
self._append_to_entities(sql, attrs)
@@ -1137,7 +1136,7 @@
assert isinstance(extid, str)
extid = b64encode(extid)
attrs = {'type': entity.cw_etype, 'eid': entity.eid, 'extid': extid,
- 'source': 'system', 'asource': source.uri}
+ 'asource': source.uri}
self._handle_insert_entity_sql(session, self.sqlgen.insert('entities', attrs), attrs)
# insert core relations: is, is_instance_of and cw_source
try:
diff -r 928732ec00dd -r fa44db7da2dc dbapi.py
--- a/dbapi.py Thu Jul 17 11:08:56 2014 +0200
+++ b/dbapi.py Fri Jul 18 17:35:25 2014 +0200
@@ -679,7 +679,16 @@
@check_not_closed
def entity_metas(self, eid):
"""return a tuple (type, sourceuri, extid) for the entity with id """
- return self._repo.entity_metas(self.sessionid, eid, **self._txid())
+ try:
+ return self._repo.entity_metas(self.sessionid, eid, **self._txid())
+ except AttributeError:
+ # talking to pre 3.19 repository
+ metas = self._repo.describe(self.sessionid, eid, **self._txid())
+ if len(metas) == 3: # even older backward compat
+ metas = list(metas)
+ metas.append(metas[1])
+ return dict(zip(('type', 'source', 'extid', 'asource'), metas))
+
@deprecated('[3.19] use .entity_metas(eid) instead')
@check_not_closed
diff -r 928732ec00dd -r fa44db7da2dc debian/changelog
--- a/debian/changelog Thu Jul 17 11:08:56 2014 +0200
+++ b/debian/changelog Fri Jul 18 17:35:25 2014 +0200
@@ -1,3 +1,15 @@
+cubicweb (3.19.3-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Julien Cristau Fri, 18 Jul 2014 16:16:32 +0200
+
+cubicweb (3.19.2-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Julien Cristau Thu, 03 Jul 2014 09:53:52 +0200
+
cubicweb (3.19.1-1) unstable; urgency=low
* new upstream release
@@ -46,6 +58,12 @@
-- Julien Cristau Fri, 10 Jan 2014 17:14:18 +0100
+cubicweb (3.17.16-1) unstable; urgency=low
+
+ * new upstream value
+
+ -- Aurelien Campeas Mon, 07 Jul 2014 19:26:12 +0200
+
cubicweb (3.17.15-1) unstable; urgency=low
* new upstream release
diff -r 928732ec00dd -r fa44db7da2dc debian/control
--- a/debian/control Thu Jul 17 11:08:56 2014 +0200
+++ b/debian/control Fri Jul 18 17:35:25 2014 +0200
@@ -124,7 +124,6 @@
${misc:Depends},
${python:Depends},
cubicweb-common (= ${source:Version}),
- python-simplejson (>= 2.0.9)
Recommends:
python-docutils (>= 0.6),
python-vobject,
diff -r 928732ec00dd -r fa44db7da2dc devtools/__init__.py
--- a/devtools/__init__.py Thu Jul 17 11:08:56 2014 +0200
+++ b/devtools/__init__.py Fri Jul 18 17:35:25 2014 +0200
@@ -21,6 +21,7 @@
import os
import sys
+import errno
import logging
import shutil
import pickle
@@ -277,8 +278,9 @@
sourcefile='/path/to/sources')
def test_something(self):
- rset = self.execute('Any X WHERE X is CWUser')
- self.view('foaf', rset)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X is CWUser')
+ self.view('foaf', rset, req=req)
"""
skip_db_create_and_restore = True
@@ -544,14 +546,29 @@
super(PostgresTestDataBaseHandler, self).__init__(*args, **kwargs)
datadir = join(self.config.apphome, 'pgdb')
if not exists(datadir):
- subprocess.check_call(['initdb', '-D', datadir, '-E', 'utf-8', '--locale=C'])
+ try:
+ subprocess.check_call(['initdb', '-D', datadir, '-E', 'utf-8', '--locale=C'])
+
+ except OSError, err:
+ if err.errno == errno.ENOENT:
+ raise OSError('"initdb" could not be found. '
+ 'You should add the postgresql bin folder to your PATH '
+ '(/usr/lib/postgresql/9.1/bin for example).')
+ raise
port = self.system_source['db-port']
directory = self.system_source['db-host']
env = os.environ.copy()
env['PGPORT'] = str(port)
env['PGHOST'] = str(directory)
- subprocess.check_call(['pg_ctl', 'start', '-w', '-D', datadir, '-o', '-h "" -k %s -p %s' % (directory, port)],
- env=env)
+ try:
+ subprocess.check_call(['pg_ctl', 'start', '-w', '-D', datadir, '-o', '-h "" -k %s -p %s' % (directory, port)],
+ env=env)
+ except OSError, err:
+ if err.errno == errno.ENOENT:
+ raise OSError('"pg_ctl" could not be found. '
+ 'You should add the postgresql bin folder to your PATH '
+ '(/usr/lib/postgresql/9.1/bin for example).')
+ raise
self.__CTL.add(datadir)
@property
diff -r 928732ec00dd -r fa44db7da2dc devtools/fill.py
--- a/devtools/fill.py Thu Jul 17 11:08:56 2014 +0200
+++ b/devtools/fill.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: iso-8859-1 -*-
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -352,7 +352,7 @@
-def select(constraints, cursor, selectvar='O', objtype=None):
+def select(constraints, cnx, selectvar='O', objtype=None):
"""returns list of eids matching should be either 'O' or 'S' to match schema definitions
@@ -361,7 +361,7 @@
rql = 'Any %s WHERE %s' % (selectvar, constraints)
if objtype:
rql += ', %s is %s' % (selectvar, objtype)
- rset = cursor.execute(rql)
+ rset = cnx.execute(rql)
except Exception:
print "could restrict eid_list with given constraints (%r)" % constraints
return []
@@ -369,7 +369,7 @@
-def make_relations_queries(schema, edict, cursor, ignored_relations=(),
+def make_relations_queries(schema, edict, cnx, ignored_relations=(),
existingrels=None):
"""returns a list of generated RQL queries for relations
:param schema: The instance schema
@@ -379,7 +379,7 @@
:param ignored_relations: list of relations to ignore (i.e. don't try
to generate insert queries for these relations)
"""
- gen = RelationsQueriesGenerator(schema, cursor, existingrels)
+ gen = RelationsQueriesGenerator(schema, cnx, existingrels)
return gen.compute_queries(edict, ignored_relations)
def composite_relation(rschema):
@@ -393,9 +393,9 @@
class RelationsQueriesGenerator(object):
rql_tmpl = 'SET S %s O WHERE S eid %%(subjeid)s, O eid %%(objeid)s'
- def __init__(self, schema, cursor, existing=None):
+ def __init__(self, schema, cnx, existing=None):
self.schema = schema
- self.cursor = cursor
+ self.cnx = cnx
self.existingrels = existing or {}
def compute_queries(self, edict, ignored_relations):
@@ -457,7 +457,7 @@
# restrict object eids if possible
# XXX the attempt to restrict below in completely wrong
# disabling it for now
- objeids = select(restrictions, self.cursor, objtype=obj)
+ objeids = select(restrictions, self.cnx, objtype=obj)
else:
objeids = oedict.get(obj, frozenset())
if subjcard in '?1' or objcard in '?1':
diff -r 928732ec00dd -r fa44db7da2dc devtools/repotest.py
--- a/devtools/repotest.py Thu Jul 17 11:08:56 2014 +0200
+++ b/devtools/repotest.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -22,17 +22,12 @@
__docformat__ = "restructuredtext en"
-from copy import deepcopy
from pprint import pprint
-from logilab.common.decorators import clear_cache
from logilab.common.testlib import SkipTest
-def tuplify(list):
- for i in range(len(list)):
- if type(list[i]) is not type(()):
- list[i] = tuple(list[i])
- return list
+def tuplify(mylist):
+ return [tuple(item) for item in mylist]
def snippet_cmp(a, b):
a = (a[0], [e.expression for e in a[1]])
@@ -40,17 +35,18 @@
return cmp(a, b)
def test_plan(self, rql, expected, kwargs=None):
- plan = self._prepare_plan(rql, kwargs)
- self.planner.build_plan(plan)
- try:
- self.assertEqual(len(plan.steps), len(expected),
- 'expected %s steps, got %s' % (len(expected), len(plan.steps)))
- # step order is important
- for i, step in enumerate(plan.steps):
- compare_steps(self, step.test_repr(), expected[i])
- except AssertionError:
- pprint([step.test_repr() for step in plan.steps])
- raise
+ with self.session.new_cnx() as cnx:
+ plan = self._prepare_plan(cnx, rql, kwargs)
+ self.planner.build_plan(plan)
+ try:
+ self.assertEqual(len(plan.steps), len(expected),
+ 'expected %s steps, got %s' % (len(expected), len(plan.steps)))
+ # step order is important
+ for i, step in enumerate(plan.steps):
+ compare_steps(self, step.test_repr(), expected[i])
+ except AssertionError:
+ pprint([step.test_repr() for step in plan.steps])
+ raise
def compare_steps(self, step, expected):
try:
@@ -161,8 +157,9 @@
def setUp(self):
self.repo = FakeRepo(self.schema, config=FakeConfig(apphome=self.datadir))
self.repo.system_source = mock_object(dbdriver=self.backend)
- self.rqlhelper = RQLHelper(self.schema, special_relations={'eid': 'uid',
- 'has_text': 'fti'},
+ self.rqlhelper = RQLHelper(self.schema,
+ special_relations={'eid': 'uid',
+ 'has_text': 'fti'},
backend=self.backend)
self.qhelper = QuerierHelper(self.repo, self.schema)
ExecutionPlan._check_permissions = _dummy_check_permissions
@@ -204,27 +201,22 @@
self.ueid = self.session.user.eid
assert self.ueid != -1
self.repo._type_source_cache = {} # clear cache
- self.cnxset = self.session.set_cnxset()
self.maxeid = self.get_max_eid()
do_monkey_patch()
self._dumb_sessions = []
def get_max_eid(self):
- return self.session.execute('Any MAX(X)')[0][0]
+ with self.session.new_cnx() as cnx:
+ return cnx.execute('Any MAX(X)')[0][0]
+
def cleanup(self):
- self.session.set_cnxset()
- self.session.execute('DELETE Any X WHERE X eid > %s' % self.maxeid)
+ with self.session.new_cnx() as cnx:
+ cnx.execute('DELETE Any X WHERE X eid > %s' % self.maxeid)
+ cnx.commit()
def tearDown(self):
undo_monkey_patch()
- self.session.rollback()
self.cleanup()
- self.commit()
- # properly close dumb sessions
- for session in self._dumb_sessions:
- session.rollback()
- session.close()
- self.repo._free_cnxset(self.cnxset)
assert self.session.user.eid != -1
def set_debug(self, debug):
@@ -239,7 +231,7 @@
rqlhelper._analyser.uid_func_mapping = {}
return rqlhelper
- def _prepare_plan(self, rql, kwargs=None, simplify=True):
+ def _prepare_plan(self, cnx, rql, kwargs=None, simplify=True):
rqlhelper = self._rqlhelper()
rqlst = rqlhelper.parse(rql)
rqlhelper.compute_solutions(rqlst, kwargs=kwargs)
@@ -247,10 +239,10 @@
rqlhelper.simplify(rqlst)
for select in rqlst.children:
select.solutions.sort()
- return self.o.plan_factory(rqlst, kwargs, self.session)
+ return self.o.plan_factory(rqlst, kwargs, cnx)
- def _prepare(self, rql, kwargs=None):
- plan = self._prepare_plan(rql, kwargs, simplify=False)
+ def _prepare(self, cnx, rql, kwargs=None):
+ plan = self._prepare_plan(cnx, rql, kwargs, simplify=False)
plan.preprocess(plan.rqlst)
rqlst = plan.rqlst.children[0]
rqlst.solutions = remove_unused_solutions(rqlst, rqlst.solutions, {}, self.repo.schema)[0]
@@ -259,21 +251,20 @@
def user_groups_session(self, *groups):
"""lightweight session using the current user with hi-jacked groups"""
# use self.session.user.eid to get correct owned_by relation, unless explicit eid
- u = self.repo._build_user(self.session, self.session.user.eid)
- u._groups = set(groups)
- s = Session(u, self.repo)
- s._cnx.cnxset = self.cnxset
- s._cnx.ctx_count = 1
- # register session to ensure it gets closed
- self._dumb_sessions.append(s)
- return s
+ with self.session.new_cnx() as cnx:
+ u = self.repo._build_user(cnx, self.session.user.eid)
+ u._groups = set(groups)
+ s = Session(u, self.repo)
+ return s
- def execute(self, rql, args=None, build_descr=True):
- return self.o.execute(self.session, rql, args, build_descr)
-
- def commit(self):
- self.session.commit()
- self.session.set_cnxset()
+ def qexecute(self, rql, args=None, build_descr=True):
+ with self.session.new_cnx() as cnx:
+ with cnx.ensure_cnx_set:
+ try:
+ return self.o.execute(cnx, rql, args, build_descr)
+ finally:
+ if rql.startswith(('INSERT', 'DELETE', 'SET')):
+ cnx.commit()
class BasePlannerTC(BaseQuerierTC):
@@ -282,31 +273,24 @@
# XXX source_defs
self.o = self.repo.querier
self.session = self.repo._sessions.values()[0]
- self.cnxset = self.session.set_cnxset()
self.schema = self.o.schema
self.system = self.repo.system_source
do_monkey_patch()
- self._dumb_sessions = [] # by hi-jacked parent setup
self.repo.vreg.rqlhelper.backend = 'postgres' # so FTIRANK is considered
def tearDown(self):
undo_monkey_patch()
- for session in self._dumb_sessions:
- if session._cnx.cnxset is not None:
- session._cnx.cnxset = None
- session.close()
- def _prepare_plan(self, rql, kwargs=None):
+ def _prepare_plan(self, cnx, rql, kwargs=None):
rqlst = self.o.parse(rql, annotate=True)
- self.o.solutions(self.session, rqlst, kwargs)
+ self.o.solutions(cnx, rqlst, kwargs)
if rqlst.TYPE == 'select':
self.repo.vreg.rqlhelper.annotate(rqlst)
for select in rqlst.children:
select.solutions.sort()
else:
rqlst.solutions.sort()
- with self.session.ensure_cnx_set:
- return self.o.plan_factory(rqlst, kwargs, self.session)
+ return self.o.plan_factory(rqlst, kwargs, cnx)
# monkey patch some methods to get predicatable results #######################
@@ -354,24 +338,6 @@
_sort=lambda rels: sorted(rels, key=sort_key))
-def _merge_input_maps(*args, **kwargs):
- return sorted(_orig_merge_input_maps(*args, **kwargs))
-
-def _choose_term(self, source, sourceterms):
- # predictable order for test purpose
- def get_key(x):
- try:
- # variable
- return x.name
- except AttributeError:
- try:
- # relation
- return x.r_type
- except AttributeError:
- # const
- return x.value
- return _orig_choose_term(self, source, DumbOrderedDict2(sourceterms, get_key))
-
def _ordered_iter_relations(stinfo):
return sorted(_orig_iter_relations(stinfo), key=lambda x:x.r_type)
diff -r 928732ec00dd -r fa44db7da2dc devtools/test/unittest_testlib.py
--- a/devtools/test/unittest_testlib.py Thu Jul 17 11:08:56 2014 +0200
+++ b/devtools/test/unittest_testlib.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -39,11 +39,13 @@
class MyWebTest(CubicWebTC):
def test_error_view(self):
- self.request().create_entity('Bug', title=u"bt")
- self.view('raising', self.execute('Bug B'), template=None)
+ with self.admin_access.web_request() as req:
+ req.create_entity('Bug', title=u"bt")
+ self.view('raising', req.execute('Bug B'), template=None, req=req)
def test_correct_view(self):
- self.view('primary', self.execute('CWUser U'), template=None)
+ with self.admin_access.web_request() as req:
+ self.view('primary', req.execute('CWUser U'), template=None, req=req)
tests = [MyWebTest('test_error_view'), MyWebTest('test_correct_view')]
result = self.runner.run(TestSuite(tests))
@@ -98,6 +100,7 @@
class HTMLPageInfoTC(TestCase):
"""test cases for PageInfo"""
+
def setUp(self):
parser = htmlparser.HTMLValidator()
# disable cleanup that would remove doctype
@@ -113,7 +116,6 @@
parser = htmlparser.DTDValidator()
self.assertRaises(AssertionError, parser.parse_string, HTML_PAGE_ERROR)
-
def test_has_title_no_level(self):
"""tests h? tags information"""
self.assertEqual(self.page_info.has_title('Test'), True)
@@ -160,6 +162,7 @@
class CWUtilitiesTC(CubicWebTC):
+
def test_temporary_permissions_eschema(self):
eschema = self.schema['CWUser']
with self.temporary_permissions(CWUser={'read': ()}):
@@ -175,11 +178,13 @@
self.assertTrue(rdef.permissions['read'], ())
def test_temporary_appobjects_registered(self):
+
class AnAppobject(object):
__registries__ = ('hip',)
__regid__ = 'hop'
__select__ = yes()
registered = None
+
@classmethod
def __registered__(cls, reg):
cls.registered = reg
@@ -190,10 +195,11 @@
self.assertNotIn(AnAppobject, self.vreg['hip']['hop'])
def test_login(self):
- """Calling login should not break self.session hook control"""
- self.hook_executed = False
- babar = self.create_user(self.request(), 'babar')
- self.commit()
+ """Calling login should not break hook control"""
+ with self.admin_access.repo_cnx() as cnx:
+ self.hook_executed = False
+ self.create_user(cnx, 'babar')
+ cnx.commit()
from cubicweb.server import hook
from cubicweb.predicates import is_instance
@@ -208,31 +214,31 @@
def __call__(self):
self.test.hook_executed = True
- self.login('babar')
- with self.temporary_appobjects(MyHook):
- with self.session.allow_all_hooks_but('test-hook'):
- req = self.request()
- prop = req.create_entity('CWProperty', pkey=u'ui.language', value=u'en')
- self.commit()
- self.assertFalse(self.hook_executed)
+ with self.new_access('babar').repo_cnx() as cnx:
+ with self.temporary_appobjects(MyHook):
+ with cnx.allow_all_hooks_but('test-hook'):
+ prop = cnx.create_entity('CWProperty', pkey=u'ui.language', value=u'en')
+ cnx.commit()
+ self.assertFalse(self.hook_executed)
class RepoAccessTC(CubicWebTC):
+
def test_repo_connection(self):
acc = self.new_access('admin')
- with acc.repo_cnx() as cnx:
+ with acc.repo_cnx() as cnx:
rset = cnx.execute('Any X WHERE X is CWUser')
self.assertTrue(rset)
def test_client_connection(self):
acc = self.new_access('admin')
- with acc.client_cnx() as cnx:
+ with acc.client_cnx() as cnx:
rset = cnx.execute('Any X WHERE X is CWUser')
self.assertTrue(rset)
def test_web_request(self):
acc = self.new_access('admin')
- with acc.web_request(elephant='babar') as req:
+ with acc.web_request(elephant='babar') as req:
rset = req.execute('Any X WHERE X is CWUser')
self.assertTrue(rset)
self.assertEqual('babar', req.form['elephant'])
diff -r 928732ec00dd -r fa44db7da2dc devtools/testlib.py
--- a/devtools/testlib.py Thu Jul 17 11:08:56 2014 +0200
+++ b/devtools/testlib.py Fri Jul 18 17:35:25 2014 +0200
@@ -823,12 +823,13 @@
def list_startup_views(self):
"""returns the list of startup views"""
- req = self.request()
- for view in self.vreg['views'].possible_views(req, None):
- if view.category == 'startupview':
- yield view.__regid__
- else:
- not_selected(self.vreg, view)
+ with self.admin_access.web_request() as req:
+ for view in self.vreg['views'].possible_views(req, None):
+ if view.category == 'startupview':
+ yield view.__regid__
+ else:
+ not_selected(self.vreg, view)
+
# web ui testing utilities #################################################
@@ -842,6 +843,7 @@
publisher.error_handler = raise_error_handler
return publisher
+ @deprecated('[3.19] use the .remote_calling method')
def remote_call(self, fname, *args):
"""remote json call simulation"""
dump = json.dumps
@@ -850,6 +852,14 @@
ctrl = self.vreg['controllers'].select('ajax', req)
return ctrl.publish(), req
+ @contextmanager
+ def remote_calling(self, fname, *args):
+ """remote json call simulation"""
+ args = [json.dumps(arg) for arg in args]
+ with self.admin_access.web_request(fname=fname, pageid='123', arg=args) as req:
+ ctrl = self.vreg['controllers'].select('ajax', req)
+ yield ctrl.publish(), req
+
def app_handle_request(self, req, path='view'):
return self.app.core_handle(req, path)
@@ -1178,7 +1188,7 @@
# XXX cleanup unprotected_entities & all mess
-def how_many_dict(schema, cursor, how_many, skip):
+def how_many_dict(schema, cnx, how_many, skip):
"""given a schema, compute how many entities by type we need to be able to
satisfy relations cardinality.
@@ -1212,7 +1222,7 @@
# step 1, compute a base number of each entity types: number of already
# existing entities of this type + `how_many`
for etype in unprotected_entities(schema, strict=True):
- howmanydict[str(etype)] = cursor.execute('Any COUNT(X) WHERE X is %s' % etype)[0][0]
+ howmanydict[str(etype)] = cnx.execute('Any COUNT(X) WHERE X is %s' % etype)[0][0]
if etype in unprotected:
howmanydict[str(etype)] += how_many
# step 2, augment nb entity per types to satisfy cardinality constraints,
@@ -1246,10 +1256,10 @@
def to_test_etypes(self):
return unprotected_entities(self.schema, strict=True)
- def custom_populate(self, how_many, cursor):
+ def custom_populate(self, how_many, cnx):
pass
- def post_populate(self, cursor):
+ def post_populate(self, cnx):
pass
@@ -1258,77 +1268,79 @@
"""this method populates the database with `how_many` entities
of each possible type. It also inserts random relations between them
"""
- with self.session.security_enabled(read=False, write=False):
- self._auto_populate(how_many)
+ with self.admin_access.repo_cnx() as cnx:
+ with cnx.security_enabled(read=False, write=False):
+ self._auto_populate(cnx, how_many)
+ cnx.commit()
- def _auto_populate(self, how_many):
- cu = self.cursor()
- self.custom_populate(how_many, cu)
+ def _auto_populate(self, cnx, how_many):
+ self.custom_populate(how_many, cnx)
vreg = self.vreg
- howmanydict = how_many_dict(self.schema, cu, how_many, self.no_auto_populate)
+ howmanydict = how_many_dict(self.schema, cnx, how_many, self.no_auto_populate)
for etype in unprotected_entities(self.schema):
if etype in self.no_auto_populate:
continue
nb = howmanydict.get(etype, how_many)
for rql, args in insert_entity_queries(etype, self.schema, vreg, nb):
- cu.execute(rql, args)
+ cnx.execute(rql, args)
edict = {}
for etype in unprotected_entities(self.schema, strict=True):
- rset = cu.execute('%s X' % etype)
+ rset = cnx.execute('%s X' % etype)
edict[str(etype)] = set(row[0] for row in rset.rows)
existingrels = {}
ignored_relations = SYSTEM_RELATIONS | self.ignored_relations
for rschema in self.schema.relations():
if rschema.final or rschema in ignored_relations:
continue
- rset = cu.execute('DISTINCT Any X,Y WHERE X %s Y' % rschema)
+ rset = cnx.execute('DISTINCT Any X,Y WHERE X %s Y' % rschema)
existingrels.setdefault(rschema.type, set()).update((x, y) for x, y in rset)
- q = make_relations_queries(self.schema, edict, cu, ignored_relations,
+ q = make_relations_queries(self.schema, edict, cnx, ignored_relations,
existingrels=existingrels)
for rql, args in q:
try:
- cu.execute(rql, args)
+ cnx.execute(rql, args)
except ValidationError as ex:
# failed to satisfy some constraint
print 'error in automatic db population', ex
- self.session.commit_state = None # reset uncommitable flag
- self.post_populate(cu)
- self.commit()
+ cnx.commit_state = None # reset uncommitable flag
+ self.post_populate(cnx)
def iter_individual_rsets(self, etypes=None, limit=None):
etypes = etypes or self.to_test_etypes()
- for etype in etypes:
- if limit:
- rql = 'Any X LIMIT %s WHERE X is %s' % (limit, etype)
- else:
- rql = 'Any X WHERE X is %s' % etype
- rset = self.execute(rql)
- for row in xrange(len(rset)):
- if limit and row > limit:
- break
- # XXX iirk
- rset2 = rset.limit(limit=1, offset=row)
- yield rset2
+ with self.admin_access.web_request() as req:
+ for etype in etypes:
+ if limit:
+ rql = 'Any X LIMIT %s WHERE X is %s' % (limit, etype)
+ else:
+ rql = 'Any X WHERE X is %s' % etype
+ rset = req.execute(rql)
+ for row in xrange(len(rset)):
+ if limit and row > limit:
+ break
+ # XXX iirk
+ rset2 = rset.limit(limit=1, offset=row)
+ yield rset2
def iter_automatic_rsets(self, limit=10):
"""generates basic resultsets for each entity type"""
etypes = self.to_test_etypes()
if not etypes:
return
- for etype in etypes:
- yield self.execute('Any X LIMIT %s WHERE X is %s' % (limit, etype))
- etype1 = etypes.pop()
- try:
- etype2 = etypes.pop()
- except KeyError:
- etype2 = etype1
- # test a mixed query (DISTINCT/GROUP to avoid getting duplicate
- # X which make muledit view failing for instance (html validation fails
- # because of some duplicate "id" attributes)
- yield self.execute('DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is %s, Y is %s' % (etype1, etype2))
- # test some application-specific queries if defined
- for rql in self.application_rql:
- yield self.execute(rql)
+ with self.admin_access.web_request() as req:
+ for etype in etypes:
+ yield req.execute('Any X LIMIT %s WHERE X is %s' % (limit, etype))
+ etype1 = etypes.pop()
+ try:
+ etype2 = etypes.pop()
+ except KeyError:
+ etype2 = etype1
+ # test a mixed query (DISTINCT/GROUP to avoid getting duplicate
+ # X which make muledit view failing for instance (html validation fails
+ # because of some duplicate "id" attributes)
+ yield req.execute('DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is %s, Y is %s' % (etype1, etype2))
+ # test some application-specific queries if defined
+ for rql in self.application_rql:
+ yield req.execute(rql)
def _test_everything_for(self, rset):
"""this method tries to find everything that can be tested
@@ -1390,8 +1402,8 @@
## startup views
def test_startup_views(self):
for vid in self.list_startup_views():
- req = self.request()
- yield self.view, vid, None, req
+ with self.admin_access.web_request() as req:
+ yield self.view, vid, None, req
# registry instrumentization ###################################################
diff -r 928732ec00dd -r fa44db7da2dc doc/book/en/annexes/rql/language.rst
--- a/doc/book/en/annexes/rql/language.rst Thu Jul 17 11:08:56 2014 +0200
+++ b/doc/book/en/annexes/rql/language.rst Fri Jul 18 17:35:25 2014 +0200
@@ -350,9 +350,10 @@
matching state of or tagged by the expected tag,
* the later will retrieve all versions, state and tags (cartesian product!),
- compute join and then exclude each row which are in the matching state of or
- tagged by the expected tag. This implies that : you won't get any result if the
- in_state or tag
+ compute join and then exclude each row which are in the matching state or
+ tagged by the expected tag. This implies that you won't get any result if the
+ in_state or tag tables are empty (ie there is no such relation in the
+ application). This is usually NOT what you want.
Another common case where you may want to use ``EXISTS`` is when you
find yourself using ``DISTINCT`` at the beginning of your query to
@@ -562,19 +563,19 @@
Aggregate functions
```````````````````
-+--------------------+----------------------------------------------------------+
-| :func:`COUNT` | return the number of rows |
-+--------------------+----------------------------------------------------------+
-| :func:`MIN` | return the minimum value |
-+--------------------+----------------------------------------------------------+
-| :func:`MAX` | return the maximum value |
-+--------------------+----------------------------------------------------------+
-| :func:`AVG` | return the average value |
-+--------------------+----------------------------------------------------------+
-| :func:`SUM` | return the sum of values |
-+--------------------+----------------------------------------------------------+
-| :func:`COMMA_JOIN` | return each value separated by a comma (for string only) |
-+--------------------+----------------------------------------------------------+
++------------------------+----------------------------------------------------------+
+| ``COUNT(Any)`` | return the number of rows |
++------------------------+----------------------------------------------------------+
+| ``MIN(Any)`` | return the minimum value |
++------------------------+----------------------------------------------------------+
+| ``MAX(Any)`` | return the maximum value |
++------------------------+----------------------------------------------------------+
+| ``AVG(Any)`` | return the average value |
++------------------------+----------------------------------------------------------+
+| ``SUM(Any)`` | return the sum of values |
++------------------------+----------------------------------------------------------+
+| ``COMMA_JOIN(String)`` | return each value separated by a comma (for string only) |
++------------------------+----------------------------------------------------------+
All aggregate functions above take a single argument. Take care some aggregate
functions (e.g. ``MAX``, ``MIN``) may return `None` if there is no
@@ -585,67 +586,67 @@
String transformation functions
```````````````````````````````
-+---------------------------------------------------+-----------------------------------------------------------------+
-| :func:`UPPER(String)` | upper case the string |
-+---------------------------------------------------+-----------------------------------------------------------------+
-| :func:`LOWER(String)` | lower case the string |
-+---------------------------------------------------+-----------------------------------------------------------------+
-| :func:`LENGTH(String)` | return the length of the string |
-+---------------------------------------------------+-----------------------------------------------------------------+
-| :func:`SUBSTRING(String, start, length)` | extract from the string a string starting at given index and of |
-| | given length |
-+---------------------------------------------------+-----------------------------------------------------------------+
-| :func:`LIMIT_SIZE(String, max size)` | if the length of the string is greater than given max size, |
-| | strip it and add ellipsis ("..."). The resulting string will |
-| | hence have max size + 3 characters |
-+---------------------------------------------------+-----------------------------------------------------------------+
-| :func:`TEXT_LIMIT_SIZE(String, format, max size)` | similar to the above, but allow to specify the MIME type of the |
-| | text contained by the string. Supported formats are text/html, |
-| | text/xhtml and text/xml. All others will be considered as plain |
-| | text. For non plain text format, sgml tags will be first removed|
-| | before limiting the string. |
-+---------------------------------------------------+-----------------------------------------------------------------+
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``UPPER(String)`` | upper case the string |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``LOWER(String)`` | lower case the string |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``LENGTH(String)`` | return the length of the string |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``SUBSTRING(String, start, length)`` | extract from the string a string starting at given index and of |
+| | given length |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``LIMIT_SIZE(String, max size)`` | if the length of the string is greater than given max size, |
+| | strip it and add ellipsis ("..."). The resulting string will |
+| | hence have max size + 3 characters |
++-----------------------------------------------+-----------------------------------------------------------------+
+| ``TEXT_LIMIT_SIZE(String, format, max size)`` | similar to the above, but allow to specify the MIME type of the |
+| | text contained by the string. Supported formats are text/html, |
+| | text/xhtml and text/xml. All others will be considered as plain |
+| | text. For non plain text format, sgml tags will be first removed|
+| | before limiting the string. |
++-----------------------------------------------+-----------------------------------------------------------------+
.. _RQLDateFunctions:
Date extraction functions
`````````````````````````
-+--------------------------+----------------------------------------+
-| :func:`YEAR(Date)` | return the year of a date or datetime |
-+--------------------------+----------------------------------------+
-| :func:`MONTH(Date)` | return the month of a date or datetime |
-+--------------------------+----------------------------------------+
-| :func:`DAY(Date)` | return the day of a date or datetime |
-+--------------------------+----------------------------------------+
-| :func:`HOUR(Datetime)` | return the hours of a datetime |
-+--------------------------+----------------------------------------+
-| :func:`MINUTE(Datetime)` | return the minutes of a datetime |
-+--------------------------+----------------------------------------+
-| :func:`SECOND(Datetime)` | return the seconds of a datetime |
-+--------------------------+----------------------------------------+
-| :func:`WEEKDAY(Date)` | return the day of week of a date or |
-| | datetime. Sunday == 1, Saturday == 7. |
-+--------------------------+----------------------------------------+
++----------------------+----------------------------------------+
+| ``YEAR(Date)`` | return the year of a date or datetime |
++----------------------+----------------------------------------+
+| ``MONTH(Date)`` | return the month of a date or datetime |
++----------------------+----------------------------------------+
+| ``DAY(Date)`` | return the day of a date or datetime |
++----------------------+----------------------------------------+
+| ``HOUR(Datetime)`` | return the hours of a datetime |
++----------------------+----------------------------------------+
+| ``MINUTE(Datetime)`` | return the minutes of a datetime |
++----------------------+----------------------------------------+
+| ``SECOND(Datetime)`` | return the seconds of a datetime |
++----------------------+----------------------------------------+
+| ``WEEKDAY(Date)`` | return the day of week of a date or |
+| | datetime. Sunday == 1, Saturday == 7. |
++----------------------+----------------------------------------+
.. _RQLOtherFunctions:
Other functions
```````````````
-+-----------------------+--------------------------------------------------------------------+
-| :func:`ABS(num)` | return the absolute value of a number |
-+-----------------------+--------------------------------------------------------------------+
-| :func:`RANDOM()` | return a pseudo-random value from 0.0 to 1.0 |
-+-----------------------+--------------------------------------------------------------------+
-| :func:`FSPATH(X)` | expect X to be an attribute whose value is stored in a |
-| | :class:`BFSStorage` and return its path on the file system |
-+-----------------------+--------------------------------------------------------------------+
-| :func:`FTIRANK(X)` | expect X to be an entity used in a has_text relation, and return a |
-| | number corresponding to the rank order of each resulting entity |
-+-----------------------+--------------------------------------------------------------------+
-| :func:`CAST(Type, X)` | expect X to be an attribute and return it casted into the given |
-| | final type |
-+-----------------------+--------------------------------------------------------------------+
++-------------------+--------------------------------------------------------------------+
+| ``ABS(num)`` | return the absolute value of a number |
++-------------------+--------------------------------------------------------------------+
+| ``RANDOM()`` | return a pseudo-random value from 0.0 to 1.0 |
++-------------------+--------------------------------------------------------------------+
+| ``FSPATH(X)`` | expect X to be an attribute whose value is stored in a |
+| | :class:`BFSStorage` and return its path on the file system |
++-------------------+--------------------------------------------------------------------+
+| ``FTIRANK(X)`` | expect X to be an entity used in a has_text relation, and return a |
+| | number corresponding to the rank order of each resulting entity |
++-------------------+--------------------------------------------------------------------+
+| ``CAST(Type, X)`` | expect X to be an attribute and return it casted into the given |
+| | final type |
++-------------------+--------------------------------------------------------------------+
.. _RQLExamples:
@@ -657,7 +658,7 @@
.. sourcecode:: sql
- Any WHERE X eid 53
+ Any X WHERE X eid 53
- *Search material such as comics, owned by syt and available*
@@ -686,7 +687,7 @@
.. sourcecode:: sql
- Any P WHERE P is Person, (P interested_by T, T name 'training') OR
+ Any P WHERE P is Person, EXISTS(P interested_by T, T name 'training') OR
(P city 'Paris')
- *The surname and firstname of all people*
diff -r 928732ec00dd -r fa44db7da2dc doc/book/en/devrepo/testing.rst
--- a/doc/book/en/devrepo/testing.rst Thu Jul 17 11:08:56 2014 +0200
+++ b/doc/book/en/devrepo/testing.rst Fri Jul 18 17:35:25 2014 +0200
@@ -25,8 +25,8 @@
http://docs.python.org/library/sqlite3.html) as a backend.
The database is stored in the mycube/test/tmpdb,
-mycube/test/tmpdb-template files. If it does not (yet) exists, it will
-be built automatically when the test suit starts.
+mycube/test/tmpdb-template files. If it does not (yet) exist, it will
+be built automatically when the test suite starts.
.. warning::
@@ -34,8 +34,8 @@
one must delete these two files. Changes concerned only with entity
or relation type properties (constraints, cardinalities,
permissions) and generally dealt with using the
- `sync_schema_props_perms()` fonction of the migration environment
- need not a database regeneration step.
+ `sync_schema_props_perms()` function of the migration environment do
+ not need a database regeneration step.
.. _hook_test:
@@ -53,56 +53,58 @@
class ClassificationHooksTC(CubicWebTC):
def setup_database(self):
- req = self.request()
- group_etype = req.find_one_entity('CWEType', name='CWGroup')
- c1 = req.create_entity('Classification', name=u'classif1',
- classifies=group_etype)
- user_etype = req.find_one_entity('CWEType', name='CWUser')
- c2 = req.create_entity('Classification', name=u'classif2',
- classifies=user_etype)
- self.kw1 = req.create_entity('Keyword', name=u'kwgroup', included_in=c1)
- self.kw2 = req.create_entity('Keyword', name=u'kwuser', included_in=c2)
+ with self.admin_access.repo_cnx() as cnx:
+ group_etype = cnx.find('CWEType', name='CWGroup').one()
+ c1 = cnx.create_entity('Classification', name=u'classif1',
+ classifies=group_etype)
+ user_etype = cnx.find('CWEType', name='CWUser').one()
+ c2 = cnx.create_entity('Classification', name=u'classif2',
+ classifies=user_etype)
+ self.kw1eid = cnx.create_entity('Keyword', name=u'kwgroup', included_in=c1).eid
+ cnx.commit()
def test_cannot_create_cycles(self):
- # direct obvious cycle
- self.assertRaises(ValidationError, self.kw1.cw_set,
- subkeyword_of=self.kw1)
- # testing indirect cycles
- kw3 = self.execute('INSERT Keyword SK: SK name "kwgroup2", SK included_in C, '
- 'SK subkeyword_of K WHERE C name "classif1", K eid %s'
- % self.kw1.eid).get_entity(0,0)
- self.kw1.cw_set(subkeyword_of=kw3)
- self.assertRaises(ValidationError, self.commit)
+ with self.admin_access.repo_cnx() as cnx:
+ kw1 = cnx.entity_from_eid(self.kw1eid)
+ # direct obvious cycle
+ with self.assertRaises(ValidationError):
+ kw1.cw_set(subkeyword_of=kw1)
+ cnx.rollback()
+ # testing indirect cycles
+ kw3 = cnx.execute('INSERT Keyword SK: SK name "kwgroup2", SK included_in C, '
+ 'SK subkeyword_of K WHERE C name "classif1", K eid %(k)s'
+ {'k': kw1}).get_entity(0,0)
+ kw3.cw_set(reverse_subkeyword_of=kw1)
+ self.assertRaises(ValidationError, cnx.commit)
The test class defines a :meth:`setup_database` method which populates the
database with initial data. Each test of the class runs with this
-pre-populated database. A commit is done automatically after the
-:meth:`setup_database` call. You don't have to call it explicitely.
+pre-populated database.
-The test case itself checks that an Operation does it job of
+The test case itself checks that an Operation does its job of
preventing cycles amongst Keyword entities.
-`create_entity` is a useful method, which easily allows to create an
-entity. You can link this entity to others entities, by specifying as
-argument, the relation name, and the entity to link, as value. In the
-above example, the `Classification` entity is linked to a `CWEtype`
-via the relation `classifies`. Conversely, if you are creating a
-`CWEtype` entity, you can link it to a `Classification` entity, by
-adding `reverse_classifies` as argument.
+The `create_entity` method of connection (or request) objects allows
+to create an entity. You can link this entity to other entities, by
+specifying as argument, the relation name, and the entity to link, as
+value. In the above example, the `Classification` entity is linked to
+a `CWEtype` via the relation `classifies`. Conversely, if you are
+creating a `CWEtype` entity, you can link it to a `Classification`
+entity, by adding `reverse_classifies` as argument.
.. note::
- :meth:`commit` method is not called automatically in test_XXX
- methods. You have to call it explicitely if needed (notably to test
- operations). It is a good practice to call :meth:`clear_all_caches`
- on entities after a commit to avoid request cache effects.
+ the :meth:`commit` method is not called automatically. You have to
+ call it explicitly if needed (notably to test operations). It is a
+ good practice to regenerate entities with :meth:`entity_from_eid`
+ after a commit to avoid request cache effects.
You can see an example of security tests in the
:ref:`adv_tuto_security`.
It is possible to have these tests run continuously using `apycot`_.
-.. _apycot: http://www.logilab.org/project/apycot
+.. _apycot: http://www.cubicweb.org/project/apycot
.. _securitytest:
@@ -113,66 +115,50 @@
support multiple connections at a time, you must be careful when
simulating security, changing users.
-By default, tests run with a user with admin privileges. This
-user/connection must never be closed.
+By default, tests run with a user with admin privileges. Connections
+using these credentials are accessible through the `admin_access` object
+of the test classes.
-Before a self.login, one has to release the connection pool in use
-with a self.commit, self.rollback or self.close.
-
-The `login` method returns a connection object that can be used as a
+The `repo_cnx()` method returns a connection object that can be used as a
context manager:
.. sourcecode:: python
- with self.login('user1') as user:
- req = user.req
- req.execute(...)
-
-On exit of the context manager, either a commit or rollback is issued,
-which releases the connection.
-
-When one is logged in as a normal user and wants to switch back to the
-admin user without committing, one has to use
-self.restore_connection().
-
-Usage with restore_connection:
-
-.. sourcecode:: python
+ # admin_access is a pre-cooked session wrapping object
+ # it is built with:
+ # self.admin_access = self.new_access('admin')
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute(...)
+ self.create_user(cnx, login='user1')
+ cnx.commit()
- # execute using default admin connection
- self.execute(...)
- # I want to login with another user, ensure to free admin connection pool
- # (could have used rollback but not close here
- # we should never close defaut admin connection)
- self.commit()
- cnx = self.login('user')
- # execute using user connection
- self.execute(...)
- # I want to login with another user or with admin user
- self.commit(); cnx.close()
- # restore admin connection, never use cnx = self.login('admin'), it will return
- # the default admin connection and one may be tempted to close it
- self.restore_connection()
+ user1access = self.new_access('user1')
+ with user1access.web_request() as req:
+ req.execute(...)
+ req.cnx.commit()
+
+On exit of the context manager, a rollback is issued, which releases
+the connection. Don't forget to issue the `cnx.commit()` calls!
.. warning::
- Do not use the references kept to the entities created with a
- connection from another !
+ Do not use references kept to the entities created with a
+ connection from another one!
Email notifications tests
`````````````````````````
-When running tests potentially generated e-mails are not really sent
-but is found in the list `MAILBOX` of module
+When running tests, potentially generated e-mails are not really sent
+but are found in the list `MAILBOX` of module
:mod:`cubicweb.devtools.testlib`.
You can test your notifications by analyzing the contents of this list, which
contains objects with two attributes:
* `recipients`, the list of recipients
-* `msg`, object email.Message
+* `msg`, email.Message object
-Let us look at simple example from the ``blog`` cube.
+Let us look at a simple example from the ``blog`` cube.
.. sourcecode:: python
@@ -182,28 +168,28 @@
"""test blog specific behaviours"""
def test_notifications(self):
- req = self.request()
- cubicweb_blog = req.create_entity('Blog', title=u'cubicweb',
- description=u'cubicweb is beautiful')
- blog_entry_1 = req.create_entity('BlogEntry', title=u'hop',
- content=u'cubicweb hop')
- blog_entry_1.cw_set(entry_of=cubicweb_blog)
- blog_entry_2 = req.create_entity('BlogEntry', title=u'yes',
- content=u'cubicweb yes')
- blog_entry_2.cw_set(entry_of=cubicweb_blog)
- self.assertEqual(len(MAILBOX), 0)
- self.commit()
- self.assertEqual(len(MAILBOX), 2)
- mail = MAILBOX[0]
- self.assertEqual(mail.subject, '[data] hop')
- mail = MAILBOX[1]
- self.assertEqual(mail.subject, '[data] yes')
+ with self.admin_access.web_request() as req:
+ cubicweb_blog = req.create_entity('Blog', title=u'cubicweb',
+ description=u'cubicweb is beautiful')
+ blog_entry_1 = req.create_entity('BlogEntry', title=u'hop',
+ content=u'cubicweb hop')
+ blog_entry_1.cw_set(entry_of=cubicweb_blog)
+ blog_entry_2 = req.create_entity('BlogEntry', title=u'yes',
+ content=u'cubicweb yes')
+ blog_entry_2.cw_set(entry_of=cubicweb_blog)
+ self.assertEqual(len(MAILBOX), 0)
+ req.cnx.commit()
+ self.assertEqual(len(MAILBOX), 2)
+ mail = MAILBOX[0]
+ self.assertEqual(mail.subject, '[data] hop')
+ mail = MAILBOX[1]
+ self.assertEqual(mail.subject, '[data] yes')
Visible actions tests
`````````````````````
It is easy to write unit tests to test actions which are visible to
-user or to a category of users. Let's take an example in the
+a user or to a category of users. Let's take an example in the
`conference cube`_.
.. _`conference cube`: http://www.cubicweb.org/project/cubicweb-conference
@@ -212,34 +198,35 @@
class ConferenceActionsTC(CubicWebTC):
def setup_database(self):
- self.conf = self.create_entity('Conference',
- title=u'my conf',
- url_id=u'conf',
- start_on=date(2010, 1, 27),
- end_on = date(2010, 1, 29),
- call_open=True,
- reverse_is_chair_at=chair,
- reverse_is_reviewer_at=reviewer)
+ with self.admin_access.repo_cnx() as cnx:
+ self.confeid = cnx.create_entity('Conference',
+ title=u'my conf',
+ url_id=u'conf',
+ start_on=date(2010, 1, 27),
+ end_on = date(2010, 1, 29),
+ call_open=True,
+ reverse_is_chair_at=chair,
+ reverse_is_reviewer_at=reviewer).eid
def test_admin(self):
- req = self.request()
- rset = req.find_entities('Conference')
- self.assertListEqual(self.pactions(req, rset),
- [('workflow', workflow.WorkflowActions),
- ('edit', confactions.ModifyAction),
- ('managepermission', actions.ManagePermissionsAction),
- ('addrelated', actions.AddRelatedActions),
- ('delete', actions.DeleteAction),
- ('generate_badge_action', badges.GenerateBadgeAction),
- ('addtalkinconf', confactions.AddTalkInConferenceAction)
- ])
- self.assertListEqual(self.action_submenu(req, rset, 'addrelated'),
- [(u'add Track in_conf Conference object',
- u'http://testing.fr/cubicweb/add/Track'
- u'?__linkto=in_conf%%3A%(conf)s%%3Asubject&'
- u'__redirectpath=conference%%2Fconf&'
- u'__redirectvid=' % {'conf': self.conf.eid}),
- ])
+ with self.admin_access.web_request() as req:
+ rset = req.find('Conference').one()
+ self.assertListEqual(self.pactions(req, rset),
+ [('workflow', workflow.WorkflowActions),
+ ('edit', confactions.ModifyAction),
+ ('managepermission', actions.ManagePermissionsAction),
+ ('addrelated', actions.AddRelatedActions),
+ ('delete', actions.DeleteAction),
+ ('generate_badge_action', badges.GenerateBadgeAction),
+ ('addtalkinconf', confactions.AddTalkInConferenceAction)
+ ])
+ self.assertListEqual(self.action_submenu(req, rset, 'addrelated'),
+ [(u'add Track in_conf Conference object',
+ u'http://testing.fr/cubicweb/add/Track'
+ u'?__linkto=in_conf%%3A%(conf)s%%3Asubject&'
+ u'__redirectpath=conference%%2Fconf&'
+ u'__redirectvid=' % {'conf': self.confeid}),
+ ])
You just have to execute a rql query corresponding to the view you want to test,
and to compare the result of
@@ -247,7 +234,7 @@
that must be visible in the interface. This is a list of tuples. The first
element is the action's `__regid__`, the second the action's class.
-To test actions in submenu, you just have to test the result of
+To test actions in a submenu, you just have to test the result of
:meth:`~cubicweb.devtools.testlib.CubicWebTC.action_submenu` method. The last
parameter of the method is the action's category. The result is a list of
tuples. The first element is the action's title, and the second element the
@@ -290,23 +277,27 @@
Cache heavy database setup
-------------------------------
-Some tests suite require a complex setup of the database that takes seconds (or
-event minutes) to complete. Doing the whole setup for all individual tests make
-the whole run very slow. The ``CubicWebTC`` class offer a simple way to prepare
-specific database once for multiple tests. The `test_db_id` class attribute of
-your ``CubicWebTC`` must be set a unique identifier and the
-:meth:`pre_setup_database` class method build the cached content. As the
-:meth:`pre_setup_database` method is not grantee to be called, you must not set
-any class attribut to be used during test there. Databases for each `test_db_id`
-are automatically created if not already in cache. Clearing the cache is up to
-the user. Cache files are found in the :file:`data/database` subdirectory of your
-test directory.
+Some test suites require a complex setup of the database that takes
+seconds (or even minutes) to complete. Doing the whole setup for each
+individual test makes the whole run very slow. The ``CubicWebTC``
+class offer a simple way to prepare a specific database once for
+multiple tests. The `test_db_id` class attribute of your
+``CubicWebTC`` subclass must be set to a unique identifier and the
+:meth:`pre_setup_database` class method must build the cached content. As
+the :meth:`pre_setup_database` method is not garanteed to be called
+every time a test method is run, you must not set any class attribute
+to be used during test *there*. Databases for each `test_db_id` are
+automatically created if not already in cache. Clearing the cache is
+up to the user. Cache files are found in the :file:`data/database`
+subdirectory of your test directory.
.. warning::
- Take care to always have the same :meth:`pre_setup_database` function for all
- call with a given `test_db_id` otherwise you test will have unpredictable
- result given the first encountered one.
+ Take care to always have the same :meth:`pre_setup_database`
+ function for all classes with a given `test_db_id` otherwise your
+ tests will have unpredictable results depending on the first
+ encountered one.
+
Testing on a real-life database
-------------------------------
@@ -332,10 +323,10 @@
sourcefile='/path/to/realdb_sources')
def test_blog_rss(self):
- req = self.request()
+ with self.admin_access.web_request() as req:
rset = req.execute('Any B ORDERBY D DESC WHERE B is BlogEntry, '
- 'B created_by U, U login "logilab", B creation_date D')
- self.view('rss', rset)
+ 'B created_by U, U login "logilab", B creation_date D')
+ self.view('rss', rset, req=req)
Testing with other cubes
@@ -351,7 +342,7 @@
The format is:
* possibly several empy lines or lines starting with ``#`` (comment lines)
-* one line containing a coma separated list of cube names.
+* one line containing a comma-separated list of cube names.
It is also possible to add a ``schema.py`` file in
``mycube/test/data``, which will be used by the testing framework,
@@ -362,12 +353,12 @@
--------------------
CubicWeb provides some literate programming capabilities. The :ref:`cubicweb-ctl`
-`shell` command accepts differents format files. If your file ends with `.txt`
-or `.rst`, the file will be parsed by :mod:`doctest.testfile` with CubicWeb
+`shell` command accepts different file formats. If your file ends with `.txt`
+or `.rst`, the file will be parsed by :mod:`doctest.testfile` with CubicWeb's
:ref:`migration` API enabled in it.
-Create a `scenario.txt` file into `test/` directory and fill with some content.
-Please refer the :mod:`doctest.testfile` `documentation`_.
+Create a `scenario.txt` file in the `test/` directory and fill with some content.
+Refer to the :mod:`doctest.testfile` `documentation`_.
.. _documentation: http://docs.python.org/library/doctest.html
@@ -404,7 +395,7 @@
Passing paramaters
``````````````````
-Using extra arguments to parametrize your scenario is possible by prepend them
+Using extra arguments to parametrize your scenario is possible by prepending them
by double dashes.
Please refer to the `cubicweb-ctl shell --help` usage.
@@ -431,7 +422,7 @@
discover them automatically)
* launch `pytest unittest_foo.py` to execute one test file
* launch `pytest unittest_foo.py bar` to execute all test methods and
- all test cases whose name contain `bar`
+ all test cases whose name contains `bar`
Additionally, the `-x` option tells pytest to exit at the first error
or failure. The `-i` option tells pytest to drop into pdb whenever an
@@ -460,7 +451,6 @@
What you need to know about request and session
-----------------------------------------------
-
.. image:: ../images/request_session.png
First, remember to think that some code run on a client side, some
@@ -474,9 +464,14 @@
The client interacts with the repository through a repoapi connection.
+.. note::
+
+ These distinctions are going to disappear in cubicweb 3.21 (if not
+ before).
+
A repoapi connection is tied to a session in the repository. The connection and
-request objects are unaccessible from repository code / the session object is
-unaccessible from client code (theoretically at least).
+request objects are inaccessible from repository code / the session object is
+inaccessible from client code (theoretically at least).
The web interface provides a request class. That `request` object provides
access to all cubicweb resources, eg:
@@ -492,7 +487,7 @@
A `session` provides an api similar to a request regarding RQL execution and
-access to global resources (registry and all), but also have the following
+access to global resources (registry and all), but also has the following
responsibilities:
* handle transaction data, that will live during the time of a single
@@ -529,45 +524,36 @@
The web publisher handles the transaction:
* commit / rollback is done automatically
-* you should not commit / rollback explicitly
-Because a session lives for a long time, and database connections are a limited
-resource, we can't bind a session to its own database connection for all its
-lifetime. The repository handles a pool of connections (4 by default), and it's
-responsible to attribute them as needed.
+* you should not commit / rollback explicitly, except if you really
+ need it
Let's detail the process:
-1. an incoming RQL query comes from a client to the repository
+1. an incoming RQL query comes from a client to the web stack
-2. the repository attributes a database connection to the session
+2. the web stack opens an authenticated database connection for the
+ request, which is associated to a user session
-3. the repository's querier executes the query
+3. the query is executed (through the repository connection)
-4. this query may trigger hooks. Hooks and operation may execute some rql queries
- through `_cw.execute`. Those queries go directly to the querier, hence don't
- touch the database connection, they use the one attributed in 2.
+4. this query may trigger hooks. Hooks and operations may execute some rql queries
+ through `cnx.execute`.
5. the repository gets the result of the query in 1. If it was a RQL read query,
the database connection is released. If it was a write query, the connection
- is then tied to the session until the transaction is commited or rollbacked.
+ is then tied to the session until the transaction is commited or rolled back.
6. results are sent back to the client
This implies several things:
-* when using a request, or code executed in hooks, this database connection
- handling is totally transparent
+* when using a request, or code executed in hooks, this database
+ connection handling is totally transparent
-* however, take care when writing tests: you are usually faking / testing both the
- server and the client side, so you have to decide when to use RepoAccess.client_cnx /
- RepoAccess.repo_cnx. Ask yourself "where the code I want to test will be running,
- client or repository side ?". The response is usually : use a client connection :)
- However, if you really need using a server-side object:
-
- - commit / rollback will free the database connection (unless explicitly told
- not to do so).
-
- - if you issue a query after that without asking for a database connection
- (`session.get_cnxset()`), you will end up with a 'None type has no attribute
- source()' error
+* however, take care when writing tests: you are usually faking /
+ testing both the server and the client side, so you have to decide
+ when to use RepoAccess.client_cnx or RepoAccess.repo_cnx. Ask
+ yourself "where will the code I want to test be running, client or
+ repository side?". The response is usually: use a repo (since the
+ "client connection" concept is going away in a couple of releases).
diff -r 928732ec00dd -r fa44db7da2dc doc/book/en/tutorials/advanced/part02_security.rst
--- a/doc/book/en/tutorials/advanced/part02_security.rst Thu Jul 17 11:08:56 2014 +0200
+++ b/doc/book/en/tutorials/advanced/part02_security.rst Fri Jul 18 17:35:25 2014 +0200
@@ -142,7 +142,7 @@
* `VISIBILITY_PERMISSIONS` provides read access to managers group, if
`visibility` attribute's value is 'public', or if user (designed by the 'U'
variable in the expression) is linked to the entity (the 'X' variable) through
- the `may_read` permission
+ the `may_be_read_by` permission
* we modify permissions of the entity types we use by importing them and
modifying their `__permissions__` attribute
@@ -168,7 +168,7 @@
commented entity.
This kind of `active` rule will be done using CubicWeb's hook
-system. Hooks are triggered on database event such as addition of new
+system. Hooks are triggered on database events such as addition of a new
entity or relation.
The tricky part of the requirement is in *unless explicitly specified*, notably
@@ -223,9 +223,9 @@
relation types to which the hook applies. To match a relation type, we use the
hook specific `match_rtype` selector.
-* usage of `set_operation`: instead of adding an operation for each added entity,
- set_operation allows to create a single one and to store entity's eids to be
- processed in session's transaction data. This is a good pratice to avoid heavy
+* usage of `DataOperationMixIn`: instead of adding an operation for each added entity,
+ DataOperationMixIn allows to create a single one and to store entity's eids to be
+ processed in the transaction data. This is a good pratice to avoid heavy
operations manipulation cost when creating a lot of entities in the same
transaction.
@@ -314,51 +314,50 @@
class SecurityTC(CubicWebTC):
def test_visibility_propagation(self):
- # create a user for later security checks
- toto = self.create_user('toto')
- # init some data using the default manager connection
- req = self.request()
- folder = req.create_entity('Folder',
- name=u'restricted',
- visibility=u'restricted')
- photo1 = req.create_entity('File',
- data_name=u'photo1.jpg',
- data=Binary('xxx'),
- filed_under=folder)
- self.commit()
- photo1.clear_all_caches() # good practice, avoid request cache effects
- # visibility propagation
- self.assertEquals(photo1.visibility, 'restricted')
- # unless explicitly specified
- photo2 = req.create_entity('File',
- data_name=u'photo2.jpg',
- data=Binary('xxx'),
- visibility=u'public',
- filed_under=folder)
- self.commit()
- self.assertEquals(photo2.visibility, 'public')
- # test security
- self.login('toto')
- req = self.request()
- self.assertEquals(len(req.execute('File X')), 1) # only the public one
- self.assertEquals(len(req.execute('Folder X')), 0) # restricted...
- # may_be_read_by propagation
- self.restore_connection()
- folder.cw_set(may_be_read_by=toto)
- self.commit()
- photo1.clear_all_caches()
- self.failUnless(photo1.may_be_read_by)
- # test security with permissions
- self.login('toto')
- req = self.request()
- self.assertEquals(len(req.execute('File X')), 2) # now toto has access to photo2
- self.assertEquals(len(req.execute('Folder X')), 1) # and to restricted folder
+
+ with self.admin_access.repo_cnx() as cnx:
+ # create a user for later security checks
+ toto = self.create_user(cnx, 'toto')
+ cnx.commit()
+ # init some data using the default manager connection
+ folder = cnx.create_entity('Folder',
+ name=u'restricted',
+ visibility=u'restricted')
+ photo1 = cnx.create_entity('File',
+ data_name=u'photo1.jpg',
+ data=Binary('xxx'),
+ filed_under=folder)
+ cnx.commit()
+ # visibility propagation
+ self.assertEquals(photo1.visibility, 'restricted')
+ # unless explicitly specified
+ photo2 = cnx.create_entity('File',
+ data_name=u'photo2.jpg',
+ data=Binary('xxx'),
+ visibility=u'public',
+ filed_under=folder)
+ cnx.commit()
+ self.assertEquals(photo2.visibility, 'public')
+
+ with self.new_access('toto').repo_cnx() as cnx:
+ # test security
+ self.assertEqual(1, len(cnx.execute('File X'))) # only the public one
+ self.assertEqual(0, len(cnx.execute('Folder X'))) # restricted...
+ # may_be_read_by propagation
+ folder = cnx.entity_from_eid(folder.eid)
+ folder.cw_set(may_be_read_by=toto)
+ cnx.commit()
+ photo1 = cnx.entity_from_eid(photo1)
+ self.failUnless(photo1.may_be_read_by)
+ # test security with permissions
+ self.assertEquals(2, len(cnx.execute('File X'))) # now toto has access to photo2
+ self.assertEquals(1, len(cnx.execute('Folder X'))) # and to restricted folder
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
unittest_main()
-It's not complete, but show most things you'll want to do in tests: adding some
+It's not complete, but shows most things you'll want to do in tests: adding some
content, creating users and connecting as them in the test, etc...
To run it type:
@@ -394,7 +393,7 @@
If you do some changes in your schema, you'll have to force regeneration of that
database. You do that by removing the tmpdb files before running the test: ::
- $ rm data/tmpdb*
+ $ rm data/database/tmpdb*
.. Note::
@@ -407,12 +406,12 @@
Step 4: writing the migration script and migrating the instance
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Prior to those changes, I created an instance, feeded it with some data, so I
+Prior to those changes, I created an instance, fed it with some data, so I
don't want to create a new one, but to migrate the existing one. Let's see how to
do that.
Migration commands should be put in the cube's *migration* directory, in a
-file named file:`_Any.py` ('Any' being there mostly for historical reason).
+file named file:`_Any.py` ('Any' being there mostly for historical reasons).
Here I'll create a *migration/0.2.0_Any.py* file containing the following
instructions:
@@ -423,11 +422,11 @@
add_relation_type('visibility')
sync_schema_props_perms()
-Then I update the version number in cube's *__pkginfo__.py* to 0.2.0. And
+Then I update the version number in the cube's *__pkginfo__.py* to 0.2.0. And
that's it! Those instructions will:
* update the instance's schema by adding our two new relations and update the
- underlying database tables accordingly (the two first instructions)
+ underlying database tables accordingly (the first two instructions)
* update schema's permissions definition (the last instruction)
diff -r 928732ec00dd -r fa44db7da2dc entities/test/unittest_base.py
--- a/entities/test/unittest_base.py Thu Jul 17 11:08:56 2014 +0200
+++ b/entities/test/unittest_base.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -21,7 +21,6 @@
from logilab.common.testlib import unittest_main
from logilab.common.decorators import clear_cache
-from logilab.common.interface import implements
from cubicweb.devtools.testlib import CubicWebTC
@@ -31,114 +30,135 @@
class BaseEntityTC(CubicWebTC):
def setup_database(self):
- req = self.request()
- self.member = self.create_user(req, 'member')
-
+ with self.admin_access.repo_cnx() as cnx:
+ self.membereid = self.create_user(cnx, 'member').eid
+ cnx.commit()
class MetadataTC(BaseEntityTC):
def test_creator(self):
- self.login(u'member')
- entity = self.request().create_entity('Bookmark', title=u"hello", path=u'project/cubicweb')
- self.commit()
- self.assertEqual(entity.creator.eid, self.member.eid)
- self.assertEqual(entity.dc_creator(), u'member')
+ with self.new_access('member').repo_cnx() as cnx:
+ entity = cnx.create_entity('Bookmark', title=u"hello", path=u'project/cubicweb')
+ cnx.commit()
+ self.assertEqual(entity.creator.eid, self.membereid)
+ self.assertEqual(entity.dc_creator(), u'member')
def test_type(self):
#dc_type may be translated
- self.assertEqual(self.member.dc_type(), 'CWUser')
+ with self.admin_access.client_cnx() as cnx:
+ member = cnx.entity_from_eid(self.membereid)
+ self.assertEqual(member.dc_type(), 'CWUser')
def test_cw_etype(self):
#cw_etype is never translated
- self.assertEqual(self.member.cw_etype, 'CWUser')
+ with self.admin_access.client_cnx() as cnx:
+ member = cnx.entity_from_eid(self.membereid)
+ self.assertEqual(member.cw_etype, 'CWUser')
def test_entity_meta_attributes(self):
# XXX move to yams
self.assertEqual(self.schema['CWUser'].meta_attributes(), {})
- self.assertEqual(dict((str(k), v) for k, v in self.schema['State'].meta_attributes().iteritems()),
+ self.assertEqual(dict((str(k), v)
+ for k, v in self.schema['State'].meta_attributes().iteritems()),
{'description_format': ('format', 'description')})
def test_fti_rql_method(self):
- eclass = self.vreg['etypes'].etype_class('EmailAddress')
- self.assertEqual(['Any X, ALIAS, ADDRESS WHERE X is EmailAddress, '
- 'X alias ALIAS, X address ADDRESS'],
- eclass.cw_fti_index_rql_queries(self.request()))
+ with self.admin_access.web_request() as req:
+ eclass = self.vreg['etypes'].etype_class('EmailAddress')
+ self.assertEqual(['Any X, ALIAS, ADDRESS WHERE X is EmailAddress, '
+ 'X alias ALIAS, X address ADDRESS'],
+ eclass.cw_fti_index_rql_queries(req))
class EmailAddressTC(BaseEntityTC):
+
def test_canonical_form(self):
- email1 = self.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
- email2 = self.execute('INSERT EmailAddress X: X address "maarten@philips.com"').get_entity(0, 0)
- email3 = self.execute('INSERT EmailAddress X: X address "toto@logilab.fr"').get_entity(0, 0)
- email1.cw_set(prefered_form=email2)
- self.assertEqual(email1.prefered.eid, email2.eid)
- self.assertEqual(email2.prefered.eid, email2.eid)
- self.assertEqual(email3.prefered.eid, email3.eid)
+ with self.admin_access.repo_cnx() as cnx:
+ email1 = cnx.execute('INSERT EmailAddress X: '
+ 'X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
+ email2 = cnx.execute('INSERT EmailAddress X: '
+ 'X address "maarten@philips.com"').get_entity(0, 0)
+ email3 = cnx.execute('INSERT EmailAddress X: '
+ 'X address "toto@logilab.fr"').get_entity(0, 0)
+ email1.cw_set(prefered_form=email2)
+ self.assertEqual(email1.prefered.eid, email2.eid)
+ self.assertEqual(email2.prefered.eid, email2.eid)
+ self.assertEqual(email3.prefered.eid, email3.eid)
def test_mangling(self):
- email = self.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
- self.assertEqual(email.display_address(), 'maarten.ter.huurne@philips.com')
- self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne@philips.com')
- self.vreg.config.global_set_option('mangle-emails', True)
- try:
- self.assertEqual(email.display_address(), 'maarten.ter.huurne at philips dot com')
- self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne at philips dot com')
- email = self.execute('INSERT EmailAddress X: X address "syt"').get_entity(0, 0)
- self.assertEqual(email.display_address(), 'syt')
- self.assertEqual(email.printable_value('address'), 'syt')
- finally:
- self.vreg.config.global_set_option('mangle-emails', False)
+ with self.admin_access.repo_cnx() as cnx:
+ email = cnx.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
+ self.assertEqual(email.display_address(), 'maarten.ter.huurne@philips.com')
+ self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne@philips.com')
+ self.vreg.config.global_set_option('mangle-emails', True)
+ try:
+ self.assertEqual(email.display_address(), 'maarten.ter.huurne at philips dot com')
+ self.assertEqual(email.printable_value('address'), 'maarten.ter.huurne at philips dot com')
+ email = cnx.execute('INSERT EmailAddress X: X address "syt"').get_entity(0, 0)
+ self.assertEqual(email.display_address(), 'syt')
+ self.assertEqual(email.printable_value('address'), 'syt')
+ finally:
+ self.vreg.config.global_set_option('mangle-emails', False)
def test_printable_value_escape(self):
- email = self.execute('INSERT EmailAddress X: X address "maarten&ter@philips.com"').get_entity(0, 0)
- self.assertEqual(email.printable_value('address'), 'maarten&ter@philips.com')
- self.assertEqual(email.printable_value('address', format='text/plain'), 'maarten&ter@philips.com')
+ with self.admin_access.repo_cnx() as cnx:
+ email = cnx.execute('INSERT EmailAddress X: '
+ 'X address "maarten&ter@philips.com"').get_entity(0, 0)
+ self.assertEqual(email.printable_value('address'),
+ 'maarten&ter@philips.com')
+ self.assertEqual(email.printable_value('address', format='text/plain'),
+ 'maarten&ter@philips.com')
class CWUserTC(BaseEntityTC):
def test_complete(self):
- e = self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
- e.complete()
+ with self.admin_access.repo_cnx() as cnx:
+ e = cnx.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
+ e.complete()
def test_matching_groups(self):
- e = self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
- self.assertTrue(e.matching_groups('managers'))
- self.assertFalse(e.matching_groups('xyz'))
- self.assertTrue(e.matching_groups(('xyz', 'managers')))
- self.assertFalse(e.matching_groups(('xyz', 'abcd')))
+ with self.admin_access.repo_cnx() as cnx:
+ e = cnx.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
+ self.assertTrue(e.matching_groups('managers'))
+ self.assertFalse(e.matching_groups('xyz'))
+ self.assertTrue(e.matching_groups(('xyz', 'managers')))
+ self.assertFalse(e.matching_groups(('xyz', 'abcd')))
def test_dc_title_and_name(self):
- e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
- self.assertEqual(e.dc_title(), 'member')
- self.assertEqual(e.name(), 'member')
- e.cw_set(firstname=u'bouah')
- self.assertEqual(e.dc_title(), 'member')
- self.assertEqual(e.name(), u'bouah')
- e.cw_set(surname=u'lôt')
- self.assertEqual(e.dc_title(), 'member')
- self.assertEqual(e.name(), u'bouah lôt')
+ with self.admin_access.repo_cnx() as cnx:
+ e = cnx.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
+ self.assertEqual(e.dc_title(), 'member')
+ self.assertEqual(e.name(), 'member')
+ e.cw_set(firstname=u'bouah')
+ self.assertEqual(e.dc_title(), 'member')
+ self.assertEqual(e.name(), u'bouah')
+ e.cw_set(surname=u'lôt')
+ self.assertEqual(e.dc_title(), 'member')
+ self.assertEqual(e.name(), u'bouah lôt')
def test_allowed_massmail_keys(self):
- e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
- # Bytes/Password attributes should be omited
- self.assertEqual(e.cw_adapt_to('IEmailable').allowed_massmail_keys(),
- set(('surname', 'firstname', 'login', 'last_login_time',
- 'creation_date', 'modification_date', 'cwuri', 'eid'))
- )
+ with self.admin_access.repo_cnx() as cnx:
+ e = cnx.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
+ # Bytes/Password attributes should be omited
+ self.assertEqual(e.cw_adapt_to('IEmailable').allowed_massmail_keys(),
+ set(('surname', 'firstname', 'login', 'last_login_time',
+ 'creation_date', 'modification_date', 'cwuri', 'eid'))
+ )
def test_cw_instantiate_object_relation(self):
""" a weird non regression test """
- e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
- self.request().create_entity('CWGroup', name=u'logilab', reverse_in_group=e)
+ with self.admin_access.repo_cnx() as cnx:
+ e = cnx.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
+ cnx.create_entity('CWGroup', name=u'logilab', reverse_in_group=e)
class HTMLtransformTC(BaseEntityTC):
def test_sanitized_html(self):
- r = self.request()
- c = r.create_entity('Company', name=u'Babar',
- description=u"""
+ with self.admin_access.repo_cnx() as cnx:
+ c = cnx.create_entity('Company', name=u'Babar',
+ description=u"""
Title
=====
@@ -148,10 +168,12 @@
""", description_format=u'text/rest')
- self.commit()
- c.cw_clear_all_caches()
- self.assertIn('alert', c.printable_value('description', format='text/plain'))
- self.assertNotIn('alert', c.printable_value('description', format='text/html'))
+ cnx.commit()
+ c.cw_clear_all_caches()
+ self.assertIn('alert',
+ c.printable_value('description', format='text/plain'))
+ self.assertNotIn('alert',
+ c.printable_value('description', format='text/html'))
class SpecializedEntityClassesTC(CubicWebTC):
diff -r 928732ec00dd -r fa44db7da2dc entity.py
--- a/entity.py Thu Jul 17 11:08:56 2014 +0200
+++ b/entity.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -344,7 +344,8 @@
cls.warning('skipping fetch_attr %s defined in %s (not found in schema)',
attr, cls.__regid__)
continue
- rdef = eschema.rdef(attr)
+ # XXX takefirst=True to remove warning triggered by ambiguous inlined relations
+ rdef = eschema.rdef(attr, takefirst=True)
if not user.matching_groups(rdef.get_groups('read')):
continue
if rschema.final or rdef.cardinality[0] in '?1':
@@ -793,8 +794,9 @@
# skip already defined relations
if getattr(self, rschema.type):
continue
+ # XXX takefirst=True to remove warning triggered by ambiguous relations
+ rdef = self.e_schema.rdef(rschema, takefirst=True)
# skip composite relation
- rdef = self.e_schema.rdef(rschema)
if rdef.composite:
continue
# skip relation with card in ?1 else we either change the copied
@@ -813,7 +815,8 @@
continue
if rschema.type in skip_copy_for['object']:
continue
- rdef = self.e_schema.rdef(rschema, 'object')
+ # XXX takefirst=True to remove warning triggered by ambiguous relations
+ rdef = self.e_schema.rdef(rschema, 'object', takefirst=True)
# skip composite relation
if rdef.composite:
continue
diff -r 928732ec00dd -r fa44db7da2dc etwist/server.py
--- a/etwist/server.py Thu Jul 17 11:08:56 2014 +0200
+++ b/etwist/server.py Fri Jul 18 17:35:25 2014 +0200
@@ -69,6 +69,7 @@
# if pyro is enabled, we have to register to the pyro name
# server, create a pyro daemon, and create a task to handle pyro
# requests
+ self.appli.repo.warning('remote repository access through pyro is deprecated')
self.pyro_daemon = self.appli.repo.pyro_register()
self.pyro_listen_timeout = 0.02
self.appli.repo.looping_task(1, self.pyro_loop_event)
diff -r 928732ec00dd -r fa44db7da2dc ext/test/unittest_rest.py
--- a/ext/test/unittest_rest.py Thu Jul 17 11:08:56 2014 +0200
+++ b/ext/test/unittest_rest.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -21,18 +21,23 @@
from cubicweb.ext.rest import rest_publish
class RestTC(CubicWebTC):
- def context(self):
- return self.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
+
+ def context(self, req):
+ return req.execute('CWUser X WHERE X login "admin"').get_entity(0, 0)
def test_eid_role(self):
- context = self.context()
- self.assertEqual(rest_publish(context, ':eid:`%s`' % context.eid),
- '
\n'))
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:table`')
+ self.assertTrue(out.endswith('anon\n'
+ '\n'))
def test_rql_role_with_vid_empty_rset(self):
- context = self.context()
- out = rest_publish(context, ':rql:`Any X WHERE X is CWUser, X login "nono":table`')
- self.assertTrue(out.endswith('
No result matching query
\n\n'))
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ out = rest_publish(context, ':rql:`Any X WHERE X is CWUser, X login "nono":table`')
+ self.assertTrue(out.endswith('
'
+ 'No result matching query
\n\n'))
def test_rql_role_with_unknown_vid(self):
- context = self.context()
- out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:toto`')
- self.assertTrue(out.startswith("
an error occurred while interpreting this rql directive: ObjectNotFound(u'toto',)
"))
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:toto`')
+ self.assertTrue(out.startswith("
an error occurred while interpreting this "
+ "rql directive: ObjectNotFound(u'toto',)
"))
def test_rql_role_without_vid(self):
- context = self.context()
- out = rest_publish(context, ':rql:`Any X WHERE X is CWUser`')
- self.assertEqual(out, u'
\n')
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ out = rest_publish(context, ':rql:`Any X WHERE X is CWUser`')
+ self.assertEqual(out, u'
\n')
def test_bookmark_role(self):
- context = self.context()
- rset = self.execute('INSERT Bookmark X: X title "hello", X path "/view?rql=Any X WHERE X is CWUser"')
- eid = rset[0][0]
- out = rest_publish(context, ':bookmark:`%s`' % eid)
- self.assertEqual(out, u'
\n')
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ rset = req.execute('INSERT Bookmark X: X title "hello", X path '
+ '"/view?rql=Any X WHERE X is CWUser"')
+ eid = rset[0][0]
+ out = rest_publish(context, ':bookmark:`%s`' % eid)
+ self.assertEqual(out, u'
')
def test_metadata_cwuri(self):
- entity = self.request().create_entity('Workflow', name=u'wf1')
- self.assertEqual(entity.cwuri, self.repo.config['base-url'] + str(entity.eid))
+ with self.admin_access.repo_cnx() as cnx:
+ entity = cnx.create_entity('Workflow', name=u'wf1')
+ self.assertEqual(entity.cwuri, self.repo.config['base-url'] + str(entity.eid))
def test_metadata_creation_modification_date(self):
- _now = datetime.now()
- entity = self.request().create_entity('Workflow', name=u'wf1')
- self.assertEqual((entity.creation_date - _now).seconds, 0)
- self.assertEqual((entity.modification_date - _now).seconds, 0)
+ with self.admin_access.repo_cnx() as cnx:
+ _now = datetime.now()
+ entity = cnx.create_entity('Workflow', name=u'wf1')
+ self.assertEqual((entity.creation_date - _now).seconds, 0)
+ self.assertEqual((entity.modification_date - _now).seconds, 0)
def test_metadata_created_by(self):
- entity = self.request().create_entity('Bookmark', title=u'wf1', path=u'/view')
- self.commit() # fire operations
- self.assertEqual(len(entity.created_by), 1) # make sure we have only one creator
- self.assertEqual(entity.created_by[0].eid, self.session.user.eid)
+ with self.admin_access.repo_cnx() as cnx:
+ entity = cnx.create_entity('Bookmark', title=u'wf1', path=u'/view')
+ cnx.commit() # fire operations
+ self.assertEqual(len(entity.created_by), 1) # make sure we have only one creator
+ self.assertEqual(entity.created_by[0].eid, self.session.user.eid)
def test_metadata_owned_by(self):
- entity = self.request().create_entity('Bookmark', title=u'wf1', path=u'/view')
- self.commit() # fire operations
- self.assertEqual(len(entity.owned_by), 1) # make sure we have only one owner
- self.assertEqual(entity.owned_by[0].eid, self.session.user.eid)
+ with self.admin_access.repo_cnx() as cnx:
+ entity = cnx.create_entity('Bookmark', title=u'wf1', path=u'/view')
+ cnx.commit() # fire operations
+ self.assertEqual(len(entity.owned_by), 1) # make sure we have only one owner
+ self.assertEqual(entity.owned_by[0].eid, self.session.user.eid)
def test_user_login_stripped(self):
- req = self.request()
- u = self.create_user(req, ' joe ')
- tname = self.execute('Any L WHERE E login L, E eid %(e)s',
- {'e': u.eid})[0][0]
- self.assertEqual(tname, 'joe')
- self.execute('SET X login " jijoe " WHERE X eid %(x)s', {'x': u.eid})
- tname = self.execute('Any L WHERE E login L, E eid %(e)s',
- {'e': u.eid})[0][0]
- self.assertEqual(tname, 'jijoe')
+ with self.admin_access.repo_cnx() as cnx:
+ u = self.create_user(cnx, ' joe ')
+ tname = cnx.execute('Any L WHERE E login L, E eid %(e)s',
+ {'e': u.eid})[0][0]
+ self.assertEqual(tname, 'joe')
+ cnx.execute('SET X login " jijoe " WHERE X eid %(x)s', {'x': u.eid})
+ tname = cnx.execute('Any L WHERE E login L, E eid %(e)s',
+ {'e': u.eid})[0][0]
+ self.assertEqual(tname, 'jijoe')
class UserGroupHooksTC(CubicWebTC):
def test_user_synchronization(self):
- req = self.request()
- self.create_user(req, 'toto', password='hop', commit=False)
- self.assertRaises(AuthenticationError,
- self.repo.connect, u'toto', password='hop')
- self.commit()
- cnxid = self.repo.connect(u'toto', password='hop')
- self.assertNotEqual(cnxid, self.session.id)
- self.execute('DELETE CWUser X WHERE X login "toto"')
- self.repo.execute(cnxid, 'State X')
- self.commit()
- self.assertRaises(BadConnectionId,
- self.repo.execute, cnxid, 'State X')
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, 'toto', password='hop', commit=False)
+ self.assertRaises(AuthenticationError,
+ self.repo.connect, u'toto', password='hop')
+ cnx.commit()
+ cnxid = self.repo.connect(u'toto', password='hop')
+ self.assertNotEqual(cnxid, self.session.id)
+ cnx.execute('DELETE CWUser X WHERE X login "toto"')
+ self.repo.execute(cnxid, 'State X')
+ cnx.commit()
+ self.assertRaises(BadConnectionId,
+ self.repo.execute, cnxid, 'State X')
def test_user_group_synchronization(self):
- user = self.session.user
- self.assertEqual(user.groups, set(('managers',)))
- self.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
- self.assertEqual(user.groups, set(('managers',)))
- self.commit()
- self.assertEqual(user.groups, set(('managers', 'guests')))
- self.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
- self.assertEqual(user.groups, set(('managers', 'guests')))
- self.commit()
- self.assertEqual(user.groups, set(('managers',)))
+ with self.admin_access.repo_cnx() as cnx:
+ user = cnx.user
+ self.assertEqual(user.groups, set(('managers',)))
+ cnx.execute('SET X in_group G WHERE X eid %s, G name "guests"' % user.eid)
+ self.assertEqual(user.groups, set(('managers',)))
+ cnx.commit()
+ self.assertEqual(user.groups, set(('managers', 'guests')))
+ cnx.execute('DELETE X in_group G WHERE X eid %s, G name "guests"' % user.eid)
+ self.assertEqual(user.groups, set(('managers', 'guests')))
+ cnx.commit()
+ self.assertEqual(user.groups, set(('managers',)))
def test_user_composite_owner(self):
- req = self.request()
- ueid = self.create_user(req, 'toto').eid
- # composite of euser should be owned by the euser regardless of who created it
- self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", U use_email X '
- 'WHERE U login "toto"')
- self.commit()
- self.assertEqual(self.execute('Any A WHERE X owned_by U, U use_email X,'
- 'U login "toto", X address A')[0][0],
- 'toto@logilab.fr')
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, 'toto').eid
+ # composite of euser should be owned by the euser regardless of who created it
+ cnx.execute('INSERT EmailAddress X: X address "toto@logilab.fr", U use_email X '
+ 'WHERE U login "toto"')
+ cnx.commit()
+ self.assertEqual(cnx.execute('Any A WHERE X owned_by U, U use_email X,'
+ 'U login "toto", X address A')[0][0],
+ 'toto@logilab.fr')
def test_no_created_by_on_deleted_entity(self):
- eid = self.execute('INSERT EmailAddress X: X address "toto@logilab.fr"')[0][0]
- self.execute('DELETE EmailAddress X WHERE X eid %s' % eid)
- self.commit()
- self.assertFalse(self.execute('Any X WHERE X created_by Y, X eid >= %(x)s', {'x': eid}))
+ with self.admin_access.repo_cnx() as cnx:
+ eid = cnx.execute('INSERT EmailAddress X: X address "toto@logilab.fr"')[0][0]
+ cnx.execute('DELETE EmailAddress X WHERE X eid %s' % eid)
+ cnx.commit()
+ self.assertFalse(cnx.execute('Any X WHERE X created_by Y, X eid >= %(x)s', {'x': eid}))
class SchemaHooksTC(CubicWebTC):
def test_duplicate_etype_error(self):
- # check we can't add a CWEType or CWRType entity if it already exists one
- # with the same name
- self.assertRaises(ValidationError,
- self.execute, 'INSERT CWEType X: X name "CWUser"')
- self.assertRaises(ValidationError,
- self.execute, 'INSERT CWRType X: X name "in_group"')
+ with self.admin_access.repo_cnx() as cnx:
+ # check we can't add a CWEType or CWRType entity if it already exists one
+ # with the same name
+ self.assertRaises(ValidationError,
+ cnx.execute, 'INSERT CWEType X: X name "CWUser"')
+ cnx.rollback()
+ self.assertRaises(ValidationError,
+ cnx.execute, 'INSERT CWRType X: X name "in_group"')
def test_validation_unique_constraint(self):
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWUser X: X login "admin"')
- ex = cm.exception
- ex.translate(unicode)
- self.assertIsInstance(ex.entity, int)
- self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
+ with self.admin_access.repo_cnx() as cnx:
+ with self.assertRaises(ValidationError) as cm:
+ cnx.execute('INSERT CWUser X: X login "admin"')
+ ex = cm.exception
+ ex.translate(unicode)
+ self.assertIsInstance(ex.entity, int)
+ self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
if __name__ == '__main__':
diff -r 928732ec00dd -r fa44db7da2dc hooks/test/unittest_integrity.py
--- a/hooks/test/unittest_integrity.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/test/unittest_integrity.py Fri Jul 18 17:35:25 2014 +0200
@@ -24,126 +24,138 @@
class CoreHooksTC(CubicWebTC):
def test_delete_internal_entities(self):
- self.assertRaises(ValidationError, self.execute,
- 'DELETE CWEType X WHERE X name "CWEType"')
- self.assertRaises(ValidationError, self.execute,
- 'DELETE CWRType X WHERE X name "relation_type"')
- self.assertRaises(ValidationError, self.execute,
- 'DELETE CWGroup X WHERE X name "owners"')
+ with self.admin_access.repo_cnx() as cnx:
+ self.assertRaises(ValidationError, cnx.execute,
+ 'DELETE CWEType X WHERE X name "CWEType"')
+ cnx.rollback()
+ self.assertRaises(ValidationError, cnx.execute,
+ 'DELETE CWRType X WHERE X name "relation_type"')
+ cnx.rollback()
+ self.assertRaises(ValidationError, cnx.execute,
+ 'DELETE CWGroup X WHERE X name "owners"')
def test_delete_required_relations_subject(self):
- self.execute('INSERT CWUser X: X login "toto", X upassword "hop", X in_group Y '
- 'WHERE Y name "users"')
- self.commit()
- self.execute('DELETE X in_group Y WHERE X login "toto", Y name "users"')
- self.assertRaises(ValidationError, self.commit)
- self.execute('DELETE X in_group Y WHERE X login "toto"')
- self.execute('SET X in_group Y WHERE X login "toto", Y name "guests"')
- self.commit()
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('INSERT CWUser X: X login "toto", X upassword "hop", X in_group Y '
+ 'WHERE Y name "users"')
+ cnx.commit()
+ cnx.execute('DELETE X in_group Y WHERE X login "toto", Y name "users"')
+ self.assertRaises(ValidationError, cnx.commit)
+ cnx.rollback()
+ cnx.execute('DELETE X in_group Y WHERE X login "toto"')
+ cnx.execute('SET X in_group Y WHERE X login "toto", Y name "guests"')
+ cnx.commit()
def test_static_vocabulary_check(self):
- self.assertRaises(ValidationError,
- self.execute,
- 'SET X composite "whatever" WHERE X from_entity FE, FE name "CWUser", X relation_type RT, RT name "in_group"')
+ with self.admin_access.repo_cnx() as cnx:
+ self.assertRaises(ValidationError,
+ cnx.execute,
+ 'SET X composite "whatever" WHERE X from_entity FE, FE name "CWUser", '
+ 'X relation_type RT, RT name "in_group"')
def test_missing_required_relations_subject_inline(self):
- # missing in_group relation
- self.execute('INSERT CWUser X: X login "toto", X upassword "hop"')
- self.assertRaises(ValidationError,
- self.commit)
+ with self.admin_access.repo_cnx() as cnx:
+ # missing in_group relation
+ cnx.execute('INSERT CWUser X: X login "toto", X upassword "hop"')
+ self.assertRaises(ValidationError, cnx.commit)
def test_composite_1(self):
- self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
- self.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, X content "this is a test"')
- self.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, X recipients Y, X parts P '
- 'WHERE Y is EmailAddress, P is EmailPart')
- self.assertTrue(self.execute('Email X WHERE X sender Y'))
- self.commit()
- self.execute('DELETE Email X')
- rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEqual(len(rset), 0)
- self.commit()
- rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEqual(len(rset), 0)
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
+ cnx.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, '
+ 'X content "this is a test"')
+ cnx.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, '
+ 'X recipients Y, X parts P '
+ 'WHERE Y is EmailAddress, P is EmailPart')
+ self.assertTrue(cnx.execute('Email X WHERE X sender Y'))
+ cnx.commit()
+ cnx.execute('DELETE Email X')
+ rset = cnx.execute('Any X WHERE X is EmailPart')
+ self.assertEqual(len(rset), 0)
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X is EmailPart')
+ self.assertEqual(len(rset), 0)
def test_composite_2(self):
- self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
- self.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, X content "this is a test"')
- self.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, X recipients Y, X parts P '
- 'WHERE Y is EmailAddress, P is EmailPart')
- self.commit()
- self.execute('DELETE Email X')
- self.execute('DELETE EmailPart X')
- self.commit()
- rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEqual(len(rset), 0)
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
+ cnx.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, '
+ 'X content "this is a test"')
+ cnx.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, '
+ 'X recipients Y, X parts P '
+ 'WHERE Y is EmailAddress, P is EmailPart')
+ cnx.commit()
+ cnx.execute('DELETE Email X')
+ cnx.execute('DELETE EmailPart X')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X is EmailPart')
+ self.assertEqual(len(rset), 0)
def test_composite_redirection(self):
- self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
- self.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, X content "this is a test"')
- self.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, X recipients Y, X parts P '
- 'WHERE Y is EmailAddress, P is EmailPart')
- self.execute('INSERT Email X: X messageid "<2345>", X subject "test2", X sender Y, X recipients Y '
- 'WHERE Y is EmailAddress')
- self.commit()
- self.execute('DELETE X parts Y WHERE X messageid "<1234>"')
- self.execute('SET X parts Y WHERE X messageid "<2345>"')
- self.commit()
- rset = self.execute('Any X WHERE X is EmailPart')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset.get_entity(0, 0).reverse_parts[0].messageid, '<2345>')
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')
+ cnx.execute('INSERT EmailPart X: X content_format "text/plain", X ordernum 1, '
+ 'X content "this is a test"')
+ cnx.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, '
+ 'X recipients Y, X parts P '
+ 'WHERE Y is EmailAddress, P is EmailPart')
+ cnx.execute('INSERT Email X: X messageid "<2345>", X subject "test2", X sender Y, '
+ 'X recipients Y '
+ 'WHERE Y is EmailAddress')
+ cnx.commit()
+ cnx.execute('DELETE X parts Y WHERE X messageid "<1234>"')
+ cnx.execute('SET X parts Y WHERE X messageid "<2345>"')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X is EmailPart')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.get_entity(0, 0).reverse_parts[0].messageid, '<2345>')
def test_composite_object_relation_deletion(self):
- req = self.request()
- root = req.create_entity('Folder', name=u'root')
- a = req.create_entity('Folder', name=u'a', parent=root)
- b = req.create_entity('Folder', name=u'b', parent=a)
- c = req.create_entity('Folder', name=u'c', parent=root)
- self.commit()
- req = self.request()
- req.execute('DELETE Folder F WHERE F name "a"')
- req.execute('DELETE F parent R WHERE R name "root"')
- self.commit()
- req = self.request()
- self.assertEqual([['root'], ['c']],
- req.execute('Any NF WHERE F is Folder, F name NF').rows)
- self.assertEqual([],
- req.execute('Any NF,NP WHERE F parent P, F name NF, P name NP').rows)
+ with self.admin_access.repo_cnx() as cnx:
+ root = cnx.create_entity('Folder', name=u'root')
+ a = cnx.create_entity('Folder', name=u'a', parent=root)
+ cnx.create_entity('Folder', name=u'b', parent=a)
+ cnx.create_entity('Folder', name=u'c', parent=root)
+ cnx.commit()
+ cnx.execute('DELETE Folder F WHERE F name "a"')
+ cnx.execute('DELETE F parent R WHERE R name "root"')
+ cnx.commit()
+ self.assertEqual([['root'], ['c']],
+ cnx.execute('Any NF WHERE F is Folder, F name NF').rows)
+ self.assertEqual([], cnx.execute('Any NF,NP WHERE F parent P, F name NF, P name NP').rows)
def test_composite_subject_relation_deletion(self):
- req = self.request()
- root = req.create_entity('Folder', name=u'root')
- a = req.create_entity('Folder', name=u'a')
- b = req.create_entity('Folder', name=u'b')
- c = req.create_entity('Folder', name=u'c')
- root.cw_set(children=(a, c))
- a.cw_set(children=b)
- self.commit()
- req = self.request()
- req.execute('DELETE Folder F WHERE F name "a"')
- req.execute('DELETE R children F WHERE R name "root"')
- self.commit()
- req = self.request()
- self.assertEqual([['root'], ['c']],
- req.execute('Any NF WHERE F is Folder, F name NF').rows)
- self.assertEqual([],
- req.execute('Any NF,NP WHERE F parent P, F name NF, P name NP').rows)
+ with self.admin_access.repo_cnx() as cnx:
+ root = cnx.create_entity('Folder', name=u'root')
+ a = cnx.create_entity('Folder', name=u'a')
+ b = cnx.create_entity('Folder', name=u'b')
+ c = cnx.create_entity('Folder', name=u'c')
+ root.cw_set(children=(a, c))
+ a.cw_set(children=b)
+ cnx.commit()
+ cnx.execute('DELETE Folder F WHERE F name "a"')
+ cnx.execute('DELETE R children F WHERE R name "root"')
+ cnx.commit()
+ self.assertEqual([['root'], ['c']],
+ cnx.execute('Any NF WHERE F is Folder, F name NF').rows)
+ self.assertEqual([], cnx.execute('Any NF,NP WHERE F parent P, F name NF, P name NP').rows)
def test_unsatisfied_constraints(self):
- releid = self.execute('SET U in_group G WHERE G name "owners", U login "admin"')[0][0]
- with self.assertRaises(ValidationError) as cm:
- self.commit()
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('SET U in_group G WHERE G name "owners", U login "admin"')[0][0]
+ with self.assertRaises(ValidationError) as cm:
+ cnx.commit()
self.assertEqual(cm.exception.errors,
- {'in_group-object': u'RQLConstraint NOT O name "owners" failed'})
+ {'in_group-object': u'RQLConstraint NOT O name "owners" failed'})
def test_unique_constraint(self):
- req = self.request()
- entity = req.create_entity('CWGroup', name=u'trout')
- self.commit()
- self.assertRaises(ValidationError, req.create_entity, 'CWGroup', name=u'trout')
- self.rollback()
- req.execute('SET X name "trout" WHERE X eid %(x)s', {'x': entity.eid})
- self.commit()
+ with self.admin_access.repo_cnx() as cnx:
+ entity = cnx.create_entity('CWGroup', name=u'trout')
+ cnx.commit()
+ self.assertRaises(ValidationError, cnx.create_entity, 'CWGroup', name=u'trout')
+ cnx.rollback()
+ cnx.execute('SET X name "trout" WHERE X eid %(x)s', {'x': entity.eid})
+ cnx.commit()
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
diff -r 928732ec00dd -r fa44db7da2dc hooks/test/unittest_syncschema.py
--- a/hooks/test/unittest_syncschema.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/test/unittest_syncschema.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -17,13 +17,13 @@
# with CubicWeb. If not, see .
"""cubicweb.server.hooks.syncschema unit and functional tests"""
-from logilab.common.testlib import TestCase, unittest_main
+from logilab.common.testlib import unittest_main
from cubicweb import ValidationError, Binary
from cubicweb.schema import META_RTYPES
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.server.sqlutils import SQL_PREFIX
-from cubicweb.devtools.repotest import schema_eids_idx, restore_schema_eids_idx
+from cubicweb.devtools.repotest import schema_eids_idx
def tearDownModule(*args):
@@ -36,320 +36,343 @@
self.repo.set_schema(self.repo.deserialize_schema(), resetvreg=False)
self.__class__.schema_eids = schema_eids_idx(self.repo.schema)
- def index_exists(self, etype, attr, unique=False):
- self.session.set_cnxset()
+ def index_exists(self, cnx, etype, attr, unique=False):
dbhelper = self.repo.system_source.dbhelper
- sqlcursor = self.session.cnxset.cu
- return dbhelper.index_exists(sqlcursor, SQL_PREFIX + etype, SQL_PREFIX + attr, unique=unique)
+ with cnx.ensure_cnx_set:
+ sqlcursor = cnx.cnxset.cu
+ return dbhelper.index_exists(sqlcursor,
+ SQL_PREFIX + etype,
+ SQL_PREFIX + attr,
+ unique=unique)
- def _set_perms(self, eid):
- self.execute('SET X read_permission G WHERE X eid %(x)s, G is CWGroup',
- {'x': eid})
- self.execute('SET X add_permission G WHERE X eid %(x)s, G is CWGroup, G name "managers"',
- {'x': eid})
- self.execute('SET X delete_permission G WHERE X eid %(x)s, G is CWGroup, G name "owners"',
- {'x': eid})
+ def _set_perms(self, cnx, eid):
+ cnx.execute('SET X read_permission G WHERE X eid %(x)s, G is CWGroup',
+ {'x': eid})
+ cnx.execute('SET X add_permission G WHERE X eid %(x)s, G is CWGroup, '
+ 'G name "managers"', {'x': eid})
+ cnx.execute('SET X delete_permission G WHERE X eid %(x)s, G is CWGroup, '
+ 'G name "owners"', {'x': eid})
- def _set_attr_perms(self, eid):
- self.execute('SET X read_permission G WHERE X eid %(x)s, G is CWGroup',
- {'x': eid})
- self.execute('SET X update_permission G WHERE X eid %(x)s, G is CWGroup, G name "managers"',
- {'x': eid})
+ def _set_attr_perms(self, cnx, eid):
+ cnx.execute('SET X read_permission G WHERE X eid %(x)s, G is CWGroup',
+ {'x': eid})
+ cnx.execute('SET X update_permission G WHERE X eid %(x)s, G is CWGroup, G name "managers"',
+ {'x': eid})
def test_base(self):
- schema = self.repo.schema
- self.session.set_cnxset()
- dbhelper = self.repo.system_source.dbhelper
- sqlcursor = self.session.cnxset.cu
- self.assertFalse(schema.has_entity('Societe2'))
- self.assertFalse(schema.has_entity('concerne2'))
- # schema should be update on insertion (after commit)
- eeid = self.execute('INSERT CWEType X: X name "Societe2", X description "", X final FALSE')[0][0]
- self._set_perms(eeid)
- self.execute('INSERT CWRType X: X name "concerne2", X description "", X final FALSE, X symmetric FALSE')
- self.assertFalse(schema.has_entity('Societe2'))
- self.assertFalse(schema.has_entity('concerne2'))
- # have to commit before adding definition relations
- self.commit()
- self.assertTrue(schema.has_entity('Societe2'))
- self.assertTrue(schema.has_relation('concerne2'))
- attreid = self.execute('INSERT CWAttribute X: X cardinality "11", X defaultval %(default)s, '
- ' X indexed TRUE, X relation_type RT, X from_entity E, X to_entity F '
- 'WHERE RT name "name", E name "Societe2", F name "String"',
- {'default': Binary.zpickle('noname')})[0][0]
- self._set_attr_perms(attreid)
- concerne2_rdef_eid = self.execute(
- 'INSERT CWRelation X: X cardinality "**", X relation_type RT, X from_entity E, X to_entity E '
- 'WHERE RT name "concerne2", E name "Societe2"')[0][0]
- self._set_perms(concerne2_rdef_eid)
- self.assertNotIn('name', schema['Societe2'].subject_relations())
- self.assertNotIn('concerne2', schema['Societe2'].subject_relations())
- self.assertFalse(self.index_exists('Societe2', 'name'))
- self.commit()
- self.assertIn('name', schema['Societe2'].subject_relations())
- self.assertIn('concerne2', schema['Societe2'].subject_relations())
- self.assertTrue(self.index_exists('Societe2', 'name'))
- # now we should be able to insert and query Societe2
- s2eid = self.execute('INSERT Societe2 X: X name "logilab"')[0][0]
- self.execute('Societe2 X WHERE X name "logilab"')
- self.execute('SET X concerne2 X WHERE X name "logilab"')
- rset = self.execute('Any X WHERE X concerne2 Y')
- self.assertEqual(rset.rows, [[s2eid]])
- # check that when a relation definition is deleted, existing relations are deleted
- rdefeid = self.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, '
- ' X from_entity E, X to_entity E '
- 'WHERE RT name "concerne2", E name "CWUser"')[0][0]
- self._set_perms(rdefeid)
- self.commit()
- self.execute('DELETE CWRelation X WHERE X eid %(x)s', {'x': concerne2_rdef_eid})
- self.commit()
- self.assertIn('concerne2', schema['CWUser'].subject_relations())
- self.assertNotIn('concerne2', schema['Societe2'].subject_relations())
- self.assertFalse(self.execute('Any X WHERE X concerne2 Y'))
- # schema should be cleaned on delete (after commit)
- self.execute('DELETE CWEType X WHERE X name "Societe2"')
- self.execute('DELETE CWRType X WHERE X name "concerne2"')
- self.assertTrue(self.index_exists('Societe2', 'name'))
- self.assertTrue(schema.has_entity('Societe2'))
- self.assertTrue(schema.has_relation('concerne2'))
- self.commit()
- self.assertFalse(self.index_exists('Societe2', 'name'))
- self.assertFalse(schema.has_entity('Societe2'))
- self.assertFalse(schema.has_entity('concerne2'))
- self.assertNotIn('concerne2', schema['CWUser'].subject_relations())
+ with self.admin_access.repo_cnx() as cnx:
+ schema = self.repo.schema
+ self.assertFalse(schema.has_entity('Societe2'))
+ self.assertFalse(schema.has_entity('concerne2'))
+ # schema should be update on insertion (after commit)
+ eeid = cnx.execute('INSERT CWEType X: X name "Societe2", '
+ 'X description "", X final FALSE')[0][0]
+ self._set_perms(cnx, eeid)
+ cnx.execute('INSERT CWRType X: X name "concerne2", X description "", '
+ 'X final FALSE, X symmetric FALSE')
+ self.assertFalse(schema.has_entity('Societe2'))
+ self.assertFalse(schema.has_entity('concerne2'))
+ # have to commit before adding definition relations
+ cnx.commit()
+ self.assertTrue(schema.has_entity('Societe2'))
+ self.assertTrue(schema.has_relation('concerne2'))
+ attreid = cnx.execute('INSERT CWAttribute X: X cardinality "11", '
+ 'X defaultval %(default)s, X indexed TRUE, '
+ 'X relation_type RT, X from_entity E, X to_entity F '
+ 'WHERE RT name "name", E name "Societe2", '
+ 'F name "String"',
+ {'default': Binary.zpickle('noname')})[0][0]
+ self._set_attr_perms(cnx, attreid)
+ concerne2_rdef_eid = cnx.execute(
+ 'INSERT CWRelation X: X cardinality "**", X relation_type RT, '
+ 'X from_entity E, X to_entity E '
+ 'WHERE RT name "concerne2", E name "Societe2"')[0][0]
+ self._set_perms(cnx, concerne2_rdef_eid)
+ self.assertNotIn('name', schema['Societe2'].subject_relations())
+ self.assertNotIn('concerne2', schema['Societe2'].subject_relations())
+ self.assertFalse(self.index_exists(cnx, 'Societe2', 'name'))
+ cnx.commit()
+ self.assertIn('name', schema['Societe2'].subject_relations())
+ self.assertIn('concerne2', schema['Societe2'].subject_relations())
+ self.assertTrue(self.index_exists(cnx, 'Societe2', 'name'))
+ # now we should be able to insert and query Societe2
+ s2eid = cnx.execute('INSERT Societe2 X: X name "logilab"')[0][0]
+ cnx.execute('Societe2 X WHERE X name "logilab"')
+ cnx.execute('SET X concerne2 X WHERE X name "logilab"')
+ rset = cnx.execute('Any X WHERE X concerne2 Y')
+ self.assertEqual(rset.rows, [[s2eid]])
+ # check that when a relation definition is deleted, existing relations are deleted
+ rdefeid = cnx.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, '
+ ' X from_entity E, X to_entity E '
+ 'WHERE RT name "concerne2", E name "CWUser"')[0][0]
+ self._set_perms(cnx, rdefeid)
+ cnx.commit()
+ cnx.execute('DELETE CWRelation X WHERE X eid %(x)s', {'x': concerne2_rdef_eid})
+ cnx.commit()
+ self.assertIn('concerne2', schema['CWUser'].subject_relations())
+ self.assertNotIn('concerne2', schema['Societe2'].subject_relations())
+ self.assertFalse(cnx.execute('Any X WHERE X concerne2 Y'))
+ # schema should be cleaned on delete (after commit)
+ cnx.execute('DELETE CWEType X WHERE X name "Societe2"')
+ cnx.execute('DELETE CWRType X WHERE X name "concerne2"')
+ self.assertTrue(self.index_exists(cnx, 'Societe2', 'name'))
+ self.assertTrue(schema.has_entity('Societe2'))
+ self.assertTrue(schema.has_relation('concerne2'))
+ cnx.commit()
+ self.assertFalse(self.index_exists(cnx, 'Societe2', 'name'))
+ self.assertFalse(schema.has_entity('Societe2'))
+ self.assertFalse(schema.has_entity('concerne2'))
+ self.assertNotIn('concerne2', schema['CWUser'].subject_relations())
def test_metartype_with_nordefs(self):
- META_RTYPES.add('custom_meta')
- self.execute('INSERT CWRType X: X name "custom_meta", X description "", '
- 'X final FALSE, X symmetric FALSE')
- self.commit()
- eeid = self.execute('INSERT CWEType X: X name "NEWEtype", '
- 'X description "", X final FALSE')[0][0]
- self._set_perms(eeid)
- self.commit()
- META_RTYPES.remove('custom_meta')
+ with self.admin_access.repo_cnx() as cnx:
+ META_RTYPES.add('custom_meta')
+ cnx.execute('INSERT CWRType X: X name "custom_meta", X description "", '
+ 'X final FALSE, X symmetric FALSE')
+ cnx.commit()
+ eeid = cnx.execute('INSERT CWEType X: X name "NEWEtype", '
+ 'X description "", X final FALSE')[0][0]
+ self._set_perms(cnx, eeid)
+ cnx.commit()
+ META_RTYPES.remove('custom_meta')
def test_metartype_with_somerdefs(self):
- META_RTYPES.add('custom_meta')
- self.execute('INSERT CWRType X: X name "custom_meta", X description "", '
- 'X final FALSE, X symmetric FALSE')
- self.commit()
- rdefeid = self.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, '
- ' X from_entity E, X to_entity E '
- 'WHERE RT name "custom_meta", E name "CWUser"')[0][0]
- self._set_perms(rdefeid)
- self.commit()
- eeid = self.execute('INSERT CWEType X: X name "NEWEtype", '
- 'X description "", X final FALSE')[0][0]
- self._set_perms(eeid)
- self.commit()
- META_RTYPES.remove('custom_meta')
+ with self.admin_access.repo_cnx() as cnx:
+ META_RTYPES.add('custom_meta')
+ cnx.execute('INSERT CWRType X: X name "custom_meta", X description "", '
+ 'X final FALSE, X symmetric FALSE')
+ cnx.commit()
+ rdefeid = cnx.execute('INSERT CWRelation X: X cardinality "**", X relation_type RT, '
+ ' X from_entity E, X to_entity E '
+ 'WHERE RT name "custom_meta", E name "CWUser"')[0][0]
+ self._set_perms(cnx, rdefeid)
+ cnx.commit()
+ eeid = cnx.execute('INSERT CWEType X: X name "NEWEtype", '
+ 'X description "", X final FALSE')[0][0]
+ self._set_perms(cnx, eeid)
+ cnx.commit()
+ META_RTYPES.remove('custom_meta')
def test_is_instance_of_insertions(self):
- seid = self.execute('INSERT Transition T: T name "subdiv"')[0][0]
- is_etypes = [etype for etype, in self.execute('Any ETN WHERE X eid %s, X is ET, ET name ETN' % seid)]
- self.assertEqual(is_etypes, ['Transition'])
- instanceof_etypes = [etype for etype, in self.execute('Any ETN WHERE X eid %s, X is_instance_of ET, ET name ETN' % seid)]
- self.assertEqual(sorted(instanceof_etypes), ['BaseTransition', 'Transition'])
- snames = [name for name, in self.execute('Any N WHERE S is BaseTransition, S name N')]
- self.assertNotIn('subdiv', snames)
- snames = [name for name, in self.execute('Any N WHERE S is_instance_of BaseTransition, S name N')]
- self.assertIn('subdiv', snames)
+ with self.admin_access.repo_cnx() as cnx:
+ seid = cnx.execute('INSERT Transition T: T name "subdiv"')[0][0]
+ is_etypes = [etype for etype, in cnx.execute('Any ETN WHERE X eid %s, '
+ 'X is ET, ET name ETN' % seid)]
+ self.assertEqual(is_etypes, ['Transition'])
+ instanceof_etypes = [etype
+ for etype, in cnx.execute('Any ETN WHERE X eid %s, '
+ 'X is_instance_of ET, ET name ETN'
+ % seid)]
+ self.assertEqual(sorted(instanceof_etypes), ['BaseTransition', 'Transition'])
+ snames = [name for name, in cnx.execute('Any N WHERE S is BaseTransition, S name N')]
+ self.assertNotIn('subdiv', snames)
+ snames = [name for name, in cnx.execute('Any N WHERE S is_instance_of BaseTransition, '
+ 'S name N')]
+ self.assertIn('subdiv', snames)
def test_perms_synchronization_1(self):
- schema = self.repo.schema
- self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users')))
- self.assertTrue(self.execute('Any X, Y WHERE X is CWEType, X name "CWUser", Y is CWGroup, Y name "users"')[0])
- self.execute('DELETE X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
- self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users', )))
- self.commit()
- self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers',)))
- self.execute('SET X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
- self.commit()
- self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users',)))
+ with self.admin_access.repo_cnx() as cnx:
+ schema = self.repo.schema
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users')))
+ self.assertTrue(cnx.execute('Any X, Y WHERE X is CWEType, X name "CWUser", '
+ 'Y is CWGroup, Y name "users"')[0])
+ cnx.execute('DELETE X read_permission Y WHERE X is CWEType, X name "CWUser", Y name "users"')
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers', 'users', )))
+ cnx.commit()
+ self.assertEqual(schema['CWUser'].get_groups('read'), set(('managers',)))
+ cnx.execute('SET X read_permission Y WHERE X is CWEType, '
+ 'X name "CWUser", Y name "users"')
+ cnx.commit()
+ self.assertEqual(schema['CWUser'].get_groups('read'),
+ set(('managers', 'users',)))
def test_perms_synchronization_2(self):
- schema = self.repo.schema['in_group'].rdefs[('CWUser', 'CWGroup')]
- self.assertEqual(schema.get_groups('read'), set(('managers', 'users', 'guests')))
- self.execute('DELETE X read_permission Y WHERE X relation_type RT, RT name "in_group", Y name "guests"')
- self.assertEqual(schema.get_groups('read'), set(('managers', 'users', 'guests')))
- self.commit()
- self.assertEqual(schema.get_groups('read'), set(('managers', 'users')))
- self.execute('SET X read_permission Y WHERE X relation_type RT, RT name "in_group", Y name "guests"')
- self.assertEqual(schema.get_groups('read'), set(('managers', 'users')))
- self.commit()
- self.assertEqual(schema.get_groups('read'), set(('managers', 'users', 'guests')))
+ with self.admin_access.repo_cnx() as cnx:
+ schema = self.repo.schema['in_group'].rdefs[('CWUser', 'CWGroup')]
+ self.assertEqual(schema.get_groups('read'),
+ set(('managers', 'users', 'guests')))
+ cnx.execute('DELETE X read_permission Y WHERE X relation_type RT, '
+ 'RT name "in_group", Y name "guests"')
+ self.assertEqual(schema.get_groups('read'),
+ set(('managers', 'users', 'guests')))
+ cnx.commit()
+ self.assertEqual(schema.get_groups('read'),
+ set(('managers', 'users')))
+ cnx.execute('SET X read_permission Y WHERE X relation_type RT, '
+ 'RT name "in_group", Y name "guests"')
+ self.assertEqual(schema.get_groups('read'),
+ set(('managers', 'users')))
+ cnx.commit()
+ self.assertEqual(schema.get_groups('read'),
+ set(('managers', 'users', 'guests')))
def test_nonregr_user_edit_itself(self):
- ueid = self.session.user.eid
- groupeids = [eid for eid, in self.execute('CWGroup G WHERE G name in ("managers", "users")')]
- self.execute('DELETE X in_group Y WHERE X eid %s' % ueid)
- self.execute('SET X surname "toto" WHERE X eid %s' % ueid)
- self.execute('SET X in_group Y WHERE X eid %s, Y name "managers"' % ueid)
- self.commit()
- eeid = self.execute('Any X WHERE X is CWEType, X name "CWEType"')[0][0]
- self.execute('DELETE X read_permission Y WHERE X eid %s' % eeid)
- self.execute('SET X final FALSE WHERE X eid %s' % eeid)
- self.execute('SET X read_permission Y WHERE X eid %s, Y eid in (%s, %s)'
- % (eeid, groupeids[0], groupeids[1]))
- self.commit()
- self.execute('Any X WHERE X is CWEType, X name "CWEType"')
+ with self.admin_access.repo_cnx() as cnx:
+ ueid = cnx.user.eid
+ groupeids = [eid for eid, in cnx.execute('CWGroup G WHERE G name '
+ 'in ("managers", "users")')]
+ cnx.execute('DELETE X in_group Y WHERE X eid %s' % ueid)
+ cnx.execute('SET X surname "toto" WHERE X eid %s' % ueid)
+ cnx.execute('SET X in_group Y WHERE X eid %s, Y name "managers"' % ueid)
+ cnx.commit()
+ eeid = cnx.execute('Any X WHERE X is CWEType, X name "CWEType"')[0][0]
+ cnx.execute('DELETE X read_permission Y WHERE X eid %s' % eeid)
+ cnx.execute('SET X final FALSE WHERE X eid %s' % eeid)
+ cnx.execute('SET X read_permission Y WHERE X eid %s, Y eid in (%s, %s)'
+ % (eeid, groupeids[0], groupeids[1]))
+ cnx.commit()
+ cnx.execute('Any X WHERE X is CWEType, X name "CWEType"')
# schema modification hooks tests #########################################
def test_uninline_relation(self):
- self.session.set_cnxset()
- dbhelper = self.repo.system_source.dbhelper
- sqlcursor = self.session.cnxset.cu
- self.assertTrue(self.schema['state_of'].inlined)
- try:
- self.execute('SET X inlined FALSE WHERE X name "state_of"')
- self.assertTrue(self.schema['state_of'].inlined)
- self.commit()
- self.assertFalse(self.schema['state_of'].inlined)
- self.assertFalse(self.index_exists('State', 'state_of'))
- rset = self.execute('Any X, Y WHERE X state_of Y')
- self.assertEqual(len(rset), 2) # user states
- except Exception:
- import traceback
- traceback.print_exc()
- finally:
- self.execute('SET X inlined TRUE WHERE X name "state_of"')
- self.assertFalse(self.schema['state_of'].inlined)
- self.commit()
- self.assertTrue(self.schema['state_of'].inlined)
- self.assertTrue(self.index_exists('State', 'state_of'))
- rset = self.execute('Any X, Y WHERE X state_of Y')
- self.assertEqual(len(rset), 2)
+ with self.admin_access.repo_cnx() as cnx:
+ try:
+ self.assertTrue(self.schema['state_of'].inlined)
+ cnx.execute('SET X inlined FALSE WHERE X name "state_of"')
+ self.assertTrue(self.schema['state_of'].inlined)
+ cnx.commit()
+ self.assertFalse(self.schema['state_of'].inlined)
+ self.assertFalse(self.index_exists(cnx, 'State', 'state_of'))
+ rset = cnx.execute('Any X, Y WHERE X state_of Y')
+ self.assertEqual(len(rset), 2) # user states
+ finally:
+ cnx.execute('SET X inlined TRUE WHERE X name "state_of"')
+ self.assertFalse(self.schema['state_of'].inlined)
+ cnx.commit()
+ self.assertTrue(self.schema['state_of'].inlined)
+ self.assertTrue(self.index_exists(cnx, 'State', 'state_of'))
+ rset = cnx.execute('Any X, Y WHERE X state_of Y')
+ self.assertEqual(len(rset), 2)
def test_indexed_change(self):
- self.session.set_cnxset()
- dbhelper = self.repo.system_source.dbhelper
- sqlcursor = self.session.cnxset.cu
- try:
- self.execute('SET X indexed FALSE WHERE X relation_type R, R name "name"')
- self.assertTrue(self.schema['name'].rdef('Workflow', 'String').indexed)
- self.assertTrue(self.index_exists('Workflow', 'name'))
- self.commit()
- self.assertFalse(self.schema['name'].rdef('Workflow', 'String').indexed)
- self.assertFalse(self.index_exists('Workflow', 'name'))
- finally:
- self.execute('SET X indexed TRUE WHERE X relation_type R, R name "name"')
- self.assertFalse(self.schema['name'].rdef('Workflow', 'String').indexed)
- self.assertFalse(self.index_exists('Workflow', 'name'))
- self.commit()
- self.assertTrue(self.schema['name'].rdef('Workflow', 'String').indexed)
- self.assertTrue(self.index_exists('Workflow', 'name'))
+ with self.admin_access.repo_cnx() as cnx:
+ try:
+ cnx.execute('SET X indexed FALSE WHERE X relation_type R, R name "name"')
+ self.assertTrue(self.schema['name'].rdef('Workflow', 'String').indexed)
+ self.assertTrue(self.index_exists(cnx, 'Workflow', 'name'))
+ cnx.commit()
+ self.assertFalse(self.schema['name'].rdef('Workflow', 'String').indexed)
+ self.assertFalse(self.index_exists(cnx, 'Workflow', 'name'))
+ finally:
+ cnx.execute('SET X indexed TRUE WHERE X relation_type R, R name "name"')
+ self.assertFalse(self.schema['name'].rdef('Workflow', 'String').indexed)
+ self.assertFalse(self.index_exists(cnx, 'Workflow', 'name'))
+ cnx.commit()
+ self.assertTrue(self.schema['name'].rdef('Workflow', 'String').indexed)
+ self.assertTrue(self.index_exists(cnx, 'Workflow', 'name'))
def test_unique_change(self):
- self.session.set_cnxset()
- dbhelper = self.repo.system_source.dbhelper
- sqlcursor = self.session.cnxset.cu
- try:
- eid = self.execute('INSERT CWConstraint X: X cstrtype CT, DEF constrained_by X '
- 'WHERE CT name "UniqueConstraint", DEF relation_type RT, DEF from_entity E,'
- 'RT name "name", E name "Workflow"').rows[0][0]
- self.assertFalse(self.schema['Workflow'].has_unique_values('name'))
- self.assertFalse(self.index_exists('Workflow', 'name', unique=True))
- self.commit()
- self.assertTrue(self.schema['Workflow'].has_unique_values('name'))
- self.assertTrue(self.index_exists('Workflow', 'name', unique=True))
- finally:
- self.execute('DELETE CWConstraint C WHERE C eid %(eid)s', {'eid': eid})
- self.commit()
- self.assertFalse(self.schema['Workflow'].has_unique_values('name'))
- self.assertFalse(self.index_exists('Workflow', 'name', unique=True))
+ with self.admin_access.repo_cnx() as cnx:
+ try:
+ eid = cnx.execute('INSERT CWConstraint X: X cstrtype CT, DEF constrained_by X '
+ 'WHERE CT name "UniqueConstraint", DEF relation_type RT, '
+ 'DEF from_entity E, RT name "name", '
+ 'E name "Workflow"').rows[0][0]
+ self.assertFalse(self.schema['Workflow'].has_unique_values('name'))
+ self.assertFalse(self.index_exists(cnx, 'Workflow', 'name', unique=True))
+ cnx.commit()
+ self.assertTrue(self.schema['Workflow'].has_unique_values('name'))
+ self.assertTrue(self.index_exists(cnx, 'Workflow', 'name', unique=True))
+ finally:
+ cnx.execute('DELETE CWConstraint C WHERE C eid %(eid)s', {'eid': eid})
+ cnx.commit()
+ self.assertFalse(self.schema['Workflow'].has_unique_values('name'))
+ self.assertFalse(self.index_exists(cnx, 'Workflow', 'name', unique=True))
def test_required_change_1(self):
- self.execute('SET DEF cardinality "?1" '
- 'WHERE DEF relation_type RT, DEF from_entity E,'
- 'RT name "title", E name "Bookmark"')
- self.commit()
- # should now be able to add bookmark without title
- self.execute('INSERT Bookmark X: X path "/view"')
- self.commit()
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('SET DEF cardinality "?1" '
+ 'WHERE DEF relation_type RT, DEF from_entity E,'
+ 'RT name "title", E name "Bookmark"')
+ cnx.commit()
+ # should now be able to add bookmark without title
+ cnx.execute('INSERT Bookmark X: X path "/view"')
+ cnx.commit()
def test_required_change_2(self):
- self.execute('SET DEF cardinality "11" '
- 'WHERE DEF relation_type RT, DEF from_entity E,'
- 'RT name "surname", E name "CWUser"')
- self.commit()
- # should not be able anymore to add cwuser without surname
- req = self.request()
- self.assertRaises(ValidationError, self.create_user, req, "toto")
- self.rollback()
- self.execute('SET DEF cardinality "?1" '
- 'WHERE DEF relation_type RT, DEF from_entity E,'
- 'RT name "surname", E name "CWUser"')
- self.commit()
-
+ with self.admin_access.repo_cnx() as cnx:
+ cnx.execute('SET DEF cardinality "11" '
+ 'WHERE DEF relation_type RT, DEF from_entity E,'
+ 'RT name "surname", E name "CWUser"')
+ cnx.commit()
+ # should not be able anymore to add cwuser without surname
+ self.assertRaises(ValidationError, self.create_user, cnx, "toto")
+ cnx.rollback()
+ cnx.execute('SET DEF cardinality "?1" '
+ 'WHERE DEF relation_type RT, DEF from_entity E,'
+ 'RT name "surname", E name "CWUser"')
+ cnx.commit()
def test_add_attribute_to_base_class(self):
- attreid = self.execute('INSERT CWAttribute X: X cardinality "11", X defaultval %(default)s, '
- 'X indexed TRUE, X relation_type RT, X from_entity E, X to_entity F '
- 'WHERE RT name "messageid", E name "BaseTransition", F name "String"',
- {'default': Binary.zpickle('noname')})[0][0]
- assert self.execute('SET X read_permission Y WHERE X eid %(x)s, Y name "managers"',
- {'x': attreid})
- self.commit()
- self.schema.rebuild_infered_relations()
- self.assertIn('Transition', self.schema['messageid'].subjects())
- self.assertIn('WorkflowTransition', self.schema['messageid'].subjects())
- self.execute('Any X WHERE X is_instance_of BaseTransition, X messageid "hop"')
+ with self.admin_access.repo_cnx() as cnx:
+ attreid = cnx.execute('INSERT CWAttribute X: X cardinality "11", X defaultval %(default)s, '
+ 'X indexed TRUE, X relation_type RT, X from_entity E, X to_entity F '
+ 'WHERE RT name "messageid", E name "BaseTransition", F name "String"',
+ {'default': Binary.zpickle('noname')})[0][0]
+ assert cnx.execute('SET X read_permission Y WHERE X eid %(x)s, Y name "managers"',
+ {'x': attreid})
+ cnx.commit()
+ self.schema.rebuild_infered_relations()
+ self.assertIn('Transition', self.schema['messageid'].subjects())
+ self.assertIn('WorkflowTransition', self.schema['messageid'].subjects())
+ cnx.execute('Any X WHERE X is_instance_of BaseTransition, X messageid "hop"')
def test_change_fulltextindexed(self):
- req = self.request()
- target = req.create_entity(u'Email', messageid=u'1234',
- subject=u'rick.roll@dance.com')
- self.commit()
- rset = req.execute('Any X WHERE X has_text "rick.roll"')
- self.assertIn(target.eid, [item[0] for item in rset])
- assert req.execute('SET A fulltextindexed FALSE '
- 'WHERE E is CWEType, E name "Email", A is CWAttribute,'
- 'A from_entity E, A relation_type R, R name "subject"')
- self.commit()
- rset = req.execute('Any X WHERE X has_text "rick.roll"')
- self.assertFalse(rset)
- assert req.execute('SET A fulltextindexed TRUE '
- 'WHERE A from_entity E, A relation_type R, '
- 'E name "Email", R name "subject"')
- self.commit()
- rset = req.execute('Any X WHERE X has_text "rick.roll"')
- self.assertIn(target.eid, [item[0] for item in rset])
+ with self.admin_access.repo_cnx() as cnx:
+ target = cnx.create_entity(u'Email', messageid=u'1234',
+ subject=u'rick.roll@dance.com')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X has_text "rick.roll"')
+ self.assertIn(target.eid, [item[0] for item in rset])
+ assert cnx.execute('SET A fulltextindexed FALSE '
+ 'WHERE E is CWEType, E name "Email", A is CWAttribute,'
+ 'A from_entity E, A relation_type R, R name "subject"')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X has_text "rick.roll"')
+ self.assertFalse(rset)
+ assert cnx.execute('SET A fulltextindexed TRUE '
+ 'WHERE A from_entity E, A relation_type R, '
+ 'E name "Email", R name "subject"')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X has_text "rick.roll"')
+ self.assertIn(target.eid, [item[0] for item in rset])
def test_change_fulltext_container(self):
- req = self.request()
- target = req.create_entity(u'EmailAddress', address=u'rick.roll@dance.com')
- target.cw_set(reverse_use_email=req.user)
- self.commit()
- rset = req.execute('Any X WHERE X has_text "rick.roll"')
- self.assertIn(req.user.eid, [item[0] for item in rset])
- assert self.execute('SET R fulltext_container NULL '
- 'WHERE R name "use_email"')
- self.commit()
- rset = self.execute('Any X WHERE X has_text "rick.roll"')
- self.assertIn(target.eid, [item[0] for item in rset])
- assert self.execute('SET R fulltext_container "subject" '
- 'WHERE R name "use_email"')
- self.commit()
- rset = req.execute('Any X WHERE X has_text "rick.roll"')
- self.assertIn(req.user.eid, [item[0] for item in rset])
+ with self.admin_access.repo_cnx() as cnx:
+ target = cnx.create_entity(u'EmailAddress', address=u'rick.roll@dance.com')
+ target.cw_set(reverse_use_email=cnx.user)
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X has_text "rick.roll"')
+ self.assertIn(cnx.user.eid, [item[0] for item in rset])
+ assert cnx.execute('SET R fulltext_container NULL '
+ 'WHERE R name "use_email"')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X has_text "rick.roll"')
+ self.assertIn(target.eid, [item[0] for item in rset])
+ assert cnx.execute('SET R fulltext_container "subject" '
+ 'WHERE R name "use_email"')
+ cnx.commit()
+ rset = cnx.execute('Any X WHERE X has_text "rick.roll"')
+ self.assertIn(cnx.user.eid, [item[0] for item in rset])
def test_update_constraint(self):
- rdef = self.schema['Transition'].rdef('type')
- cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
- if not getattr(cstr, 'eid', None):
- self.skipTest('start me alone') # bug in schema reloading, constraint's eid not restored
- self.execute('SET X value %(v)s WHERE X eid %(x)s',
- {'x': cstr.eid, 'v': u"u'normal', u'auto', u'new'"})
- self.execute('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X '
- 'WHERE CT name %(ct)s, EDEF eid %(x)s',
- {'ct': 'SizeConstraint', 'value': u'max=10', 'x': rdef.eid})
- self.commit()
- cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
- self.assertEqual(cstr.values, (u'normal', u'auto', u'new'))
- self.execute('INSERT Transition T: T name "hop", T type "new"')
+ with self.admin_access.repo_cnx() as cnx:
+ rdef = self.schema['Transition'].rdef('type')
+ cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
+ if not getattr(cstr, 'eid', None):
+ # bug in schema reloading, constraint's eid not restored
+ self.skipTest('start me alone')
+ cnx.execute('SET X value %(v)s WHERE X eid %(x)s',
+ {'x': cstr.eid, 'v': u"u'normal', u'auto', u'new'"})
+ cnx.execute('INSERT CWConstraint X: X value %(value)s, X cstrtype CT, '
+ 'EDEF constrained_by X WHERE CT name %(ct)s, EDEF eid %(x)s',
+ {'ct': 'SizeConstraint', 'value': u'max=10', 'x': rdef.eid})
+ cnx.commit()
+ cstr = rdef.constraint_by_type('StaticVocabularyConstraint')
+ self.assertEqual(cstr.values, (u'normal', u'auto', u'new'))
+ cnx.execute('INSERT Transition T: T name "hop", T type "new"')
if __name__ == '__main__':
unittest_main()
diff -r 928732ec00dd -r fa44db7da2dc hooks/test/unittest_syncsession.py
--- a/hooks/test/unittest_syncsession.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/test/unittest_syncsession.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -28,32 +28,46 @@
class CWPropertyHooksTC(CubicWebTC):
def test_unexistant_cwproperty(self):
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop", X for_user U')
- cm.exception.translate(unicode)
- self.assertEqual(cm.exception.errors, {'pkey-subject': 'unknown property key bla.bla'})
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
- cm.exception.translate(unicode)
- self.assertEqual(cm.exception.errors, {'pkey-subject': 'unknown property key bla.bla'})
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(ValidationError) as cm:
+ req.execute('INSERT CWProperty X: X pkey "bla.bla", '
+ 'X value "hop", X for_user U')
+ cm.exception.translate(unicode)
+ self.assertEqual(cm.exception.errors,
+ {'pkey-subject': 'unknown property key bla.bla'})
+
+ with self.assertRaises(ValidationError) as cm:
+ req.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
+ cm.exception.translate(unicode)
+ self.assertEqual(cm.exception.errors,
+ {'pkey-subject': 'unknown property key bla.bla'})
def test_site_wide_cwproperty(self):
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWProperty X: X pkey "ui.site-title", X value "hop", X for_user U')
- self.assertEqual(cm.exception.errors, {'for_user-subject': "site-wide property can't be set for user"})
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(ValidationError) as cm:
+ req.execute('INSERT CWProperty X: X pkey "ui.site-title", '
+ 'X value "hop", X for_user U')
+ self.assertEqual(cm.exception.errors,
+ {'for_user-subject': "site-wide property can't be set for user"})
def test_system_cwproperty(self):
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWProperty X: X pkey "system.version.cubicweb", X value "hop", X for_user U')
- self.assertEqual(cm.exception.errors, {'for_user-subject': "site-wide property can't be set for user"})
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(ValidationError) as cm:
+ req.execute('INSERT CWProperty X: X pkey "system.version.cubicweb", '
+ 'X value "hop", X for_user U')
+ self.assertEqual(cm.exception.errors,
+ {'for_user-subject': "site-wide property can't be set for user"})
def test_bad_type_cwproperty(self):
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWProperty X: X pkey "ui.language", X value "hop", X for_user U')
- self.assertEqual(cm.exception.errors, {'value-subject': u'unauthorized value'})
- with self.assertRaises(ValidationError) as cm:
- self.execute('INSERT CWProperty X: X pkey "ui.language", X value "hop"')
- self.assertEqual(cm.exception.errors, {'value-subject': u'unauthorized value'})
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(ValidationError) as cm:
+ req.execute('INSERT CWProperty X: X pkey "ui.language", '
+ 'X value "hop", X for_user U')
+ self.assertEqual(cm.exception.errors,
+ {'value-subject': u'unauthorized value'})
+ with self.assertRaises(ValidationError) as cm:
+ req.execute('INSERT CWProperty X: X pkey "ui.language", X value "hop"')
+ self.assertEqual(cm.exception.errors, {'value-subject': u'unauthorized value'})
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
diff -r 928732ec00dd -r fa44db7da2dc hooks/zmq.py
--- a/hooks/zmq.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/zmq.py Fri Jul 18 17:35:25 2014 +0200
@@ -71,6 +71,7 @@
address = config.get('zmq-repository-address')
if not address:
return
+ self.repo.warning('remote access to the repository via zmq/pickle is deprecated')
from cubicweb.server import cwzmq
self.repo.zmq_repo_server = server = cwzmq.ZMQRepositoryServer(self.repo)
server.connect(address)
diff -r 928732ec00dd -r fa44db7da2dc migration.py
--- a/migration.py Thu Jul 17 11:08:56 2014 +0200
+++ b/migration.py Fri Jul 18 17:35:25 2014 +0200
@@ -414,7 +414,9 @@
toremove = (cube,)
origcubes = self.config._cubes
basecubes = [c for c in origcubes if not c in toremove]
- self.config._cubes = tuple(self.config.expand_cubes(basecubes))
+ # don't fake-add any new ones, or we won't be able to really-add them later
+ self.config._cubes = tuple(cube for cube in self.config.expand_cubes(basecubes)
+ if cube in origcubes)
removed = [p for p in origcubes if not p in self.config._cubes]
if not cube in removed and cube in origcubes:
raise ConfigurationError("can't remove cube %s, "
diff -r 928732ec00dd -r fa44db7da2dc rset.py
--- a/rset.py Thu Jul 17 11:08:56 2014 +0200
+++ b/rset.py Fri Jul 18 17:35:25 2014 +0200
@@ -541,7 +541,8 @@
else:
attr_cols[attr] = i
else:
- rdef = eschema.rdef(attr, role)
+ # XXX takefirst=True to remove warning triggered by ambiguous relations
+ rdef = eschema.rdef(attr, role, takefirst=True)
# only keep value if it can't be multivalued
if rdef.role_cardinality(role) in '1?':
rel_cols[(attr, role)] = i
diff -r 928732ec00dd -r fa44db7da2dc server/repository.py
--- a/server/repository.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/repository.py Fri Jul 18 17:35:25 2014 +0200
@@ -880,7 +880,7 @@
"""
mintime = time() - self.cleanup_session_time
self.debug('cleaning session unused since %s',
- strftime('%T', localtime(mintime)))
+ strftime('%H:%M:%S', localtime(mintime)))
nbclosed = 0
for session in self._sessions.values():
if session.timestamp < mintime:
diff -r 928732ec00dd -r fa44db7da2dc server/serverctl.py
--- a/server/serverctl.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/serverctl.py Fri Jul 18 17:35:25 2014 +0200
@@ -677,6 +677,7 @@
def run(self, args):
from logilab.common.daemon import daemonize, setugid
from cubicweb.cwctl import init_cmdline_log_threshold
+ print 'WARNING: Standalone repository with pyro or zmq access is deprecated'
appid = args[0]
debug = self['debug']
if sys.platform == 'win32' and not debug:
diff -r 928732ec00dd -r fa44db7da2dc server/sources/datafeed.py
--- a/server/sources/datafeed.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/sources/datafeed.py Fri Jul 18 17:35:25 2014 +0200
@@ -126,18 +126,18 @@
self.parser_id = source_entity.parser
self.load_mapping(source_entity._cw)
- def _get_parser(self, session, **kwargs):
+ def _get_parser(self, cnx, **kwargs):
return self.repo.vreg['parsers'].select(
- self.parser_id, session, source=self, **kwargs)
+ self.parser_id, cnx, source=self, **kwargs)
- def load_mapping(self, session):
+ def load_mapping(self, cnx):
self.mapping = {}
self.mapping_idx = {}
try:
- parser = self._get_parser(session)
+ parser = self._get_parser(cnx)
except (RegistryNotFound, ObjectNotFound):
return # no parser yet, don't go further
- self._load_mapping(session, parser=parser)
+ self._load_mapping(cnx, parser=parser)
def add_schema_config(self, schemacfg, checkonly=False, parser=None):
"""added CWSourceSchemaConfig, modify mapping accordingly"""
@@ -159,7 +159,7 @@
def update_latest_retrieval(self, cnx):
self.latest_retrieval = datetime.utcnow()
cnx.execute('SET X latest_retrieval %(date)s WHERE X eid %(x)s',
- {'x': self.eid, 'date': self.latest_retrieval})
+ {'x': self.eid, 'date': self.latest_retrieval})
cnx.commit()
def acquire_synchronization_lock(self, cnx):
@@ -178,7 +178,7 @@
def release_synchronization_lock(self, cnx):
cnx.execute('SET X in_synchronization NULL WHERE X eid %(x)s',
- {'x': self.eid})
+ {'x': self.eid})
cnx.commit()
def pull_data(self, cnx, force=False, raise_on_error=False):
@@ -238,7 +238,7 @@
error = True
return error
- def before_entity_insertion(self, session, lid, etype, eid, sourceparams):
+ def before_entity_insertion(self, cnx, lid, etype, eid, sourceparams):
"""called by the repository when an eid has been attributed for an
entity stored here but the entity has not been inserted in the system
table yet.
@@ -247,40 +247,40 @@
entity.
"""
entity = super(DataFeedSource, self).before_entity_insertion(
- session, lid, etype, eid, sourceparams)
+ cnx, lid, etype, eid, sourceparams)
entity.cw_edited['cwuri'] = lid.decode('utf-8')
entity.cw_edited.set_defaults()
sourceparams['parser'].before_entity_copy(entity, sourceparams)
return entity
- def after_entity_insertion(self, session, lid, entity, sourceparams):
+ def after_entity_insertion(self, cnx, lid, entity, sourceparams):
"""called by the repository after an entity stored here has been
inserted in the system table.
"""
- relations = preprocess_inlined_relations(session, entity)
- if session.is_hook_category_activated('integrity'):
+ relations = preprocess_inlined_relations(cnx, entity)
+ if cnx.is_hook_category_activated('integrity'):
entity.cw_edited.check(creation=True)
- self.repo.system_source.add_entity(session, entity)
+ self.repo.system_source.add_entity(cnx, entity)
entity.cw_edited.saved = entity._cw_is_saved = True
sourceparams['parser'].after_entity_copy(entity, sourceparams)
# call hooks for inlined relations
call_hooks = self.repo.hm.call_hooks
if self.should_call_hooks:
for attr, value in relations:
- call_hooks('before_add_relation', session,
+ call_hooks('before_add_relation', cnx,
eidfrom=entity.eid, rtype=attr, eidto=value)
- call_hooks('after_add_relation', session,
+ call_hooks('after_add_relation', cnx,
eidfrom=entity.eid, rtype=attr, eidto=value)
- def source_cwuris(self, session):
+ def source_cwuris(self, cnx):
sql = ('SELECT extid, eid, type FROM entities, cw_source_relation '
'WHERE entities.eid=cw_source_relation.eid_from '
'AND cw_source_relation.eid_to=%s' % self.eid)
return dict((b64decode(uri), (eid, type))
- for uri, eid, type in session.system_sql(sql).fetchall())
+ for uri, eid, type in cnx.system_sql(sql).fetchall())
- def init_import_log(self, session, **kwargs):
- dataimport = session.create_entity('CWDataImport', cw_import_of=self,
+ def init_import_log(self, cnx, **kwargs):
+ dataimport = cnx.create_entity('CWDataImport', cw_import_of=self,
start_timestamp=datetime.utcnow(),
**kwargs)
dataimport.init()
@@ -290,8 +290,8 @@
class DataFeedParser(AppObject):
__registry__ = 'parsers'
- def __init__(self, session, source, sourceuris=None, import_log=None, **kwargs):
- super(DataFeedParser, self).__init__(session, **kwargs)
+ def __init__(self, cnx, source, sourceuris=None, import_log=None, **kwargs):
+ super(DataFeedParser, self).__init__(cnx, **kwargs)
self.source = source
self.sourceuris = sourceuris
self.import_log = import_log
@@ -345,20 +345,20 @@
"""return an entity for the given uri. May return None if it should be
skipped
"""
- session = self._cw
+ cnx = self._cw
# if cwsource is specified and repository has a source with the same
# name, call extid2eid on that source so entity will be properly seen as
# coming from this source
source_uri = sourceparams.pop('cwsource', None)
if source_uri is not None and source_uri != 'system':
- source = session.repo.sources_by_uri.get(source_uri, self.source)
+ source = cnx.repo.sources_by_uri.get(source_uri, self.source)
else:
source = self.source
sourceparams['parser'] = self
if isinstance(uri, unicode):
uri = uri.encode('utf-8')
try:
- eid = session.repo.extid2eid(source, str(uri), etype, session,
+ eid = cnx.repo.extid2eid(source, str(uri), etype, cnx,
sourceparams=sourceparams)
except ValidationError as ex:
# XXX use critical so they are seen during tests. Should consider
@@ -373,14 +373,14 @@
# Don't give etype to entity_from_eid so we get UnknownEid if the
# entity has been removed
try:
- entity = session.entity_from_eid(-eid)
+ entity = cnx.entity_from_eid(-eid)
except UnknownEid:
return None
self.notify_updated(entity) # avoid later update from the source's data
return entity
if self.sourceuris is not None:
self.sourceuris.pop(str(uri), None)
- return session.entity_from_eid(eid, etype)
+ return cnx.entity_from_eid(eid, etype)
def process(self, url, raise_on_error=False):
"""main callback: process the url"""
@@ -411,7 +411,7 @@
"""
return True
- def handle_deletion(self, config, session, myuris):
+ def handle_deletion(self, config, cnx, myuris):
if config['delete-entities'] and myuris:
byetype = {}
for extid, (eid, etype) in myuris.iteritems():
@@ -419,10 +419,9 @@
byetype.setdefault(etype, []).append(str(eid))
for etype, eids in byetype.iteritems():
self.warning('delete %s %s entities', len(eids), etype)
- session.set_cnxset()
- session.execute('DELETE %s X WHERE X eid IN (%s)'
- % (etype, ','.join(eids)))
- session.commit()
+ cnx.execute('DELETE %s X WHERE X eid IN (%s)'
+ % (etype, ','.join(eids)))
+ cnx.commit()
def update_if_necessary(self, entity, attrs):
entity.complete(tuple(attrs))
@@ -450,13 +449,8 @@
self.import_log.record_error(str(ex))
return True
error = False
- # Check whether self._cw is a session or a connection
- if getattr(self._cw, 'commit', None) is not None:
- commit = self._cw.commit
- rollback = self._cw.rollback
- else:
- commit = self._cw.cnx.commit
- rollback = self._cw.cnx.rollback
+ commit = self._cw.commit
+ rollback = self._cw.rollback
for args in parsed:
try:
self.process_item(*args)
diff -r 928732ec00dd -r fa44db7da2dc server/test/data/schema.py
--- a/server/test/data/schema.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/test/data/schema.py Fri Jul 18 17:35:25 2014 +0200
@@ -202,7 +202,6 @@
name = 'ecrit_par'
subject = 'Note'
object ='Personne'
- constraints = [RQLConstraint('E concerns P, S version_of P')]
cardinality = '?*'
class ecrit_par_2(RelationDefinition):
diff -r 928732ec00dd -r fa44db7da2dc server/test/unittest_datafeed.py
--- a/server/test/unittest_datafeed.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/test/unittest_datafeed.py Fri Jul 18 17:35:25 2014 +0200
@@ -104,11 +104,11 @@
self.assertEqual(self.repo._extid_cache['http://www.cubicweb.org/'],
entity.eid)
- self.assertEqual(dfsource.source_cwuris(self.session),
- {'http://www.cubicweb.org/': (entity.eid, 'Card')}
- )
- self.assertTrue(dfsource.latest_retrieval)
- self.assertTrue(dfsource.fresh())
+ self.assertEqual(dfsource.source_cwuris(cnx),
+ {'http://www.cubicweb.org/': (entity.eid, 'Card')}
+ )
+ self.assertTrue(dfsource.latest_retrieval)
+ self.assertTrue(dfsource.fresh())
# test_rename_source
with self.admin_access.repo_cnx() as cnx:
diff -r 928732ec00dd -r fa44db7da2dc server/test/unittest_querier.py
--- a/server/test/unittest_querier.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/test/unittest_querier.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: iso-8859-1 -*-
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -110,167 +110,193 @@
pass
def test_preprocess_1(self):
- reid = self.execute('Any X WHERE X is CWRType, X name "owned_by"')[0][0]
- rqlst = self._prepare('Any COUNT(RDEF) WHERE RDEF relation_type X, X eid %(x)s', {'x': reid})
- self.assertEqual(rqlst.solutions, [{'RDEF': 'CWAttribute'}, {'RDEF': 'CWRelation'}])
+ with self.session.new_cnx() as cnx:
+ reid = cnx.execute('Any X WHERE X is CWRType, X name "owned_by"')[0][0]
+ rqlst = self._prepare(cnx, 'Any COUNT(RDEF) WHERE RDEF relation_type X, X eid %(x)s',
+ {'x': reid})
+ self.assertEqual([{'RDEF': 'CWAttribute'}, {'RDEF': 'CWRelation'}],
+ rqlst.solutions)
def test_preprocess_2(self):
- teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
- #geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
- #self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
- # {'g': geid, 't': teid}, 'g')
- rqlst = self._prepare('Any X WHERE E eid %(x)s, E tags X', {'x': teid})
- # the query may be optimized, should keep only one solution
- # (any one, etype will be discarded)
- self.assertEqual(len(rqlst.solutions), 1)
+ with self.session.new_cnx() as cnx:
+ teid = cnx.execute("INSERT Tag X: X name 'tag'")[0][0]
+ #geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
+ #self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
+ # {'g': geid, 't': teid}, 'g')
+ rqlst = self._prepare(cnx, 'Any X WHERE E eid %(x)s, E tags X', {'x': teid})
+ # the query may be optimized, should keep only one solution
+ # (any one, etype will be discarded)
+ self.assertEqual(1, len(rqlst.solutions))
+
+ def assertRQLEqual(self, expected, got):
+ from rql import parse
+ self.assertMultiLineEqual(unicode(parse(expected)),
+ unicode(parse(got)))
def test_preprocess_security(self):
- plan = self._prepare_plan('Any ETN,COUNT(X) GROUPBY ETN '
- 'WHERE X is ET, ET name ETN')
- plan.cnx = self.user_groups_session('users')
- union = plan.rqlst
- plan.preprocess(union)
- self.assertEqual(len(union.children), 1)
- self.assertEqual(len(union.children[0].with_), 1)
- subq = union.children[0].with_[0].query
- self.assertEqual(len(subq.children), 4)
- self.assertEqual([t.as_string() for t in union.children[0].selection],
- ['ETN','COUNT(X)'])
- self.assertEqual([t.as_string() for t in union.children[0].groupby],
- ['ETN'])
- partrqls = sorted(((rqlst.as_string(), rqlst.solutions) for rqlst in subq.children))
- rql, solutions = partrqls[0]
- self.assertEqual(rql,
- 'Any ETN,X WHERE X is ET, ET name ETN, (EXISTS(X owned_by %(B)s))'
- ' OR ((((EXISTS(D concerne C?, C owned_by %(B)s, X identity D, C is Division, D is Affaire))'
- ' OR (EXISTS(H concerne G?, G owned_by %(B)s, G is SubDivision, X identity H, H is Affaire)))'
- ' OR (EXISTS(I concerne F?, F owned_by %(B)s, F is Societe, X identity I, I is Affaire)))'
- ' OR (EXISTS(J concerne E?, E owned_by %(B)s, E is Note, X identity J, J is Affaire)))'
- ', ET is CWEType, X is Affaire')
- self.assertEqual(solutions, [{'C': 'Division',
- 'D': 'Affaire',
- 'E': 'Note',
- 'F': 'Societe',
- 'G': 'SubDivision',
- 'H': 'Affaire',
- 'I': 'Affaire',
- 'J': 'Affaire',
- 'X': 'Affaire',
- 'ET': 'CWEType', 'ETN': 'String'}])
- rql, solutions = partrqls[1]
- self.assertEqual(rql, 'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, CWRelation, CWSource, CWUniqueTogetherConstraint, CWUser, Card, Comment, Division, Email, EmailPart, EmailThread, ExternalUri, File, Folder, Note, Old, Personne, RQLExpression, Societe, State, SubDivision, SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
- self.assertListEqual(sorted(solutions),
- sorted([{'X': 'BaseTransition', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Card', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Comment', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Division', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWCache', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWConstraint', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWConstraintType', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWEType', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWAttribute', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWGroup', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWRelation', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWPermission', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWProperty', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWRType', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWSource', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWUniqueTogetherConstraint', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'CWUser', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Email', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'EmailPart', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'EmailThread', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'ExternalUri', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'File', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Folder', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Note', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Old', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Personne', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'RQLExpression', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Societe', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'State', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'SubDivision', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'SubWorkflowExitPoint', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Tag', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Transition', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'TrInfo', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'Workflow', 'ETN': 'String', 'ET': 'CWEType'},
- {'X': 'WorkflowTransition', 'ETN': 'String', 'ET': 'CWEType'}]))
- rql, solutions = partrqls[2]
- self.assertEqual(rql,
- 'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(%(D)s use_email X), '
- 'ET is CWEType, X is EmailAddress')
- self.assertEqual(solutions, [{'X': 'EmailAddress', 'ET': 'CWEType', 'ETN': 'String'}])
- rql, solutions = partrqls[3]
- self.assertEqual(rql,
- 'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(X owned_by %(C)s), '
- 'ET is CWEType, X is Basket')
- self.assertEqual(solutions, [{'X': 'Basket', 'ET': 'CWEType', 'ETN': 'String'}])
+ s = self.user_groups_session('users')
+ with s.new_cnx() as cnx:
+ plan = self._prepare_plan(cnx, 'Any ETN,COUNT(X) GROUPBY ETN '
+ 'WHERE X is ET, ET name ETN')
+ union = plan.rqlst
+ plan.preprocess(union)
+ self.assertEqual(len(union.children), 1)
+ self.assertEqual(len(union.children[0].with_), 1)
+ subq = union.children[0].with_[0].query
+ self.assertEqual(len(subq.children), 4)
+ self.assertEqual([t.as_string() for t in union.children[0].selection],
+ ['ETN','COUNT(X)'])
+ self.assertEqual([t.as_string() for t in union.children[0].groupby],
+ ['ETN'])
+ partrqls = sorted(((rqlst.as_string(), rqlst.solutions) for rqlst in subq.children))
+ rql, solutions = partrqls[0]
+ self.assertRQLEqual(rql,
+ 'Any ETN,X WHERE X is ET, ET name ETN, (EXISTS(X owned_by %(B)s))'
+ ' OR ((((EXISTS(D concerne C?, C owned_by %(B)s, '
+ ' X identity D, C is Division, D is Affaire))'
+ ' OR (EXISTS(H concerne G?, G owned_by %(B)s, G is SubDivision, '
+ ' X identity H, H is Affaire)))'
+ ' OR (EXISTS(I concerne F?, F owned_by %(B)s, F is Societe, '
+ ' X identity I, I is Affaire)))'
+ ' OR (EXISTS(J concerne E?, E owned_by %(B)s, E is Note, '
+ ' X identity J, J is Affaire)))'
+ ', ET is CWEType, X is Affaire')
+ self.assertEqual(solutions, [{'C': 'Division',
+ 'D': 'Affaire',
+ 'E': 'Note',
+ 'F': 'Societe',
+ 'G': 'SubDivision',
+ 'H': 'Affaire',
+ 'I': 'Affaire',
+ 'J': 'Affaire',
+ 'X': 'Affaire',
+ 'ET': 'CWEType', 'ETN': 'String'}])
+ rql, solutions = partrqls[1]
+ self.assertRQLEqual(rql, 'Any ETN,X WHERE X is ET, ET name ETN, ET is CWEType, '
+ 'X is IN(BaseTransition, Bookmark, CWAttribute, CWCache, CWConstraint, '
+ ' CWConstraintType, CWEType, CWGroup, CWPermission, CWProperty, CWRType, '
+ ' CWRelation, CWSource, CWUniqueTogetherConstraint, CWUser, Card, Comment, '
+ ' Division, Email, EmailPart, EmailThread, ExternalUri, File, Folder, Note, '
+ ' Old, Personne, RQLExpression, Societe, State, SubDivision, '
+ ' SubWorkflowExitPoint, Tag, TrInfo, Transition, Workflow, WorkflowTransition)')
+ self.assertListEqual(sorted(solutions),
+ sorted([{'X': 'BaseTransition', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Bookmark', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Card', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Comment', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Division', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWCache', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWConstraint', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWConstraintType', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWEType', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWAttribute', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWGroup', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWRelation', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWPermission', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWProperty', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWRType', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWSource', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWUniqueTogetherConstraint', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'CWUser', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Email', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'EmailPart', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'EmailThread', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'ExternalUri', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'File', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Folder', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Note', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Old', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Personne', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'RQLExpression', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Societe', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'State', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'SubDivision', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'SubWorkflowExitPoint', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Tag', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Transition', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'TrInfo', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'Workflow', 'ETN': 'String', 'ET': 'CWEType'},
+ {'X': 'WorkflowTransition', 'ETN': 'String', 'ET': 'CWEType'}]))
+ rql, solutions = partrqls[2]
+ self.assertEqual(rql,
+ 'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(%(D)s use_email X), '
+ 'ET is CWEType, X is EmailAddress')
+ self.assertEqual(solutions, [{'X': 'EmailAddress', 'ET': 'CWEType', 'ETN': 'String'}])
+ rql, solutions = partrqls[3]
+ self.assertEqual(rql,
+ 'Any ETN,X WHERE X is ET, ET name ETN, EXISTS(X owned_by %(C)s), '
+ 'ET is CWEType, X is Basket')
+ self.assertEqual(solutions, [{'X': 'Basket', 'ET': 'CWEType', 'ETN': 'String'}])
def test_preprocess_security_aggregat(self):
- plan = self._prepare_plan('Any MAX(X)')
- plan.cnx = self.user_groups_session('users')
- union = plan.rqlst
- plan.preprocess(union)
- self.assertEqual(len(union.children), 1)
- self.assertEqual(len(union.children[0].with_), 1)
- subq = union.children[0].with_[0].query
- self.assertEqual(len(subq.children), 4)
- self.assertEqual([t.as_string() for t in union.children[0].selection],
- ['MAX(X)'])
+ s = self.user_groups_session('users')
+ with s.new_cnx() as cnx:
+ plan = self._prepare_plan(cnx, 'Any MAX(X)')
+ union = plan.rqlst
+ plan.preprocess(union)
+ self.assertEqual(len(union.children), 1)
+ self.assertEqual(len(union.children[0].with_), 1)
+ subq = union.children[0].with_[0].query
+ self.assertEqual(len(subq.children), 4)
+ self.assertEqual([t.as_string() for t in union.children[0].selection],
+ ['MAX(X)'])
def test_preprocess_nonregr(self):
- rqlst = self._prepare('Any S ORDERBY SI WHERE NOT S ecrit_par O, S para SI')
- self.assertEqual(len(rqlst.solutions), 1)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any S ORDERBY SI WHERE NOT S ecrit_par O, S para SI')
+ self.assertEqual(len(rqlst.solutions), 1)
def test_build_description(self):
# should return an empty result set
- rset = self.execute('Any X WHERE X eid %(x)s', {'x': self.session.user.eid})
+ rset = self.qexecute('Any X WHERE X eid %(x)s', {'x': self.session.user.eid})
self.assertEqual(rset.description[0][0], 'CWUser')
- rset = self.execute('Any 1')
+ rset = self.qexecute('Any 1')
self.assertEqual(rset.description[0][0], 'Int')
- rset = self.execute('Any TRUE')
+ rset = self.qexecute('Any TRUE')
self.assertEqual(rset.description[0][0], 'Boolean')
- rset = self.execute('Any "hop"')
+ rset = self.qexecute('Any "hop"')
self.assertEqual(rset.description[0][0], 'String')
- rset = self.execute('Any TODAY')
+ rset = self.qexecute('Any TODAY')
self.assertEqual(rset.description[0][0], 'Date')
- rset = self.execute('Any NOW')
+ rset = self.qexecute('Any NOW')
self.assertEqual(rset.description[0][0], 'Datetime')
- rset = self.execute('Any %(x)s', {'x': 1})
+ rset = self.qexecute('Any %(x)s', {'x': 1})
self.assertEqual(rset.description[0][0], 'Int')
- rset = self.execute('Any %(x)s', {'x': 1L})
+ rset = self.qexecute('Any %(x)s', {'x': 1L})
self.assertEqual(rset.description[0][0], 'Int')
- rset = self.execute('Any %(x)s', {'x': True})
+ rset = self.qexecute('Any %(x)s', {'x': True})
self.assertEqual(rset.description[0][0], 'Boolean')
- rset = self.execute('Any %(x)s', {'x': 1.0})
+ rset = self.qexecute('Any %(x)s', {'x': 1.0})
self.assertEqual(rset.description[0][0], 'Float')
- rset = self.execute('Any %(x)s', {'x': datetime.now()})
+ rset = self.qexecute('Any %(x)s', {'x': datetime.now()})
self.assertEqual(rset.description[0][0], 'Datetime')
- rset = self.execute('Any %(x)s', {'x': 'str'})
+ rset = self.qexecute('Any %(x)s', {'x': 'str'})
self.assertEqual(rset.description[0][0], 'String')
- rset = self.execute('Any %(x)s', {'x': u'str'})
+ rset = self.qexecute('Any %(x)s', {'x': u'str'})
self.assertEqual(rset.description[0][0], 'String')
def test_build_descr1(self):
- rset = self.execute('(Any U,L WHERE U login L) UNION (Any G,N WHERE G name N, G is CWGroup)')
- rset.req = self.session
- orig_length = len(rset)
- rset.rows[0][0] = 9999999
- description = manual_build_descr(rset.req, rset.syntax_tree(), None, rset.rows)
- self.assertEqual(len(description), orig_length - 1)
- self.assertEqual(len(rset.rows), orig_length - 1)
- self.assertNotEqual(rset.rows[0][0], 9999999)
+ with self.session.new_cnx() as cnx:
+ rset = cnx.execute('(Any U,L WHERE U login L) UNION '
+ '(Any G,N WHERE G name N, G is CWGroup)')
+ # rset.req = self.session
+ orig_length = len(rset)
+ rset.rows[0][0] = 9999999
+ description = manual_build_descr(cnx, rset.syntax_tree(), None, rset.rows)
+ self.assertEqual(len(description), orig_length - 1)
+ self.assertEqual(len(rset.rows), orig_length - 1)
+ self.assertNotEqual(rset.rows[0][0], 9999999)
def test_build_descr2(self):
- rset = self.execute('Any X,Y WITH X,Y BEING ((Any G,NULL WHERE G is CWGroup) UNION (Any U,G WHERE U in_group G))')
+ rset = self.qexecute('Any X,Y WITH X,Y BEING ((Any G,NULL WHERE G is CWGroup) UNION '
+ '(Any U,G WHERE U in_group G))')
for x, y in rset.description:
if y is not None:
self.assertEqual(y, 'CWGroup')
def test_build_descr3(self):
- rset = self.execute('(Any G,NULL WHERE G is CWGroup) UNION (Any U,G WHERE U in_group G)')
+ rset = self.qexecute('(Any G,NULL WHERE G is CWGroup) UNION '
+ '(Any U,G WHERE U in_group G)')
for x, y in rset.description:
if y is not None:
self.assertEqual(y, 'CWGroup')
@@ -281,284 +307,298 @@
tearDownClass = classmethod(tearDownClass)
def test_encoding_pb(self):
- self.assertRaises(RQLSyntaxError, self.execute,
+ self.assertRaises(RQLSyntaxError, self.qexecute,
'Any X WHERE X is CWRType, X name "öwned_by"')
def test_unknown_eid(self):
# should return an empty result set
- self.assertFalse(self.execute('Any X WHERE X eid 99999999'))
+ self.assertFalse(self.qexecute('Any X WHERE X eid 99999999'))
def test_typed_eid(self):
# should return an empty result set
- rset = self.execute('Any X WHERE X eid %(x)s', {'x': '1'})
+ rset = self.qexecute('Any X WHERE X eid %(x)s', {'x': '1'})
self.assertIsInstance(rset[0][0], (int, long))
def test_bytes_storage(self):
- feid = self.execute('INSERT File X: X data_name "foo.pdf", X data_format "text/plain", X data %(data)s',
+ feid = self.qexecute('INSERT File X: X data_name "foo.pdf", '
+ 'X data_format "text/plain", X data %(data)s',
{'data': Binary("xxx")})[0][0]
- fdata = self.execute('Any D WHERE X data D, X eid %(x)s', {'x': feid})[0][0]
+ fdata = self.qexecute('Any D WHERE X data D, X eid %(x)s', {'x': feid})[0][0]
self.assertIsInstance(fdata, Binary)
self.assertEqual(fdata.getvalue(), 'xxx')
# selection queries tests #################################################
def test_select_1(self):
- rset = self.execute('Any X ORDERBY X WHERE X is CWGroup')
+ rset = self.qexecute('Any X ORDERBY X WHERE X is CWGroup')
result, descr = rset.rows, rset.description
self.assertEqual(tuplify(result), [(2,), (3,), (4,), (5,)])
self.assertEqual(descr, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
def test_select_2(self):
- rset = self.execute('Any X ORDERBY N WHERE X is CWGroup, X name N')
+ rset = self.qexecute('Any X ORDERBY N WHERE X is CWGroup, X name N')
self.assertEqual(tuplify(rset.rows), [(2,), (3,), (4,), (5,)])
self.assertEqual(rset.description, [('CWGroup',), ('CWGroup',), ('CWGroup',), ('CWGroup',)])
- rset = self.execute('Any X ORDERBY N DESC WHERE X is CWGroup, X name N')
+ rset = self.qexecute('Any X ORDERBY N DESC WHERE X is CWGroup, X name N')
self.assertEqual(tuplify(rset.rows), [(5,), (4,), (3,), (2,)])
def test_select_3(self):
- rset = self.execute('Any N GROUPBY N WHERE X is CWGroup, X name N')
+ rset = self.qexecute('Any N GROUPBY N WHERE X is CWGroup, X name N')
result, descr = rset.rows, rset.description
result.sort()
self.assertEqual(tuplify(result), [('guests',), ('managers',), ('owners',), ('users',)])
self.assertEqual(descr, [('String',), ('String',), ('String',), ('String',)])
def test_select_is(self):
- rset = self.execute('Any X, TN ORDERBY TN LIMIT 10 WHERE X is T, T name TN')
+ rset = self.qexecute('Any X, TN ORDERBY TN LIMIT 10 WHERE X is T, T name TN')
result, descr = rset.rows, rset.description
self.assertEqual(result[0][1], descr[0][0])
def test_select_is_aggr(self):
- rset = self.execute('Any TN, COUNT(X) GROUPBY TN ORDERBY 2 DESC WHERE X is T, T name TN')
+ rset = self.qexecute('Any TN, COUNT(X) GROUPBY TN ORDERBY 2 DESC WHERE X is T, T name TN')
result, descr = rset.rows, rset.description
self.assertEqual(descr[0][0], 'String')
self.assertEqual(descr[0][1], 'Int')
self.assertEqual(result[0][0], 'CWRelation') # XXX may change as schema evolve
def test_select_groupby_orderby(self):
- rset = self.execute('Any N GROUPBY N ORDERBY N WHERE X is CWGroup, X name N')
+ rset = self.qexecute('Any N GROUPBY N ORDERBY N WHERE X is CWGroup, X name N')
self.assertEqual(tuplify(rset.rows), [('guests',), ('managers',), ('owners',), ('users',)])
self.assertEqual(rset.description, [('String',), ('String',), ('String',), ('String',)])
def test_select_complex_groupby(self):
- rset = self.execute('Any N GROUPBY N WHERE X name N')
- rset = self.execute('Any N,MAX(D) GROUPBY N LIMIT 5 WHERE X name N, X creation_date D')
+ rset = self.qexecute('Any N GROUPBY N WHERE X name N')
+ rset = self.qexecute('Any N,MAX(D) GROUPBY N LIMIT 5 WHERE X name N, X creation_date D')
def test_select_inlined_groupby(self):
- seid = self.execute('State X WHERE X name "deactivated"')[0][0]
- rset = self.execute('Any U,L,S GROUPBY U,L,S WHERE X in_state S, U login L, S eid %s' % seid)
+ seid = self.qexecute('State X WHERE X name "deactivated"')[0][0]
+ rset = self.qexecute('Any U,L,S GROUPBY U,L,S WHERE X in_state S, U login L, S eid %s' % seid)
def test_select_groupby_funccall(self):
- rset = self.execute('Any YEAR(CD), COUNT(X) GROUPBY YEAR(CD) WHERE X is CWUser, X creation_date CD')
+ rset = self.qexecute('Any YEAR(CD), COUNT(X) GROUPBY YEAR(CD) '
+ 'WHERE X is CWUser, X creation_date CD')
self.assertListEqual(rset.rows, [[date.today().year, 2]])
def test_select_groupby_colnumber(self):
- rset = self.execute('Any YEAR(CD), COUNT(X) GROUPBY 1 WHERE X is CWUser, X creation_date CD')
+ rset = self.qexecute('Any YEAR(CD), COUNT(X) GROUPBY 1 '
+ 'WHERE X is CWUser, X creation_date CD')
self.assertListEqual(rset.rows, [[date.today().year, 2]])
def test_select_complex_orderby(self):
- rset1 = self.execute('Any N ORDERBY N WHERE X name N')
+ rset1 = self.qexecute('Any N ORDERBY N WHERE X name N')
self.assertEqual(sorted(rset1.rows), rset1.rows)
- rset = self.execute('Any N ORDERBY N LIMIT 5 OFFSET 1 WHERE X name N')
+ rset = self.qexecute('Any N ORDERBY N LIMIT 5 OFFSET 1 WHERE X name N')
self.assertEqual(rset.rows[0][0], rset1.rows[1][0])
self.assertEqual(len(rset), 5)
def test_select_5(self):
- rset = self.execute('Any X, TMP ORDERBY TMP WHERE X name TMP, X is CWGroup')
- self.assertEqual(tuplify(rset.rows), [(2, 'guests',), (3, 'managers',), (4, 'owners',), (5, 'users',)])
- self.assertEqual(rset.description, [('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',), ('CWGroup', 'String',)])
+ rset = self.qexecute('Any X, TMP ORDERBY TMP WHERE X name TMP, X is CWGroup')
+ self.assertEqual(tuplify(rset.rows),
+ [(2, 'guests',),
+ (3, 'managers',),
+ (4, 'owners',),
+ (5, 'users',)])
+ self.assertEqual(rset.description,
+ [('CWGroup', 'String',),
+ ('CWGroup', 'String',),
+ ('CWGroup', 'String',),
+ ('CWGroup', 'String',)])
def test_select_6(self):
- self.execute("INSERT Personne X: X nom 'bidule'")[0]
- rset = self.execute('Any Y where X name TMP, Y nom in (TMP, "bidule")')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")[0]
+ rset = self.qexecute('Any Y where X name TMP, Y nom in (TMP, "bidule")')
#self.assertEqual(rset.description, [('Personne',), ('Personne',)])
self.assertIn(('Personne',), rset.description)
- rset = self.execute('DISTINCT Any Y where X name TMP, Y nom in (TMP, "bidule")')
+ rset = self.qexecute('DISTINCT Any Y where X name TMP, Y nom in (TMP, "bidule")')
self.assertIn(('Personne',), rset.description)
def test_select_not_attr(self):
- peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- seid = self.execute("INSERT Societe X: X nom 'chouette'")[0][0]
- rset = self.execute('Personne X WHERE NOT X nom "bidule"')
+ peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ seid = self.qexecute("INSERT Societe X: X nom 'chouette'")[0][0]
+ rset = self.qexecute('Personne X WHERE NOT X nom "bidule"')
self.assertEqual(len(rset.rows), 0, rset.rows)
- rset = self.execute('Personne X WHERE NOT X nom "bid"')
+ rset = self.qexecute('Personne X WHERE NOT X nom "bid"')
self.assertEqual(len(rset.rows), 1, rset.rows)
- self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
- rset = self.execute('Personne X WHERE NOT X travaille S')
+ self.qexecute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
+ rset = self.qexecute('Personne X WHERE NOT X travaille S')
self.assertEqual(len(rset.rows), 0, rset.rows)
def test_select_is_in(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Societe X: X nom 'chouette'")
- self.assertEqual(len(self.execute("Any X WHERE X is IN (Personne, Societe)")),
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Societe X: X nom 'chouette'")
+ self.assertEqual(len(self.qexecute("Any X WHERE X is IN (Personne, Societe)")),
2)
def test_select_not_rel(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Societe X: X nom 'chouette'")
- self.execute("INSERT Personne X: X nom 'autre'")
- self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
- rset = self.execute('Personne X WHERE NOT X travaille S')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Societe X: X nom 'chouette'")
+ self.qexecute("INSERT Personne X: X nom 'autre'")
+ self.qexecute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
+ rset = self.qexecute('Personne X WHERE NOT X travaille S')
self.assertEqual(len(rset.rows), 1, rset.rows)
- rset = self.execute('Personne X WHERE NOT X travaille S, S nom "chouette"')
+ rset = self.qexecute('Personne X WHERE NOT X travaille S, S nom "chouette"')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_nonregr_inlined(self):
- self.execute("INSERT Note X: X para 'bidule'")
- self.execute("INSERT Personne X: X nom 'chouette'")
- self.execute("INSERT Personne X: X nom 'autre'")
- self.execute("SET X ecrit_par P WHERE X para 'bidule', P nom 'chouette'")
- rset = self.execute('Any U,T ORDERBY T DESC WHERE U is CWUser, '
- 'N ecrit_par U, N type T')#, {'x': self.ueid})
+ self.qexecute("INSERT Note X: X para 'bidule'")
+ self.qexecute("INSERT Personne X: X nom 'chouette'")
+ self.qexecute("INSERT Personne X: X nom 'autre'")
+ self.qexecute("SET X ecrit_par P WHERE X para 'bidule', P nom 'chouette'")
+ rset = self.qexecute('Any U,T ORDERBY T DESC WHERE U is CWUser, '
+ 'N ecrit_par U, N type T')#, {'x': self.ueid})
self.assertEqual(len(rset.rows), 0)
def test_select_nonregr_edition_not(self):
groupeids = set((2, 3, 4))
- groupreadperms = set(r[0] for r in self.execute('Any Y WHERE X name "CWGroup", Y eid IN(2, 3, 4), X read_permission Y'))
- rset = self.execute('DISTINCT Any Y WHERE X is CWEType, X name "CWGroup", Y eid IN(2, 3, 4), NOT X read_permission Y')
+ groupreadperms = set(r[0] for r in self.qexecute('Any Y WHERE X name "CWGroup", '
+ 'Y eid IN(2, 3, 4), X read_permission Y'))
+ rset = self.qexecute('DISTINCT Any Y WHERE X is CWEType, X name "CWGroup", '
+ 'Y eid IN(2, 3, 4), NOT X read_permission Y')
self.assertEqual(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
- rset = self.execute('DISTINCT Any Y WHERE X name "CWGroup", Y eid IN(2, 3, 4), NOT X read_permission Y')
+ rset = self.qexecute('DISTINCT Any Y WHERE X name "CWGroup", '
+ 'Y eid IN(2, 3, 4), NOT X read_permission Y')
self.assertEqual(sorted(r[0] for r in rset.rows), sorted(groupeids - groupreadperms))
def test_select_outer_join(self):
- peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- peid2 = self.execute("INSERT Personne X: X nom 'autre'")[0][0]
- seid1 = self.execute("INSERT Societe X: X nom 'chouette'")[0][0]
- seid2 = self.execute("INSERT Societe X: X nom 'chouetos'")[0][0]
- rset = self.execute('Any X,S ORDERBY X WHERE X travaille S?')
+ peid1 = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ peid2 = self.qexecute("INSERT Personne X: X nom 'autre'")[0][0]
+ seid1 = self.qexecute("INSERT Societe X: X nom 'chouette'")[0][0]
+ seid2 = self.qexecute("INSERT Societe X: X nom 'chouetos'")[0][0]
+ rset = self.qexecute('Any X,S ORDERBY X WHERE X travaille S?')
self.assertEqual(rset.rows, [[peid1, None], [peid2, None]])
- self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
- rset = self.execute('Any X,S ORDERBY X WHERE X travaille S?')
+ self.qexecute("SET P travaille S WHERE P nom 'bidule', S nom 'chouette'")
+ rset = self.qexecute('Any X,S ORDERBY X WHERE X travaille S?')
self.assertEqual(rset.rows, [[peid1, seid1], [peid2, None]])
- rset = self.execute('Any S,X ORDERBY S WHERE X? travaille S')
+ rset = self.qexecute('Any S,X ORDERBY S WHERE X? travaille S')
self.assertEqual(rset.rows, [[seid1, peid1], [seid2, None]])
def test_select_outer_join_optimized(self):
- peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- rset = self.execute('Any X WHERE X eid %(x)s, P? connait X', {'x':peid1})
+ peid1 = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ rset = self.qexecute('Any X WHERE X eid %(x)s, P? connait X', {'x':peid1})
self.assertEqual(rset.rows, [[peid1]])
- rset = self.execute('Any X WHERE X eid %(x)s, X require_permission P?',
+ rset = self.qexecute('Any X WHERE X eid %(x)s, X require_permission P?',
{'x':peid1})
self.assertEqual(rset.rows, [[peid1]])
def test_select_left_outer_join(self):
- rset = self.execute('DISTINCT Any G WHERE U? in_group G')
+ rset = self.qexecute('DISTINCT Any G WHERE U? in_group G')
self.assertEqual(len(rset), 4)
- rset = self.execute('DISTINCT Any G WHERE U? in_group G, U eid %(x)s',
+ rset = self.qexecute('DISTINCT Any G WHERE U? in_group G, U eid %(x)s',
{'x': self.session.user.eid})
self.assertEqual(len(rset), 4)
def test_select_ambigous_outer_join(self):
- teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
- self.execute("INSERT Tag X: X name 'tagbis'")[0][0]
- geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
- self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
+ teid = self.qexecute("INSERT Tag X: X name 'tag'")[0][0]
+ self.qexecute("INSERT Tag X: X name 'tagbis'")[0][0]
+ geid = self.qexecute("CWGroup G WHERE G name 'users'")[0][0]
+ self.qexecute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
{'g': geid, 't': teid})
- rset = self.execute("Any GN,TN ORDERBY GN WHERE T? tags G, T name TN, G name GN")
+ rset = self.qexecute("Any GN,TN ORDERBY GN WHERE T? tags G, T name TN, G name GN")
self.assertIn(['users', 'tag'], rset.rows)
self.assertIn(['activated', None], rset.rows)
- rset = self.execute("Any GN,TN ORDERBY GN WHERE T tags G?, T name TN, G name GN")
+ rset = self.qexecute("Any GN,TN ORDERBY GN WHERE T tags G?, T name TN, G name GN")
self.assertEqual(rset.rows, [[None, 'tagbis'], ['users', 'tag']])
def test_select_not_inline_rel(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Note X: X type 'a'")
- self.execute("INSERT Note X: X type 'b'")
- self.execute("SET X ecrit_par Y WHERE X type 'a', Y nom 'bidule'")
- rset = self.execute('Note X WHERE NOT X ecrit_par P')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Note X: X type 'a'")
+ self.qexecute("INSERT Note X: X type 'b'")
+ self.qexecute("SET X ecrit_par Y WHERE X type 'a', Y nom 'bidule'")
+ rset = self.qexecute('Note X WHERE NOT X ecrit_par P')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_not_unlinked_multiple_solutions(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Note X: X type 'a'")
- self.execute("INSERT Note X: X type 'b'")
- self.execute("SET Y evaluee X WHERE X type 'a', Y nom 'bidule'")
- rset = self.execute('Note X WHERE NOT Y evaluee X')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Note X: X type 'a'")
+ self.qexecute("INSERT Note X: X type 'b'")
+ self.qexecute("SET Y evaluee X WHERE X type 'a', Y nom 'bidule'")
+ rset = self.qexecute('Note X WHERE NOT Y evaluee X')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_date_extraction(self):
- self.execute("INSERT Personne X: X nom 'foo', X datenaiss %(d)s",
+ self.qexecute("INSERT Personne X: X nom 'foo', X datenaiss %(d)s",
{'d': datetime(2001, 2,3, 12,13)})
test_data = [('YEAR', 2001), ('MONTH', 2), ('DAY', 3),
('HOUR', 12), ('MINUTE', 13), ('WEEKDAY', 6)]
for funcname, result in test_data:
- rset = self.execute('Any %s(D) WHERE X is Personne, X datenaiss D'
+ rset = self.qexecute('Any %s(D) WHERE X is Personne, X datenaiss D'
% funcname)
self.assertEqual(len(rset.rows), 1)
self.assertEqual(rset.rows[0][0], result)
self.assertEqual(rset.description, [('Int',)])
def test_regexp_based_pattern_matching(self):
- peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- peid2 = self.execute("INSERT Personne X: X nom 'cidule'")[0][0]
- rset = self.execute('Any X WHERE X is Personne, X nom REGEXP "^b"')
+ peid1 = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ peid2 = self.qexecute("INSERT Personne X: X nom 'cidule'")[0][0]
+ rset = self.qexecute('Any X WHERE X is Personne, X nom REGEXP "^b"')
self.assertEqual(len(rset.rows), 1, rset.rows)
self.assertEqual(rset.rows[0][0], peid1)
- rset = self.execute('Any X WHERE X is Personne, X nom REGEXP "idu"')
+ rset = self.qexecute('Any X WHERE X is Personne, X nom REGEXP "idu"')
self.assertEqual(len(rset.rows), 2, rset.rows)
def test_select_aggregat_count(self):
- rset = self.execute('Any COUNT(X)')
+ rset = self.qexecute('Any COUNT(X)')
self.assertEqual(len(rset.rows), 1)
self.assertEqual(len(rset.rows[0]), 1)
self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_sum(self):
- rset = self.execute('Any SUM(O) WHERE X ordernum O')
+ rset = self.qexecute('Any SUM(O) WHERE X ordernum O')
self.assertEqual(len(rset.rows), 1)
self.assertEqual(len(rset.rows[0]), 1)
self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_min(self):
- rset = self.execute('Any MIN(X) WHERE X is Personne')
+ rset = self.qexecute('Any MIN(X) WHERE X is Personne')
self.assertEqual(len(rset.rows), 1)
self.assertEqual(len(rset.rows[0]), 1)
self.assertEqual(rset.description, [('Personne',)])
- rset = self.execute('Any MIN(O) WHERE X ordernum O')
+ rset = self.qexecute('Any MIN(O) WHERE X ordernum O')
self.assertEqual(len(rset.rows), 1)
self.assertEqual(len(rset.rows[0]), 1)
self.assertEqual(rset.description, [('Int',)])
def test_select_aggregat_max(self):
- rset = self.execute('Any MAX(X) WHERE X is Personne')
+ rset = self.qexecute('Any MAX(X) WHERE X is Personne')
self.assertEqual(len(rset.rows), 1)
self.assertEqual(len(rset.rows[0]), 1)
self.assertEqual(rset.description, [('Personne',)])
- rset = self.execute('Any MAX(O) WHERE X ordernum O')
+ rset = self.qexecute('Any MAX(O) WHERE X ordernum O')
self.assertEqual(len(rset.rows), 1)
self.assertEqual(len(rset.rows[0]), 1)
self.assertEqual(rset.description, [('Int',)])
def test_select_custom_aggregat_concat_string(self):
- rset = self.execute('Any GROUP_CONCAT(N) WHERE X is CWGroup, X name N')
+ rset = self.qexecute('Any GROUP_CONCAT(N) WHERE X is CWGroup, X name N')
self.assertTrue(rset)
self.assertEqual(sorted(rset[0][0].split(', ')), ['guests', 'managers',
'owners', 'users'])
def test_select_custom_regproc_limit_size(self):
- rset = self.execute('Any TEXT_LIMIT_SIZE(N, 3) WHERE X is CWGroup, X name N, X name "managers"')
+ rset = self.qexecute('Any TEXT_LIMIT_SIZE(N, 3) WHERE X is CWGroup, X name N, X name "managers"')
self.assertTrue(rset)
self.assertEqual(rset[0][0], 'man...')
- self.execute("INSERT Basket X: X name 'bidule', X description 'hop hop', X description_format 'text/html'")
- rset = self.execute('Any LIMIT_SIZE(D, DF, 3) WHERE X is Basket, X description D, X description_format DF')
+ self.qexecute("INSERT Basket X: X name 'bidule', X description 'hop hop', X description_format 'text/html'")
+ rset = self.qexecute('Any LIMIT_SIZE(D, DF, 3) WHERE X is Basket, X description D, X description_format DF')
self.assertTrue(rset)
self.assertEqual(rset[0][0], 'hop...')
def test_select_regproc_orderby(self):
- rset = self.execute('DISTINCT Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N, X name "managers"')
+ rset = self.qexecute('DISTINCT Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N, X name "managers"')
self.assertEqual(len(rset), 1)
self.assertEqual(rset[0][1], 'managers')
- rset = self.execute('Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N, NOT U in_group X, U login "admin"')
+ rset = self.qexecute('Any X,N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N, NOT U in_group X, U login "admin"')
self.assertEqual(len(rset), 3)
self.assertEqual(rset[0][1], 'owners')
def test_select_aggregat_sort(self):
- rset = self.execute('Any G, COUNT(U) GROUPBY G ORDERBY 2 WHERE U in_group G')
+ rset = self.qexecute('Any G, COUNT(U) GROUPBY G ORDERBY 2 WHERE U in_group G')
self.assertEqual(len(rset.rows), 2)
self.assertEqual(len(rset.rows[0]), 2)
self.assertEqual(rset.description[0], ('CWGroup', 'Int',))
def test_select_aggregat_having(self):
- rset = self.execute('Any N,COUNT(RDEF) GROUPBY N ORDERBY 2,N '
+ rset = self.qexecute('Any N,COUNT(RDEF) GROUPBY N ORDERBY 2,N '
'WHERE RT name N, RDEF relation_type RT '
'HAVING COUNT(RDEF) > 10')
self.assertListEqual(rset.rows,
@@ -577,21 +617,21 @@
def test_select_aggregat_having_dumb(self):
# dumb but should not raise an error
- rset = self.execute('Any U,COUNT(X) GROUPBY U '
+ rset = self.qexecute('Any U,COUNT(X) GROUPBY U '
'WHERE U eid %(x)s, X owned_by U '
'HAVING COUNT(X) > 10', {'x': self.ueid})
self.assertEqual(len(rset.rows), 1)
self.assertEqual(rset.rows[0][0], self.ueid)
def test_select_having_non_aggregat_1(self):
- rset = self.execute('Any L WHERE X login L, X creation_date CD '
+ rset = self.qexecute('Any L WHERE X login L, X creation_date CD '
'HAVING YEAR(CD) = %s' % date.today().year)
self.assertListEqual(rset.rows,
[[u'admin'],
[u'anon']])
def test_select_having_non_aggregat_2(self):
- rset = self.execute('Any L GROUPBY L WHERE X login L, X in_group G, '
+ rset = self.qexecute('Any L GROUPBY L WHERE X login L, X in_group G, '
'X creation_date CD HAVING YEAR(CD) = %s OR COUNT(G) > 1'
% date.today().year)
self.assertListEqual(rset.rows,
@@ -600,226 +640,225 @@
def test_select_complex_sort(self):
"""need sqlite including http://www.sqlite.org/cvstrac/tktview?tn=3773 fix"""
- rset = self.execute('Any X ORDERBY X,D LIMIT 5 WHERE X creation_date D')
+ rset = self.qexecute('Any X ORDERBY X,D LIMIT 5 WHERE X creation_date D')
result = rset.rows
result.sort()
self.assertEqual(tuplify(result), [(1,), (2,), (3,), (4,), (5,)])
def test_select_upper(self):
- rset = self.execute('Any X, UPPER(L) ORDERBY L WHERE X is CWUser, X login L')
+ rset = self.qexecute('Any X, UPPER(L) ORDERBY L WHERE X is CWUser, X login L')
self.assertEqual(len(rset.rows), 2)
self.assertEqual(rset.rows[0][1], 'ADMIN')
self.assertEqual(rset.description[0], ('CWUser', 'String',))
self.assertEqual(rset.rows[1][1], 'ANON')
self.assertEqual(rset.description[1], ('CWUser', 'String',))
eid = rset.rows[0][0]
- rset = self.execute('Any UPPER(L) WHERE X eid %s, X login L'%eid)
+ rset = self.qexecute('Any UPPER(L) WHERE X eid %s, X login L'%eid)
self.assertEqual(rset.rows[0][0], 'ADMIN')
self.assertEqual(rset.description, [('String',)])
def test_select_float_abs(self):
# test positive number
- eid = self.execute('INSERT Affaire A: A invoiced %(i)s', {'i': 1.2})[0][0]
- rset = self.execute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
+ eid = self.qexecute('INSERT Affaire A: A invoiced %(i)s', {'i': 1.2})[0][0]
+ rset = self.qexecute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
self.assertEqual(rset.rows[0][0], 1.2)
# test negative number
- eid = self.execute('INSERT Affaire A: A invoiced %(i)s', {'i': -1.2})[0][0]
- rset = self.execute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
+ eid = self.qexecute('INSERT Affaire A: A invoiced %(i)s', {'i': -1.2})[0][0]
+ rset = self.qexecute('Any ABS(I) WHERE X eid %(x)s, X invoiced I', {'x': eid})
self.assertEqual(rset.rows[0][0], 1.2)
def test_select_int_abs(self):
# test positive number
- eid = self.execute('INSERT Affaire A: A duration %(d)s', {'d': 12})[0][0]
- rset = self.execute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
+ eid = self.qexecute('INSERT Affaire A: A duration %(d)s', {'d': 12})[0][0]
+ rset = self.qexecute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
self.assertEqual(rset.rows[0][0], 12)
# test negative number
- eid = self.execute('INSERT Affaire A: A duration %(d)s', {'d': -12})[0][0]
- rset = self.execute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
+ eid = self.qexecute('INSERT Affaire A: A duration %(d)s', {'d': -12})[0][0]
+ rset = self.qexecute('Any ABS(D) WHERE X eid %(x)s, X duration D', {'x': eid})
self.assertEqual(rset.rows[0][0], 12)
## def test_select_simplified(self):
## ueid = self.session.user.eid
-## rset = self.execute('Any L WHERE %s login L'%ueid)
+## rset = self.qexecute('Any L WHERE %s login L'%ueid)
## self.assertEqual(rset.rows[0][0], 'admin')
-## rset = self.execute('Any L WHERE %(x)s login L', {'x':ueid})
+## rset = self.qexecute('Any L WHERE %(x)s login L', {'x':ueid})
## self.assertEqual(rset.rows[0][0], 'admin')
def test_select_searchable_text_1(self):
- rset = self.execute(u"INSERT Personne X: X nom 'bidüle'")
- rset = self.execute(u"INSERT Societe X: X nom 'bidüle'")
- rset = self.execute("INSERT Societe X: X nom 'chouette'")
- self.commit()
- rset = self.execute('Any X where X has_text %(text)s', {'text': u'bidüle'})
+ rset = self.qexecute(u"INSERT Personne X: X nom 'bidüle'")
+ rset = self.qexecute(u"INSERT Societe X: X nom 'bidüle'")
+ rset = self.qexecute("INSERT Societe X: X nom 'chouette'")
+ rset = self.qexecute('Any X where X has_text %(text)s', {'text': u'bidüle'})
self.assertEqual(len(rset.rows), 2, rset.rows)
- rset = self.execute(u'Any N where N has_text "bidüle"')
+ rset = self.qexecute(u'Any N where N has_text "bidüle"')
self.assertEqual(len(rset.rows), 2, rset.rows)
biduleeids = [r[0] for r in rset.rows]
- rset = self.execute(u'Any N where NOT N has_text "bidüle"')
+ rset = self.qexecute(u'Any N where NOT N has_text "bidüle"')
self.assertFalse([r[0] for r in rset.rows if r[0] in biduleeids])
# duh?
- rset = self.execute('Any X WHERE X has_text %(text)s', {'text': u'ça'})
+ rset = self.qexecute('Any X WHERE X has_text %(text)s', {'text': u'ça'})
def test_select_searchable_text_2(self):
- rset = self.execute("INSERT Personne X: X nom 'bidule'")
- rset = self.execute("INSERT Personne X: X nom 'chouette'")
- rset = self.execute("INSERT Societe X: X nom 'bidule'")
- self.commit()
- rset = self.execute('Personne N where N has_text "bidule"')
+ rset = self.qexecute("INSERT Personne X: X nom 'bidule'")
+ rset = self.qexecute("INSERT Personne X: X nom 'chouette'")
+ rset = self.qexecute("INSERT Societe X: X nom 'bidule'")
+ rset = self.qexecute('Personne N where N has_text "bidule"')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_searchable_text_3(self):
- rset = self.execute("INSERT Personne X: X nom 'bidule', X sexe 'M'")
- rset = self.execute("INSERT Personne X: X nom 'bidule', X sexe 'F'")
- rset = self.execute("INSERT Societe X: X nom 'bidule'")
- self.commit()
- rset = self.execute('Any X where X has_text "bidule" and X sexe "M"')
+ rset = self.qexecute("INSERT Personne X: X nom 'bidule', X sexe 'M'")
+ rset = self.qexecute("INSERT Personne X: X nom 'bidule', X sexe 'F'")
+ rset = self.qexecute("INSERT Societe X: X nom 'bidule'")
+ rset = self.qexecute('Any X where X has_text "bidule" and X sexe "M"')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_multiple_searchable_text(self):
- self.execute(u"INSERT Personne X: X nom 'bidüle'")
- self.execute("INSERT Societe X: X nom 'chouette', S travaille X")
- self.execute(u"INSERT Personne X: X nom 'bidüle'")
- self.commit()
- rset = self.execute('Personne X WHERE X has_text %(text)s, X travaille S, S has_text %(text2)s',
+ self.qexecute(u"INSERT Personne X: X nom 'bidüle'")
+ self.qexecute("INSERT Societe X: X nom 'chouette', S travaille X")
+ self.qexecute(u"INSERT Personne X: X nom 'bidüle'")
+ rset = self.qexecute('Personne X WHERE X has_text %(text)s, X travaille S, S has_text %(text2)s',
{'text': u'bidüle',
'text2': u'chouette',}
)
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_no_descr(self):
- rset = self.execute('Any X WHERE X is CWGroup', build_descr=0)
+ rset = self.qexecute('Any X WHERE X is CWGroup', build_descr=0)
rset.rows.sort()
self.assertEqual(tuplify(rset.rows), [(2,), (3,), (4,), (5,)])
self.assertEqual(rset.description, ())
def test_select_limit_offset(self):
- rset = self.execute('CWGroup X ORDERBY N LIMIT 2 WHERE X name N')
+ rset = self.qexecute('CWGroup X ORDERBY N LIMIT 2 WHERE X name N')
self.assertEqual(tuplify(rset.rows), [(2,), (3,)])
self.assertEqual(rset.description, [('CWGroup',), ('CWGroup',)])
- rset = self.execute('CWGroup X ORDERBY N LIMIT 2 OFFSET 2 WHERE X name N')
+ rset = self.qexecute('CWGroup X ORDERBY N LIMIT 2 OFFSET 2 WHERE X name N')
self.assertEqual(tuplify(rset.rows), [(4,), (5,)])
def test_select_symmetric(self):
- self.execute("INSERT Personne X: X nom 'machin'")
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Personne X: X nom 'chouette'")
- self.execute("INSERT Personne X: X nom 'trucmuche'")
- self.execute("SET X connait Y WHERE X nom 'chouette', Y nom 'bidule'")
- self.execute("SET X connait Y WHERE X nom 'machin', Y nom 'chouette'")
- rset = self.execute('Any P WHERE P connait P2')
+ self.qexecute("INSERT Personne X: X nom 'machin'")
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Personne X: X nom 'chouette'")
+ self.qexecute("INSERT Personne X: X nom 'trucmuche'")
+ self.qexecute("SET X connait Y WHERE X nom 'chouette', Y nom 'bidule'")
+ self.qexecute("SET X connait Y WHERE X nom 'machin', Y nom 'chouette'")
+ rset = self.qexecute('Any P WHERE P connait P2')
self.assertEqual(len(rset.rows), 4, rset.rows)
- rset = self.execute('Any P WHERE NOT P connait P2')
+ rset = self.qexecute('Any P WHERE NOT P connait P2')
self.assertEqual(len(rset.rows), 1, rset.rows) # trucmuche
- rset = self.execute('Any P WHERE P connait P2, P2 nom "bidule"')
+ rset = self.qexecute('Any P WHERE P connait P2, P2 nom "bidule"')
self.assertEqual(len(rset.rows), 1, rset.rows)
- rset = self.execute('Any P WHERE P2 connait P, P2 nom "bidule"')
+ rset = self.qexecute('Any P WHERE P2 connait P, P2 nom "bidule"')
self.assertEqual(len(rset.rows), 1, rset.rows)
- rset = self.execute('Any P WHERE P connait P2, P2 nom "chouette"')
+ rset = self.qexecute('Any P WHERE P connait P2, P2 nom "chouette"')
self.assertEqual(len(rset.rows), 2, rset.rows)
- rset = self.execute('Any P WHERE P2 connait P, P2 nom "chouette"')
+ rset = self.qexecute('Any P WHERE P2 connait P, P2 nom "chouette"')
self.assertEqual(len(rset.rows), 2, rset.rows)
def test_select_inline(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Note X: X type 'a'")
- self.execute("SET X ecrit_par Y WHERE X type 'a', Y nom 'bidule'")
- rset = self.execute('Any N where N ecrit_par X, X nom "bidule"')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Note X: X type 'a'")
+ self.qexecute("SET X ecrit_par Y WHERE X type 'a', Y nom 'bidule'")
+ rset = self.qexecute('Any N where N ecrit_par X, X nom "bidule"')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_creation_date(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- rset = self.execute('Any D WHERE X nom "bidule", X creation_date D')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ rset = self.qexecute('Any D WHERE X nom "bidule", X creation_date D')
self.assertEqual(len(rset.rows), 1)
def test_select_or_relation(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Personne X: X nom 'chouette'")
- self.execute("INSERT Societe X: X nom 'logilab'")
- self.execute("INSERT Societe X: X nom 'caesium'")
- self.execute("SET P travaille S WHERE P nom 'bidule', S nom 'logilab'")
- rset = self.execute('DISTINCT Any P WHERE P travaille S1 OR P travaille S2, S1 nom "logilab", S2 nom "caesium"')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Personne X: X nom 'chouette'")
+ self.qexecute("INSERT Societe X: X nom 'logilab'")
+ self.qexecute("INSERT Societe X: X nom 'caesium'")
+ self.qexecute("SET P travaille S WHERE P nom 'bidule', S nom 'logilab'")
+ rset = self.qexecute('DISTINCT Any P WHERE P travaille S1 OR P travaille S2, '
+ 'S1 nom "logilab", S2 nom "caesium"')
self.assertEqual(len(rset.rows), 1)
- self.execute("SET P travaille S WHERE P nom 'chouette', S nom 'caesium'")
- rset = self.execute('DISTINCT Any P WHERE P travaille S1 OR P travaille S2, S1 nom "logilab", S2 nom "caesium"')
+ self.qexecute("SET P travaille S WHERE P nom 'chouette', S nom 'caesium'")
+ rset = self.qexecute('DISTINCT Any P WHERE P travaille S1 OR P travaille S2, '
+ 'S1 nom "logilab", S2 nom "caesium"')
self.assertEqual(len(rset.rows), 2)
def test_select_or_sym_relation(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Personne X: X nom 'chouette'")
- self.execute("INSERT Personne X: X nom 'truc'")
- self.execute("SET P connait S WHERE P nom 'bidule', S nom 'chouette'")
- rset = self.execute('DISTINCT Any P WHERE S connait P, S nom "chouette"')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Personne X: X nom 'chouette'")
+ self.qexecute("INSERT Personne X: X nom 'truc'")
+ self.qexecute("SET P connait S WHERE P nom 'bidule', S nom 'chouette'")
+ rset = self.qexecute('DISTINCT Any P WHERE S connait P, S nom "chouette"')
self.assertEqual(len(rset.rows), 1, rset.rows)
- rset = self.execute('DISTINCT Any P WHERE P connait S or S connait P, S nom "chouette"')
+ rset = self.qexecute('DISTINCT Any P WHERE P connait S or S connait P, S nom "chouette"')
self.assertEqual(len(rset.rows), 1, rset.rows)
- self.execute("SET P connait S WHERE P nom 'chouette', S nom 'truc'")
- rset = self.execute('DISTINCT Any P WHERE S connait P, S nom "chouette"')
+ self.qexecute("SET P connait S WHERE P nom 'chouette', S nom 'truc'")
+ rset = self.qexecute('DISTINCT Any P WHERE S connait P, S nom "chouette"')
self.assertEqual(len(rset.rows), 2, rset.rows)
- rset = self.execute('DISTINCT Any P WHERE P connait S OR S connait P, S nom "chouette"')
+ rset = self.qexecute('DISTINCT Any P WHERE P connait S OR S connait P, S nom "chouette"')
self.assertEqual(len(rset.rows), 2, rset.rows)
def test_select_follow_relation(self):
- self.execute("INSERT Affaire X: X sujet 'cool'")
- self.execute("INSERT Societe X: X nom 'chouette'")
- self.execute("SET A concerne S WHERE A is Affaire, S is Societe")
- self.execute("INSERT Note X: X para 'truc'")
- self.execute("SET S evaluee N WHERE S is Societe, N is Note")
- self.execute("INSERT Societe X: X nom 'bidule'")
- self.execute("INSERT Note X: X para 'troc'")
- self.execute("SET S evaluee N WHERE S nom 'bidule', N para 'troc'")
- rset = self.execute('DISTINCT Any A,N WHERE A concerne S, S evaluee N')
+ self.qexecute("INSERT Affaire X: X sujet 'cool'")
+ self.qexecute("INSERT Societe X: X nom 'chouette'")
+ self.qexecute("SET A concerne S WHERE A is Affaire, S is Societe")
+ self.qexecute("INSERT Note X: X para 'truc'")
+ self.qexecute("SET S evaluee N WHERE S is Societe, N is Note")
+ self.qexecute("INSERT Societe X: X nom 'bidule'")
+ self.qexecute("INSERT Note X: X para 'troc'")
+ self.qexecute("SET S evaluee N WHERE S nom 'bidule', N para 'troc'")
+ rset = self.qexecute('DISTINCT Any A,N WHERE A concerne S, S evaluee N')
self.assertEqual(len(rset.rows), 1, rset.rows)
def test_select_ordered_distinct_1(self):
self.assertRaises(BadRQLQuery,
- self.execute, 'DISTINCT Any S ORDERBY R WHERE A is Affaire, A sujet S, A ref R')
+ self.qexecute, 'DISTINCT Any S ORDERBY R WHERE A is Affaire, A sujet S, A ref R')
def test_select_ordered_distinct_2(self):
- self.execute("INSERT Affaire X: X sujet 'minor'")
- self.execute("INSERT Affaire X: X sujet 'zou'")
- self.execute("INSERT Affaire X: X sujet 'abcd'")
- rset = self.execute('DISTINCT Any S ORDERBY S WHERE A is Affaire, A sujet S')
+ self.qexecute("INSERT Affaire X: X sujet 'minor'")
+ self.qexecute("INSERT Affaire X: X sujet 'zou'")
+ self.qexecute("INSERT Affaire X: X sujet 'abcd'")
+ rset = self.qexecute('DISTINCT Any S ORDERBY S WHERE A is Affaire, A sujet S')
self.assertEqual(rset.rows, [['abcd'], ['minor'], ['zou']])
def test_select_ordered_distinct_3(self):
- rset = self.execute('DISTINCT Any N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N')
+ rset = self.qexecute('DISTINCT Any N ORDERBY GROUP_SORT_VALUE(N) WHERE X is CWGroup, X name N')
self.assertEqual(rset.rows, [['owners'], ['guests'], ['users'], ['managers']])
def test_select_or_value(self):
- rset = self.execute('Any U WHERE U in_group G, G name "owners" OR G name "users"')
+ rset = self.qexecute('Any U WHERE U in_group G, G name "owners" OR G name "users"')
self.assertEqual(len(rset.rows), 0)
- rset = self.execute('Any U WHERE U in_group G, G name "guests" OR G name "managers"')
+ rset = self.qexecute('Any U WHERE U in_group G, G name "guests" OR G name "managers"')
self.assertEqual(len(rset.rows), 2)
def test_select_explicit_eid(self):
- rset = self.execute('Any X,E WHERE X owned_by U, X eid E, U eid %(u)s', {'u': self.session.user.eid})
+ rset = self.qexecute('Any X,E WHERE X owned_by U, X eid E, U eid %(u)s',
+ {'u': self.session.user.eid})
self.assertTrue(rset)
self.assertEqual(rset.description[0][1], 'Int')
# def test_select_rewritten_optional(self):
-# eid = self.execute("INSERT Affaire X: X sujet 'cool'")[0][0]
-# rset = self.execute('Any X WHERE X eid %(x)s, EXISTS(X owned_by U) OR EXISTS(X concerne S?, S owned_by U)',
+# eid = self.qexecute("INSERT Affaire X: X sujet 'cool'")[0][0]
+# rset = self.qexecute('Any X WHERE X eid %(x)s, EXISTS(X owned_by U) OR EXISTS(X concerne S?, S owned_by U)',
# {'x': eid}, 'x')
# self.assertEqual(rset.rows, [[eid]])
def test_today_bug(self):
- self.execute("INSERT Tag X: X name 'bidule', X creation_date NOW")
- self.execute("INSERT Tag Y: Y name 'toto'")
- rset = self.execute("Any D WHERE X name in ('bidule', 'toto') , X creation_date D")
+ self.qexecute("INSERT Tag X: X name 'bidule', X creation_date NOW")
+ self.qexecute("INSERT Tag Y: Y name 'toto'")
+ rset = self.qexecute("Any D WHERE X name in ('bidule', 'toto') , X creation_date D")
self.assertIsInstance(rset.rows[0][0], datetime)
- rset = self.execute('Tag X WHERE X creation_date TODAY')
+ rset = self.qexecute('Tag X WHERE X creation_date TODAY')
self.assertEqual(len(rset.rows), 2)
- rset = self.execute('Any MAX(D) WHERE X is Tag, X creation_date D')
+ rset = self.qexecute('Any MAX(D) WHERE X is Tag, X creation_date D')
self.assertIsInstance(rset[0][0], datetime)
def test_today(self):
- self.execute("INSERT Tag X: X name 'bidule', X creation_date TODAY")
- self.execute("INSERT Tag Y: Y name 'toto'")
- rset = self.execute('Tag X WHERE X creation_date TODAY')
+ self.qexecute("INSERT Tag X: X name 'bidule', X creation_date TODAY")
+ self.qexecute("INSERT Tag Y: Y name 'toto'")
+ rset = self.qexecute('Tag X WHERE X creation_date TODAY')
self.assertEqual(len(rset.rows), 2)
def test_select_boolean(self):
- rset = self.execute('Any N WHERE X is CWEType, X name N, X final %(val)s',
+ rset = self.qexecute('Any N WHERE X is CWEType, X name N, X final %(val)s',
{'val': True})
self.assertEqual(sorted(r[0] for r in rset.rows), ['BigInt', 'Boolean', 'Bytes',
'Date', 'Datetime',
@@ -828,7 +867,7 @@
'Password', 'String',
'TZDatetime', 'TZTime',
'Time'])
- rset = self.execute('Any N WHERE X is CWEType, X name N, X final TRUE')
+ rset = self.qexecute('Any N WHERE X is CWEType, X name N, X final TRUE')
self.assertEqual(sorted(r[0] for r in rset.rows), ['BigInt', 'Boolean', 'Bytes',
'Date', 'Datetime',
'Decimal', 'Float',
@@ -836,32 +875,33 @@
'Password', 'String',
'TZDatetime', 'TZTime',
'Time'])
- req = self.session
- req.create_entity('Personne', nom=u'louis', test=True)
- self.assertEqual(len(req.execute('Any X WHERE X test %(val)s', {'val': True})), 1)
- self.assertEqual(len(req.execute('Any X WHERE X test TRUE')), 1)
- self.assertEqual(len(req.execute('Any X WHERE X test %(val)s', {'val': False})), 0)
- self.assertEqual(len(req.execute('Any X WHERE X test FALSE')), 0)
+ with self.session.new_cnx() as cnx:
+ cnx.create_entity('Personne', nom=u'louis', test=True)
+ self.assertEqual(len(cnx.execute('Any X WHERE X test %(val)s', {'val': True})), 1)
+ self.assertEqual(len(cnx.execute('Any X WHERE X test TRUE')), 1)
+ self.assertEqual(len(cnx.execute('Any X WHERE X test %(val)s', {'val': False})), 0)
+ self.assertEqual(len(cnx.execute('Any X WHERE X test FALSE')), 0)
def test_select_constant(self):
- rset = self.execute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
+ rset = self.qexecute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
self.assertEqual(rset.rows,
map(list, zip((2,3,4,5), ('toto','toto','toto','toto',))))
self.assertIsInstance(rset[0][1], unicode)
self.assertEqual(rset.description,
zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
('String', 'String', 'String', 'String',)))
- rset = self.execute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
+ rset = self.qexecute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
self.assertEqual(rset.rows,
map(list, zip((2,3,4,5), ('toto','toto','toto','toto',))))
self.assertIsInstance(rset[0][1], unicode)
self.assertEqual(rset.description,
zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
('String', 'String', 'String', 'String',)))
- rset = self.execute('Any X,GN WHERE X is CWUser, G is CWGroup, X login "syt", X in_group G, G name GN')
+ rset = self.qexecute('Any X,GN WHERE X is CWUser, G is CWGroup, X login "syt", '
+ 'X in_group G, G name GN')
def test_select_union(self):
- rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
+ rset = self.qexecute('Any X,N ORDERBY N WITH X,N BEING '
'((Any X,N WHERE X name N, X transition_of WF, WF workflow_of E, E name %(name)s)'
' UNION '
'(Any X,N WHERE X name N, X state_of WF, WF workflow_of E, E name %(name)s))',
@@ -875,23 +915,26 @@
def test_select_union_aggregat(self):
# meaningless, the goal in to have group by done on different attribute
# for each sub-query
- self.execute('(Any N,COUNT(X) GROUPBY N WHERE X name N, X is State)'
+ self.qexecute('(Any N,COUNT(X) GROUPBY N WHERE X name N, X is State)'
' UNION '
'(Any N,COUNT(X) GROUPBY N ORDERBY 2 WHERE X login N)')
def test_select_union_aggregat_independant_group(self):
- self.execute('INSERT State X: X name "hop"')
- self.execute('INSERT State X: X name "hop"')
- self.execute('INSERT Transition X: X name "hop"')
- self.execute('INSERT Transition X: X name "hop"')
- rset = self.execute('Any N,NX ORDERBY 2 WITH N,NX BEING '
- '((Any N,COUNT(X) GROUPBY N WHERE X name N, X is State HAVING COUNT(X)>1)'
- ' UNION '
- '(Any N,COUNT(X) GROUPBY N WHERE X name N, X is Transition HAVING COUNT(X)>1))')
- self.assertEqual(rset.rows, [[u'hop', 2], [u'hop', 2]])
+ with self.session.new_cnx() as cnx:
+ cnx.execute('INSERT State X: X name "hop"')
+ cnx.execute('INSERT State X: X name "hop"')
+ cnx.execute('INSERT Transition X: X name "hop"')
+ cnx.execute('INSERT Transition X: X name "hop"')
+ rset = cnx.execute('Any N,NX ORDERBY 2 WITH N,NX BEING '
+ '((Any N,COUNT(X) GROUPBY N WHERE X name N, '
+ ' X is State HAVING COUNT(X)>1)'
+ ' UNION '
+ '(Any N,COUNT(X) GROUPBY N WHERE X name N, '
+ ' X is Transition HAVING COUNT(X)>1))')
+ self.assertEqual(rset.rows, [[u'hop', 2], [u'hop', 2]])
def test_select_union_selection_with_diff_variables(self):
- rset = self.execute('(Any N WHERE X name N, X is State)'
+ rset = self.qexecute('(Any N WHERE X name N, X is State)'
' UNION '
'(Any NN WHERE XX name NN, XX is Transition)')
self.assertEqual(sorted(r[0] for r in rset.rows),
@@ -901,51 +944,51 @@
'start', 'todo'])
def test_select_union_description_diff_var(self):
- eid1 = self.execute('CWGroup X WHERE X name "managers"')[0][0]
- eid2 = self.execute('CWUser X WHERE X login "admin"')[0][0]
- rset = self.execute('(Any X WHERE X eid %(x)s)'
+ eid1 = self.qexecute('CWGroup X WHERE X name "managers"')[0][0]
+ eid2 = self.qexecute('CWUser X WHERE X login "admin"')[0][0]
+ rset = self.qexecute('(Any X WHERE X eid %(x)s)'
' UNION '
'(Any Y WHERE Y eid %(y)s)',
{'x': eid1, 'y': eid2})
self.assertEqual(rset.description[:], [('CWGroup',), ('CWUser',)])
def test_exists(self):
- geid = self.execute("INSERT CWGroup X: X name 'lulufanclub'")[0][0]
- self.execute("SET U in_group G WHERE G name 'lulufanclub'")
- peid = self.execute("INSERT Personne X: X prenom 'lulu', X nom 'petit'")[0][0]
- rset = self.execute("Any X WHERE X prenom 'lulu',"
+ geid = self.qexecute("INSERT CWGroup X: X name 'lulufanclub'")[0][0]
+ self.qexecute("SET U in_group G WHERE G name 'lulufanclub'")
+ peid = self.qexecute("INSERT Personne X: X prenom 'lulu', X nom 'petit'")[0][0]
+ rset = self.qexecute("Any X WHERE X prenom 'lulu',"
"EXISTS (U in_group G, G name 'lulufanclub' OR G name 'managers');")
self.assertEqual(rset.rows, [[peid]])
def test_identity(self):
- eid = self.execute('Any X WHERE X identity Y, Y eid 1')[0][0]
+ eid = self.qexecute('Any X WHERE X identity Y, Y eid 1')[0][0]
self.assertEqual(eid, 1)
- eid = self.execute('Any X WHERE Y identity X, Y eid 1')[0][0]
+ eid = self.qexecute('Any X WHERE Y identity X, Y eid 1')[0][0]
self.assertEqual(eid, 1)
- login = self.execute('Any L WHERE X login "admin", X identity Y, Y login L')[0][0]
+ login = self.qexecute('Any L WHERE X login "admin", X identity Y, Y login L')[0][0]
self.assertEqual(login, 'admin')
def test_select_date_mathexp(self):
- rset = self.execute('Any X, TODAY - CD WHERE X is CWUser, X creation_date CD')
+ rset = self.qexecute('Any X, TODAY - CD WHERE X is CWUser, X creation_date CD')
self.assertTrue(rset)
self.assertEqual(rset.description[0][1], 'Interval')
- eid, = self.execute("INSERT Personne X: X nom 'bidule'")[0]
- rset = self.execute('Any X, NOW - CD WHERE X is Personne, X creation_date CD')
+ eid, = self.qexecute("INSERT Personne X: X nom 'bidule'")[0]
+ rset = self.qexecute('Any X, NOW - CD WHERE X is Personne, X creation_date CD')
self.assertEqual(rset.description[0][1], 'Interval')
def test_select_subquery_aggregat_1(self):
# percent users by groups
- self.execute('SET X in_group G WHERE G name "users"')
- rset = self.execute('Any GN, COUNT(X)*100/T GROUPBY GN ORDERBY 2,1'
+ self.qexecute('SET X in_group G WHERE G name "users"')
+ rset = self.qexecute('Any GN, COUNT(X)*100/T GROUPBY GN ORDERBY 2,1'
' WHERE G name GN, X in_group G'
' WITH T BEING (Any COUNT(U) WHERE U is CWUser)')
self.assertEqual(rset.rows, [[u'guests', 50], [u'managers', 50], [u'users', 100]])
self.assertEqual(rset.description, [('String', 'Int'), ('String', 'Int'), ('String', 'Int')])
def test_select_subquery_aggregat_2(self):
- expected = self.execute('Any X, 0, COUNT(T) GROUPBY X '
+ expected = self.qexecute('Any X, 0, COUNT(T) GROUPBY X '
'WHERE X is Workflow, T transition_of X').rows
- rset = self.execute('''
+ rset = self.qexecute('''
Any P1,B,E WHERE P1 identity P2 WITH
P1,B BEING (Any P,COUNT(T) GROUPBY P WHERE P is Workflow, T is Transition,
T? transition_of P, T type "auto"),
@@ -954,116 +997,120 @@
self.assertEqual(sorted(rset.rows), sorted(expected))
def test_select_subquery_const(self):
- rset = self.execute('Any X WITH X BEING ((Any NULL) UNION (Any "toto"))')
+ rset = self.qexecute('Any X WITH X BEING ((Any NULL) UNION (Any "toto"))')
self.assertEqual(rset.rows, [[None], ['toto']])
self.assertEqual(rset.description, [(None,), ('String',)])
# insertion queries tests #################################################
def test_insert_is(self):
- eid, = self.execute("INSERT Personne X: X nom 'bidule'")[0]
- etype, = self.execute("Any TN WHERE X is T, X eid %s, T name TN" % eid)[0]
+ eid, = self.qexecute("INSERT Personne X: X nom 'bidule'")[0]
+ etype, = self.qexecute("Any TN WHERE X is T, X eid %s, T name TN" % eid)[0]
self.assertEqual(etype, 'Personne')
- self.execute("INSERT Personne X: X nom 'managers'")
+ self.qexecute("INSERT Personne X: X nom 'managers'")
def test_insert_1(self):
- rset = self.execute("INSERT Personne X: X nom 'bidule'")
+ rset = self.qexecute("INSERT Personne X: X nom 'bidule'")
self.assertEqual(len(rset.rows), 1)
self.assertEqual(rset.description, [('Personne',)])
- rset = self.execute('Personne X WHERE X nom "bidule"')
+ rset = self.qexecute('Personne X WHERE X nom "bidule"')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne',)])
def test_insert_1_multiple(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Personne X: X nom 'chouette'")
- rset = self.execute("INSERT Societe Y: Y nom N, P travaille Y WHERE P nom N")
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Personne X: X nom 'chouette'")
+ rset = self.qexecute("INSERT Societe Y: Y nom N, P travaille Y WHERE P nom N")
self.assertEqual(len(rset.rows), 2)
self.assertEqual(rset.description, [('Societe',), ('Societe',)])
def test_insert_2(self):
- rset = self.execute("INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'tutu'")
+ rset = self.qexecute("INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'tutu'")
self.assertEqual(rset.description, [('Personne', 'Personne')])
- rset = self.execute('Personne X WHERE X nom "bidule" or X nom "tutu"')
+ rset = self.qexecute('Personne X WHERE X nom "bidule" or X nom "tutu"')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne',), ('Personne',)])
def test_insert_3(self):
- self.execute("INSERT Personne X: X nom Y WHERE U login 'admin', U login Y")
- rset = self.execute('Personne X WHERE X nom "admin"')
+ self.qexecute("INSERT Personne X: X nom Y WHERE U login 'admin', U login Y")
+ rset = self.qexecute('Personne X WHERE X nom "admin"')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne',)])
def test_insert_4(self):
- self.execute("INSERT Societe Y: Y nom 'toto'")
- self.execute("INSERT Personne X: X nom 'bidule', X travaille Y WHERE Y nom 'toto'")
- rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
+ self.qexecute("INSERT Societe Y: Y nom 'toto'")
+ self.qexecute("INSERT Personne X: X nom 'bidule', X travaille Y WHERE Y nom 'toto'")
+ rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_4bis(self):
- peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- seid = self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
+ peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ seid = self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
{'x': str(peid)})[0][0]
- self.assertEqual(len(self.execute('Any X, Y WHERE X travaille Y')), 1)
- self.execute("INSERT Personne X: X nom 'chouette', X travaille Y WHERE Y eid %(x)s",
+ self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 1)
+ self.qexecute("INSERT Personne X: X nom 'chouette', X travaille Y WHERE Y eid %(x)s",
{'x': str(seid)})
- self.assertEqual(len(self.execute('Any X, Y WHERE X travaille Y')), 2)
+ self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 2)
def test_insert_4ter(self):
- peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- seid = self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
+ peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ seid = self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
{'x': unicode(peid)})[0][0]
- self.assertEqual(len(self.execute('Any X, Y WHERE X travaille Y')), 1)
- self.execute("INSERT Personne X: X nom 'chouette', X travaille Y WHERE Y eid %(x)s",
+ self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 1)
+ self.qexecute("INSERT Personne X: X nom 'chouette', X travaille Y WHERE Y eid %(x)s",
{'x': unicode(seid)})
- self.assertEqual(len(self.execute('Any X, Y WHERE X travaille Y')), 2)
+ self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 2)
def test_insert_5(self):
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X nom 'bidule'")
- rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X nom 'bidule'")
+ rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_5bis(self):
- peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- self.execute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
+ peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
{'x': peid})
- rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
+ rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_6(self):
- self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto', X travaille Y")
- rset = self.execute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
+ self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto', X travaille Y")
+ rset = self.qexecute('Any X, Y WHERE X nom "bidule", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_7(self):
- self.execute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', X travaille Y WHERE U login 'admin', U login N")
- rset = self.execute('Any X, Y WHERE X nom "admin", Y nom "toto", X travaille Y')
+ self.qexecute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', "
+ "X travaille Y WHERE U login 'admin', U login N")
+ rset = self.qexecute('Any X, Y WHERE X nom "admin", Y nom "toto", X travaille Y')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_7_2(self):
- self.execute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', X travaille Y WHERE U login N")
- rset = self.execute('Any X, Y WHERE Y nom "toto", X travaille Y')
+ self.qexecute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', "
+ "X travaille Y WHERE U login N")
+ rset = self.qexecute('Any X, Y WHERE Y nom "toto", X travaille Y')
self.assertEqual(len(rset), 2)
self.assertEqual(rset.description, [('Personne', 'Societe',),
('Personne', 'Societe',)])
def test_insert_8(self):
- self.execute("INSERT Societe Y, Personne X: Y nom N, X nom 'toto', X travaille Y WHERE U login 'admin', U login N")
- rset = self.execute('Any X, Y WHERE X nom "toto", Y nom "admin", X travaille Y')
+ self.qexecute("INSERT Societe Y, Personne X: Y nom N, X nom 'toto', X travaille Y "
+ "WHERE U login 'admin', U login N")
+ rset = self.qexecute('Any X, Y WHERE X nom "toto", Y nom "admin", X travaille Y')
self.assert_(rset.rows)
self.assertEqual(rset.description, [('Personne', 'Societe',)])
def test_insert_9(self):
- self.execute("INSERT Societe X: X nom 'Lo'")
- self.execute("INSERT Societe X: X nom 'Gi'")
- self.execute("INSERT SubDivision X: X nom 'Lab'")
- rset = self.execute("INSERT Personne X: X nom N, X travaille Y, X travaille_subdivision Z WHERE Y is Societe, Z is SubDivision, Y nom N")
+ self.qexecute("INSERT Societe X: X nom 'Lo'")
+ self.qexecute("INSERT Societe X: X nom 'Gi'")
+ self.qexecute("INSERT SubDivision X: X nom 'Lab'")
+ rset = self.qexecute("INSERT Personne X: X nom N, X travaille Y, X travaille_subdivision Z "
+ "WHERE Y is Societe, Z is SubDivision, Y nom N")
self.assertEqual(len(rset), 2)
self.assertEqual(rset.description, [('Personne',), ('Personne',)])
# self.assertSetEqual(set(x.nom for x in rset.entities()),
@@ -1075,21 +1122,21 @@
def test_insert_query_error(self):
self.assertRaises(Exception,
- self.execute,
+ self.qexecute,
"INSERT Personne X: X nom 'toto', X is Personne")
self.assertRaises(Exception,
- self.execute,
+ self.qexecute,
"INSERT Personne X: X nom 'toto', X is_instance_of Personne")
self.assertRaises(QueryError,
- self.execute,
+ self.qexecute,
"INSERT Personne X: X nom 'toto', X has_text 'tutu'")
self.assertRaises(QueryError,
- self.execute,
+ self.qexecute,
"INSERT CWUser X: X login 'toto', X eid %s" % cnx.user(self.session).eid)
def test_insertion_description_with_where(self):
- rset = self.execute('INSERT CWUser E, EmailAddress EM: E login "X", E upassword "X", '
+ rset = self.qexecute('INSERT CWUser E, EmailAddress EM: E login "X", E upassword "X", '
'E primary_email EM, EM address "X", E in_group G '
'WHERE G name "managers"')
self.assertEqual(list(rset.description[0]), ['CWUser', 'EmailAddress'])
@@ -1097,54 +1144,58 @@
# deletion queries tests ##################################################
def test_delete_1(self):
- self.execute("INSERT Personne Y: Y nom 'toto'")
- rset = self.execute('Personne X WHERE X nom "toto"')
+ self.qexecute("INSERT Personne Y: Y nom 'toto'")
+ rset = self.qexecute('Personne X WHERE X nom "toto"')
self.assertEqual(len(rset.rows), 1)
- drset = self.execute("DELETE Personne Y WHERE Y nom 'toto'")
+ drset = self.qexecute("DELETE Personne Y WHERE Y nom 'toto'")
self.assertEqual(drset.rows, rset.rows)
- rset = self.execute('Personne X WHERE X nom "toto"')
+ rset = self.qexecute('Personne X WHERE X nom "toto"')
self.assertEqual(len(rset.rows), 0)
def test_delete_2(self):
- rset = self.execute("INSERT Personne X, Personne Y, Societe Z : X nom 'syt', Y nom 'adim', Z nom 'Logilab', X travaille Z, Y travaille Z")
+ rset = self.qexecute("INSERT Personne X, Personne Y, Societe Z : "
+ "X nom 'syt', Y nom 'adim', Z nom 'Logilab', X travaille Z, Y travaille Z")
self.assertEqual(len(rset), 1)
self.assertEqual(len(rset[0]), 3)
self.assertEqual(rset.description[0], ('Personne', 'Personne', 'Societe'))
- self.assertEqual(self.execute('Any N WHERE X nom N, X eid %s'% rset[0][0])[0][0], 'syt')
- rset = self.execute('Personne X WHERE X travaille Y, Y nom "Logilab"')
+ self.assertEqual(self.qexecute('Any N WHERE X nom N, X eid %s'% rset[0][0])[0][0], 'syt')
+ rset = self.qexecute('Personne X WHERE X travaille Y, Y nom "Logilab"')
self.assertEqual(len(rset.rows), 2, rset.rows)
- self.execute("DELETE X travaille Y WHERE X is Personne, Y nom 'Logilabo'")
- rset = self.execute('Personne X WHERE X travaille Y, Y nom "Logilab"')
+ self.qexecute("DELETE X travaille Y WHERE X is Personne, Y nom 'Logilabo'")
+ rset = self.qexecute('Personne X WHERE X travaille Y, Y nom "Logilab"')
self.assertEqual(len(rset.rows), 2, rset.rows)
- self.execute("DELETE X travaille Y WHERE X is Personne, Y nom 'Logilab'")
- rset = self.execute('Personne X WHERE X travaille Y, Y nom "Logilab"')
+ self.qexecute("DELETE X travaille Y WHERE X is Personne, Y nom 'Logilab'")
+ rset = self.qexecute('Personne X WHERE X travaille Y, Y nom "Logilab"')
self.assertEqual(len(rset.rows), 0, rset.rows)
def test_delete_3(self):
s = self.user_groups_session('users')
- peid, = self.o.execute(s, "INSERT Personne P: P nom 'toto'")[0]
- seid, = self.o.execute(s, "INSERT Societe S: S nom 'logilab'")[0]
- self.o.execute(s, "SET P travaille S")
- rset = self.execute('Personne P WHERE P travaille S')
+ with s.new_cnx() as cnx:
+ with cnx.ensure_cnx_set:
+ peid, = self.o.execute(cnx, "INSERT Personne P: P nom 'toto'")[0]
+ seid, = self.o.execute(cnx, "INSERT Societe S: S nom 'logilab'")[0]
+ self.o.execute(cnx, "SET P travaille S")
+ cnx.commit()
+ rset = self.qexecute('Personne P WHERE P travaille S')
self.assertEqual(len(rset.rows), 1)
- self.execute("DELETE X travaille Y WHERE X eid %s, Y eid %s" % (peid, seid))
- rset = self.execute('Personne P WHERE P travaille S')
+ self.qexecute("DELETE X travaille Y WHERE X eid %s, Y eid %s" % (peid, seid))
+ rset = self.qexecute('Personne P WHERE P travaille S')
self.assertEqual(len(rset.rows), 0)
def test_delete_symmetric(self):
- teid1 = self.execute("INSERT Folder T: T name 'toto'")[0][0]
- teid2 = self.execute("INSERT Folder T: T name 'tutu'")[0][0]
- self.execute('SET X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
- rset = self.execute('Any X,Y WHERE X see_also Y')
+ teid1 = self.qexecute("INSERT Folder T: T name 'toto'")[0][0]
+ teid2 = self.qexecute("INSERT Folder T: T name 'tutu'")[0][0]
+ self.qexecute('SET X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
+ rset = self.qexecute('Any X,Y WHERE X see_also Y')
self.assertEqual(len(rset) , 2, rset.rows)
- self.execute('DELETE X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
- rset = self.execute('Any X,Y WHERE X see_also Y')
+ self.qexecute('DELETE X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
+ rset = self.qexecute('Any X,Y WHERE X see_also Y')
self.assertEqual(len(rset) , 0)
- self.execute('SET X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
- rset = self.execute('Any X,Y WHERE X see_also Y')
+ self.qexecute('SET X see_also Y WHERE X eid %s, Y eid %s' % (teid1, teid2))
+ rset = self.qexecute('Any X,Y WHERE X see_also Y')
self.assertEqual(len(rset) , 2)
- self.execute('DELETE X see_also Y WHERE X eid %s, Y eid %s' % (teid2, teid1))
- rset = self.execute('Any X,Y WHERE X see_also Y')
+ self.qexecute('DELETE X see_also Y WHERE X eid %s, Y eid %s' % (teid2, teid1))
+ rset = self.qexecute('Any X,Y WHERE X see_also Y')
self.assertEqual(len(rset) , 0)
def test_nonregr_delete_cache(self):
@@ -1152,204 +1203,221 @@
(using cachekey on sql generation returned always the same query for an eid,
whatever the relation)
"""
- aeid, = self.execute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')[0]
+ aeid, = self.qexecute('INSERT EmailAddress X: X address "toto@logilab.fr", X alias "hop"')[0]
# XXX would be nice if the rql below was enough...
#'INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, X recipients Y'
- eeid, = self.execute('INSERT Email X: X messageid "<1234>", X subject "test", X sender Y, X recipients Y WHERE Y is EmailAddress')[0]
- self.execute("DELETE Email X")
- sqlc = self.session.cnxset.cu
- sqlc.execute('SELECT * FROM recipients_relation')
- self.assertEqual(len(sqlc.fetchall()), 0)
- sqlc.execute('SELECT * FROM owned_by_relation WHERE eid_from=%s'%eeid)
- self.assertEqual(len(sqlc.fetchall()), 0)
+ eeid, = self.qexecute('INSERT Email X: X messageid "<1234>", X subject "test", '
+ 'X sender Y, X recipients Y WHERE Y is EmailAddress')[0]
+ self.qexecute("DELETE Email X")
+ with self.session.new_cnx() as cnx:
+ with cnx.ensure_cnx_set:
+ sqlc = cnx.cnxset.cu
+ sqlc.execute('SELECT * FROM recipients_relation')
+ self.assertEqual(len(sqlc.fetchall()), 0)
+ sqlc.execute('SELECT * FROM owned_by_relation WHERE eid_from=%s'%eeid)
+ self.assertEqual(len(sqlc.fetchall()), 0)
def test_nonregr_delete_cache2(self):
- eid = self.execute("INSERT Folder T: T name 'toto'")[0][0]
- self.commit()
+ eid = self.qexecute("INSERT Folder T: T name 'toto'")[0][0]
# fill the cache
- self.execute("Any X WHERE X eid %(x)s", {'x': eid})
- self.execute("Any X WHERE X eid %s" % eid)
- self.execute("Folder X WHERE X eid %(x)s", {'x': eid})
- self.execute("Folder X WHERE X eid %s" % eid)
- self.execute("DELETE Folder T WHERE T eid %s" % eid)
- self.commit()
- rset = self.execute("Any X WHERE X eid %(x)s", {'x': eid})
+ self.qexecute("Any X WHERE X eid %(x)s", {'x': eid})
+ self.qexecute("Any X WHERE X eid %s" % eid)
+ self.qexecute("Folder X WHERE X eid %(x)s", {'x': eid})
+ self.qexecute("Folder X WHERE X eid %s" % eid)
+ self.qexecute("DELETE Folder T WHERE T eid %s" % eid)
+ rset = self.qexecute("Any X WHERE X eid %(x)s", {'x': eid})
self.assertEqual(rset.rows, [])
- rset = self.execute("Any X WHERE X eid %s" % eid)
+ rset = self.qexecute("Any X WHERE X eid %s" % eid)
self.assertEqual(rset.rows, [])
- rset = self.execute("Folder X WHERE X eid %(x)s", {'x': eid})
+ rset = self.qexecute("Folder X WHERE X eid %(x)s", {'x': eid})
self.assertEqual(rset.rows, [])
- rset = self.execute("Folder X WHERE X eid %s" %eid)
+ rset = self.qexecute("Folder X WHERE X eid %s" %eid)
self.assertEqual(rset.rows, [])
# update queries tests ####################################################
def test_update_1(self):
- peid = self.execute("INSERT Personne Y: Y nom 'toto'")[0][0]
- rset = self.execute('Personne X WHERE X nom "toto"')
+ peid = self.qexecute("INSERT Personne Y: Y nom 'toto'")[0][0]
+ rset = self.qexecute('Personne X WHERE X nom "toto"')
self.assertEqual(len(rset.rows), 1)
- rset = self.execute("SET X nom 'tutu', X prenom 'original' WHERE X is Personne, X nom 'toto'")
+ rset = self.qexecute("SET X nom 'tutu', X prenom 'original' WHERE X is Personne, X nom 'toto'")
self.assertEqual(tuplify(rset.rows), [(peid, 'tutu', 'original')])
- rset = self.execute('Any Y, Z WHERE X is Personne, X nom Y, X prenom Z')
+ rset = self.qexecute('Any Y, Z WHERE X is Personne, X nom Y, X prenom Z')
self.assertEqual(tuplify(rset.rows), [('tutu', 'original')])
def test_update_2(self):
- peid, seid = self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")[0]
- rset = self.execute("SET X travaille Y WHERE X nom 'bidule', Y nom 'toto'")
+ peid, seid = self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")[0]
+ rset = self.qexecute("SET X travaille Y WHERE X nom 'bidule', Y nom 'toto'")
self.assertEqual(tuplify(rset.rows), [(peid, seid)])
- rset = self.execute('Any X, Y WHERE X travaille Y')
+ rset = self.qexecute('Any X, Y WHERE X travaille Y')
self.assertEqual(len(rset.rows), 1)
def test_update_2bis(self):
- rset = self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
+ rset = self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
eid1, eid2 = rset[0][0], rset[0][1]
- self.execute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s",
+ self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s",
{'x': str(eid1), 'y': str(eid2)})
- rset = self.execute('Any X, Y WHERE X travaille Y')
+ rset = self.qexecute('Any X, Y WHERE X travaille Y')
self.assertEqual(len(rset.rows), 1)
# test add of an existant relation but with NOT X rel Y protection
- self.assertFalse(self.execute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s,"
+ self.assertFalse(self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s,"
"NOT X travaille Y",
{'x': str(eid1), 'y': str(eid2)}))
def test_update_2ter(self):
- rset = self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
+ rset = self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
eid1, eid2 = rset[0][0], rset[0][1]
- self.execute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s",
+ self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s",
{'x': unicode(eid1), 'y': unicode(eid2)})
- rset = self.execute('Any X, Y WHERE X travaille Y')
+ rset = self.qexecute('Any X, Y WHERE X travaille Y')
self.assertEqual(len(rset.rows), 1)
def test_update_multiple1(self):
- peid1 = self.execute("INSERT Personne Y: Y nom 'tutu'")[0][0]
- peid2 = self.execute("INSERT Personne Y: Y nom 'toto'")[0][0]
- self.execute("SET X nom 'tutu', Y nom 'toto' WHERE X nom 'toto', Y nom 'tutu'")
- self.assertEqual(self.execute('Any X WHERE X nom "toto"').rows, [[peid1]])
- self.assertEqual(self.execute('Any X WHERE X nom "tutu"').rows, [[peid2]])
+ peid1 = self.qexecute("INSERT Personne Y: Y nom 'tutu'")[0][0]
+ peid2 = self.qexecute("INSERT Personne Y: Y nom 'toto'")[0][0]
+ self.qexecute("SET X nom 'tutu', Y nom 'toto' WHERE X nom 'toto', Y nom 'tutu'")
+ self.assertEqual(self.qexecute('Any X WHERE X nom "toto"').rows, [[peid1]])
+ self.assertEqual(self.qexecute('Any X WHERE X nom "tutu"').rows, [[peid2]])
def test_update_multiple2(self):
- ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
- peid1 = self.execute("INSERT Personne Y: Y nom 'turlu'")[0][0]
- peid2 = self.execute("INSERT Personne Y: Y nom 'tutu'")[0][0]
- self.execute('SET P1 owned_by U, P2 owned_by U '
- 'WHERE P1 eid %s, P2 eid %s, U eid %s' % (peid1, peid2, ueid))
- self.assertTrue(self.execute('Any X WHERE X eid %s, X owned_by U, U eid %s'
- % (peid1, ueid)))
- self.assertTrue(self.execute('Any X WHERE X eid %s, X owned_by U, U eid %s'
- % (peid2, ueid)))
+ with self.session.new_cnx() as cnx:
+ ueid = cnx.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
+ peid1 = cnx.execute("INSERT Personne Y: Y nom 'turlu'")[0][0]
+ peid2 = cnx.execute("INSERT Personne Y: Y nom 'tutu'")[0][0]
+ cnx.execute('SET P1 owned_by U, P2 owned_by U '
+ 'WHERE P1 eid %s, P2 eid %s, U eid %s' % (peid1, peid2, ueid))
+ self.assertTrue(cnx.execute('Any X WHERE X eid %s, X owned_by U, U eid %s'
+ % (peid1, ueid)))
+ self.assertTrue(cnx.execute('Any X WHERE X eid %s, X owned_by U, U eid %s'
+ % (peid2, ueid)))
def test_update_math_expr(self):
- orders = [r[0] for r in self.execute('Any O ORDERBY O WHERE ST name "Personne", X from_entity ST, X ordernum O')]
+ orders = [r[0] for r in self.qexecute('Any O ORDERBY O WHERE ST name "Personne", '
+ 'X from_entity ST, X ordernum O')]
for i,v in enumerate(orders):
if v != orders[0]:
splitidx = i
break
- self.execute('SET X ordernum Y+1 WHERE X from_entity SE, SE name "Personne", X ordernum Y, X ordernum >= %(order)s',
+ self.qexecute('SET X ordernum Y+1 WHERE X from_entity SE, SE name "Personne", '
+ 'X ordernum Y, X ordernum >= %(order)s',
{'order': orders[splitidx]})
- orders2 = [r[0] for r in self.execute('Any O ORDERBY O WHERE ST name "Personne", X from_entity ST, X ordernum O')]
+ orders2 = [r[0] for r in self.qexecute('Any O ORDERBY O WHERE ST name "Personne", '
+ 'X from_entity ST, X ordernum O')]
orders = orders[:splitidx] + [o+1 for o in orders[splitidx:]]
self.assertEqual(orders2, orders)
def test_update_string_concat(self):
- beid = self.execute("INSERT Bookmark Y: Y title 'toto', Y path '/view'")[0][0]
- self.execute('SET X title XN + %(suffix)s WHERE X is Bookmark, X title XN', {'suffix': u'-moved'})
- newname = self.execute('Any XN WHERE X eid %(x)s, X title XN', {'x': beid})[0][0]
+ beid = self.qexecute("INSERT Bookmark Y: Y title 'toto', Y path '/view'")[0][0]
+ self.qexecute('SET X title XN + %(suffix)s WHERE X is Bookmark, X title XN',
+ {'suffix': u'-moved'})
+ newname = self.qexecute('Any XN WHERE X eid %(x)s, X title XN', {'x': beid})[0][0]
self.assertEqual(newname, 'toto-moved')
def test_update_not_exists(self):
- rset = self.execute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
+ rset = self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
eid1, eid2 = rset[0][0], rset[0][1]
- rset = self.execute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s, "
+ rset = self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s, "
"NOT EXISTS(Z ecrit_par X)",
{'x': unicode(eid1), 'y': unicode(eid2)})
self.assertEqual(tuplify(rset.rows), [(eid1, eid2)])
def test_update_query_error(self):
- self.execute("INSERT Personne Y: Y nom 'toto'")
- self.assertRaises(Exception, self.execute, "SET X nom 'toto', X is Personne")
- self.assertRaises(QueryError, self.execute, "SET X nom 'toto', X has_text 'tutu' WHERE X is Personne")
- self.assertRaises(QueryError, self.execute, "SET X login 'tutu', X eid %s" % cnx.user(self.session).eid)
+ self.qexecute("INSERT Personne Y: Y nom 'toto'")
+ self.assertRaises(Exception, self.qexecute, "SET X nom 'toto', X is Personne")
+ self.assertRaises(QueryError, self.qexecute, "SET X nom 'toto', X has_text 'tutu' "
+ "WHERE X is Personne")
+ self.assertRaises(QueryError,
+ self.qexecute,
+ "SET X login 'tutu', X eid %s" % cnx.user(self.session).eid)
# HAVING on write queries test #############################################
def test_update_having(self):
- peid1 = self.execute("INSERT Personne Y: Y nom 'hop', Y tel 1")[0][0]
- peid2 = self.execute("INSERT Personne Y: Y nom 'hop', Y tel 2")[0][0]
- rset = self.execute("SET X tel 3 WHERE X tel TEL HAVING TEL&1=1")
+ peid1 = self.qexecute("INSERT Personne Y: Y nom 'hop', Y tel 1")[0][0]
+ peid2 = self.qexecute("INSERT Personne Y: Y nom 'hop', Y tel 2")[0][0]
+ rset = self.qexecute("SET X tel 3 WHERE X tel TEL HAVING TEL&1=1")
self.assertEqual(tuplify(rset.rows), [(peid1, 3)])
def test_insert_having(self):
self.skipTest('unsupported yet')
- self.execute("INSERT Personne Y: Y nom 'hop', Y tel 1")[0][0]
- self.assertFalse(self.execute("INSERT Personne Y: Y nom 'hop', Y tel 2 WHERE X tel XT HAVING XT&2=2"))
- self.assertTrue(self.execute("INSERT Personne Y: Y nom 'hop', Y tel 2 WHERE X tel XT HAVING XT&1=1"))
+ self.qexecute("INSERT Personne Y: Y nom 'hop', Y tel 1")[0][0]
+ self.assertFalse(self.qexecute("INSERT Personne Y: Y nom 'hop', Y tel 2 "
+ "WHERE X tel XT HAVING XT&2=2"))
+ self.assertTrue(self.qexecute("INSERT Personne Y: Y nom 'hop', Y tel 2 "
+ "WHERE X tel XT HAVING XT&1=1"))
def test_delete_having(self):
- self.execute("INSERT Personne Y: Y nom 'hop', Y tel 1")[0][0]
- self.assertFalse(self.execute("DELETE Personne Y WHERE X tel XT HAVING XT&2=2"))
- self.assertTrue(self.execute("DELETE Personne Y WHERE X tel XT HAVING XT&1=1"))
+ self.qexecute("INSERT Personne Y: Y nom 'hop', Y tel 1")[0][0]
+ self.assertFalse(self.qexecute("DELETE Personne Y WHERE X tel XT HAVING XT&2=2"))
+ self.assertTrue(self.qexecute("DELETE Personne Y WHERE X tel XT HAVING XT&1=1"))
# upassword encryption tests #################################################
def test_insert_upassword(self):
- rset = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")
+ rset = self.qexecute("INSERT CWUser X: X login 'bob', X upassword 'toto', "
+ "X in_group G WHERE G name 'users'")
self.assertEqual(len(rset.rows), 1)
self.assertEqual(rset.description, [('CWUser',)])
self.assertRaises(Unauthorized,
- self.execute, "Any P WHERE X is CWUser, X login 'bob', X upassword P")
- cursor = self.cnxset.cu
- cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
- % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
- passwd = str(cursor.fetchone()[0])
- self.assertEqual(passwd, crypt_password('toto', passwd))
- rset = self.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
+ self.qexecute, "Any P WHERE X is CWUser, X login 'bob', X upassword P")
+ with self.session.new_cnx() as cnx:
+ with cnx.ensure_cnx_set:
+ cursor = cnx.cnxset.cu
+ cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
+ % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
+ passwd = str(cursor.fetchone()[0])
+ self.assertEqual(passwd, crypt_password('toto', passwd))
+ rset = self.qexecute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
{'pwd': Binary(passwd)})
self.assertEqual(len(rset.rows), 1)
self.assertEqual(rset.description, [('CWUser',)])
def test_update_upassword(self):
- rset = self.execute("INSERT CWUser X: X login 'bob', X upassword %(pwd)s", {'pwd': 'toto'})
- self.assertEqual(rset.description[0][0], 'CWUser')
- rset = self.execute("SET X upassword %(pwd)s WHERE X is CWUser, X login 'bob'",
- {'pwd': 'tutu'})
- cursor = self.cnxset.cu
- cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
- % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
- passwd = str(cursor.fetchone()[0])
- self.assertEqual(passwd, crypt_password('tutu', passwd))
- rset = self.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
- {'pwd': Binary(passwd)})
- self.assertEqual(len(rset.rows), 1)
- self.assertEqual(rset.description, [('CWUser',)])
+ with self.session.new_cnx() as cnx:
+ with cnx.ensure_cnx_set:
+ rset = cnx.execute("INSERT CWUser X: X login 'bob', X upassword %(pwd)s",
+ {'pwd': 'toto'})
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ rset = cnx.execute("SET X upassword %(pwd)s WHERE X is CWUser, X login 'bob'",
+ {'pwd': 'tutu'})
+ cursor = cnx.cnxset.cu
+ cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
+ % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
+ passwd = str(cursor.fetchone()[0])
+ self.assertEqual(passwd, crypt_password('tutu', passwd))
+ rset = cnx.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
+ {'pwd': Binary(passwd)})
+ self.assertEqual(len(rset.rows), 1)
+ self.assertEqual(rset.description, [('CWUser',)])
# ZT datetime tests ########################################################
def test_tz_datetime(self):
- self.execute("INSERT Personne X: X nom 'bob', X tzdatenaiss %(date)s",
+ self.qexecute("INSERT Personne X: X nom 'bob', X tzdatenaiss %(date)s",
{'date': datetime(1977, 6, 7, 2, 0, tzinfo=FixedOffset(1))})
- datenaiss = self.execute("Any XD WHERE X nom 'bob', X tzdatenaiss XD")[0][0]
+ datenaiss = self.qexecute("Any XD WHERE X nom 'bob', X tzdatenaiss XD")[0][0]
self.assertEqual(datenaiss.tzinfo, None)
self.assertEqual(datenaiss.utctimetuple()[:5], (1977, 6, 7, 1, 0))
# non regression tests #####################################################
def test_nonregr_1(self):
- teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
- self.execute("SET X tags Y WHERE X name 'tag', Y is State, Y name 'activated'")
- rset = self.execute('Any X WHERE T tags X')
+ teid = self.qexecute("INSERT Tag X: X name 'tag'")[0][0]
+ self.qexecute("SET X tags Y WHERE X name 'tag', Y is State, Y name 'activated'")
+ rset = self.qexecute('Any X WHERE T tags X')
self.assertEqual(len(rset.rows), 1, rset.rows)
- rset = self.execute('Any T WHERE T tags X, X is State')
+ rset = self.qexecute('Any T WHERE T tags X, X is State')
self.assertEqual(rset.rows, [[teid]])
- rset = self.execute('Any T WHERE T tags X')
+ rset = self.qexecute('Any T WHERE T tags X')
self.assertEqual(rset.rows, [[teid]])
def test_nonregr_2(self):
- teid = self.execute("INSERT Tag X: X name 'tag'")[0][0]
- geid = self.execute("CWGroup G WHERE G name 'users'")[0][0]
- self.execute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
+ teid = self.qexecute("INSERT Tag X: X name 'tag'")[0][0]
+ geid = self.qexecute("CWGroup G WHERE G name 'users'")[0][0]
+ self.qexecute("SET X tags Y WHERE X eid %(t)s, Y eid %(g)s",
{'g': geid, 't': teid})
- rset = self.execute('Any X WHERE E eid %(x)s, E tags X',
+ rset = self.qexecute('Any X WHERE E eid %(x)s, E tags X',
{'x': teid})
self.assertEqual(rset.rows, [[geid]])
@@ -1357,7 +1425,7 @@
"""bad sql generated on the second query (destination_state is not
detected as an inlined relation)
"""
- rset = self.execute('Any S,ES,T WHERE S state_of WF, WF workflow_of ET, ET name "CWUser",'
+ rset = self.qexecute('Any S,ES,T WHERE S state_of WF, WF workflow_of ET, ET name "CWUser",'
'ES allowed_transition T, T destination_state S')
self.assertEqual(len(rset.rows), 2)
@@ -1365,26 +1433,28 @@
# fix variables'type, else we get (nb of entity types with a 'name' attribute)**3
# union queries and that make for instance a 266Ko sql query which is refused
# by the server (or client lib)
- rset = self.execute('Any ER,SE,OE WHERE SE name "Comment", ER name "comments", OE name "Comment",'
+ rset = self.qexecute('Any ER,SE,OE WHERE SE name "Comment", ER name "comments", OE name "Comment",'
'ER is CWRType, SE is CWEType, OE is CWEType')
self.assertEqual(len(rset), 1)
def test_nonregr_5(self):
# jpl #15505: equivalent queries returning different result sets
- teid1 = self.execute("INSERT Folder X: X name 'hop'")[0][0]
- teid2 = self.execute("INSERT Folder X: X name 'hip'")[0][0]
- neid = self.execute("INSERT Note X: X todo_by U, X filed_under T WHERE U login 'admin', T name 'hop'")[0][0]
- weid = self.execute("INSERT Affaire X: X concerne N, X filed_under T WHERE N is Note, T name 'hip'")[0][0]
- rset1 = self.execute('Any N,U WHERE N filed_under T, T eid %s,'
+ teid1 = self.qexecute("INSERT Folder X: X name 'hop'")[0][0]
+ teid2 = self.qexecute("INSERT Folder X: X name 'hip'")[0][0]
+ neid = self.qexecute("INSERT Note X: X todo_by U, X filed_under T "
+ "WHERE U login 'admin', T name 'hop'")[0][0]
+ weid = self.qexecute("INSERT Affaire X: X concerne N, X filed_under T "
+ "WHERE N is Note, T name 'hip'")[0][0]
+ rset1 = self.qexecute('Any N,U WHERE N filed_under T, T eid %s,'
'N todo_by U, W concerne N,'
'W is Affaire, W filed_under A, A eid %s' % (teid1, teid2))
- rset2 = self.execute('Any N,U WHERE N filed_under T, T eid %s,'
+ rset2 = self.qexecute('Any N,U WHERE N filed_under T, T eid %s,'
'N todo_by U, W concerne N,'
'W filed_under A, A eid %s' % (teid1, teid2))
- rset3 = self.execute('Any N,U WHERE N todo_by U, T eid %s,'
+ rset3 = self.qexecute('Any N,U WHERE N todo_by U, T eid %s,'
'N filed_under T, W concerne N,'
'W is Affaire, W filed_under A, A eid %s' % (teid1, teid2))
- rset4 = self.execute('Any N,U WHERE N todo_by U, T eid %s,'
+ rset4 = self.qexecute('Any N,U WHERE N todo_by U, T eid %s,'
'N filed_under T, W concerne N,'
'W filed_under A, A eid %s' % (teid1, teid2))
self.assertEqual(rset1.rows, rset2.rows)
@@ -1392,19 +1462,19 @@
self.assertEqual(rset1.rows, rset4.rows)
def test_nonregr_6(self):
- self.execute('Any N,COUNT(S) GROUPBY N ORDERBY COUNT(N) WHERE S name N, S is State')
+ self.qexecute('Any N,COUNT(S) GROUPBY N ORDERBY COUNT(N) WHERE S name N, S is State')
def test_sqlite_encoding(self):
"""XXX this test was trying to show a bug on use of lower which only
occurs with non ascii string and misconfigured locale
"""
- self.execute("INSERT Tag X: X name %(name)s,"
+ self.qexecute("INSERT Tag X: X name %(name)s,"
"X modification_date %(modification_date)s,"
"X creation_date %(creation_date)s",
{'name': u'éname0',
'modification_date': '2003/03/12 11:00',
'creation_date': '2000/07/03 11:00'})
- rset = self.execute('Any lower(N) ORDERBY LOWER(N) WHERE X is Tag, X name N,'
+ rset = self.qexecute('Any lower(N) ORDERBY LOWER(N) WHERE X is Tag, X name N,'
'X owned_by U, U eid %(x)s',
{'x':self.session.user.eid})
self.assertEqual(rset.rows, [[u'\xe9name0']])
@@ -1415,35 +1485,34 @@
solutions may be "fusionned" into one by the querier while all solutions
are needed to build the result's description
"""
- self.execute("INSERT Personne X: X nom 'bidule'")
- self.execute("INSERT Societe Y: Y nom 'toto'")
- beid = self.execute("INSERT Basket B: B name 'mybasket'")[0][0]
- self.execute("SET X in_basket B WHERE X is Personne")
- self.execute("SET X in_basket B WHERE X is Societe")
- rset = self.execute('Any X WHERE X in_basket B, B eid %s' % beid)
+ self.qexecute("INSERT Personne X: X nom 'bidule'")
+ self.qexecute("INSERT Societe Y: Y nom 'toto'")
+ beid = self.qexecute("INSERT Basket B: B name 'mybasket'")[0][0]
+ self.qexecute("SET X in_basket B WHERE X is Personne")
+ self.qexecute("SET X in_basket B WHERE X is Societe")
+ rset = self.qexecute('Any X WHERE X in_basket B, B eid %s' % beid)
self.assertEqual(len(rset), 2)
self.assertEqual(rset.description, [('Personne',), ('Societe',)])
def test_nonregr_cache_1(self):
- peid = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- beid = self.execute("INSERT Basket X: X name 'tag'")[0][0]
- self.execute("SET X in_basket Y WHERE X is Personne, Y eid %(y)s",
+ peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ beid = self.qexecute("INSERT Basket X: X name 'tag'")[0][0]
+ self.qexecute("SET X in_basket Y WHERE X is Personne, Y eid %(y)s",
{'y': beid})
- rset = self.execute("Any X WHERE X in_basket B, B eid %(x)s",
+ rset = self.qexecute("Any X WHERE X in_basket B, B eid %(x)s",
{'x': beid})
self.assertEqual(rset.rows, [[peid]])
- rset = self.execute("Any X WHERE X in_basket B, B eid %(x)s",
+ rset = self.qexecute("Any X WHERE X in_basket B, B eid %(x)s",
{'x': beid})
self.assertEqual(rset.rows, [[peid]])
def test_nonregr_has_text_cache(self):
- eid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- eid2 = self.execute("INSERT Personne X: X nom 'tag'")[0][0]
- self.commit()
- rset = self.execute("Any X WHERE X has_text %(text)s", {'text': 'bidule'})
+ eid1 = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ eid2 = self.qexecute("INSERT Personne X: X nom 'tag'")[0][0]
+ rset = self.qexecute("Any X WHERE X has_text %(text)s", {'text': 'bidule'})
self.assertEqual(rset.rows, [[eid1]])
- rset = self.execute("Any X WHERE X has_text %(text)s", {'text': 'tag'})
+ rset = self.qexecute("Any X WHERE X has_text %(text)s", {'text': 'tag'})
self.assertEqual(rset.rows, [[eid2]])
def test_nonregr_sortterm_management(self):
@@ -1454,133 +1523,133 @@
need sqlite including http://www.sqlite.org/cvstrac/tktview?tn=3773 fix
"""
- self.execute('Any X ORDERBY D DESC WHERE X creation_date D')
+ self.qexecute('Any X ORDERBY D DESC WHERE X creation_date D')
def test_nonregr_extra_joins(self):
ueid = self.session.user.eid
- teid1 = self.execute("INSERT Folder X: X name 'folder1'")[0][0]
- teid2 = self.execute("INSERT Folder X: X name 'folder2'")[0][0]
- neid1 = self.execute("INSERT Note X: X para 'note1'")[0][0]
- neid2 = self.execute("INSERT Note X: X para 'note2'")[0][0]
- self.execute("SET X filed_under Y WHERE X eid %s, Y eid %s"
+ teid1 = self.qexecute("INSERT Folder X: X name 'folder1'")[0][0]
+ teid2 = self.qexecute("INSERT Folder X: X name 'folder2'")[0][0]
+ neid1 = self.qexecute("INSERT Note X: X para 'note1'")[0][0]
+ neid2 = self.qexecute("INSERT Note X: X para 'note2'")[0][0]
+ self.qexecute("SET X filed_under Y WHERE X eid %s, Y eid %s"
% (neid1, teid1))
- self.execute("SET X filed_under Y WHERE X eid %s, Y eid %s"
+ self.qexecute("SET X filed_under Y WHERE X eid %s, Y eid %s"
% (neid2, teid2))
- self.execute("SET X todo_by Y WHERE X is Note, Y eid %s" % ueid)
- rset = self.execute('Any N WHERE N todo_by U, N is Note, U eid %s, N filed_under T, T eid %s'
+ self.qexecute("SET X todo_by Y WHERE X is Note, Y eid %s" % ueid)
+ rset = self.qexecute('Any N WHERE N todo_by U, N is Note, U eid %s, N filed_under T, T eid %s'
% (ueid, teid1))
self.assertEqual(len(rset), 1)
def test_nonregr_XXX(self):
- teid = self.execute('Transition S WHERE S name "deactivate"')[0][0]
- rset = self.execute('Any O WHERE O is State, '
+ teid = self.qexecute('Transition S WHERE S name "deactivate"')[0][0]
+ rset = self.qexecute('Any O WHERE O is State, '
'S eid %(x)s, S transition_of ET, O state_of ET', {'x': teid})
self.assertEqual(len(rset), 2)
- rset = self.execute('Any O WHERE O is State, NOT S destination_state O, '
+ rset = self.qexecute('Any O WHERE O is State, NOT S destination_state O, '
'S eid %(x)s, S transition_of ET, O state_of ET', {'x': teid})
self.assertEqual(len(rset), 1)
def test_nonregr_set_datetime(self):
# huum, psycopg specific
- self.execute('SET X creation_date %(date)s WHERE X eid 1', {'date': date.today()})
-
- def test_nonregr_set_query(self):
- ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto'")[0][0]
- self.execute("SET E in_group G, E firstname %(firstname)s, E surname %(surname)s "
- "WHERE E eid %(x)s, G name 'users'",
- {'x':ueid, 'firstname': u'jean', 'surname': u'paul'})
+ self.qexecute('SET X creation_date %(date)s WHERE X eid 1', {'date': date.today()})
def test_nonregr_u_owned_by_u(self):
- ueid = self.execute("INSERT CWUser X: X login 'bob', X upassword 'toto', X in_group G "
+ ueid = self.qexecute("INSERT CWUser X: X login 'bob', X upassword 'toto', X in_group G "
"WHERE G name 'users'")[0][0]
- rset = self.execute("CWUser U")
+ rset = self.qexecute("CWUser U")
self.assertEqual(len(rset), 3) # bob + admin + anon
- rset = self.execute("Any U WHERE NOT U owned_by U")
- self.assertEqual(len(rset), 0) # even admin created at repo initialization time should belong to itself
+ rset = self.qexecute("Any U WHERE NOT U owned_by U")
+ # even admin created at repo initialization time should belong to itself
+ self.assertEqual(len(rset), 0)
def test_nonreg_update_index(self):
# this is the kind of queries generated by "cubicweb-ctl db-check -ry"
- self.execute("SET X description D WHERE X is State, X description D")
+ self.qexecute("SET X description D WHERE X is State, X description D")
def test_nonregr_is(self):
- uteid = self.execute('Any ET WHERE ET name "CWUser"')[0][0]
- self.execute('Any X, ET WHERE X is ET, ET eid %s' % uteid)
+ uteid = self.qexecute('Any ET WHERE ET name "CWUser"')[0][0]
+ self.qexecute('Any X, ET WHERE X is ET, ET eid %s' % uteid)
def test_nonregr_orderby(self):
- seid = self.execute('Any X WHERE X name "activated"')[0][0]
- self.execute('Any X,S, MAX(T) GROUPBY X,S ORDERBY S WHERE X is CWUser, T tags X, S eid IN(%s), X in_state S' % seid)
+ seid = self.qexecute('Any X WHERE X name "activated"')[0][0]
+ self.qexecute('Any X,S, MAX(T) GROUPBY X,S ORDERBY S '
+ 'WHERE X is CWUser, T tags X, S eid IN(%s), X in_state S' % seid)
def test_nonregr_solution_cache(self):
self.skipTest('XXX should be fixed or documented') # (doesn't occur if cache key is provided.)
- rset = self.execute('Any X WHERE X is CWUser, X eid %(x)s', {'x':self.ueid})
+ rset = self.qexecute('Any X WHERE X is CWUser, X eid %(x)s', {'x':self.ueid})
self.assertEqual(len(rset), 1)
- rset = self.execute('Any X WHERE X is CWUser, X eid %(x)s', {'x':12345})
+ rset = self.qexecute('Any X WHERE X is CWUser, X eid %(x)s', {'x':12345})
self.assertEqual(len(rset), 0)
def test_nonregr_final_norestr(self):
- self.assertRaises(BadRQLQuery, self.execute, 'Date X')
+ self.assertRaises(BadRQLQuery, self.qexecute, 'Date X')
def test_nonregr_eid_cmp(self):
- peid1 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- peid2 = self.execute("INSERT Personne X: X nom 'bidule'")[0][0]
- rset = self.execute('Any X,Y WHERE X is Personne, Y is Personne, X nom XD, Y nom XD, X eid Z, Y eid > Z')
+ peid1 = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ peid2 = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
+ rset = self.qexecute('Any X,Y WHERE X is Personne, Y is Personne, '
+ 'X nom XD, Y nom XD, X eid Z, Y eid > Z')
self.assertEqual(rset.rows, [[peid1, peid2]])
- rset = self.execute('Any X,Y WHERE X nom XD, Y nom XD, X eid Z, Y eid > Z')
+ rset = self.qexecute('Any X,Y WHERE X nom XD, Y nom XD, X eid Z, Y eid > Z')
self.assertEqual(rset.rows, [[peid1, peid2]])
def test_nonregr_has_text_ambiguity_1(self):
- peid = self.execute("INSERT CWUser X: X login 'bidule', X upassword 'bidule', X in_group G WHERE G name 'users'")[0][0]
- aeid = self.execute("INSERT Affaire X: X ref 'bidule'")[0][0]
- self.commit()
- rset = self.execute('Any X WHERE X is CWUser, X has_text "bidule"')
+ peid = self.qexecute("INSERT CWUser X: X login 'bidule', X upassword 'bidule', "
+ "X in_group G WHERE G name 'users'")[0][0]
+ aeid = self.qexecute("INSERT Affaire X: X ref 'bidule'")[0][0]
+ rset = self.qexecute('Any X WHERE X is CWUser, X has_text "bidule"')
self.assertEqual(rset.rows, [[peid]])
- rset = self.execute('Any X WHERE X is CWUser, X has_text "bidule", X in_state S, S name SN')
+ rset = self.qexecute('Any X WHERE X is CWUser, X has_text "bidule", '
+ 'X in_state S, S name SN')
self.assertEqual(rset.rows, [[peid]])
def test_nonregr_sql_cache(self):
# different SQL generated when 'name' is None or not (IS NULL).
- self.assertFalse(self.execute('Any X WHERE X is CWEType, X name %(name)s', {'name': None}))
- self.assertTrue(self.execute('Any X WHERE X is CWEType, X name %(name)s', {'name': 'CWEType'}))
+ self.assertFalse(self.qexecute('Any X WHERE X is CWEType, X name %(name)s',
+ {'name': None}))
+ self.assertTrue(self.qexecute('Any X WHERE X is CWEType, X name %(name)s',
+ {'name': 'CWEType'}))
class NonRegressionTC(CubicWebTC):
def test_has_text_security_cache_bug(self):
- req = self.request()
- self.create_user(req, 'user', ('users',))
- aff1 = req.create_entity('Societe', nom=u'aff1')
- aff2 = req.create_entity('Societe', nom=u'aff2')
- self.commit()
- with self.login('user', password='user'):
- res = self.execute('Any X WHERE X has_text %(text)s', {'text': 'aff1'})
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, 'user', ('users',))
+ aff1 = cnx.create_entity('Societe', nom=u'aff1')
+ aff2 = cnx.create_entity('Societe', nom=u'aff2')
+ cnx.commit()
+ with self.new_access('user').repo_cnx() as cnx:
+ res = cnx.execute('Any X WHERE X has_text %(text)s', {'text': 'aff1'})
self.assertEqual(res.rows, [[aff1.eid]])
- res = self.execute('Any X WHERE X has_text %(text)s', {'text': 'aff2'})
+ res = cnx.execute('Any X WHERE X has_text %(text)s', {'text': 'aff2'})
self.assertEqual(res.rows, [[aff2.eid]])
def test_set_relations_eid(self):
- req = self.request()
- # create 3 email addresses
- a1 = req.create_entity('EmailAddress', address=u'a1')
- a2 = req.create_entity('EmailAddress', address=u'a2')
- a3 = req.create_entity('EmailAddress', address=u'a3')
- # SET relations using '>=' operator on eids
- req.execute('SET U use_email A WHERE U login "admin", A eid >= %s' % a2.eid)
- self.assertEqual(
- [[a2.eid], [a3.eid]],
- req.execute('Any A ORDERBY A WHERE U use_email A, U login "admin"').rows)
- # DELETE
- req.execute('DELETE U use_email A WHERE U login "admin", A eid > %s' % a2.eid)
- self.assertEqual(
- [[a2.eid]],
- req.execute('Any A ORDERBY A WHERE U use_email A, U login "admin"').rows)
- req.execute('DELETE U use_email A WHERE U login "admin"')
- # SET relations using '<' operator on eids
- req.execute('SET U use_email A WHERE U login "admin", A eid < %s' % a2.eid)
- self.assertEqual(
- [[a1.eid]],
- req.execute('Any A ORDERBY A WHERE U use_email A, U login "admin"').rows)
+ with self.admin_access.repo_cnx() as cnx:
+ # create 3 email addresses
+ a1 = cnx.create_entity('EmailAddress', address=u'a1')
+ a2 = cnx.create_entity('EmailAddress', address=u'a2')
+ a3 = cnx.create_entity('EmailAddress', address=u'a3')
+ # SET relations using '>=' operator on eids
+ cnx.execute('SET U use_email A WHERE U login "admin", A eid >= %s' % a2.eid)
+ self.assertEqual(
+ [[a2.eid], [a3.eid]],
+ cnx.execute('Any A ORDERBY A WHERE U use_email A, U login "admin"').rows)
+ # DELETE
+ cnx.execute('DELETE U use_email A WHERE U login "admin", A eid > %s' % a2.eid)
+ self.assertEqual(
+ [[a2.eid]],
+ cnx.execute('Any A ORDERBY A WHERE U use_email A, U login "admin"').rows)
+ cnx.execute('DELETE U use_email A WHERE U login "admin"')
+ # SET relations using '<' operator on eids
+ cnx.execute('SET U use_email A WHERE U login "admin", A eid < %s' % a2.eid)
+ self.assertEqual(
+ [[a1.eid]],
+ cnx.execute('Any A ORDERBY A WHERE U use_email A, U login "admin"').rows)
if __name__ == '__main__':
unittest_main()
diff -r 928732ec00dd -r fa44db7da2dc server/test/unittest_rqlannotation.py
--- a/server/test/unittest_rqlannotation.py Thu Jul 17 11:08:56 2014 +0200
+++ b/server/test/unittest_rqlannotation.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: iso-8859-1 -*-
-# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -21,340 +21,424 @@
from cubicweb.devtools import TestServerConfiguration, get_test_db_handler
from cubicweb.devtools.repotest import BaseQuerierTC
-
-def setUpModule(*args):
- handler = get_test_db_handler(TestServerConfiguration(
- 'data2', apphome=SQLGenAnnotatorTC.datadir))
- handler.build_db_cache()
- global repo, cnx
- repo, cnx = handler.get_repo_and_cnx()
-
-def tearDownModule(*args):
- global repo, cnx
- del repo, cnx
-
-
class SQLGenAnnotatorTC(BaseQuerierTC):
def setUp(self):
+ handler = get_test_db_handler(TestServerConfiguration(
+ 'data2', apphome=SQLGenAnnotatorTC.datadir))
+ handler.build_db_cache()
+ repo, _cnx = handler.get_repo_and_cnx()
self.__class__.repo = repo
super(SQLGenAnnotatorTC, self).setUp()
def get_max_eid(self):
# no need for cleanup here
return None
+
def cleanup(self):
# no need for cleanup here
pass
def test_0_1(self):
- rqlst = self._prepare('Any SEN,RN,OEN WHERE X from_entity SE, SE eid 44, X relation_type R, R eid 139, X to_entity OE, OE eid 42, R name RN, SE name SEN, OE name OEN')
- self.assertEqual(rqlst.defined_vars['SE']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['OE']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['R']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['SE'].stinfo['attrvar'], None)
- self.assertEqual(rqlst.defined_vars['OE'].stinfo['attrvar'], None)
- self.assertEqual(rqlst.defined_vars['R'].stinfo['attrvar'], None)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any SEN,RN,OEN WHERE X from_entity SE, '
+ 'SE eid 44, X relation_type R, R eid 139, '
+ 'X to_entity OE, OE eid 42, R name RN, SE name SEN, '
+ 'OE name OEN')
+ self.assertEqual(rqlst.defined_vars['SE']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['OE']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['R']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['SE'].stinfo['attrvar'], None)
+ self.assertEqual(rqlst.defined_vars['OE'].stinfo['attrvar'], None)
+ self.assertEqual(rqlst.defined_vars['R'].stinfo['attrvar'], None)
def test_0_2(self):
- rqlst = self._prepare('Any O WHERE NOT S ecrit_par O, S eid 1, S inline1 P, O inline2 P')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['O'].stinfo['attrvar'], None)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any O WHERE NOT S ecrit_par O, S eid 1, '
+ 'S inline1 P, O inline2 P')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['O'].stinfo['attrvar'], None)
def test_0_4(self):
- rqlst = self._prepare('Any A,B,C WHERE A eid 12,A comment B, A ?wf_info_for C')
- self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
- self.assert_(rqlst.defined_vars['B'].stinfo['attrvar'])
- self.assertEqual(rqlst.defined_vars['C']._q_invariant, False)
- self.assertEqual(rqlst.solutions, [{'A': 'TrInfo', 'B': 'String', 'C': 'Affaire'},
- {'A': 'TrInfo', 'B': 'String', 'C': 'CWUser'},
- {'A': 'TrInfo', 'B': 'String', 'C': 'Note'}])
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any A,B,C WHERE A eid 12,A comment B, '
+ 'A ?wf_info_for C')
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
+ self.assert_(rqlst.defined_vars['B'].stinfo['attrvar'])
+ self.assertEqual(rqlst.defined_vars['C']._q_invariant, False)
+ self.assertEqual(rqlst.solutions, [{'A': 'TrInfo', 'B': 'String', 'C': 'Affaire'},
+ {'A': 'TrInfo', 'B': 'String', 'C': 'CWUser'},
+ {'A': 'TrInfo', 'B': 'String', 'C': 'Note'}])
def test_0_5(self):
- rqlst = self._prepare('Any P WHERE N ecrit_par P, N eid 0')
- self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any P WHERE N ecrit_par P, N eid 0')
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
def test_0_6(self):
- rqlst = self._prepare('Any P WHERE NOT N ecrit_par P, N eid 512')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any P WHERE NOT N ecrit_par P, N eid 512')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
def test_0_7(self):
- rqlst = self._prepare('Personne X,Y where X nom NX, Y nom NX, X eid XE, not Y eid XE')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
- self.assert_(rqlst.defined_vars['XE'].stinfo['attrvar'])
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Personne X,Y where X nom NX, '
+ 'Y nom NX, X eid XE, not Y eid XE')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ self.assert_(rqlst.defined_vars['XE'].stinfo['attrvar'])
def test_0_8(self):
- rqlst = self._prepare('Any P WHERE X eid 0, NOT X connait P')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
- #self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEqual(len(rqlst.solutions), 1, rqlst.solutions)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any P WHERE X eid 0, NOT X connait P')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ #self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(len(rqlst.solutions), 1, rqlst.solutions)
def test_0_10(self):
- rqlst = self._prepare('Any X WHERE X concerne Y, Y is Note')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X concerne Y, Y is Note')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_0_11(self):
- rqlst = self._prepare('Any X WHERE X todo_by Y, X is Affaire')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X todo_by Y, X is Affaire')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_0_12(self):
- rqlst = self._prepare('Personne P WHERE P concerne A, A concerne S, S nom "Logilab"')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Personne P WHERE P concerne A, '
+ 'A concerne S, S nom "Logilab"')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
def test_1_0(self):
- rqlst = self._prepare('Any X,Y WHERE X created_by Y, X eid 5, NOT Y eid 6')
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,Y WHERE X created_by Y, '
+ 'X eid 5, NOT Y eid 6')
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_1_1(self):
- rqlst = self._prepare('Any X,Y WHERE X created_by Y, X eid 5, NOT Y eid IN (6,7)')
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,Y WHERE X created_by Y, X eid 5, '
+ 'NOT Y eid IN (6,7)')
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_2(self):
- rqlst = self._prepare('Any X WHERE X identity Y, Y eid 1')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X identity Y, Y eid 1')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_7(self):
- rqlst = self._prepare('Personne X,Y where X nom NX, Y nom NX, X eid XE, not Y eid XE')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Personne X,Y where X nom NX, Y nom NX, '
+ 'X eid XE, not Y eid XE')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_8(self):
- # DISTINCT Any P WHERE P require_group %(g)s, NOT %(u)s has_group_permission P, P is CWPermission
- rqlst = self._prepare('DISTINCT Any X WHERE A concerne X, NOT N migrated_from X, '
- 'X is Note, N eid 1')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ # DISTINCT Any P WHERE P require_group %(g)s,
+ # NOT %(u)s has_group_permission P, P is CWPermission
+ rqlst = self._prepare(cnx, 'DISTINCT Any X WHERE A concerne X, '
+ 'NOT N migrated_from X, '
+ 'X is Note, N eid 1')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_diff_scope_identity_deamb(self):
- rqlst = self._prepare('Any X WHERE X concerne Y, Y is Note, EXISTS(Y identity Z, Z migrated_from N)')
- self.assertEqual(rqlst.defined_vars['Z']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X concerne Y, Y is Note, '
+ 'EXISTS(Y identity Z, Z migrated_from N)')
+ self.assertEqual(rqlst.defined_vars['Z']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_optional_inlined(self):
- rqlst = self._prepare('Any X,S where X from_state S?')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,S where X from_state S?')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
def test_optional_inlined_2(self):
- rqlst = self._prepare('Any N,A WHERE N? inline1 A')
- self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any N,A WHERE N? inline1 A')
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
def test_optional_1(self):
- rqlst = self._prepare('Any X,S WHERE X travaille S?')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,S WHERE X travaille S?')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
def test_greater_eid(self):
- rqlst = self._prepare('Any X WHERE X eid > 5')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X eid > 5')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_greater_eid_typed(self):
- rqlst = self._prepare('Any X WHERE X eid > 5, X is Note')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X eid > 5, X is Note')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_max_eid(self):
- rqlst = self._prepare('Any MAX(X)')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any MAX(X)')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_max_eid_typed(self):
- rqlst = self._prepare('Any MAX(X) WHERE X is Note')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any MAX(X) WHERE X is Note')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_all_entities(self):
- rqlst = self._prepare('Any X')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_all_typed_entity(self):
- rqlst = self._prepare('Any X WHERE X is Note')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X is Note')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_has_text_1(self):
- rqlst = self._prepare('Any X WHERE X has_text "toto tata"')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'has_text')
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X has_text "toto tata"')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type,
+ 'has_text')
def test_has_text_2(self):
- rqlst = self._prepare('Any X WHERE X is Personne, X has_text "coucou"')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'has_text')
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X is Personne, '
+ 'X has_text "coucou"')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type,
+ 'has_text')
def test_not_relation_1(self):
- # P can't be invariant since deambiguification caused by "NOT X require_permission P"
- # is not considered by generated sql (NOT EXISTS(...))
- rqlst = self._prepare('Any P,G WHERE P require_group G, NOT X require_permission P')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['G']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ # P can't be invariant since deambiguification caused by "NOT X require_permission P"
+ # is not considered by generated sql (NOT EXISTS(...))
+ rqlst = self._prepare(cnx, 'Any P,G WHERE P require_group G, '
+ 'NOT X require_permission P')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['G']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_not_relation_2(self):
- rqlst = self._prepare('TrInfo X WHERE X eid 2, NOT X from_state Y, Y is State')
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'TrInfo X WHERE X eid 2, '
+ 'NOT X from_state Y, Y is State')
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_not_relation_3(self):
- rqlst = self._prepare('Any X, Y WHERE X eid 1, Y eid in (2, 3)')
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X, Y WHERE X eid 1, Y eid in (2, 3)')
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_4_1(self):
- rqlst = self._prepare('Note X WHERE NOT Y evaluee X')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Note X WHERE NOT Y evaluee X')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_not_relation_4_2(self):
- rqlst = self._prepare('Any X WHERE NOT Y evaluee X')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE NOT Y evaluee X')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_not_relation_4_3(self):
- rqlst = self._prepare('Any Y WHERE NOT Y evaluee X')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any Y WHERE NOT Y evaluee X')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_4_4(self):
- rqlst = self._prepare('Any X WHERE NOT Y evaluee X, Y is CWUser')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE NOT Y evaluee X, Y is CWUser')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_4_5(self):
- rqlst = self._prepare('Any X WHERE NOT Y evaluee X, Y eid %s, X is Note' % self.ueid)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.solutions, [{'X': 'Note'}])
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE NOT Y evaluee X, '
+ 'Y eid %s, X is Note' % self.ueid)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.solutions, [{'X': 'Note'}])
def test_not_relation_5_1(self):
- rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,Y WHERE X name "CWGroup", '
+ 'Y eid IN(1, 2, 3), NOT X read_permission Y')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_5_2(self):
- rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT X read_permission Y')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'DISTINCT Any X,Y WHERE X name "CWGroup", '
+ 'Y eid IN(1, 2, 3), NOT X read_permission Y')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_relation_6(self):
- rqlst = self._prepare('Personne P where NOT P concerne A')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Personne P where NOT P concerne A')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
def test_not_relation_7(self):
- rqlst = self._prepare('Any K,V WHERE P is CWProperty, P pkey K, P value V, NOT P for_user U')
- self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any K,V WHERE P is CWProperty, '
+ 'P pkey K, P value V, NOT P for_user U')
+ self.assertEqual(rqlst.defined_vars['P']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
def test_exists_1(self):
- rqlst = self._prepare('Any U WHERE U eid IN (1,2), EXISTS(X owned_by U)')
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any U WHERE U eid IN (1,2), EXISTS(X owned_by U)')
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_exists_2(self):
- rqlst = self._prepare('Any U WHERE EXISTS(U eid IN (1,2), X owned_by U)')
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any U WHERE EXISTS(U eid IN (1,2), X owned_by U)')
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_exists_3(self):
- rqlst = self._prepare('Any U WHERE EXISTS(X owned_by U, X bookmarked_by U)')
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any U WHERE EXISTS(X owned_by U, X bookmarked_by U)')
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_exists_4(self):
- rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,Y WHERE X name "CWGroup", '
+ 'Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_exists_5(self):
- rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'DISTINCT Any X,Y WHERE X name "CWGroup", '
+ 'Y eid IN(1, 2, 3), EXISTS(X read_permission Y)')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_not_exists_1(self):
- rqlst = self._prepare('Any U WHERE NOT EXISTS(X owned_by U, X bookmarked_by U)')
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any U WHERE NOT EXISTS(X owned_by U, '
+ 'X bookmarked_by U)')
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_not_exists_2(self):
- rqlst = self._prepare('Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X,Y WHERE X name "CWGroup", '
+ 'Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_not_exists_distinct_1(self):
- rqlst = self._prepare('DISTINCT Any X,Y WHERE X name "CWGroup", Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'DISTINCT Any X,Y WHERE X name "CWGroup", '
+ 'Y eid IN(1, 2, 3), NOT EXISTS(X read_permission Y)')
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, False)
def test_or_1(self):
- rqlst = self._prepare('Any X WHERE X concerne B OR C concerne X, B eid 12, C eid 13')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X concerne B OR '
+ 'C concerne X, B eid 12, C eid 13')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
def test_or_2(self):
- rqlst = self._prepare('Any X WHERE X created_by U, X concerne B OR C concerne X, B eid 12, C eid 13')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'created_by')
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X created_by U, X concerne B OR '
+ 'C concerne X, B eid 12, C eid 13')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['X'].stinfo['principal'].r_type, 'created_by')
def test_or_3(self):
- rqlst = self._prepare('Any N WHERE A evaluee N or EXISTS(N todo_by U)')
- self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any N WHERE A evaluee N or EXISTS(N todo_by U)')
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, True)
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, True)
def test_or_exists_1(self):
- # query generated by security rewriting
- rqlst = self._prepare('DISTINCT Any A,S WHERE A is Affaire, S nom "chouette", S is IN(Division, Societe, SubDivision),'
- '(EXISTS(A owned_by D)) '
- 'OR ((((EXISTS(E concerne C?, C owned_by D, A identity E, C is Note, E is Affaire)) '
- 'OR (EXISTS(I concerne H?, H owned_by D, H is Societe, A identity I, I is Affaire))) '
- 'OR (EXISTS(J concerne G?, G owned_by D, G is SubDivision, A identity J, J is Affaire))) '
- 'OR (EXISTS(K concerne F?, F owned_by D, F is Division, A identity K, K is Affaire)))')
- self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ # query generated by security rewriting
+ rqlst = self._prepare(cnx, 'DISTINCT Any A,S WHERE A is Affaire, S nom "chouette", '
+ 'S is IN(Division, Societe, SubDivision),'
+ '(EXISTS(A owned_by D)) '
+ 'OR ((((EXISTS(E concerne C?, C owned_by D, A identity E, '
+ ' C is Note, E is Affaire)) '
+ 'OR (EXISTS(I concerne H?, H owned_by D, H is Societe, '
+ ' A identity I, I is Affaire))) '
+ 'OR (EXISTS(J concerne G?, G owned_by D, G is SubDivision, '
+ ' A identity J, J is Affaire))) '
+ 'OR (EXISTS(K concerne F?, F owned_by D, F is Division, '
+ ' A identity K, K is Affaire)))')
+ self.assertEqual(rqlst.defined_vars['A']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
def test_or_exists_2(self):
- rqlst = self._prepare('Any U WHERE EXISTS(U in_group G, G name "managers") OR EXISTS(X owned_by U, X bookmarked_by U)')
- self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['G']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any U WHERE EXISTS(U in_group G, G name "managers") OR '
+ 'EXISTS(X owned_by U, X bookmarked_by U)')
+ self.assertEqual(rqlst.defined_vars['U']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['G']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, True)
def test_or_exists_3(self):
- rqlst = self._prepare('Any COUNT(S),CS GROUPBY CS ORDERBY 1 DESC LIMIT 10 '
- 'WHERE C is Societe, S concerne C, C nom CS, '
- '(EXISTS(S owned_by D)) OR (EXISTS(S documented_by N, N title "published"))')
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
- rqlst = self._prepare('Any COUNT(S),CS GROUPBY CS ORDERBY 1 DESC LIMIT 10 '
- 'WHERE S is Affaire, C is Societe, S concerne C, C nom CS, '
- '(EXISTS(S owned_by D)) OR (EXISTS(S documented_by N, N title "published"))')
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any COUNT(S),CS GROUPBY CS ORDERBY 1 DESC LIMIT 10 '
+ 'WHERE C is Societe, S concerne C, C nom CS, '
+ '(EXISTS(S owned_by D)) OR (EXISTS(S documented_by N, N title "published"))')
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
+ rqlst = self._prepare(cnx, 'Any COUNT(S),CS GROUPBY CS ORDERBY 1 DESC LIMIT 10 '
+ 'WHERE S is Affaire, C is Societe, S concerne C, C nom CS, '
+ '(EXISTS(S owned_by D)) OR (EXISTS(S documented_by N, N title "published"))')
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, True)
def test_nonregr_ambiguity(self):
- rqlst = self._prepare('Note N WHERE N attachment F')
- # N may be an image as well, not invariant
- self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['F']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Note N WHERE N attachment F')
+ # N may be an image as well, not invariant
+ self.assertEqual(rqlst.defined_vars['N']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['F']._q_invariant, True)
def test_nonregr_ambiguity_2(self):
- rqlst = self._prepare('Any S,SN WHERE X has_text "tot", X in_state S, S name SN, X is CWUser')
- # X use has_text but should not be invariant as ambiguous, and has_text
- # may not be its principal
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any S,SN WHERE X has_text "tot", X in_state S, S name SN, X is CWUser')
+ # X use has_text but should not be invariant as ambiguous, and has_text
+ # may not be its principal
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['S']._q_invariant, False)
def test_remove_from_deleted_source_1(self):
- rqlst = self._prepare('Note X WHERE X eid 999998, NOT X cw_source Y')
- self.assertNotIn('X', rqlst.defined_vars) # simplified
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Note X WHERE X eid 999998, NOT X cw_source Y')
+ self.assertNotIn('X', rqlst.defined_vars) # simplified
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_remove_from_deleted_source_2(self):
- rqlst = self._prepare('Note X WHERE X eid IN (999998, 999999), NOT X cw_source Y')
- self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
- self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
-
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Note X WHERE X eid IN (999998, 999999), NOT X cw_source Y')
+ self.assertEqual(rqlst.defined_vars['X']._q_invariant, False)
+ self.assertEqual(rqlst.defined_vars['Y']._q_invariant, True)
def test_has_text_security_cache_bug(self):
- rqlst = self._prepare('Any X WHERE X has_text "toto" WITH X BEING '
- '(Any C WHERE C is Societe, C nom CS)')
- self.assertTrue(rqlst.parent.has_text_query)
+ with self.session.new_cnx() as cnx:
+ rqlst = self._prepare(cnx, 'Any X WHERE X has_text "toto" WITH X BEING '
+ '(Any C WHERE C is Societe, C nom CS)')
+ self.assertTrue(rqlst.parent.has_text_query)
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
diff -r 928732ec00dd -r fa44db7da2dc sobjects/ldapparser.py
--- a/sobjects/ldapparser.py Thu Jul 17 11:08:56 2014 +0200
+++ b/sobjects/ldapparser.py Fri Jul 18 17:35:25 2014 +0200
@@ -92,9 +92,9 @@
for groupdict in self.group_source_entities_by_extid.itervalues():
self._process('CWGroup', groupdict)
- def handle_deletion(self, config, session, myuris):
+ def handle_deletion(self, config, cnx, myuris):
if config['delete-entities']:
- super(DataFeedLDAPAdapter, self).handle_deletion(config, session, myuris)
+ super(DataFeedLDAPAdapter, self).handle_deletion(config, cnx, myuris)
return
if myuris:
byetype = {}
@@ -107,9 +107,9 @@
continue
self.info('deactivate %s %s entities', len(eids), etype)
for eid in eids:
- wf = session.entity_from_eid(eid).cw_adapt_to('IWorkflowable')
+ wf = cnx.entity_from_eid(eid).cw_adapt_to('IWorkflowable')
wf.fire_transition_if_possible('deactivate')
- session.commit(free_cnxset=False)
+ cnx.commit()
def update_if_necessary(self, entity, attrs):
# disable read security to allow password selection
diff -r 928732ec00dd -r fa44db7da2dc sobjects/test/unittest_cwxmlparser.py
--- a/sobjects/test/unittest_cwxmlparser.py Thu Jul 17 11:08:56 2014 +0200
+++ b/sobjects/test/unittest_cwxmlparser.py Fri Jul 18 17:35:25 2014 +0200
@@ -132,13 +132,14 @@
REMOVE THE DATABASE TEMPLATE else it won't be considered
"""
test_db_id = 'xmlparser'
+
@classmethod
- def pre_setup_database(cls, session, config):
- myfeed = session.create_entity('CWSource', name=u'myfeed', type=u'datafeed',
+ def pre_setup_database(cls, cnx, config):
+ myfeed = cnx.create_entity('CWSource', name=u'myfeed', type=u'datafeed',
parser=u'cw.entityxml', url=BASEXML)
- myotherfeed = session.create_entity('CWSource', name=u'myotherfeed', type=u'datafeed',
- parser=u'cw.entityxml', url=OTHERXML)
- session.commit()
+ myotherfeed = cnx.create_entity('CWSource', name=u'myotherfeed', type=u'datafeed',
+ parser=u'cw.entityxml', url=OTHERXML)
+ cnx.commit()
myfeed.init_mapping([(('CWUser', 'use_email', '*'),
u'role=subject\naction=copy'),
(('CWUser', 'in_group', '*'),
@@ -153,7 +154,8 @@
(('CWUser', 'in_state', '*'),
u'role=subject\naction=link\nlinkattr=name'),
])
- session.create_entity('Tag', name=u'hop')
+ cnx.create_entity('Tag', name=u'hop')
+ cnx.commit()
def test_complete_url(self):
dfsource = self.repo.sources_by_uri['myfeed']
diff -r 928732ec00dd -r fa44db7da2dc test/unittest_entity.py
--- a/test/unittest_entity.py Thu Jul 17 11:08:56 2014 +0200
+++ b/test/unittest_entity.py Fri Jul 18 17:35:25 2014 +0200
@@ -23,13 +23,13 @@
from logilab.common import tempattr
from logilab.common.decorators import clear_cache
-from cubicweb import Binary, Unauthorized
+from cubicweb import Binary
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.mttransforms import HAS_TAL
from cubicweb.entity import can_use_rest_path
from cubicweb.entities import fetch_config
from cubicweb.uilib import soup2xhtml
-from cubicweb.schema import RQLVocabularyConstraint, RRQLExpression
+from cubicweb.schema import RRQLExpression
class EntityTC(CubicWebTC):
@@ -45,16 +45,16 @@
cls.fetch_attrs, cls.cw_fetch_order = self.backup_dict[cls]
def test_no_prefill_related_cache_bug(self):
- session = self.session
- usine = session.create_entity('Usine', lieu=u'Montbeliard')
- produit = session.create_entity('Produit')
- # usine was prefilled in glob_add_entity
- # let's simulate produit creation without prefill
- produit._cw_related_cache.clear()
- # use add_relations
- session.add_relations([('fabrique_par', [(produit.eid, usine.eid)])])
- self.assertEqual(1, len(usine.reverse_fabrique_par))
- self.assertEqual(1, len(produit.fabrique_par))
+ with self.admin_access.repo_cnx() as cnx:
+ usine = cnx.create_entity('Usine', lieu=u'Montbeliard')
+ produit = cnx.create_entity('Produit')
+ # usine was prefilled in glob_add_entity
+ # let's simulate produit creation without prefill
+ produit._cw_related_cache.clear()
+ # use add_relations
+ cnx.add_relations([('fabrique_par', [(produit.eid, usine.eid)])])
+ self.assertEqual(1, len(usine.reverse_fabrique_par))
+ self.assertEqual(1, len(produit.fabrique_par))
def test_boolean_value(self):
with self.admin_access.web_request() as req:
@@ -717,11 +717,11 @@
self.assertFalse(p1.reverse_evaluee)
def test_complete_relation(self):
- with self.admin_access.repo_cnx() as session:
- eid = session.execute(
+ with self.admin_access.repo_cnx() as cnx:
+ eid = cnx.execute(
'INSERT TrInfo X: X comment "zou", X wf_info_for U, X from_state S1, X to_state S2 '
'WHERE U login "admin", S1 name "activated", S2 name "deactivated"')[0][0]
- trinfo = session.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
+ trinfo = cnx.execute('Any X WHERE X eid %(x)s', {'x': eid}).get_entity(0, 0)
trinfo.complete()
self.assertIsInstance(trinfo.cw_attr_cache['creation_date'], datetime)
self.assertTrue(trinfo.cw_relation_cached('from_state', 'subject'))
diff -r 928732ec00dd -r fa44db7da2dc web/application.py
--- a/web/application.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/application.py Fri Jul 18 17:35:25 2014 +0200
@@ -35,7 +35,7 @@
from cubicweb import (
ValidationError, Unauthorized, Forbidden,
AuthenticationError, NoSelectableObject,
- BadConnectionId, CW_EVENT_MANAGER)
+ CW_EVENT_MANAGER)
from cubicweb.repoapi import anonymous_cnx
from cubicweb.web import LOGGER, component, cors
from cubicweb.web import (
@@ -88,22 +88,15 @@
closed, total = 0, 0
for session in self.current_sessions():
total += 1
- try:
- last_usage_time = session.cnx.check()
- except AttributeError:
- last_usage_time = session.mtime
- except BadConnectionId:
+ last_usage_time = session.mtime
+ no_use_time = (time() - last_usage_time)
+ if session.anonymous_session:
+ if no_use_time >= self.cleanup_anon_session_time:
+ self.close_session(session)
+ closed += 1
+ elif session_time is not None and no_use_time >= session_time:
self.close_session(session)
closed += 1
- else:
- no_use_time = (time() - last_usage_time)
- if session.anonymous_session:
- if no_use_time >= self.cleanup_anon_session_time:
- self.close_session(session)
- closed += 1
- elif session_time is not None and no_use_time >= session_time:
- self.close_session(session)
- closed += 1
return closed, total - closed
def current_sessions(self):
@@ -300,6 +293,21 @@
"""wrapper around _publish to log all queries executed for a given
accessed path
"""
+ def wrap_set_cnx(func):
+ def wrap_execute(cnx):
+ orig_execute = cnx.execute
+ def execute(rql, kwargs=None, build_descr=True):
+ tstart, cstart = time(), clock()
+ rset = orig_execute(rql, kwargs, build_descr=build_descr)
+ cnx.executed_queries.append((rql, kwargs, time() - tstart, clock() - cstart))
+ return rset
+ return execute
+ def set_cnx(cnx):
+ func(cnx)
+ cnx.execute = wrap_execute(cnx)
+ cnx.executed_queries = []
+ return set_cnx
+ req.set_cnx = wrap_set_cnx(req.set_cnx)
try:
return self.main_handle_request(req, path)
finally:
diff -r 928732ec00dd -r fa44db7da2dc web/data/cubicweb.css
--- a/web/data/cubicweb.css Thu Jul 17 11:08:56 2014 +0200
+++ b/web/data/cubicweb.css Fri Jul 18 17:35:25 2014 +0200
@@ -200,9 +200,15 @@
visibility: hidden;
}
-li.invisible {
- background: none;
- padding: 0px 0px 1px 1px;
+/* copied verbatim from bootstrap 3.0 */
+.invisible {
+ visibility: hidden;
+}
+
+/* copied verbatim from bootstrap 3.0 */
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
}
.caption {
diff -r 928732ec00dd -r fa44db7da2dc web/data/cubicweb.edition.js
--- a/web/data/cubicweb.edition.js Thu Jul 17 11:08:56 2014 +0200
+++ b/web/data/cubicweb.edition.js Fri Jul 18 17:35:25 2014 +0200
@@ -328,7 +328,7 @@
_postAjaxLoad(dom);
});
d.addErrback(function(xxx) {
- log('xxx =', xxx);
+ cw.log('xxx =', xxx);
});
}
diff -r 928732ec00dd -r fa44db7da2dc web/data/cubicweb.old.css
--- a/web/data/cubicweb.old.css Thu Jul 17 11:08:56 2014 +0200
+++ b/web/data/cubicweb.old.css Fri Jul 18 17:35:25 2014 +0200
@@ -219,10 +219,15 @@
visibility: hidden;
}
-li.invisible {
+/* copied verbatim from bootstrap 3.0 */
+.invisible {
+ visibility: hidden;
+}
+
+/* copied verbatim from bootstrap 3.0 */
+.list-unstyled {
+ padding-left: 0;
list-style: none;
- background: none;
- padding: 0px 0px 1px 1px;
}
.caption {
diff -r 928732ec00dd -r fa44db7da2dc web/request.py
--- a/web/request.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/request.py Fri Jul 18 17:35:25 2014 +0200
@@ -30,7 +30,6 @@
from datetime import date, datetime
from urlparse import urlsplit
import httplib
-from itertools import count
from warnings import warn
from rql.utils import rqlvar_maker
@@ -82,6 +81,24 @@
return [v for v in value if v != INTERNAL_FIELD_VALUE]
+class Counter(object):
+ """A picklable counter object, usable for e.g. page tab index count"""
+ __slots__ = ('value',)
+
+ def __init__(self, initialvalue=0):
+ self.value = initialvalue
+
+ def __call__(self):
+ value = self.value
+ self.value += 1
+ return value
+
+ def __getstate__(self):
+ return {'value': self.value}
+
+ def __setstate__(self, state):
+ self.value = state['value']
+
class _CubicWebRequestBase(RequestSessionBase):
"""abstract HTTP request, should be extended according to the HTTP backend
@@ -201,7 +218,7 @@
def next_tabindex(self):
nextfunc = self.get_page_data('nexttabfunc')
if nextfunc is None:
- nextfunc = count(1).next
+ nextfunc = Counter(1)
self.set_page_data('nexttabfunc', nextfunc)
return nextfunc()
diff -r 928732ec00dd -r fa44db7da2dc web/test/test_views.py
--- a/web/test/test_views.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/test_views.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -16,8 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see .
"""automatic tests"""
-from cubicweb.devtools import htmlparser
-from cubicweb.devtools.testlib import CubicWebTC, AutoPopulateTest, AutomaticWebTest
+from cubicweb.devtools.testlib import AutoPopulateTest, AutomaticWebTest
from cubicweb.view import AnyRsetView
class AutomaticWebTest(AutomaticWebTest):
@@ -28,8 +27,8 @@
]
def to_test_etypes(self):
- # We do not really want to test cube views here. So we can drop testing
- # some EntityType. The two Blog types below require the sioc cube that
+ # We do not really want to test cube views here. So we can drop testing
+ # some EntityType. The two Blog types below require the sioc cube that
# we do not want to add as a dependency.
etypes = super(AutomaticWebTest, self).to_test_etypes()
etypes -= set(('Blog', 'BlogEntry'))
@@ -50,29 +49,34 @@
"""regression test: make sure we can ask a copy of a
composite entity
"""
- rset = self.execute('CWUser X WHERE X login "admin"')
- self.view('copy', rset)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X WHERE X login "admin"')
+ self.view('copy', rset, req=req)
def test_sortable_js_added(self):
- rset = self.execute('CWUser X')
- # sortable.js should not be included by default
- self.assertFalse('jquery.tablesorter.js' in self.view('oneline', rset))
- # but should be included by the tableview
- rset = self.execute('Any P,F,S LIMIT 1 WHERE P is CWUser, P firstname F, P surname S')
- self.assertIn('jquery.tablesorter.js', self.view('table', rset).source)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ # sortable.js should not be included by default
+ self.assertFalse('jquery.tablesorter.js' in self.view('oneline', rset, req=req))
+ # but should be included by the tableview
+ rset = req.execute('Any P,F,S LIMIT 1 WHERE P is CWUser, P firstname F, P surname S')
+ self.assertIn('jquery.tablesorter.js', self.view('table', rset, req=req).source)
def test_js_added_only_once(self):
- self.vreg._loadedmods[__name__] = {}
- self.vreg.register(SomeView)
- rset = self.execute('CWUser X')
- source = self.view('someview', rset).source
- self.assertEqual(source.count('spam.js'), 1)
+ with self.admin_access.web_request() as req:
+ self.vreg._loadedmods[__name__] = {}
+ self.vreg.register(SomeView)
+ rset = req.execute('CWUser X')
+ source = self.view('someview', rset, req=req).source
+ self.assertEqual(source.count('spam.js'), 1)
def test_unrelateddivs(self):
- rset = self.execute('Any X WHERE X is CWUser, X login "admin"')
- group = self.request().create_entity('CWGroup', name=u'R&D')
- req = self.request(relation='in_group_subject')
- self.view('unrelateddivs', rset, req)
+ with self.admin_access.client_cnx() as cnx:
+ group = cnx.create_entity('CWGroup', name=u'R&D')
+ cnx.commit()
+ with self.admin_access.web_request(relation='in_group_subject') as req:
+ rset = req.execute('Any X WHERE X is CWUser, X login "admin"')
+ self.view('unrelateddivs', rset, req=req)
if __name__ == '__main__':
diff -r 928732ec00dd -r fa44db7da2dc web/test/unittest_application.py
--- a/web/test/unittest_application.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_application.py Fri Jul 18 17:35:25 2014 +0200
@@ -18,14 +18,12 @@
"""unit tests for cubicweb.web.application"""
import base64, Cookie
-import sys
import httplib
-from urllib import unquote
from logilab.common.testlib import TestCase, unittest_main
from logilab.common.decorators import clear_cache, classproperty
-from cubicweb import AuthenticationError, Unauthorized
+from cubicweb import AuthenticationError
from cubicweb import view
from cubicweb.devtools.testlib import CubicWebTC, real_error_handling
from cubicweb.devtools.fake import FakeRequest
@@ -182,7 +180,7 @@
def test_publish_validation_error(self):
with self.admin_access.web_request() as req:
- user = self.user()
+ user = self.user(req)
eid = unicode(user.eid)
req.form = {
'eid': eid,
diff -r 928732ec00dd -r fa44db7da2dc web/test/unittest_breadcrumbs.py
--- a/web/test/unittest_breadcrumbs.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_breadcrumbs.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -29,14 +29,19 @@
{'f1' : f1.eid, 'f2' : f2.eid})
req.cnx.commit()
self.assertEqual(f2.view('breadcrumbs'),
- 'chi&ld' % f2.eid)
+ ''
+ 'chi&ld' % f2.eid)
childrset = f2.as_rset()
ibc = self.vreg['ctxcomponents'].select('breadcrumbs', req, rset=childrset)
l = []
ibc.render(l.append)
- self.assertEqual(''.join(l),
- """ > Folder_plural > par&ent >
-chi&ld""" % (f1.eid, f2.eid))
+ self.assertMultiLineEqual(' > '
+ 'Folder_plural'
+ ' > par&ent > \n'
+ ''
+ 'chi&ld' % (f1.eid, f2.eid),
+ ''.join(l))
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
diff -r 928732ec00dd -r fa44db7da2dc web/test/unittest_propertysheet.py
--- a/web/test/unittest_propertysheet.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_propertysheet.py Fri Jul 18 17:35:25 2014 +0200
@@ -4,7 +4,7 @@
from logilab.common.testlib import TestCase, unittest_main
-from cubicweb.web.propertysheet import *
+from cubicweb.web.propertysheet import PropertySheet, lazystr
DATADIR = join(dirname(__file__), 'data')
CACHEDIR = join(DATADIR, 'uicache')
diff -r 928732ec00dd -r fa44db7da2dc web/test/unittest_reledit.py
--- a/web/test/unittest_reledit.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_reledit.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -34,9 +34,9 @@
class ClickAndEditFormTC(ReleditMixinTC, CubicWebTC):
def test_default_config(self):
- reledit = {'title': '''
cubicweb-world-domination
''',
- 'long_desc': '''
<not specified>
''',
- 'manager': '''
<not specified>
''',
+ reledit = {'title': '''
cubicweb-world-domination
''',
+ 'long_desc': '''
<not specified>
''',
+ 'manager': '''
<not specified>
''',
'composite_card11_2ttypes': """<not specified>""",
'concerns': """<not specified>"""}
@@ -53,7 +53,7 @@
def test_default_forms(self):
self.skipTest('Need to check if this test should still run post reledit/doreledit merge')
- doreledit = {'title': """