--- 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
--- 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
--- 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
--- 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
--- 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:
--- 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 <eid>"""
- 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
--- 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 <julien.cristau@logilab.fr> Fri, 18 Jul 2014 16:16:32 +0200
+
+cubicweb (3.19.2-1) unstable; urgency=low
+
+ * new upstream release
+
+ -- Julien Cristau <julien.cristau@logilab.fr> 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 <julien.cristau@logilab.fr> Fri, 10 Jan 2014 17:14:18 +0100
+cubicweb (3.17.16-1) unstable; urgency=low
+
+ * new upstream value
+
+ -- Aurelien Campeas <aurelien.campeas@logilab.fr> Mon, 07 Jul 2014 19:26:12 +0200
+
cubicweb (3.17.15-1) unstable; urgency=low
* new upstream release
--- 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,
--- 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
--- 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 <constraints>
<selectvar> 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':
--- 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)
--- 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'])
--- 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 ###################################################
--- 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*
--- 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).
--- 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:`<X.Y.Z>_Any.py` ('Any' being there mostly for historical reason).
+file named file:`<X.Y.Z>_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)
--- 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 @@
<script>alert("coucou")</script>
""", 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):
--- 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
--- 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)
--- 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),
- '<p><a class="reference" href="http://testing.fr/cubicweb/cwuser/admin">#%s</a></p>\n' % context.eid)
- self.assertEqual(rest_publish(context, ':eid:`%s:some text`' % context.eid),
- '<p><a class="reference" href="http://testing.fr/cubicweb/cwuser/admin">some text</a></p>\n')
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ self.assertEqual(rest_publish(context, ':eid:`%s`' % context.eid),
+ '<p><a class="reference" href="http://testing.fr/cubicweb/cwuser/admin">'
+ '#%s</a></p>\n' % context.eid)
+ self.assertEqual(rest_publish(context, ':eid:`%s:some text`' % context.eid),
+ '<p><a class="reference" href="http://testing.fr/cubicweb/cwuser/admin">'
+ 'some text</a></p>\n')
def test_bad_rest_no_crash(self):
- data = rest_publish(self.context(), '''
+ with self.admin_access.web_request() as req:
+ rest_publish(self.context(req), '''
| card | implication |
--------------------------
| 1-1 | N1 = N2 |
@@ -55,159 +60,172 @@
def test_rql_role_with_vid(self):
- context = self.context()
- out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:table`')
- self.assertTrue(out.endswith('<a href="http://testing.fr/cubicweb/cwuser/anon" title="">anon</a>'
- '</td></tr>\n</tbody></table></div></p>\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('<a href="http://testing.fr/cubicweb/cwuser/anon" '
+ 'title="">anon</a></td></tr>\n</tbody></table>'
+ '</div></p>\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('<p><div class="searchMessage"><strong>No result matching query</strong></div>\n</p>\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('<p><div class="searchMessage"><strong>'
+ 'No result matching query</strong></div>\n</p>\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("<p>an error occurred while interpreting this rql directive: ObjectNotFound(u'toto',)</p>"))
+ 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("<p>an error occurred while interpreting this "
+ "rql directive: ObjectNotFound(u'toto',)</p>"))
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'<p><h1>CWUser_plural</h1><div class="section"><a href="http://testing.fr/cubicweb/cwuser/admin" title="">admin</a></div><div class="section"><a href="http://testing.fr/cubicweb/cwuser/anon" title="">anon</a></div></p>\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'<p><h1>CWUser_plural</h1><div class="section">'
+ '<a href="http://testing.fr/cubicweb/cwuser/admin" title="">admin</a>'
+ '</div><div class="section">'
+ '<a href="http://testing.fr/cubicweb/cwuser/anon" title="">anon</a>'
+ '</div></p>\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'<p><h1>CWUser_plural</h1><div class="section"><a href="http://testing.fr/cubicweb/cwuser/admin" title="">admin</a></div><div class="section"><a href="http://testing.fr/cubicweb/cwuser/anon" title="">anon</a></div></p>\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'<p><h1>CWUser_plural</h1><div class="section">'
+ '<a href="http://testing.fr/cubicweb/cwuser/admin" title="">admin'
+ '</a></div><div class="section">'
+ '<a href="http://testing.fr/cubicweb/cwuser/anon" title="">anon'
+ '</a></div></p>\n')
def test_rqltable_nocontent(self):
- context = self.context()
- out = rest_publish(context, """.. rql-table::""")
- self.assertIn("System Message: ERROR", out)
- self.assertIn("Content block expected for the "rql-table" "
- "directive; none found" , out)
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ out = rest_publish(context, """.. rql-table::""")
+ self.assertIn("System Message: ERROR", out)
+ self.assertIn("Content block expected for the "rql-table" "
+ "directive; none found" , out)
def test_rqltable_norset(self):
- context = self.context()
- rql = "Any X WHERE X is CWUser, X firstname 'franky'"
- out = rest_publish(
- context, """\
+ with self.admin_access.web_request() as req:
+ context = self.context(req)
+ rql = "Any X WHERE X is CWUser, X firstname 'franky'"
+ out = rest_publish(
+ context, """\
.. rql-table::
- %(rql)s""" % {'rql': rql})
- self.assertIn("System Message: WARNING", out)
- self.assertIn("empty result set", out)
+ %(rql)s""" % {'rql': rql})
+ self.assertIn("System Message: WARNING", out)
+ self.assertIn("empty result set", out)
def test_rqltable_nooptions(self):
- rql = """Any S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- out = rest_publish(
- self.context(), """\
+ with self.admin_access.web_request() as req:
+ rql = "Any S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ out = rest_publish(
+ self.context(req), """\
.. rql-table::
%(rql)s
- """ % {'rql': rql})
- req = self.request()
- view = self.vreg['views'].select('table', req, rset=req.execute(rql))
- self.assertEqual(view.render(w=None)[49:], out[49:])
+ """ % {'rql': rql})
+ view = self.vreg['views'].select('table', req, rset=req.execute(rql))
+ self.assertEqual(view.render(w=None)[49:], out[49:])
def test_rqltable_vid(self):
- rql = """Any S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- vid = 'mytable'
- out = rest_publish(
- self.context(), """\
+ with self.admin_access.web_request() as req:
+ rql = "Any S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ vid = 'mytable'
+ out = rest_publish(
+ self.context(req), """\
.. rql-table::
:vid: %(vid)s
%(rql)s
- """ % {'rql': rql, 'vid': vid})
- req = self.request()
- view = self.vreg['views'].select(vid, req, rset=req.execute(rql))
- self.assertEqual(view.render(w=None)[49:], out[49:])
- self.assertIn(vid, out[:49])
+ """ % {'rql': rql, 'vid': vid})
+ view = self.vreg['views'].select(vid, req, rset=req.execute(rql))
+ self.assertEqual(view.render(w=None)[49:], out[49:])
+ self.assertIn(vid, out[:49])
def test_rqltable_badvid(self):
- rql = """Any S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- vid = 'mytabel'
- out = rest_publish(
- self.context(), """\
+ with self.admin_access.web_request() as req:
+ rql = "Any S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ vid = 'mytabel'
+ out = rest_publish(
+ self.context(req), """\
.. rql-table::
:vid: %(vid)s
%(rql)s
- """ % {'rql': rql, 'vid': vid})
- self.assertIn("fail to select '%s' view" % vid, out)
+ """ % {'rql': rql, 'vid': vid})
+ self.assertIn("fail to select '%s' view" % vid, out)
def test_rqltable_headers(self):
- rql = """Any S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- headers = ["nom", "prenom", "identifiant"]
- out = rest_publish(
- self.context(), """\
-.. rql-table::
- :headers: %(headers)s
-
- %(rql)s
- """ % {'rql': rql, 'headers': ', '.join(headers)})
- req = self.request()
- view = self.vreg['views'].select('table', req, rset=req.execute(rql))
- view.headers = headers
- self.assertEqual(view.render(w=None)[49:], out[49:])
-
- def test_rqltable_headers_missing(self):
- rql = """Any S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- headers = ["nom", "", "identifiant"]
- out = rest_publish(
- self.context(), """\
+ with self.admin_access.web_request() as req:
+ rql = "Any S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ headers = ["nom", "prenom", "identifiant"]
+ out = rest_publish(
+ self.context(req), """\
.. rql-table::
:headers: %(headers)s
%(rql)s
- """ % {'rql': rql, 'headers': ', '.join(headers)})
- req = self.request()
- view = self.vreg['views'].select('table', req, rset=req.execute(rql))
- view.headers = [headers[0], None, headers[2]]
- self.assertEqual(view.render(w=None)[49:], out[49:])
+ """ % {'rql': rql, 'headers': ', '.join(headers)})
+ view = self.vreg['views'].select('table', req, rset=req.execute(rql))
+ view.headers = headers
+ self.assertEqual(view.render(w=None)[49:], out[49:])
- def test_rqltable_headers_missing_edges(self):
- rql = """Any S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- headers = [" ", "prenom", ""]
- out = rest_publish(
- self.context(), """\
+ def test_rqltable_headers_missing(self):
+ with self.admin_access.web_request() as req:
+ rql = "Any S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ headers = ["nom", "", "identifiant"]
+ out = rest_publish(
+ self.context(req), """\
.. rql-table::
:headers: %(headers)s
%(rql)s
- """ % {'rql': rql, 'headers': ', '.join(headers)})
- req = self.request()
- view = self.vreg['views'].select('table', req, rset=req.execute(rql))
- view.headers = [None, headers[1], None]
- self.assertEqual(view.render(w=None)[49:], out[49:])
+ """ % {'rql': rql, 'headers': ', '.join(headers)})
+ view = self.vreg['views'].select('table', req, rset=req.execute(rql))
+ view.headers = [headers[0], None, headers[2]]
+ self.assertEqual(view.render(w=None)[49:], out[49:])
+
+ def test_rqltable_headers_missing_edges(self):
+ with self.admin_access.web_request() as req:
+ rql = "Any S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ headers = [" ", "prenom", ""]
+ out = rest_publish(
+ self.context(req), """\
+.. rql-table::
+ :headers: %(headers)s
+
+ %(rql)s
+ """ % {'rql': rql, 'headers': ', '.join(headers)})
+ view = self.vreg['views'].select('table', req, rset=req.execute(rql))
+ view.headers = [None, headers[1], None]
+ self.assertEqual(view.render(w=None)[49:], out[49:])
def test_rqltable_colvids(self):
- rql = """Any X,S,F,L WHERE X is CWUser, X surname S,
- X firstname F, X login L"""
- colvids = {0: "oneline"}
- out = rest_publish(
- self.context(), """\
+ with self.admin_access.web_request() as req:
+ rql = "Any X,S,F,L WHERE X is CWUser, X surname S, X firstname F, X login L"
+ colvids = {0: "oneline"}
+ out = rest_publish(
+ self.context(req), """\
.. rql-table::
:colvids: %(colvids)s
%(rql)s
- """ % {'rql': rql,
- 'colvids': ', '.join(["%d=%s" % (k, v)
- for k, v in colvids.iteritems()])
- })
- req = self.request()
- view = self.vreg['views'].select('table', req, rset=req.execute(rql))
- view.cellvids = colvids
- self.assertEqual(view.render(w=None)[49:], out[49:])
+ """ % {'rql': rql,
+ 'colvids': ', '.join(["%d=%s" % (k, v)
+ for k, v in colvids.iteritems()])
+ })
+ view = self.vreg['views'].select('table', req, rset=req.execute(rql))
+ view.cellvids = colvids
+ self.assertEqual(view.render(w=None)[49:], out[49:])
if __name__ == '__main__':
--- a/hooks/syncschema.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/syncschema.py Fri Jul 18 17:35:25 2014 +0200
@@ -653,6 +653,9 @@
else:
self.critical('constraint %s for rdef %s was missing or already removed',
self.oldcstr, rdef)
+ if cnx.deleted_in_transaction(rdef.eid):
+ # don't try to alter a table that's going away (or is already gone)
+ return
# then update database: alter the physical schema on size/unique
# constraint changes
syssource = cnx.repo.system_source
--- a/hooks/test/unittest_bookmarks.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/test/unittest_bookmarks.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# 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.
@@ -22,16 +22,17 @@
def test_auto_delete_bookmarks(self):
- beid = self.execute('INSERT Bookmark X: X title "hop", X path "view", X bookmarked_by U '
- 'WHERE U login "admin"')[0][0]
- self.execute('SET X bookmarked_by U WHERE U login "anon"')
- self.commit()
- self.execute('DELETE X bookmarked_by U WHERE U login "admin"')
- self.commit()
- self.assertTrue(self.execute('Any X WHERE X eid %(x)s', {'x': beid}))
- self.execute('DELETE X bookmarked_by U WHERE U login "anon"')
- self.commit()
- self.assertFalse(self.execute('Any X WHERE X eid %(x)s', {'x': beid}))
+ with self.admin_access.repo_cnx() as cnx:
+ beid = cnx.execute('INSERT Bookmark X: X title "hop", X path "view", X bookmarked_by U '
+ 'WHERE U login "admin"')[0][0]
+ cnx.execute('SET X bookmarked_by U WHERE U login "anon"')
+ cnx.commit()
+ cnx.execute('DELETE X bookmarked_by U WHERE U login "admin"')
+ cnx.commit()
+ self.assertTrue(cnx.execute('Any X WHERE X eid %(x)s', {'x': beid}))
+ cnx.execute('DELETE X bookmarked_by U WHERE U login "anon"')
+ cnx.commit()
+ self.assertFalse(cnx.execute('Any X WHERE X eid %(x)s', {'x': beid}))
if __name__ == '__main__':
unittest_main()
--- a/hooks/test/unittest_hooks.py Thu Jul 17 11:08:56 2014 +0200
+++ b/hooks/test/unittest_hooks.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# 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.
@@ -30,177 +30,189 @@
class CoreHooksTC(CubicWebTC):
def test_inlined(self):
- self.assertEqual(self.repo.schema['sender'].inlined, True)
- 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"')
- eeid = 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')[0][0]
- self.execute('SET X sender Y WHERE X is Email, Y is EmailAddress')
- rset = self.execute('Any S WHERE X sender S, X eid %s' % eeid)
- self.assertEqual(len(rset), 1)
+ with self.admin_access.repo_cnx() as cnx:
+ self.assertEqual(self.repo.schema['sender'].inlined, True)
+ 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"')
+ eeid = 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')[0][0]
+ cnx.execute('SET X sender Y WHERE X is Email, Y is EmailAddress')
+ rset = cnx.execute('Any S WHERE X sender S, X eid %s' % eeid)
+ self.assertEqual(len(rset), 1)
def test_symmetric(self):
- req = self.request()
- u1 = self.create_user(req, u'1')
- u2 = self.create_user(req, u'2')
- u3 = self.create_user(req, u'3')
- ga = req.create_entity('CWGroup', name=u'A')
- gb = req.create_entity('CWGroup', name=u'B')
- u1.cw_set(friend=u2)
- u2.cw_set(friend=u3)
- ga.cw_set(friend=gb)
- ga.cw_set(friend=u1)
- self.commit()
- req = self.request()
- for l1, l2 in ((u'1', u'2'),
- (u'2', u'3')):
- self.assertTrue(req.execute('Any U1,U2 WHERE U1 friend U2, U1 login %(l1)s, U2 login %(l2)s',
- {'l1': l1, 'l2': l2}))
- self.assertTrue(req.execute('Any U1,U2 WHERE U2 friend U1, U1 login %(l1)s, U2 login %(l2)s',
- {'l1': l1, 'l2': l2}))
- self.assertTrue(req.execute('Any GA,GB WHERE GA friend GB, GA name "A", GB name "B"'))
- self.assertTrue(req.execute('Any GA,GB WHERE GB friend GA, GA name "A", GB name "B"'))
- self.assertTrue(req.execute('Any GA,U1 WHERE GA friend U1, GA name "A", U1 login "1"'))
- self.assertTrue(req.execute('Any GA,U1 WHERE U1 friend GA, GA name "A", U1 login "1"'))
- self.assertFalse(req.execute('Any GA,U WHERE GA friend U, GA name "A", U login "2"'))
- for l1, l2 in ((u'1', u'3'),
- (u'3', u'1')):
- self.assertFalse(req.execute('Any U1,U2 WHERE U1 friend U2, U1 login %(l1)s, U2 login %(l2)s',
- {'l1': l1, 'l2': l2}))
- self.assertFalse(req.execute('Any U1,U2 WHERE U2 friend U1, U1 login %(l1)s, U2 login %(l2)s',
- {'l1': l1, 'l2': l2}))
+ with self.admin_access.repo_cnx() as cnx:
+ u1 = self.create_user(cnx, u'1')
+ u2 = self.create_user(cnx, u'2')
+ u3 = self.create_user(cnx, u'3')
+ ga = cnx.create_entity('CWGroup', name=u'A')
+ gb = cnx.create_entity('CWGroup', name=u'B')
+ u1.cw_set(friend=u2)
+ u2.cw_set(friend=u3)
+ ga.cw_set(friend=gb)
+ ga.cw_set(friend=u1)
+ cnx.commit()
+ for l1, l2 in ((u'1', u'2'),
+ (u'2', u'3')):
+ self.assertTrue(cnx.execute('Any U1,U2 WHERE U1 friend U2, U1 login %(l1)s, U2 login %(l2)s',
+ {'l1': l1, 'l2': l2}))
+ self.assertTrue(cnx.execute('Any U1,U2 WHERE U2 friend U1, U1 login %(l1)s, U2 login %(l2)s',
+ {'l1': l1, 'l2': l2}))
+ self.assertTrue(cnx.execute('Any GA,GB WHERE GA friend GB, GA name "A", GB name "B"'))
+ self.assertTrue(cnx.execute('Any GA,GB WHERE GB friend GA, GA name "A", GB name "B"'))
+ self.assertTrue(cnx.execute('Any GA,U1 WHERE GA friend U1, GA name "A", U1 login "1"'))
+ self.assertTrue(cnx.execute('Any GA,U1 WHERE U1 friend GA, GA name "A", U1 login "1"'))
+ self.assertFalse(cnx.execute('Any GA,U WHERE GA friend U, GA name "A", U login "2"'))
+ for l1, l2 in ((u'1', u'3'),
+ (u'3', u'1')):
+ self.assertFalse(cnx.execute('Any U1,U2 WHERE U1 friend U2, U1 login %(l1)s, U2 login %(l2)s',
+ {'l1': l1, 'l2': l2}))
+ self.assertFalse(cnx.execute('Any U1,U2 WHERE U2 friend U1, U1 login %(l1)s, U2 login %(l2)s',
+ {'l1': l1, 'l2': l2}))
def test_html_tidy_hook(self):
- req = self.request()
- entity = req.create_entity('Workflow', name=u'wf1',
- description_format=u'text/html',
- description=u'yo')
- self.assertEqual(entity.description, u'yo')
- entity = req.create_entity('Workflow', name=u'wf2',
- description_format=u'text/html',
- description=u'<b>yo')
- self.assertEqual(entity.description, u'<b>yo</b>')
- entity = req.create_entity('Workflow', name=u'wf3',
- description_format=u'text/html',
- description=u'<b>yo</b>')
- self.assertEqual(entity.description, u'<b>yo</b>')
- entity = req.create_entity('Workflow', name=u'wf4',
- description_format=u'text/html',
- description=u'<b>R&D</b>')
- self.assertEqual(entity.description, u'<b>R&D</b>')
- entity = req.create_entity('Workflow', name=u'wf5',
- description_format=u'text/html',
- description=u"<div>c'est <b>l'été")
- self.assertEqual(entity.description, u"<div>c'est <b>l'été</b></div>")
+ with self.admin_access.client_cnx() as cnx:
+ entity = cnx.create_entity('Workflow', name=u'wf1',
+ description_format=u'text/html',
+ description=u'yo')
+ self.assertEqual(entity.description, u'yo')
+ entity = cnx.create_entity('Workflow', name=u'wf2',
+ description_format=u'text/html',
+ description=u'<b>yo')
+ self.assertEqual(entity.description, u'<b>yo</b>')
+ entity = cnx.create_entity('Workflow', name=u'wf3',
+ description_format=u'text/html',
+ description=u'<b>yo</b>')
+ self.assertEqual(entity.description, u'<b>yo</b>')
+ entity = cnx.create_entity('Workflow', name=u'wf4',
+ description_format=u'text/html',
+ description=u'<b>R&D</b>')
+ self.assertEqual(entity.description, u'<b>R&D</b>')
+ entity = cnx.create_entity('Workflow', name=u'wf5',
+ description_format=u'text/html',
+ description=u"<div>c'est <b>l'été")
+ self.assertEqual(entity.description, u"<div>c'est <b>l'été</b></div>")
def test_nonregr_html_tidy_hook_no_update(self):
- entity = self.request().create_entity('Workflow', name=u'wf1',
- description_format=u'text/html',
- description=u'yo')
- entity.cw_set(name=u'wf2')
- self.assertEqual(entity.description, u'yo')
- entity.cw_set(description=u'R&D<p>yo')
- self.assertEqual(entity.description, u'R&D<p>yo</p>')
+ with self.admin_access.client_cnx() as cnx:
+ entity = cnx.create_entity('Workflow', name=u'wf1',
+ description_format=u'text/html',
+ description=u'yo')
+ entity.cw_set(name=u'wf2')
+ self.assertEqual(entity.description, u'yo')
+ entity.cw_set(description=u'R&D<p>yo')
+ self.assertEqual(entity.description, u'R&D<p>yo</p>')
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__':
--- 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
--- 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 <http://www.gnu.org/licenses/>.
"""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()
--- 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
--- 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)
--- 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, "
--- 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
--- 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:
--- 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:
--- 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)
--- 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):
--- 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:
--- 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 '<b>hop hop</b>', 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 '<b>hop hop</b>', 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()
--- 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
--- 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
--- 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']
--- 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'))
--- 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:
--- 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 {
--- 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);
});
}
--- 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 {
--- 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()
--- 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 <http://www.gnu.org/licenses/>.
"""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__':
--- 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,
--- 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'),
- '<a href="http://testing.fr/cubicweb/folder/%s" title="">chi&ld</a>' % f2.eid)
+ '<a href="http://testing.fr/cubicweb/folder/%s" title="">'
+ 'chi&ld</a>' % f2.eid)
childrset = f2.as_rset()
ibc = self.vreg['ctxcomponents'].select('breadcrumbs', req, rset=childrset)
l = []
ibc.render(l.append)
- self.assertEqual(''.join(l),
- """<span id="breadcrumbs" class="pathbar"> > <a href="http://testing.fr/cubicweb/Folder">Folder_plural</a> > <a href="http://testing.fr/cubicweb/folder/%s" title="">par&ent</a> > 
-<a href="http://testing.fr/cubicweb/folder/%s" title="">chi&ld</a></span>""" % (f1.eid, f2.eid))
+ self.assertMultiLineEqual('<span id="breadcrumbs" class="pathbar"> > '
+ '<a href="http://testing.fr/cubicweb/Folder">Folder_plural</a>'
+ ' > <a href="http://testing.fr/cubicweb/folder/%s" '
+ 'title="">par&ent</a> > \n'
+ '<a href="http://testing.fr/cubicweb/folder/%s" title="">'
+ 'chi&ld</a></span>' % (f1.eid, f2.eid),
+ ''.join(l))
if __name__ == '__main__':
from logilab.common.testlib import unittest_main
--- 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')
--- 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': '''<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><div id="title-subject-%(eid)s" class="editableField hidden"><div id="title-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'title', 'subject', 'title-subject-%(eid)s', false, '', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>''',
- 'long_desc': '''<div id="long_desc-subject-%(eid)s-reledit" onmouseout="jQuery('#long_desc-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#long_desc-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="long_desc-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><div id="long_desc-subject-%(eid)s" class="editableField hidden"><div id="long_desc-subject-%(eid)s-add" class="editableField" onclick="cw.reledit.loadInlineEditionForm('edition', %(eid)s, 'long_desc', 'subject', 'long_desc-subject-%(eid)s', false, 'autolimited', 'add');" title="click to add a value"><img title="click to add a value" src="http://testing.fr/cubicweb/data/plus.png" alt="click to add a value"/></div></div></div>''',
- 'manager': '''<div id="manager-subject-%(eid)s-reledit" onmouseout="jQuery('#manager-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#manager-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="manager-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><div id="manager-subject-%(eid)s" class="editableField hidden"><div id="manager-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>''',
+ reledit = {'title': '''<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><div id="title-subject-%(eid)s" class="editableField invisible"><div id="title-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'title', 'subject', 'title-subject-%(eid)s', false, '', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>''',
+ 'long_desc': '''<div id="long_desc-subject-%(eid)s-reledit" onmouseout="jQuery('#long_desc-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#long_desc-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="long_desc-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><div id="long_desc-subject-%(eid)s" class="editableField invisible"><div id="long_desc-subject-%(eid)s-add" class="editableField" onclick="cw.reledit.loadInlineEditionForm('edition', %(eid)s, 'long_desc', 'subject', 'long_desc-subject-%(eid)s', false, 'autolimited', 'add');" title="click to add a value"><img title="click to add a value" src="http://testing.fr/cubicweb/data/plus.png" alt="click to add a value"/></div></div></div>''',
+ 'manager': '''<div id="manager-subject-%(eid)s-reledit" onmouseout="jQuery('#manager-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#manager-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="manager-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><div id="manager-subject-%(eid)s" class="editableField invisible"><div id="manager-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>''',
'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': """<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="title-subject-%(eid)s-form" onsubmit="return freezeFormButtons('title-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
+ doreledit = {'title': """<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="title-subject-%(eid)s-form" onsubmit="return freezeFormButtons('title-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
<fieldset>
<input name="__form_id" type="hidden" value="base" />
<input name="__errorurl" type="hidden" value="http://testing.fr/cubicweb/view?rql=Blop&vid=blop#title-subject-%(eid)s-form" />
@@ -82,12 +82,12 @@
<td><button class="validateButton" onclick="cw.reledit.cleanupAfterCancel('title-subject-%(eid)s')" tabindex="3" type="button" value="button_cancel"><img alt="CANCEL_ICON" src="http://testing.fr/cubicweb/data/cancel.png" />button_cancel</button></td>
</tr></table>
</fieldset>
-</form><div id="title-subject-%(eid)s" class="editableField hidden"><div id="title-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'title', 'subject', 'title-subject-%(eid)s', false, '');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
+</form><div id="title-subject-%(eid)s" class="editableField invisible"><div id="title-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'title', 'subject', 'title-subject-%(eid)s', false, '');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
- 'long_desc': """<div id="long_desc-subject-%(eid)s-reledit" onmouseout="jQuery('#long_desc-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#long_desc-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="long_desc-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="long_desc-subject-%(eid)s-form" onsubmit="return freezeFormButtons('long_desc-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
+ 'long_desc': """<div id="long_desc-subject-%(eid)s-reledit" onmouseout="jQuery('#long_desc-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#long_desc-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="long_desc-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="long_desc-subject-%(eid)s-form" onsubmit="return freezeFormButtons('long_desc-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
<fieldset>
-<input name="__form_id" type="hidden" value="edition" />
-<input name="__errorurl" type="hidden" value="http://testing.fr/cubicweb/view?rql=Blop&vid=blop#long_desc-subject-%(eid)s-form" />
+<input name="__form_id" type="invisible" value="edition" />
+<input name="__errorurl" type="invisible" value="http://testing.fr/cubicweb/view?rql=Blop&vid=blop#long_desc-subject-%(eid)s-form" />
<input name="__domid" type="hidden" value="long_desc-subject-%(eid)s-form" />
<input name="__type:A" type="hidden" value="Blog" />
<input name="eid" type="hidden" value="A" />
@@ -126,9 +126,9 @@
<td><button class="validateButton" onclick="cw.reledit.cleanupAfterCancel('long_desc-subject-%(eid)s')" tabindex="8" type="button" value="button_cancel"><img alt="CANCEL_ICON" src="http://testing.fr/cubicweb/data/cancel.png" />button_cancel</button></td>
</tr></table>
</fieldset>
-</form><div id="long_desc-subject-%(eid)s" class="editableField hidden"><div id="long_desc-subject-%(eid)s-add" class="editableField" onclick="cw.reledit.loadInlineEditionForm('edition', %(eid)s, 'long_desc', 'subject', 'long_desc-subject-%(eid)s', false, 'autolimited');" title="click to add a value"><img title="click to add a value" src="http://testing.fr/cubicweb/data/plus.png" alt="click to add a value"/></div></div></div>""",
+</form><div id="long_desc-subject-%(eid)s" class="editableField invisible"><div id="long_desc-subject-%(eid)s-add" class="editableField" onclick="cw.reledit.loadInlineEditionForm('edition', %(eid)s, 'long_desc', 'subject', 'long_desc-subject-%(eid)s', false, 'autolimited');" title="click to add a value"><img title="click to add a value" src="http://testing.fr/cubicweb/data/plus.png" alt="click to add a value"/></div></div></div>""",
- 'manager': """<div id="manager-subject-%(eid)s-reledit" onmouseout="jQuery('#manager-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#manager-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="manager-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="manager-subject-%(eid)s-form" onsubmit="return freezeFormButtons('manager-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
+ 'manager': """<div id="manager-subject-%(eid)s-reledit" onmouseout="jQuery('#manager-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#manager-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="manager-subject-%(eid)s-value" class="editableFieldValue"><not specified></div><form action="http://testing.fr/cubicweb/validateform?__onsuccess=window.parent.cw.reledit.onSuccess" method="post" enctype="application/x-www-form-urlencoded" id="manager-subject-%(eid)s-form" onsubmit="return freezeFormButtons('manager-subject-%(eid)s-form');" class="releditForm" cubicweb:target="eformframe">
<fieldset>
<input name="__form_id" type="hidden" value="base" />
<input name="__errorurl" type="hidden" value="http://testing.fr/cubicweb/view?rql=Blop&vid=blop#manager-subject-%(eid)s-form" />
@@ -162,7 +162,7 @@
<td><button class="validateButton" onclick="cw.reledit.cleanupAfterCancel('manager-subject-%(eid)s')" tabindex="11" type="button" value="button_cancel"><img alt="CANCEL_ICON" src="http://testing.fr/cubicweb/data/cancel.png" />button_cancel</button></td>
</tr></table>
</fieldset>
-</form><div id="manager-subject-%(eid)s" class="editableField hidden"><div id="manager-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
+</form><div id="manager-subject-%(eid)s" class="editableField invisible"><div id="manager-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
'composite_card11_2ttypes': """<not specified>""",
'concerns': """<not specified>"""
}
@@ -198,11 +198,11 @@
reledit_ctrl.tag_object_of(('Ticket', 'concerns', 'Project'),
{'edit_target': 'rtype'})
reledit = {
- 'title': """<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><div id="title-subject-%(eid)s" class="editableField hidden"><div id="title-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'title', 'subject', 'title-subject-%(eid)s', true, '', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
- 'long_desc': """<div id="long_desc-subject-%(eid)s-reledit" onmouseout="jQuery('#long_desc-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#long_desc-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="long_desc-subject-%(eid)s-value" class="editableFieldValue"><long_desc is required></div><div id="long_desc-subject-%(eid)s" class="editableField hidden"><div id="long_desc-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'long_desc', 'subject', 'long_desc-subject-%(eid)s', true, 'autolimited', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
- 'manager': """<div id="manager-subject-%(eid)s-reledit" onmouseout="jQuery('#manager-subject-%(eid)s').addClass('hidden')" onmouseover="jQuery('#manager-subject-%(eid)s').removeClass('hidden')" class="releditField"><div id="manager-subject-%(eid)s-value" class="editableFieldValue"><a href="http://testing.fr/cubicweb/personne/%(toto)s" title="">Toto</a></div><div id="manager-subject-%(eid)s" class="editableField hidden"><div id="manager-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('edition', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited', 'edit_related');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div><div id="manager-subject-%(eid)s-delete" class="editableField" onclick="cw.reledit.loadInlineEditionForm('deleteconf', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited', 'delete');" title="click to delete this value"><img title="click to delete this value" src="http://testing.fr/cubicweb/data/cancel.png" alt="click to delete this value"/></div></div></div>""",
+ 'title': """<div id="title-subject-%(eid)s-reledit" onmouseout="jQuery('#title-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#title-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="title-subject-%(eid)s-value" class="editableFieldValue">cubicweb-world-domination</div><div id="title-subject-%(eid)s" class="editableField invisible"><div id="title-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'title', 'subject', 'title-subject-%(eid)s', true, '', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
+ 'long_desc': """<div id="long_desc-subject-%(eid)s-reledit" onmouseout="jQuery('#long_desc-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#long_desc-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="long_desc-subject-%(eid)s-value" class="editableFieldValue"><long_desc is required></div><div id="long_desc-subject-%(eid)s" class="editableField invisible"><div id="long_desc-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'long_desc', 'subject', 'long_desc-subject-%(eid)s', true, 'autolimited', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>""",
+ 'manager': """<div id="manager-subject-%(eid)s-reledit" onmouseout="jQuery('#manager-subject-%(eid)s').addClass('invisible')" onmouseover="jQuery('#manager-subject-%(eid)s').removeClass('invisible')" class="releditField"><div id="manager-subject-%(eid)s-value" class="editableFieldValue"><a href="http://testing.fr/cubicweb/personne/%(toto)s" title="">Toto</a></div><div id="manager-subject-%(eid)s" class="editableField invisible"><div id="manager-subject-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('edition', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited', 'edit_related');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div><div id="manager-subject-%(eid)s-delete" class="editableField" onclick="cw.reledit.loadInlineEditionForm('deleteconf', %(eid)s, 'manager', 'subject', 'manager-subject-%(eid)s', false, 'autolimited', 'delete');" title="click to delete this value"><img title="click to delete this value" src="http://testing.fr/cubicweb/data/cancel.png" alt="click to delete this value"/></div></div></div>""",
'composite_card11_2ttypes': """<not specified>""",
- 'concerns': """<div id="concerns-object-%(eid)s-reledit" onmouseout="jQuery('#concerns-object-%(eid)s').addClass('hidden')" onmouseover="jQuery('#concerns-object-%(eid)s').removeClass('hidden')" class="releditField"><div id="concerns-object-%(eid)s-value" class="editableFieldValue"><a href="http://testing.fr/cubicweb/ticket/%(tick)s" title="">write the code</a></div><div id="concerns-object-%(eid)s" class="editableField hidden"><div id="concerns-object-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'concerns', 'object', 'concerns-object-%(eid)s', false, 'autolimited', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>"""
+ 'concerns': """<div id="concerns-object-%(eid)s-reledit" onmouseout="jQuery('#concerns-object-%(eid)s').addClass('invisible')" onmouseover="jQuery('#concerns-object-%(eid)s').removeClass('invisible')" class="releditField"><div id="concerns-object-%(eid)s-value" class="editableFieldValue"><a href="http://testing.fr/cubicweb/ticket/%(tick)s" title="">write the code</a></div><div id="concerns-object-%(eid)s" class="editableField invisible"><div id="concerns-object-%(eid)s-update" class="editableField" onclick="cw.reledit.loadInlineEditionForm('base', %(eid)s, 'concerns', 'object', 'concerns-object-%(eid)s', false, 'autolimited', 'edit_rtype');" title="click to edit this field"><img title="click to edit this field" src="http://testing.fr/cubicweb/data/pen_icon.png" alt="click to edit this field"/></div></div></div>"""
}
with self.admin_access.web_request() as req:
proj = req.entity_from_eid(self.proj)
--- a/web/test/unittest_urlpublisher.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_urlpublisher.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.
@@ -33,106 +33,135 @@
"""test suite for QSPreProcessor"""
def setup_database(self):
- req = self.request()
- self.create_user(req, u'ÿsaÿe')
- b = req.create_entity('BlogEntry', title=u'hell\'o', content=u'blabla')
- c = req.create_entity('Tag', name=u'yo') # take care: Tag's name normalized to lower case
- self.execute('SET C tags B WHERE C eid %(c)s, B eid %(b)s', {'c':c.eid, 'b':b.eid})
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, u'ÿsaÿe')
+ b = cnx.create_entity('BlogEntry', title=u'hell\'o', content=u'blabla')
+ # take care: Tag's name normalized to lower case
+ c = cnx.create_entity('Tag', name=u'yo')
+ cnx.execute('SET C tags B WHERE C eid %(c)s, B eid %(b)s',
+ {'c':c.eid, 'b':b.eid})
+ cnx.commit()
- def process(self, url):
- req = self.req = self.request()
+ def process(self, req, url):
return self.app.url_resolver.process(req, url)
def test_raw_path(self):
"""tests raw path resolution'"""
- self.assertEqual(self.process('view'), ('view', None))
- self.assertEqual(self.process('edit'), ('edit', None))
- self.assertRaises(NotFound, self.process, 'whatever')
+ with self.admin_access.web_request() as req:
+ self.assertEqual(self.process(req, 'view'), ('view', None))
+ self.assertEqual(self.process(req, 'edit'), ('edit', None))
+ self.assertRaises(NotFound, self.process, req, 'whatever')
def test_eid_path(self):
"""tests eid path resolution"""
- self.assertIsInstance(self.process('123')[1], ResultSet)
- self.assertEqual(len(self.process('123')[1]), 1)
- self.assertRaises(NotFound, self.process, '123/345')
- self.assertRaises(NotFound, self.process, 'not_eid')
+ with self.admin_access.web_request() as req:
+ self.assertIsInstance(self.process(req, '123')[1], ResultSet)
+ self.assertEqual(len(self.process(req, '123')[1]), 1)
+ self.assertRaises(NotFound, self.process, req, '123/345')
+ self.assertRaises(NotFound, self.process, req, 'not_eid')
def test_rest_path_etype(self):
"""tests the rest path resolution"""
- ctrl, rset = self.process('CWEType')
- self.assertEqual(ctrl, 'view')
- self.assertEqual(rset.description[0][0], 'CWEType')
- self.assertEqual(rset.printable_rql(),
- "Any X,AA,AB ORDERBY AA WHERE X is_instance_of CWEType, X name AA, X modification_date AB")
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'CWEType')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(rset.description[0][0], 'CWEType')
+ self.assertEqual("Any X,AA,AB ORDERBY AA WHERE X is_instance_of CWEType, "
+ "X name AA, X modification_date AB",
+ rset.printable_rql())
def test_rest_path_by_attr(self):
- ctrl, rset = self.process('CWUser/login/admin')
- self.assertEqual(ctrl, 'view')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset.description[0][0], 'CWUser')
- self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "admin"')
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'CWUser/login/admin')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual('Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, '
+ 'X login AA, X firstname AB, X surname AC, '
+ 'X modification_date AD, X login "admin"',
+ rset.printable_rql())
def test_rest_path_unique_attr(self):
- ctrl, rset = self.process('cwuser/admin')
- self.assertEqual(ctrl, 'view')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset.description[0][0], 'CWUser')
- self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "admin"')
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'cwuser/admin')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual('Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, '
+ 'X login AA, X firstname AB, X surname AC, '
+ 'X modification_date AD, X login "admin"',
+ rset.printable_rql())
def test_rest_path_eid(self):
- ctrl, rset = self.process('cwuser/eid/%s' % self.user().eid)
- self.assertEqual(ctrl, 'view')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset.description[0][0], 'CWUser')
- self.assertEqual(rset.printable_rql(), 'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X eid %s' % rset[0][0])
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'cwuser/eid/%s' % self.user(req).eid)
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual('Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, '
+ 'X login AA, X firstname AB, X surname AC, '
+ 'X modification_date AD, X eid %s' % rset[0][0],
+ rset.printable_rql())
def test_rest_path_non_ascii_paths(self):
- ctrl, rset = self.process('CWUser/login/%C3%BFsa%C3%BFe')
- self.assertEqual(ctrl, 'view')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset.description[0][0], 'CWUser')
- self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, X login AA, X firstname AB, X surname AC, X modification_date AD, X login "\xffsa\xffe"')
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'CWUser/login/%C3%BFsa%C3%BFe')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'CWUser')
+ self.assertEqual(u'Any X,AA,AB,AC,AD WHERE X is_instance_of CWUser, '
+ u'X login AA, X firstname AB, X surname AC, '
+ u'X modification_date AD, X login "\xffsa\xffe"',
+ rset.printable_rql())
def test_rest_path_quoted_paths(self):
- ctrl, rset = self.process('BlogEntry/title/hell%27o')
- self.assertEqual(ctrl, 'view')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset.description[0][0], 'BlogEntry')
- self.assertEqual(rset.printable_rql(), u'Any X,AA,AB,AC WHERE X is_instance_of BlogEntry, X creation_date AA, X title AB, X modification_date AC, X title "hell\'o"')
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'BlogEntry/title/hell%27o')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset.description[0][0], 'BlogEntry')
+ self.assertEqual(u'Any X,AA,AB,AC WHERE X is_instance_of BlogEntry, '
+ 'X creation_date AA, X title AB, X modification_date AC, '
+ 'X title "hell\'o"',
+ rset.printable_rql())
def test_rest_path_errors(self):
- self.assertRaises(NotFound, self.process, 'CWUser/eid/30000')
- self.assertRaises(NotFound, self.process, 'Workcases')
- self.assertRaises(NotFound, self.process, 'CWUser/inexistant_attribute/joe')
+ with self.admin_access.web_request() as req:
+ self.assertRaises(NotFound, self.process, req, 'CWUser/eid/30000')
+ self.assertRaises(NotFound, self.process, req, 'Workcases')
+ self.assertRaises(NotFound, self.process, req, 'CWUser/inexistant_attribute/joe')
def test_action_path(self):
"""tests the action path resolution"""
- self.assertRaises(Redirect, self.process, '1/edit')
- self.assertRaises(Redirect, self.process, 'Tag/name/yo/edit')
- self.assertRaises(Redirect, self.process, 'Tag/yo/edit')
- self.assertRaises(NotFound, self.process, 'view/edit')
- self.assertRaises(NotFound, self.process, '1/non_action')
- self.assertRaises(NotFound, self.process, 'CWUser/login/admin/non_action')
+ with self.admin_access.web_request() as req:
+ self.assertRaises(Redirect, self.process, req, '1/edit')
+ self.assertRaises(Redirect, self.process, req, 'Tag/name/yo/edit')
+ self.assertRaises(Redirect, self.process, req, 'Tag/yo/edit')
+ self.assertRaises(NotFound, self.process, req, 'view/edit')
+ self.assertRaises(NotFound, self.process, req, '1/non_action')
+ self.assertRaises(NotFound, self.process, req, 'CWUser/login/admin/non_action')
def test_regexp_path(self):
"""tests the regexp path resolution"""
- ctrl, rset = self.process('add/Task')
- self.assertEqual(ctrl, 'view')
- self.assertEqual(rset, None)
- self.assertEqual(self.req.form, {'etype' : "Task", 'vid' : "creation"})
- self.assertRaises(NotFound, self.process, 'add/foo/bar')
-
+ with self.admin_access.web_request() as req:
+ ctrl, rset = self.process(req, 'add/Task')
+ self.assertEqual(ctrl, 'view')
+ self.assertEqual(rset, None)
+ self.assertEqual(req.form, {'etype' : "Task", 'vid' : "creation"})
+ self.assertRaises(NotFound, self.process, req, 'add/foo/bar')
def test_nonascii_path(self):
oldrules = SimpleReqRewriter.rules
SimpleReqRewriter.rules = [(re.compile('/\w+', re.U), dict(vid='foo')),]
- try:
- path = str(FakeRequest().url_quote(u'été'))
- ctrl, rset = self.process(path)
- self.assertEqual(rset, None)
- self.assertEqual(self.req.form, {'vid' : "foo"})
- finally:
- SimpleReqRewriter.rules = oldrules
+ with self.admin_access.web_request() as req:
+ try:
+ path = str(FakeRequest().url_quote(u'été'))
+ ctrl, rset = self.process(req, path)
+ self.assertEqual(rset, None)
+ self.assertEqual(req.form, {'vid' : "foo"})
+ finally:
+ SimpleReqRewriter.rules = oldrules
if __name__ == '__main__':
--- a/web/test/unittest_urlrewrite.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_urlrewrite.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,7 +21,8 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.devtools.fake import FakeRequest
-from cubicweb.web.views.urlrewrite import SimpleReqRewriter, SchemaBasedRewriter, rgx, rgx_action
+from cubicweb.web.views.urlrewrite import (SimpleReqRewriter, SchemaBasedRewriter,
+ rgx, rgx_action)
class UrlRewriteTC(CubicWebTC):
@@ -99,47 +100,51 @@
def test_inheritance(self):
BaseTransition = self.vreg['etypes'].etype_class('BaseTransition')
- req = self.request()
- x = req.create_entity('WorkflowTransition', name=u'test')
- ctrlid, rset = self.app.url_resolver.process(req, 'basetransition/%s' % x.eid)
- self.assertEqual(ctrlid, 'view')
- self.assertEqual(x.eid, rset[0][0])
- # cw_rest_attr_info is cached but clear_cache doesn't like cached class
- # method
- del BaseTransition._cw_rest_attr_info_cache_
- try:
- with tempattr(BaseTransition, 'rest_attr', 'name'):
+ with self.admin_access.web_request() as req:
+ x = req.create_entity('WorkflowTransition', name=u'test')
+ ctrlid, rset = self.app.url_resolver.process(req, 'basetransition/%s' % x.eid)
+ self.assertEqual(ctrlid, 'view')
+ self.assertEqual(x.eid, rset[0][0])
+ # cw_rest_attr_info is cached but clear_cache doesn't like cached class
+ # method
+ del BaseTransition._cw_rest_attr_info_cache_
+ try:
+ with tempattr(BaseTransition, 'rest_attr', 'name'):
- ctrlid, rset = self.app.url_resolver.process(req, 'basetransition/%s' % x.name)
- self.assertEqual(ctrlid, 'view')
- self.assertEqual(x.eid, rset[0][0])
- finally:
- del BaseTransition._cw_rest_attr_info_cache_
+ ctrlid, rset = self.app.url_resolver.process(req, 'basetransition/%s' % x.name)
+ self.assertEqual(ctrlid, 'view')
+ self.assertEqual(x.eid, rset[0][0])
+ finally:
+ del BaseTransition._cw_rest_attr_info_cache_
class RgxActionRewriteTC(CubicWebTC):
def setup_database(self):
- req = self.request()
- self.p1 = self.create_user(req, u'user1')
- self.p1.cw_set(firstname=u'joe', surname=u'Dalton')
- self.p2 = self.create_user(req, u'user2')
- self.p2.cw_set(firstname=u'jack', surname=u'Dalton')
+ with self.admin_access.repo_cnx() as cnx:
+ p1 = self.create_user(cnx, u'user1')
+ p1.cw_set(firstname=u'joe', surname=u'Dalton')
+ p2 = self.create_user(cnx, u'user2')
+ p2.cw_set(firstname=u'jack', surname=u'Dalton')
+ self.p1eid = p1.eid
+ cnx.commit()
def test_rgx_action_with_transforms(self):
class TestSchemaBasedRewriter(SchemaBasedRewriter):
rules = [
- (rgx('/(?P<sn>\w+)/(?P<fn>\w+)'), rgx_action(r'Any X WHERE X surname %(sn)s, X firstname %(fn)s',
- argsgroups=('sn', 'fn'),
- transforms={'sn' : unicode.capitalize,
- 'fn' : unicode.lower,})),
+ (rgx('/(?P<sn>\w+)/(?P<fn>\w+)'),
+ rgx_action(r'Any X WHERE X surname %(sn)s, '
+ 'X firstname %(fn)s',
+ argsgroups=('sn', 'fn'),
+ transforms={'sn' : unicode.capitalize,
+ 'fn' : unicode.lower,})),
]
- req = self.request()
- rewriter = TestSchemaBasedRewriter(req)
- pmid, rset = rewriter.rewrite(req, u'/DaLToN/JoE')
- self.assertEqual(len(rset), 1)
- self.assertEqual(rset[0][0], self.p1.eid)
+ with self.admin_access.web_request() as req:
+ rewriter = TestSchemaBasedRewriter(req)
+ _pmid, rset = rewriter.rewrite(req, u'/DaLToN/JoE')
+ self.assertEqual(len(rset), 1)
+ self.assertEqual(rset[0][0], self.p1eid)
def test_inheritance_precedence(self):
RQL1 = 'Any C WHERE C is CWEType'
@@ -160,20 +165,20 @@
),
]
- req = self.request()
- rewriter = Rewriter(req)
- pmid, rset = rewriter.rewrite(req, '/collector')
- self.assertEqual(rset.rql, RQL1)
- self.assertEqual(req.form, {'vid' : "baseindex"})
- pmid, rset = rewriter.rewrite(req, '/collector/something')
- self.assertEqual(rset.rql, RQL2)
- self.assertEqual(req.form, {'vid' : "index"})
- pmid, rset = rewriter.rewrite(req, '/collector/something/')
- self.assertEqual(req.form, {'vid' : "index"})
- self.assertEqual(rset.rql, RQL2)
- pmid, rset = rewriter.rewrite(req, '/collector/somethingelse/')
- self.assertEqual(rset.rql, RQL1)
- self.assertEqual(req.form, {'vid' : "baseindex"})
+ with self.admin_access.web_request() as req:
+ rewriter = Rewriter(req)
+ _pmid, rset = rewriter.rewrite(req, '/collector')
+ self.assertEqual(rset.rql, RQL1)
+ self.assertEqual(req.form, {'vid' : "baseindex"})
+ _pmid, rset = rewriter.rewrite(req, '/collector/something')
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
+ _pmid, rset = rewriter.rewrite(req, '/collector/something/')
+ self.assertEqual(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
+ _pmid, rset = rewriter.rewrite(req, '/collector/somethingelse/')
+ self.assertEqual(rset.rql, RQL1)
+ self.assertEqual(req.form, {'vid' : "baseindex"})
def test_inheritance_precedence_same_rgx(self):
RQL1 = 'Any C WHERE C is CWEType'
@@ -194,20 +199,20 @@
),
]
- req = self.request()
- rewriter = Rewriter(req)
- pmid, rset = rewriter.rewrite(req, '/collector')
- self.assertEqual(rset.rql, RQL2)
- self.assertEqual(req.form, {'vid' : "index"})
- pmid, rset = rewriter.rewrite(req, '/collector/something')
- self.assertEqual(rset.rql, RQL2)
- self.assertEqual(req.form, {'vid' : "index"})
- pmid, rset = rewriter.rewrite(req, '/collector/something/')
- self.assertEqual(req.form, {'vid' : "index"})
- self.assertEqual(rset.rql, RQL2)
- pmid, rset = rewriter.rewrite(req, '/collector/somethingelse/')
- self.assertEqual(rset.rql, RQL2)
- self.assertEqual(req.form, {'vid' : "index"})
+ with self.admin_access.web_request() as req:
+ rewriter = Rewriter(req)
+ _pmid, rset = rewriter.rewrite(req, '/collector')
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
+ _pmid, rset = rewriter.rewrite(req, '/collector/something')
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
+ _pmid, rset = rewriter.rewrite(req, '/collector/something/')
+ self.assertEqual(req.form, {'vid' : "index"})
+ self.assertEqual(rset.rql, RQL2)
+ _pmid, rset = rewriter.rewrite(req, '/collector/somethingelse/')
+ self.assertEqual(rset.rql, RQL2)
+ self.assertEqual(req.form, {'vid' : "index"})
if __name__ == '__main__':
--- a/web/test/unittest_views_basecontrollers.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_basecontrollers.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.
@@ -23,18 +23,16 @@
from urlparse import parse_qs as url_parse_query
except ImportError:
from cgi import parse_qs as url_parse_query
-from logilab.common.testlib import unittest_main, mock_object
+from logilab.common.testlib import unittest_main
from logilab.common.decorators import monkeypatch
from cubicweb import Binary, NoSelectableObject, ValidationError
-from cubicweb.view import STRICT_DOCTYPE
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.utils import json_dumps
from cubicweb.uilib import rql_for_eid
-from cubicweb.web import INTERNAL_FIELD_VALUE, Redirect, RequestError, RemoteCallFailed
+from cubicweb.web import Redirect, RemoteCallFailed
import cubicweb.server.session
from cubicweb.server.session import Connection as OldConnection
-from cubicweb.entities.authobjs import CWUser
from cubicweb.web.views.autoform import get_pending_inserts, get_pending_deletes
from cubicweb.web.views.basecontrollers import JSonController, xhtmlize, jsonize
from cubicweb.web.views.ajaxcontroller import ajaxfunc, AjaxFunction
@@ -42,15 +40,15 @@
from cubicweb.server.hook import Hook, Operation
from cubicweb.predicates import is_instance
-u = unicode
-
def req_form(user):
return {'eid': [str(user.eid)],
'_cw_entity_fields:%s' % user.eid: '_cw_generic_field',
'__type:%s' % user.eid: user.__regid__
}
+
class EditControllerTC(CubicWebTC):
+
def setUp(self):
CubicWebTC.setUp(self)
self.assertIn('users', self.schema.eschema('CWGroup').get_groups('read'))
@@ -62,611 +60,146 @@
def test_noparam_edit(self):
"""check behaviour of this controller without any form parameter
"""
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(self.request())
- self.assertEqual(cm.exception.errors, {None: u'no selected entities'})
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ self.assertEqual(cm.exception.errors, {None: u'no selected entities'})
def test_validation_unique(self):
"""test creation of two linked entities
"""
- user = self.user()
- req = self.request()
- req.form = {'eid': 'X', '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,upassword-subject',
- 'login-subject:X': u'admin',
- 'upassword-subject:X': u'toto',
- 'upassword-subject-confirm:X': u'toto',
+ with self.admin_access.web_request() as req:
+ req.form = {'eid': 'X', '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,upassword-subject',
+ 'login-subject:X': u'admin',
+ 'upassword-subject:X': u'toto',
+ 'upassword-subject-confirm:X': u'toto',
}
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(req)
- cm.exception.translate(unicode)
- self.assertEqual(cm.exception.errors, {'login-subject': 'the value "admin" is already used, use another one'})
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ cm.exception.translate(unicode)
+ self.assertEqual({'login-subject': 'the value "admin" is already used, use another one'},
+ cm.exception.errors)
def test_user_editing_itself(self):
"""checking that a manager user can edit itself
"""
- user = self.user()
- basegroups = [u(eid) for eid, in self.execute('CWGroup G WHERE X in_group G, X eid %(x)s', {'x': user.eid})]
- groupeids = [eid for eid, in self.execute('CWGroup G WHERE G name in ("managers", "users")')]
- groups = [u(eid) for eid in groupeids]
- req = self.request()
- eid = u(user.eid)
- req.form = {
- 'eid': eid, '__type:'+eid: 'CWUser',
- '_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject,in_group-subject',
- 'login-subject:'+eid: u(user.login),
- 'surname-subject:'+eid: u'Th\xe9nault',
- 'firstname-subject:'+eid: u'Sylvain',
- 'in_group-subject:'+eid: groups,
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
- self.assertEqual(e.firstname, u'Sylvain')
- self.assertEqual(e.surname, u'Th\xe9nault')
- self.assertEqual(e.login, user.login)
- self.assertEqual([g.eid for g in e.in_group], groupeids)
+ with self.admin_access.web_request() as req:
+ user = req.user
+ groupeids = [eid for eid, in req.execute('CWGroup G WHERE G name '
+ 'in ("managers", "users")')]
+ groups = [unicode(eid) for eid in groupeids]
+ eid = unicode(user.eid)
+ req.form = {
+ 'eid': eid, '__type:'+eid: 'CWUser',
+ '_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject,in_group-subject',
+ 'login-subject:'+eid: unicode(user.login),
+ 'surname-subject:'+eid: u'Th\xe9nault',
+ 'firstname-subject:'+eid: u'Sylvain',
+ 'in_group-subject:'+eid: groups,
+ }
+ self.expect_redirect_handle_request(req, 'edit')
+ e = req.execute('Any X WHERE X eid %(x)s',
+ {'x': user.eid}).get_entity(0, 0)
+ self.assertEqual(e.firstname, u'Sylvain')
+ self.assertEqual(e.surname, u'Th\xe9nault')
+ self.assertEqual(e.login, user.login)
+ self.assertEqual([g.eid for g in e.in_group], groupeids)
def test_user_can_change_its_password(self):
- req = self.request()
- user = self.create_user(req, 'user')
- cnx = self.login('user')
- eid = u(user.eid)
- req.form = {
- 'eid': eid, '__maineid' : eid,
- '__type:'+eid: 'CWUser',
- '_cw_entity_fields:'+eid: 'upassword-subject',
- 'upassword-subject:'+eid: 'tournicoton',
- 'upassword-subject-confirm:'+eid: 'tournicoton',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- cnx.commit() # commit to check we don't get late validation error for instance
- self.assertEqual(path, 'cwuser/user')
- self.assertNotIn('vid', params)
+ with self.admin_access.repo_cnx() as cnx:
+ self.create_user(cnx, 'user')
+ cnx.commit()
+ with self.new_access('user').web_request() as req:
+ eid = unicode(req.user.eid)
+ req.form = {
+ 'eid': eid, '__maineid' : eid,
+ '__type:'+eid: 'CWUser',
+ '_cw_entity_fields:'+eid: 'upassword-subject',
+ 'upassword-subject:'+eid: 'tournicoton',
+ 'upassword-subject-confirm:'+eid: 'tournicoton',
+ }
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ req.cnx.commit() # commit to check we don't get late validation error for instance
+ self.assertEqual(path, 'cwuser/user')
+ self.assertNotIn('vid', params)
def test_user_editing_itself_no_relation(self):
"""checking we can edit an entity without specifying some required
relations (meaning no changes)
"""
- user = self.user()
- groupeids = [g.eid for g in user.in_group]
- req = self.request()
- eid = u(user.eid)
- req.form = {
- 'eid': eid,
- '__type:'+eid: 'CWUser',
- '_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject',
- 'login-subject:'+eid: u(user.login),
- 'firstname-subject:'+eid: u'Th\xe9nault',
- 'surname-subject:'+eid: u'Sylvain',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- e = self.execute('Any X WHERE X eid %(x)s', {'x': user.eid}).get_entity(0, 0)
- self.assertEqual(e.login, user.login)
- self.assertEqual(e.firstname, u'Th\xe9nault')
- self.assertEqual(e.surname, u'Sylvain')
- self.assertEqual([g.eid for g in e.in_group], groupeids)
- self.assertEqual(e.cw_adapt_to('IWorkflowable').state, 'activated')
+ with self.admin_access.web_request() as req:
+ user = req.user
+ groupeids = [g.eid for g in user.in_group]
+ eid = unicode(user.eid)
+ req.form = {
+ 'eid': eid,
+ '__type:'+eid: 'CWUser',
+ '_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject',
+ 'login-subject:'+eid: unicode(user.login),
+ 'firstname-subject:'+eid: u'Th\xe9nault',
+ 'surname-subject:'+eid: u'Sylvain',
+ }
+ self.expect_redirect_handle_request(req, 'edit')
+ e = req.execute('Any X WHERE X eid %(x)s',
+ {'x': user.eid}).get_entity(0, 0)
+ self.assertEqual(e.login, user.login)
+ self.assertEqual(e.firstname, u'Th\xe9nault')
+ self.assertEqual(e.surname, u'Sylvain')
+ self.assertEqual([g.eid for g in e.in_group], groupeids)
+ self.assertEqual(e.cw_adapt_to('IWorkflowable').state, 'activated')
def test_create_multiple_linked(self):
- gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
- req = self.request()
- req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
-
- '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,upassword-subject,surname-subject,in_group-subject',
- 'login-subject:X': u'adim',
- 'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
- 'surname-subject:X': u'Di Mascio',
- 'in_group-subject:X': u(gueid),
+ with self.admin_access.web_request() as req:
+ gueid = req.execute('CWGroup G WHERE G name "users"')[0][0]
+ req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
+ '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,upassword-subject,surname-subject,in_group-subject',
+ 'login-subject:X': u'adim',
+ 'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
+ 'surname-subject:X': u'Di Mascio',
+ 'in_group-subject:X': unicode(gueid),
- '__type:Y': 'EmailAddress',
- '_cw_entity_fields:Y': 'address-subject,use_email-object',
- 'address-subject:Y': u'dima@logilab.fr',
- 'use_email-object:Y': 'X',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- # should be redirected on the created person
- self.assertEqual(path, 'cwuser/adim')
- e = self.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
- self.assertEqual(e.surname, 'Di Mascio')
- email = e.use_email[0]
- self.assertEqual(email.address, 'dima@logilab.fr')
+ '__type:Y': 'EmailAddress',
+ '_cw_entity_fields:Y': 'address-subject,use_email-object',
+ 'address-subject:Y': u'dima@logilab.fr',
+ 'use_email-object:Y': 'X',
+ }
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ # should be redirected on the created person
+ self.assertEqual(path, 'cwuser/adim')
+ e = req.execute('Any P WHERE P surname "Di Mascio"').get_entity(0, 0)
+ self.assertEqual(e.surname, 'Di Mascio')
+ email = e.use_email[0]
+ self.assertEqual(email.address, 'dima@logilab.fr')
def test_create_mandatory_inlined(self):
- req = self.request()
- req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
+ with self.admin_access.web_request() as req:
+ req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
- '__type:X': 'Salesterm',
- '_cw_entity_fields:X': '',
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': '',
- '__type:Y': 'File',
- '_cw_entity_fields:Y': 'data-subject,described_by_test-object',
- 'data-subject:Y': (u'coucou.txt', Binary('coucou')),
- 'described_by_test-object:Y': 'X',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertTrue(path.startswith('salesterm/'), path)
- eid = path.split('/')[1]
- salesterm = req.entity_from_eid(eid)
- # The NOT NULL constraint of mandatory relation implies that the File
- # must be created before the Salesterm, otherwise Salesterm insertion
- # will fail.
- # NOTE: sqlite does have NOT NULL constraint, unlike Postgres so the
- # insertion does not fail and we have to check dumbly that File is
- # created before.
- self.assertGreater(salesterm.eid, salesterm.described_by_test[0].eid)
+ '__type:Y': 'File',
+ '_cw_entity_fields:Y': 'data-subject,described_by_test-object',
+ 'data-subject:Y': (u'coucou.txt', Binary('coucou')),
+ 'described_by_test-object:Y': 'X',
+ }
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertTrue(path.startswith('salesterm/'), path)
+ eid = path.split('/')[1]
+ salesterm = req.entity_from_eid(eid)
+ # The NOT NULL constraint of mandatory relation implies that the File
+ # must be created before the Salesterm, otherwise Salesterm insertion
+ # will fail.
+ # NOTE: sqlite does have NOT NULL constraint, unlike Postgres so the
+ # insertion does not fail and we have to check dumbly that File is
+ # created before.
+ self.assertGreater(salesterm.eid, salesterm.described_by_test[0].eid)
def test_create_mandatory_inlined2(self):
- req = self.request()
- req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
-
- '__type:X': 'Salesterm',
- '_cw_entity_fields:X': 'described_by_test-subject',
- 'described_by_test-subject:X': 'Y',
-
- '__type:Y': 'File',
- '_cw_entity_fields:Y': 'data-subject',
- 'data-subject:Y': (u'coucou.txt', Binary('coucou')),
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertTrue(path.startswith('salesterm/'), path)
- eid = path.split('/')[1]
- salesterm = req.entity_from_eid(eid)
- # The NOT NULL constraint of mandatory relation implies that the File
- # must be created before the Salesterm, otherwise Salesterm insertion
- # will fail.
- # NOTE: sqlite does have NOT NULL constraint, unlike Postgres so the
- # insertion does not fail and we have to check dumbly that File is
- # created before.
- self.assertGreater(salesterm.eid, salesterm.described_by_test[0].eid)
-
- def test_edit_mandatory_inlined3_object(self):
- # non regression test for #3120495. Without the fix, leads to
- # "unhashable type: 'list'" error
- req = self.request()
- cwrelation = u(req.execute('CWEType X WHERE X name "CWSource"')[0][0])
- req.form = {'eid': [cwrelation], '__maineid' : cwrelation,
-
- '__type:'+cwrelation: 'CWEType',
- '_cw_entity_fields:'+cwrelation: 'to_entity-object',
- 'to_entity-object:'+cwrelation: [9999, 9998],
- }
- with self.session.deny_all_hooks_but():
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertTrue(path.startswith('cwetype/CWSource'), path)
-
- def test_edit_multiple_linked(self):
- req = self.request()
- peid = u(self.create_user(req, 'adim').eid)
- req.form = {'eid': [peid, 'Y'], '__maineid': peid,
-
- '__type:'+peid: u'CWUser',
- '_cw_entity_fields:'+peid: u'surname-subject',
- 'surname-subject:'+peid: u'Di Masci',
-
- '__type:Y': u'EmailAddress',
- '_cw_entity_fields:Y': u'address-subject,use_email-object',
- 'address-subject:Y': u'dima@logilab.fr',
- 'use_email-object:Y': peid,
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- # should be redirected on the created person
- self.assertEqual(path, 'cwuser/adim')
- e = self.execute('Any P WHERE P surname "Di Masci"').get_entity(0, 0)
- email = e.use_email[0]
- self.assertEqual(email.address, 'dima@logilab.fr')
-
- emaileid = u(email.eid)
- req = self.request()
- req.form = {'eid': [peid, emaileid],
-
- '__type:'+peid: u'CWUser',
- '_cw_entity_fields:'+peid: u'surname-subject',
- 'surname-subject:'+peid: u'Di Masci',
-
- '__type:'+emaileid: u'EmailAddress',
- '_cw_entity_fields:'+emaileid: u'address-subject,use_email-object',
- 'address-subject:'+emaileid: u'adim@logilab.fr',
- 'use_email-object:'+emaileid: peid,
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- email.cw_clear_all_caches()
- self.assertEqual(email.address, 'adim@logilab.fr')
-
-
- def test_password_confirm(self):
- """test creation of two linked entities
- """
- user = self.user()
- req = self.request()
- req.form = {'eid': 'X',
- '__cloned_eid:X': u(user.eid), '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,upassword-subject',
- 'login-subject:X': u'toto',
- 'upassword-subject:X': u'toto',
- }
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(req)
- self.assertEqual(cm.exception.errors, {'upassword-subject': u'password and confirmation don\'t match'})
- req = self.request()
- req.form = {'__cloned_eid:X': u(user.eid),
- 'eid': 'X', '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,upassword-subject',
- 'login-subject:X': u'toto',
- 'upassword-subject:X': u'toto',
- 'upassword-subject-confirm:X': u'tutu',
- }
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(req)
- self.assertEqual(cm.exception.errors, {'upassword-subject': u'password and confirmation don\'t match'})
-
-
- def test_interval_bound_constraint_success(self):
- feid = self.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
- {'data': Binary('yo')})[0][0]
- self.commit()
- req = self.request(rollbackfirst=True)
- req.form = {'eid': ['X'],
- '__type:X': 'Salesterm',
- '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
- 'amount-subject:X': u'-10',
- 'described_by_test-subject:X': u(feid),
- }
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(req)
- cm.exception.translate(unicode)
- self.assertEqual(cm.exception.errors, {'amount-subject': 'value -10 must be >= 0'})
- req = self.request(rollbackfirst=True)
- req.form = {'eid': ['X'],
- '__type:X': 'Salesterm',
- '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
- 'amount-subject:X': u'110',
- 'described_by_test-subject:X': u(feid),
- }
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(req)
- cm.exception.translate(unicode)
- self.assertEqual(cm.exception.errors, {'amount-subject': 'value 110 must be <= 100'})
-
- req = self.request(rollbackfirst=True)
- req.form = {'eid': ['X'],
- '__type:X': 'Salesterm',
- '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
- 'amount-subject:X': u'10',
- 'described_by_test-subject:X': u(feid),
- }
- self.expect_redirect_handle_request(req, 'edit')
- # should be redirected on the created
- #eid = params['rql'].split()[-1]
- e = self.execute('Salesterm X').get_entity(0, 0)
- self.assertEqual(e.amount, 10)
-
- def test_interval_bound_constraint_validateform(self):
- """Test the FormValidatorController controller on entity with
- constrained attributes"""
- feid = self.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
- {'data': Binary('yo')})[0][0]
- seid = self.request().create_entity('Salesterm', amount=0, described_by_test=feid).eid
- self.commit()
-
- # ensure a value that violate a constraint is properly detected
- req = self.request(rollbackfirst=True)
- req.form = {'eid': [unicode(seid)],
- '__type:%s'%seid: 'Salesterm',
- '_cw_entity_fields:%s'%seid: 'amount-subject',
- 'amount-subject:%s'%seid: u'-10',
- }
- self.assertEqual('''<script type="text/javascript">
- window.parent.handleFormValidationResponse('entityForm', null, null, [false, [%s, {"amount-subject": "value -10 must be >= 0"}], null], null);
-</script>'''%seid, self.ctrl_publish(req, 'validateform'))
-
- # ensure a value that comply a constraint is properly processed
- req = self.request(rollbackfirst=True)
- req.form = {'eid': [unicode(seid)],
- '__type:%s'%seid: 'Salesterm',
- '_cw_entity_fields:%s'%seid: 'amount-subject',
- 'amount-subject:%s'%seid: u'20',
- }
- self.assertEqual('''<script type="text/javascript">
- window.parent.handleFormValidationResponse('entityForm', null, null, [true, "http://testing.fr/cubicweb/view", null], null);
-</script>''', self.ctrl_publish(req, 'validateform'))
- self.assertEqual(20, self.execute('Any V WHERE X amount V, X eid %(eid)s', {'eid': seid})[0][0])
-
- req = self.request(rollbackfirst=True)
- req.form = {'eid': ['X'],
- '__type:X': 'Salesterm',
- '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
- 'amount-subject:X': u'0',
- 'described_by_test-subject:X': u(feid),
- }
-
- # ensure a value that is modified in an operation on a modify
- # hook works as it should (see
- # https://www.cubicweb.org/ticket/2509729 )
- class MyOperation(Operation):
- def precommit_event(self):
- self.entity.cw_set(amount=-10)
- class ValidationErrorInOpAfterHook(Hook):
- __regid__ = 'valerror-op-after-hook'
- __select__ = Hook.__select__ & is_instance('Salesterm')
- events = ('after_add_entity',)
- def __call__(self):
- MyOperation(self._cw, entity=self.entity)
-
- with self.temporary_appobjects(ValidationErrorInOpAfterHook):
- self.assertEqual('''<script type="text/javascript">
- window.parent.handleFormValidationResponse('entityForm', null, null, [false, ["X", {"amount-subject": "value -10 must be >= 0"}], null], null);
-</script>''', self.ctrl_publish(req, 'validateform'))
-
- self.assertEqual('''<script type="text/javascript">
- window.parent.handleFormValidationResponse('entityForm', null, null, [true, "http://testing.fr/cubicweb/view", null], null);
-</script>''', self.ctrl_publish(req, 'validateform'))
-
- def test_req_pending_insert(self):
- """make sure req's pending insertions are taken into account"""
- tmpgroup = self.request().create_entity('CWGroup', name=u"test")
- user = self.user()
- req = self.request(**req_form(user))
- req.session.data['pending_insert'] = set([(user.eid, 'in_group', tmpgroup.eid)])
- path, params = self.expect_redirect_handle_request(req, 'edit')
- usergroups = [gname for gname, in
- self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- self.assertCountEqual(usergroups, ['managers', 'test'])
- self.assertEqual(get_pending_inserts(req), [])
-
- def test_req_pending_delete(self):
- """make sure req's pending deletions are taken into account"""
- user = self.user()
- groupeid = self.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
- {'x': user.eid})[0][0]
- usergroups = [gname for gname, in
- self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- # just make sure everything was set correctly
- self.assertCountEqual(usergroups, ['managers', 'test'])
- # now try to delete the relation
- req = self.request(**req_form(user))
- req.session.data['pending_delete'] = set([(user.eid, 'in_group', groupeid)])
- path, params = self.expect_redirect_handle_request(req, 'edit')
- usergroups = [gname for gname, in
- self.execute('Any N WHERE G name N, U in_group G, U eid %(u)s', {'u': user.eid})]
- self.assertCountEqual(usergroups, ['managers'])
- self.assertEqual(get_pending_deletes(req), [])
-
- def test_redirect_apply_button(self):
- redirectrql = rql_for_eid(4012) # whatever
- req = self.request()
- req.form = {
- 'eid': 'A', '__maineid' : 'A',
- '__type:A': 'BlogEntry', '_cw_entity_fields:A': 'content-subject,title-subject',
- 'content-subject:A': u'"13:03:43"',
- 'title-subject:A': u'huuu',
- '__redirectrql': redirectrql,
- '__redirectvid': 'primary',
- '__redirectparams': 'toto=tutu&tata=titi',
- '__form_id': 'edition',
- '__action_apply': '',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertTrue(path.startswith('blogentry/'))
- eid = path.split('/')[1]
- self.assertEqual(params['vid'], 'edition')
- self.assertNotEqual(int(eid), 4012)
- self.assertEqual(params['__redirectrql'], redirectrql)
- self.assertEqual(params['__redirectvid'], 'primary')
- self.assertEqual(params['__redirectparams'], 'toto=tutu&tata=titi')
-
- def test_redirect_ok_button(self):
- redirectrql = rql_for_eid(4012) # whatever
- req = self.request()
- req.form = {
- 'eid': 'A', '__maineid' : 'A',
- '__type:A': 'BlogEntry', '_cw_entity_fields:A': 'content-subject,title-subject',
- 'content-subject:A': u'"13:03:43"',
- 'title-subject:A': u'huuu',
- '__redirectrql': redirectrql,
- '__redirectvid': 'primary',
- '__redirectparams': 'toto=tutu&tata=titi',
- '__form_id': 'edition',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertEqual(path, 'view')
- self.assertEqual(params['rql'], redirectrql)
- self.assertEqual(params['vid'], 'primary')
- self.assertEqual(params['tata'], 'titi')
- self.assertEqual(params['toto'], 'tutu')
-
- def test_redirect_delete_button(self):
- req = self.request()
- eid = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
- req.form = {'eid': u(eid), '__type:%s'%eid: 'BlogEntry',
- '__action_delete': ''}
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertEqual(path, 'blogentry')
- self.assertIn('_cwmsgid', params)
- eid = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
- self.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
- {'x': self.session.user.eid, 'e': eid})
- self.commit()
- req = req
- req.form = {'eid': u(eid), '__type:%s'%eid: 'EmailAddress',
- '__action_delete': ''}
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertEqual(path, 'cwuser/admin')
- self.assertIn('_cwmsgid', params)
- eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
- eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
- req = self.request()
- req.form = {'eid': [u(eid1), u(eid2)],
- '__type:%s'%eid1: 'BlogEntry',
- '__type:%s'%eid2: 'EmailAddress',
- '__action_delete': ''}
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertEqual(path, 'view')
- self.assertIn('_cwmsgid', params)
-
- def test_simple_copy(self):
- req = self.request()
- blog = req.create_entity('Blog', title=u'my-blog')
- blogentry = req.create_entity('BlogEntry', title=u'entry1',
- content=u'content1', entry_of=blog)
- req = self.request()
- req.form = {'__maineid' : 'X', 'eid': 'X',
- '__cloned_eid:X': blogentry.eid, '__type:X': 'BlogEntry',
- '_cw_entity_fields:X': 'title-subject,content-subject',
- 'title-subject:X': u'entry1-copy',
- 'content-subject:X': u'content1',
- }
- self.expect_redirect_handle_request(req, 'edit')
- blogentry2 = req.find_one_entity('BlogEntry', title=u'entry1-copy')
- self.assertEqual(blogentry2.entry_of[0].eid, blog.eid)
-
- def test_skip_copy_for(self):
- req = self.request()
- blog = req.create_entity('Blog', title=u'my-blog')
- blogentry = req.create_entity('BlogEntry', title=u'entry1',
- content=u'content1', entry_of=blog)
- blogentry.__class__.cw_skip_copy_for = [('entry_of', 'subject')]
- try:
- req = self.request()
- req.form = {'__maineid' : 'X', 'eid': 'X',
- '__cloned_eid:X': blogentry.eid, '__type:X': 'BlogEntry',
- '_cw_entity_fields:X': 'title-subject,content-subject',
- 'title-subject:X': u'entry1-copy',
- 'content-subject:X': u'content1',
- }
- self.expect_redirect_handle_request(req, 'edit')
- blogentry2 = req.find_one_entity('BlogEntry', title=u'entry1-copy')
- # entry_of should not be copied
- self.assertEqual(len(blogentry2.entry_of), 0)
- finally:
- blogentry.__class__.cw_skip_copy_for = []
-
- def test_nonregr_eetype_etype_editing(self):
- """non-regression test checking that a manager user can edit a CWEType entity
- """
- groupeids = sorted(eid for eid, in self.execute('CWGroup G WHERE G name in ("managers", "users")'))
- groups = [u(eid) for eid in groupeids]
- cwetypeeid = self.execute('CWEType X WHERE X name "CWEType"')[0][0]
- basegroups = [u(eid) for eid, in self.execute('CWGroup G WHERE X read_permission G, X eid %(x)s', {'x': cwetypeeid})]
- cwetypeeid = u(cwetypeeid)
- req = self.request()
- req.form = {
- 'eid': cwetypeeid,
- '__type:'+cwetypeeid: 'CWEType',
- '_cw_entity_fields:'+cwetypeeid: 'name-subject,final-subject,description-subject,read_permission-subject',
- 'name-subject:'+cwetypeeid: u'CWEType',
- 'final-subject:'+cwetypeeid: '',
- 'description-subject:'+cwetypeeid: u'users group',
- 'read_permission-subject:'+cwetypeeid: groups,
- }
- try:
- path, params = self.expect_redirect_handle_request(req, 'edit')
- e = self.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}).get_entity(0, 0)
- self.assertEqual(e.name, 'CWEType')
- self.assertEqual(sorted(g.eid for g in e.read_permission), groupeids)
- finally:
- # restore
- self.execute('SET X read_permission Y WHERE X name "CWEType", Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
- self.commit()
-
- def test_nonregr_strange_text_input(self):
- """non-regression test checking text input containing "13:03:43"
-
- this seems to be postgres (tsearch?) specific
- """
- req = self.request()
- req.form = {
- 'eid': 'A', '__maineid' : 'A',
- '__type:A': 'BlogEntry', '_cw_entity_fields:A': 'title-subject,content-subject',
- 'title-subject:A': u'"13:03:40"',
- 'content-subject:A': u'"13:03:43"',}
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertTrue(path.startswith('blogentry/'))
- eid = path.split('/')[1]
- e = self.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}).get_entity(0, 0)
- self.assertEqual(e.title, '"13:03:40"')
- self.assertEqual(e.content, '"13:03:43"')
-
-
- def test_nonregr_multiple_empty_email_addr(self):
- gueid = self.execute('CWGroup G WHERE G name "users"')[0][0]
- req = self.request()
- req.form = {'eid': ['X', 'Y'],
-
- '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,upassword-subject,in_group-subject',
- 'login-subject:X': u'adim',
- 'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
- 'in_group-subject:X': `gueid`,
-
- '__type:Y': 'EmailAddress',
- '_cw_entity_fields:Y': 'address-subject,alias-subject,use_email-object',
- 'address-subject:Y': u'',
- 'alias-subject:Y': u'',
- 'use_email-object:Y': 'X',
- }
- with self.assertRaises(ValidationError) as cm:
- self.ctrl_publish(req)
- self.assertEqual(cm.exception.errors, {'address-subject': u'required field'})
-
- def test_nonregr_copy(self):
- user = self.user()
- req = self.request()
- req.form = {'__maineid' : 'X', 'eid': 'X',
- '__cloned_eid:X': user.eid, '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,upassword-subject',
- 'login-subject:X': u'toto',
- 'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
- }
- path, params = self.expect_redirect_handle_request(req, 'edit')
- self.assertEqual(path, 'cwuser/toto')
- e = self.execute('Any X WHERE X is CWUser, X login "toto"').get_entity(0, 0)
- self.assertEqual(e.login, 'toto')
- self.assertEqual(e.in_group[0].name, 'managers')
-
-
- def test_nonregr_rollback_on_validation_error(self):
- req = self.request()
- p = self.create_user(req, "doe")
- # do not try to skip 'primary_email' for this test
- old_skips = p.__class__.skip_copy_for
- p.__class__.skip_copy_for = ()
- try:
- e = self.request().create_entity('EmailAddress', address=u'doe@doe.com')
- self.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
- {'p' : p.eid, 'e' : e.eid})
- req = self.request()
- req.form = {'eid': 'X',
- '__cloned_eid:X': p.eid, '__type:X': 'CWUser',
- '_cw_entity_fields:X': 'login-subject,surname-subject',
- 'login-subject': u'dodo',
- 'surname-subject:X': u'Boom',
- '__errorurl' : "whatever but required",
- }
- # try to emulate what really happens in the web application
- # 1/ validate form => EditController.publish raises a ValidationError
- # which fires a Redirect
- # 2/ When re-publishing the copy form, the publisher implicitly commits
- try:
- self.app_handle_request(req, 'edit')
- except Redirect:
- req = self.request()
- req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
- req.form['vid'] = 'copy'
- self.app_handle_request(req, 'view')
- rset = self.execute('CWUser P WHERE P surname "Boom"')
- self.assertEqual(len(rset), 0)
- finally:
- p.__class__.skip_copy_for = old_skips
-
- def test_regr_inlined_forms(self):
- self.schema['described_by_test'].inlined = False
- try:
- req = self.request()
- req.data['eidmap'] = {}
- req.data['pending_others'] = set()
- req.data['pending_inlined'] = {}
+ with self.admin_access.web_request() as req:
req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
'__type:X': 'Salesterm',
@@ -677,25 +210,507 @@
'_cw_entity_fields:Y': 'data-subject',
'data-subject:Y': (u'coucou.txt', Binary('coucou')),
}
- values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2))
- for eid in req.edited_eids())
- editctrl = self.vreg['controllers'].select('edit', req)
- # don't call publish to enforce select order
- editctrl.errors = []
- editctrl._to_create = {}
- editctrl.edit_entity(values_by_eid['X']) # #3064653 raise ValidationError
- editctrl.edit_entity(values_by_eid['Y'])
- finally:
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertTrue(path.startswith('salesterm/'), path)
+ eid = path.split('/')[1]
+ salesterm = req.entity_from_eid(eid)
+ # The NOT NULL constraint of mandatory relation implies that the File
+ # must be created before the Salesterm, otherwise Salesterm insertion
+ # will fail.
+ # NOTE: sqlite does have NOT NULL constraint, unlike Postgres so the
+ # insertion does not fail and we have to check dumbly that File is
+ # created before.
+ self.assertGreater(salesterm.eid, salesterm.described_by_test[0].eid)
+
+ def test_edit_mandatory_inlined3_object(self):
+ # non regression test for #3120495. Without the fix, leads to
+ # "unhashable type: 'list'" error
+ with self.admin_access.web_request() as req:
+ cwrelation = unicode(req.execute('CWEType X WHERE X name "CWSource"')[0][0])
+ req.form = {'eid': [cwrelation], '__maineid' : cwrelation,
+
+ '__type:'+cwrelation: 'CWEType',
+ '_cw_entity_fields:'+cwrelation: 'to_entity-object',
+ 'to_entity-object:'+cwrelation: [9999, 9998],
+ }
+ with req.cnx.deny_all_hooks_but():
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertTrue(path.startswith('cwetype/CWSource'), path)
+
+ def test_edit_multiple_linked(self):
+ with self.admin_access.web_request() as req:
+ peid = unicode(self.create_user(req, 'adim').eid)
+ req.form = {'eid': [peid, 'Y'], '__maineid': peid,
+
+ '__type:'+peid: u'CWUser',
+ '_cw_entity_fields:'+peid: u'surname-subject',
+ 'surname-subject:'+peid: u'Di Masci',
+
+ '__type:Y': u'EmailAddress',
+ '_cw_entity_fields:Y': u'address-subject,use_email-object',
+ 'address-subject:Y': u'dima@logilab.fr',
+ 'use_email-object:Y': peid,
+ }
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ # should be redirected on the created person
+ self.assertEqual(path, 'cwuser/adim')
+ e = req.execute('Any P WHERE P surname "Di Masci"').get_entity(0, 0)
+ email = e.use_email[0]
+ self.assertEqual(email.address, 'dima@logilab.fr')
+
+ # with self.admin_access.web_request() as req:
+ emaileid = unicode(email.eid)
+ req.form = {'eid': [peid, emaileid],
+
+ '__type:'+peid: u'CWUser',
+ '_cw_entity_fields:'+peid: u'surname-subject',
+ 'surname-subject:'+peid: u'Di Masci',
+
+ '__type:'+emaileid: u'EmailAddress',
+ '_cw_entity_fields:'+emaileid: u'address-subject,use_email-object',
+ 'address-subject:'+emaileid: u'adim@logilab.fr',
+ 'use_email-object:'+emaileid: peid,
+ }
+ self.expect_redirect_handle_request(req, 'edit')
+ email.cw_clear_all_caches()
+ self.assertEqual(email.address, 'adim@logilab.fr')
+
+ def test_password_confirm(self):
+ """test creation of two linked entities
+ """
+ with self.admin_access.web_request() as req:
+ user = req.user
+ req.form = {'eid': 'X',
+ '__cloned_eid:X': unicode(user.eid), '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,upassword-subject',
+ 'login-subject:X': u'toto',
+ 'upassword-subject:X': u'toto',
+ }
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ self.assertEqual({'upassword-subject': u'password and confirmation don\'t match'},
+ cm.exception.errors)
+ req.form = {'__cloned_eid:X': unicode(user.eid),
+ 'eid': 'X', '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,upassword-subject',
+ 'login-subject:X': u'toto',
+ 'upassword-subject:X': u'toto',
+ 'upassword-subject-confirm:X': u'tutu',
+ }
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ self.assertEqual({'upassword-subject': u'password and confirmation don\'t match'},
+ cm.exception.errors)
+
+
+ def test_interval_bound_constraint_success(self):
+ with self.admin_access.repo_cnx() as cnx:
+ feid = cnx.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
+ {'data': Binary('yo')})[0][0]
+ cnx.commit()
+
+ with self.admin_access.web_request(rollbackfirst=True) as req:
+ req.form = {'eid': ['X'],
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
+ 'amount-subject:X': u'-10',
+ 'described_by_test-subject:X': unicode(feid),
+ }
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ cm.exception.translate(unicode)
+ self.assertEqual({'amount-subject': 'value -10 must be >= 0'},
+ cm.exception.errors)
+
+ with self.admin_access.web_request(rollbackfirst=True) as req:
+ req.form = {'eid': ['X'],
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
+ 'amount-subject:X': u'110',
+ 'described_by_test-subject:X': unicode(feid),
+ }
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ cm.exception.translate(unicode)
+ self.assertEqual(cm.exception.errors, {'amount-subject': 'value 110 must be <= 100'})
+
+ with self.admin_access.web_request(rollbackfirst=True) as req:
+ req.form = {'eid': ['X'],
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
+ 'amount-subject:X': u'10',
+ 'described_by_test-subject:X': unicode(feid),
+ }
+ self.expect_redirect_handle_request(req, 'edit')
+ # should be redirected on the created
+ #eid = params['rql'].split()[-1]
+ e = req.execute('Salesterm X').get_entity(0, 0)
+ self.assertEqual(e.amount, 10)
+
+ def test_interval_bound_constraint_validateform(self):
+ """Test the FormValidatorController controller on entity with
+ constrained attributes"""
+ with self.admin_access.repo_cnx() as cnx:
+ feid = cnx.execute('INSERT File X: X data_name "toto.txt", X data %(data)s',
+ {'data': Binary('yo')})[0][0]
+ seid = cnx.create_entity('Salesterm', amount=0, described_by_test=feid).eid
+ cnx.commit()
+
+ # ensure a value that violate a constraint is properly detected
+ with self.admin_access.web_request(rollbackfirst=True) as req:
+ req.form = {'eid': [unicode(seid)],
+ '__type:%s'%seid: 'Salesterm',
+ '_cw_entity_fields:%s'%seid: 'amount-subject',
+ 'amount-subject:%s'%seid: u'-10',
+ }
+ self.assertMultiLineEqual('''<script type="text/javascript">
+ window.parent.handleFormValidationResponse('entityForm', null, null, [false, [%s, {"amount-subject": "value -10 must be >= 0"}], null], null);
+</script>'''%seid, self.ctrl_publish(req, 'validateform'))
+
+ # ensure a value that comply a constraint is properly processed
+ with self.admin_access.web_request(rollbackfirst=True) as req:
+ req.form = {'eid': [unicode(seid)],
+ '__type:%s'%seid: 'Salesterm',
+ '_cw_entity_fields:%s'%seid: 'amount-subject',
+ 'amount-subject:%s'%seid: u'20',
+ }
+ self.assertMultiLineEqual('''<script type="text/javascript">
+ window.parent.handleFormValidationResponse('entityForm', null, null, [true, "http://testing.fr/cubicweb/view", null], null);
+</script>''', self.ctrl_publish(req, 'validateform'))
+ self.assertEqual(20, req.execute('Any V WHERE X amount V, X eid %(eid)s',
+ {'eid': seid})[0][0])
+
+ with self.admin_access.web_request(rollbackfirst=True) as req:
+ req.form = {'eid': ['X'],
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
+ 'amount-subject:X': u'0',
+ 'described_by_test-subject:X': unicode(feid),
+ }
+
+ # ensure a value that is modified in an operation on a modify
+ # hook works as it should (see
+ # https://www.cubicweb.org/ticket/2509729 )
+ class MyOperation(Operation):
+ def precommit_event(self):
+ self.entity.cw_set(amount=-10)
+ class ValidationErrorInOpAfterHook(Hook):
+ __regid__ = 'valerror-op-after-hook'
+ __select__ = Hook.__select__ & is_instance('Salesterm')
+ events = ('after_add_entity',)
+ def __call__(self):
+ MyOperation(self._cw, entity=self.entity)
+
+ with self.temporary_appobjects(ValidationErrorInOpAfterHook):
+ self.assertMultiLineEqual('''<script type="text/javascript">
+ window.parent.handleFormValidationResponse('entityForm', null, null, [false, ["X", {"amount-subject": "value -10 must be >= 0"}], null], null);
+</script>''', self.ctrl_publish(req, 'validateform'))
+
+ self.assertMultiLineEqual('''<script type="text/javascript">
+ window.parent.handleFormValidationResponse('entityForm', null, null, [true, "http://testing.fr/cubicweb/view", null], null);
+</script>''', self.ctrl_publish(req, 'validateform'))
+
+ def test_req_pending_insert(self):
+ """make sure req's pending insertions are taken into account"""
+ with self.admin_access.web_request() as req:
+ tmpgroup = req.create_entity('CWGroup', name=u"test")
+ user = req.user
+ req.cnx.commit()
+ with self.admin_access.web_request(**req_form(user)) as req:
+ req.session.data['pending_insert'] = set([(user.eid, 'in_group', tmpgroup.eid)])
+ self.expect_redirect_handle_request(req, 'edit')
+ usergroups = [gname for gname, in
+ req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s',
+ {'u': user.eid})]
+ self.assertCountEqual(usergroups, ['managers', 'test'])
+ self.assertEqual(get_pending_inserts(req), [])
+
+ def test_req_pending_delete(self):
+ """make sure req's pending deletions are taken into account"""
+ with self.admin_access.web_request() as req:
+ user = req.user
+ groupeid = req.execute('INSERT CWGroup G: G name "test", U in_group G WHERE U eid %(x)s',
+ {'x': user.eid})[0][0]
+ usergroups = [gname for gname, in
+ req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s',
+ {'u': user.eid})]
+ # just make sure everything was set correctly
+ self.assertCountEqual(usergroups, ['managers', 'test'])
+ req.cnx.commit()
+ # now try to delete the relation
+ with self.admin_access.web_request(**req_form(user)) as req:
+ req.session.data['pending_delete'] = set([(user.eid, 'in_group', groupeid)])
+ self.expect_redirect_handle_request(req, 'edit')
+ usergroups = [gname for gname, in
+ req.execute('Any N WHERE G name N, U in_group G, U eid %(u)s',
+ {'u': user.eid})]
+ self.assertCountEqual(usergroups, ['managers'])
+ self.assertEqual(get_pending_deletes(req), [])
+
+ def test_redirect_apply_button(self):
+ with self.admin_access.web_request() as req:
+ redirectrql = rql_for_eid(4012) # whatever
+ req.form = {
+ 'eid': 'A', '__maineid' : 'A',
+ '__type:A': 'BlogEntry', '_cw_entity_fields:A': 'content-subject,title-subject',
+ 'content-subject:A': u'"13:03:43"',
+ 'title-subject:A': u'huuu',
+ '__redirectrql': redirectrql,
+ '__redirectvid': 'primary',
+ '__redirectparams': 'toto=tutu&tata=titi',
+ '__form_id': 'edition',
+ '__action_apply': '',
+ }
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertTrue(path.startswith('blogentry/'))
+ eid = path.split('/')[1]
+ self.assertEqual(params['vid'], 'edition')
+ self.assertNotEqual(int(eid), 4012)
+ self.assertEqual(params['__redirectrql'], redirectrql)
+ self.assertEqual(params['__redirectvid'], 'primary')
+ self.assertEqual(params['__redirectparams'], 'toto=tutu&tata=titi')
+
+ def test_redirect_ok_button(self):
+ with self.admin_access.web_request() as req:
+ redirectrql = rql_for_eid(4012) # whatever
+ req.form = {
+ 'eid': 'A', '__maineid' : 'A',
+ '__type:A': 'BlogEntry', '_cw_entity_fields:A': 'content-subject,title-subject',
+ 'content-subject:A': u'"13:03:43"',
+ 'title-subject:A': u'huuu',
+ '__redirectrql': redirectrql,
+ '__redirectvid': 'primary',
+ '__redirectparams': 'toto=tutu&tata=titi',
+ '__form_id': 'edition',
+ }
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertEqual(path, 'view')
+ self.assertEqual(params['rql'], redirectrql)
+ self.assertEqual(params['vid'], 'primary')
+ self.assertEqual(params['tata'], 'titi')
+ self.assertEqual(params['toto'], 'tutu')
+
+ def test_redirect_delete_button(self):
+ with self.admin_access.web_request() as req:
+ eid = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
+ req.form = {'eid': unicode(eid), '__type:%s'%eid: 'BlogEntry',
+ '__action_delete': ''}
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertEqual(path, 'blogentry')
+ self.assertIn('_cwmsgid', params)
+ eid = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
+ req.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
+ {'x': self.session.user.eid, 'e': eid})
+ req.cnx.commit()
+ req.form = {'eid': unicode(eid), '__type:%s'%eid: 'EmailAddress',
+ '__action_delete': ''}
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertEqual(path, 'cwuser/admin')
+ self.assertIn('_cwmsgid', params)
+ eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
+ eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
+ req.form = {'eid': [unicode(eid1), unicode(eid2)],
+ '__type:%s'%eid1: 'BlogEntry',
+ '__type:%s'%eid2: 'EmailAddress',
+ '__action_delete': ''}
+ path, params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertEqual(path, 'view')
+ self.assertIn('_cwmsgid', params)
+
+ def test_simple_copy(self):
+ with self.admin_access.web_request() as req:
+ blog = req.create_entity('Blog', title=u'my-blog')
+ blogentry = req.create_entity('BlogEntry', title=u'entry1',
+ content=u'content1', entry_of=blog)
+ req.form = {'__maineid' : 'X', 'eid': 'X',
+ '__cloned_eid:X': blogentry.eid, '__type:X': 'BlogEntry',
+ '_cw_entity_fields:X': 'title-subject,content-subject',
+ 'title-subject:X': u'entry1-copy',
+ 'content-subject:X': u'content1',
+ }
+ self.expect_redirect_handle_request(req, 'edit')
+ blogentry2 = req.find('BlogEntry', title=u'entry1-copy').one()
+ self.assertEqual(blogentry2.entry_of[0].eid, blog.eid)
+
+ def test_skip_copy_for(self):
+ with self.admin_access.web_request() as req:
+ blog = req.create_entity('Blog', title=u'my-blog')
+ blogentry = req.create_entity('BlogEntry', title=u'entry1',
+ content=u'content1', entry_of=blog)
+ blogentry.__class__.cw_skip_copy_for = [('entry_of', 'subject')]
+ try:
+ req.form = {'__maineid' : 'X', 'eid': 'X',
+ '__cloned_eid:X': blogentry.eid, '__type:X': 'BlogEntry',
+ '_cw_entity_fields:X': 'title-subject,content-subject',
+ 'title-subject:X': u'entry1-copy',
+ 'content-subject:X': u'content1',
+ }
+ self.expect_redirect_handle_request(req, 'edit')
+ blogentry2 = req.find('BlogEntry', title=u'entry1-copy').one()
+ # entry_of should not be copied
+ self.assertEqual(len(blogentry2.entry_of), 0)
+ finally:
+ blogentry.__class__.cw_skip_copy_for = []
+
+ def test_nonregr_eetype_etype_editing(self):
+ """non-regression test checking that a manager user can edit a CWEType entity
+ """
+ with self.admin_access.web_request() as req:
+ groupeids = sorted(eid
+ for eid, in req.execute('CWGroup G '
+ 'WHERE G name in ("managers", "users")'))
+ groups = [unicode(eid) for eid in groupeids]
+ cwetypeeid = req.execute('CWEType X WHERE X name "CWEType"')[0][0]
+ basegroups = [unicode(eid)
+ for eid, in req.execute('CWGroup G '
+ 'WHERE X read_permission G, X eid %(x)s',
+ {'x': cwetypeeid})]
+ cwetypeeid = unicode(cwetypeeid)
+ req.form = {
+ 'eid': cwetypeeid,
+ '__type:'+cwetypeeid: 'CWEType',
+ '_cw_entity_fields:'+cwetypeeid: 'name-subject,final-subject,description-subject,read_permission-subject',
+ 'name-subject:'+cwetypeeid: u'CWEType',
+ 'final-subject:'+cwetypeeid: '',
+ 'description-subject:'+cwetypeeid: u'users group',
+ 'read_permission-subject:'+cwetypeeid: groups,
+ }
+ try:
+ self.expect_redirect_handle_request(req, 'edit')
+ e = req.execute('Any X WHERE X eid %(x)s', {'x': cwetypeeid}).get_entity(0, 0)
+ self.assertEqual(e.name, 'CWEType')
+ self.assertEqual(sorted(g.eid for g in e.read_permission), groupeids)
+ finally:
+ # restore
+ req.execute('SET X read_permission Y WHERE X name "CWEType", '
+ 'Y eid IN (%s), NOT X read_permission Y' % (','.join(basegroups)))
+ req.cnx.commit()
+
+ def test_nonregr_strange_text_input(self):
+ """non-regression test checking text input containing "13:03:43"
+
+ this seems to be postgres (tsearch?) specific
+ """
+ with self.admin_access.web_request() as req:
+ req.form = {
+ 'eid': 'A', '__maineid' : 'A',
+ '__type:A': 'BlogEntry', '_cw_entity_fields:A': 'title-subject,content-subject',
+ 'title-subject:A': u'"13:03:40"',
+ 'content-subject:A': u'"13:03:43"',}
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertTrue(path.startswith('blogentry/'))
+ eid = path.split('/')[1]
+ e = req.execute('Any C, T WHERE C eid %(x)s, C content T', {'x': eid}).get_entity(0, 0)
+ self.assertEqual(e.title, '"13:03:40"')
+ self.assertEqual(e.content, '"13:03:43"')
+
+
+ def test_nonregr_multiple_empty_email_addr(self):
+ with self.admin_access.web_request() as req:
+ gueid = req.execute('CWGroup G WHERE G name "users"')[0][0]
+ req.form = {'eid': ['X', 'Y'],
+
+ '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,upassword-subject,in_group-subject',
+ 'login-subject:X': u'adim',
+ 'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
+ 'in_group-subject:X': `gueid`,
+
+ '__type:Y': 'EmailAddress',
+ '_cw_entity_fields:Y': 'address-subject,alias-subject,use_email-object',
+ 'address-subject:Y': u'',
+ 'alias-subject:Y': u'',
+ 'use_email-object:Y': 'X',
+ }
+ with self.assertRaises(ValidationError) as cm:
+ self.ctrl_publish(req)
+ self.assertEqual(cm.exception.errors, {'address-subject': u'required field'})
+
+ def test_nonregr_copy(self):
+ with self.admin_access.web_request() as req:
+ user = req.user
+ req.form = {'__maineid' : 'X', 'eid': 'X',
+ '__cloned_eid:X': user.eid, '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,upassword-subject',
+ 'login-subject:X': u'toto',
+ 'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
+ }
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertEqual(path, 'cwuser/toto')
+ e = req.execute('Any X WHERE X is CWUser, X login "toto"').get_entity(0, 0)
+ self.assertEqual(e.login, 'toto')
+ self.assertEqual(e.in_group[0].name, 'managers')
+
+
+ def test_nonregr_rollback_on_validation_error(self):
+ with self.admin_access.web_request() as req:
+ p = self.create_user(req, "doe")
+ # do not try to skip 'primary_email' for this test
+ old_skips = p.__class__.skip_copy_for
+ p.__class__.skip_copy_for = ()
+ try:
+ e = req.create_entity('EmailAddress', address=u'doe@doe.com')
+ req.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
+ {'p' : p.eid, 'e' : e.eid})
+ req.form = {'eid': 'X',
+ '__cloned_eid:X': p.eid, '__type:X': 'CWUser',
+ '_cw_entity_fields:X': 'login-subject,surname-subject',
+ 'login-subject': u'dodo',
+ 'surname-subject:X': u'Boom',
+ '__errorurl' : "whatever but required",
+ }
+ # try to emulate what really happens in the web application
+ # 1/ validate form => EditController.publish raises a ValidationError
+ # which fires a Redirect
+ # 2/ When re-publishing the copy form, the publisher implicitly commits
+ try:
+ self.app_handle_request(req, 'edit')
+ except Redirect:
+ req.form['rql'] = 'Any X WHERE X eid %s' % p.eid
+ req.form['vid'] = 'copy'
+ self.app_handle_request(req, 'view')
+ rset = req.execute('CWUser P WHERE P surname "Boom"')
+ self.assertEqual(len(rset), 0)
+ finally:
+ p.__class__.skip_copy_for = old_skips
+
+ def test_regr_inlined_forms(self):
+ with self.admin_access.web_request() as req:
self.schema['described_by_test'].inlined = False
+ try:
+ req.data['eidmap'] = {}
+ req.data['pending_others'] = set()
+ req.data['pending_inlined'] = {}
+ req.form = {'eid': ['X', 'Y'], '__maineid' : 'X',
+
+ '__type:X': 'Salesterm',
+ '_cw_entity_fields:X': 'described_by_test-subject',
+ 'described_by_test-subject:X': 'Y',
+
+ '__type:Y': 'File',
+ '_cw_entity_fields:Y': 'data-subject',
+ 'data-subject:Y': (u'coucou.txt', Binary('coucou')),
+ }
+ values_by_eid = dict((eid, req.extract_entity_params(eid, minparams=2))
+ for eid in req.edited_eids())
+ editctrl = self.vreg['controllers'].select('edit', req)
+ # don't call publish to enforce select order
+ editctrl.errors = []
+ editctrl._to_create = {}
+ editctrl.edit_entity(values_by_eid['X']) # #3064653 raise ValidationError
+ editctrl.edit_entity(values_by_eid['Y'])
+ finally:
+ self.schema['described_by_test'].inlined = False
class ReportBugControllerTC(CubicWebTC):
def test_usable_by_guest(self):
- self.login('anon')
- self.assertRaises(NoSelectableObject,
- self.vreg['controllers'].select, 'reportbug', self.request())
- self.vreg['controllers'].select('reportbug', self.request(description='hop'))
+ with self.new_access('anon').web_request() as req:
+ self.assertRaises(NoSelectableObject,
+ self.vreg['controllers'].select, 'reportbug', req)
+ with self.new_access('anon').web_request(description='hop') as req:
+ self.vreg['controllers'].select('reportbug', req)
class AjaxControllerTC(CubicWebTC):
@@ -706,21 +721,21 @@
return self.vreg['controllers'].select(self.tested_controller, req)
def setup_database(self):
- req = self.request()
- self.pytag = req.create_entity('Tag', name=u'python')
- self.cubicwebtag = req.create_entity('Tag', name=u'cubicweb')
- self.john = self.create_user(req, u'John')
-
+ with self.admin_access.repo_cnx() as cnx:
+ self.pytag = cnx.create_entity('Tag', name=u'python')
+ self.cubicwebtag = cnx.create_entity('Tag', name=u'cubicweb')
+ self.john = self.create_user(cnx, u'John')
+ cnx.commit()
## tests ##################################################################
def test_simple_exec(self):
- req = self.request(rql='CWUser P WHERE P login "John"',
- pageid='123', fname='view')
- ctrl = self.ctrl(req)
- rset = self.john.as_rset()
- rset.req = req
- source = ctrl.publish()
- self.assertTrue(source.startswith('<div>'))
+ with self.admin_access.web_request(rql='CWUser P WHERE P login "John"',
+ pageid='123', fname='view') as req:
+ ctrl = self.ctrl(req)
+ rset = self.john.as_rset()
+ rset.req = req
+ source = ctrl.publish()
+ self.assertTrue(source.startswith('<div>'))
# def test_json_exec(self):
# rql = 'Any T,N WHERE T is Tag, T name N'
@@ -729,92 +744,94 @@
# json_dumps(self.execute(rql).rows))
def test_remote_add_existing_tag(self):
- self.remote_call('tag_entity', self.john.eid, ['python'])
- self.assertCountEqual(
- [tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
- ['python', 'cubicweb'])
- self.assertEqual(
- self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
- [['python']])
+ with self.remote_calling('tag_entity', self.john.eid, ['python']) as (_, req):
+ self.assertCountEqual(
+ [tname for tname, in req.execute('Any N WHERE T is Tag, T name N')],
+ ['python', 'cubicweb'])
+ self.assertEqual(
+ req.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
+ [['python']])
def test_remote_add_new_tag(self):
- self.remote_call('tag_entity', self.john.eid, ['javascript'])
- self.assertCountEqual(
- [tname for tname, in self.execute('Any N WHERE T is Tag, T name N')],
- ['python', 'cubicweb', 'javascript'])
- self.assertEqual(
- self.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
- [['javascript']])
+ with self.remote_calling('tag_entity', self.john.eid, ['javascript']) as (_, req):
+ self.assertCountEqual(
+ [tname for tname, in req.execute('Any N WHERE T is Tag, T name N')],
+ ['python', 'cubicweb', 'javascript'])
+ self.assertEqual(
+ req.execute('Any N WHERE T tags P, P is CWUser, T name N').rows,
+ [['javascript']])
def test_pending_insertion(self):
- res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '13']])
- deletes = get_pending_deletes(req)
- self.assertEqual(deletes, [])
- inserts = get_pending_inserts(req)
- self.assertEqual(inserts, ['12:tags:13'])
- res, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
- deletes = get_pending_deletes(req)
- self.assertEqual(deletes, [])
- inserts = get_pending_inserts(req)
- self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
- inserts = get_pending_inserts(req, 12)
- self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
- inserts = get_pending_inserts(req, 13)
- self.assertEqual(inserts, ['12:tags:13'])
- inserts = get_pending_inserts(req, 14)
- self.assertEqual(inserts, ['12:tags:14'])
- req.remove_pending_operations()
+ with self.remote_calling('add_pending_inserts', [['12', 'tags', '13']]) as (_, req):
+ deletes = get_pending_deletes(req)
+ self.assertEqual(deletes, [])
+ inserts = get_pending_inserts(req)
+ self.assertEqual(inserts, ['12:tags:13'])
+ with self.remote_calling('add_pending_inserts', [['12', 'tags', '14']]) as (_, req):
+ deletes = get_pending_deletes(req)
+ self.assertEqual(deletes, [])
+ inserts = get_pending_inserts(req)
+ self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
+ inserts = get_pending_inserts(req, 12)
+ self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
+ inserts = get_pending_inserts(req, 13)
+ self.assertEqual(inserts, ['12:tags:13'])
+ inserts = get_pending_inserts(req, 14)
+ self.assertEqual(inserts, ['12:tags:14'])
+ req.remove_pending_operations()
def test_pending_deletion(self):
- res, req = self.remote_call('add_pending_delete', ['12', 'tags', '13'])
- inserts = get_pending_inserts(req)
- self.assertEqual(inserts, [])
- deletes = get_pending_deletes(req)
- self.assertEqual(deletes, ['12:tags:13'])
- res, req = self.remote_call('add_pending_delete', ['12', 'tags', '14'])
- inserts = get_pending_inserts(req)
- self.assertEqual(inserts, [])
- deletes = get_pending_deletes(req)
- self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
- deletes = get_pending_deletes(req, 12)
- self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
- deletes = get_pending_deletes(req, 13)
- self.assertEqual(deletes, ['12:tags:13'])
- deletes = get_pending_deletes(req, 14)
- self.assertEqual(deletes, ['12:tags:14'])
- req.remove_pending_operations()
+ with self.remote_calling('add_pending_delete', ['12', 'tags', '13']) as (_, req):
+ inserts = get_pending_inserts(req)
+ self.assertEqual(inserts, [])
+ deletes = get_pending_deletes(req)
+ self.assertEqual(deletes, ['12:tags:13'])
+ with self.remote_calling('add_pending_delete', ['12', 'tags', '14']) as (_, req):
+ inserts = get_pending_inserts(req)
+ self.assertEqual(inserts, [])
+ deletes = get_pending_deletes(req)
+ self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
+ deletes = get_pending_deletes(req, 12)
+ self.assertEqual(deletes, ['12:tags:13', '12:tags:14'])
+ deletes = get_pending_deletes(req, 13)
+ self.assertEqual(deletes, ['12:tags:13'])
+ deletes = get_pending_deletes(req, 14)
+ self.assertEqual(deletes, ['12:tags:14'])
+ req.remove_pending_operations()
def test_remove_pending_operations(self):
- self.remote_call('add_pending_delete', ['12', 'tags', '13'])
- _, req = self.remote_call('add_pending_inserts', [['12', 'tags', '14']])
- inserts = get_pending_inserts(req)
- self.assertEqual(inserts, ['12:tags:14'])
- deletes = get_pending_deletes(req)
- self.assertEqual(deletes, ['12:tags:13'])
- req.remove_pending_operations()
- self.assertEqual(get_pending_deletes(req), [])
- self.assertEqual(get_pending_inserts(req), [])
-
+ with self.remote_calling('add_pending_delete', ['12', 'tags', '13']):
+ pass
+ with self.remote_calling('add_pending_inserts', [['12', 'tags', '14']]) as (_, req):
+ inserts = get_pending_inserts(req)
+ self.assertEqual(inserts, ['12:tags:14'])
+ deletes = get_pending_deletes(req)
+ self.assertEqual(deletes, ['12:tags:13'])
+ req.remove_pending_operations()
+ self.assertEqual(get_pending_deletes(req), [])
+ self.assertEqual(get_pending_inserts(req), [])
def test_add_inserts(self):
- res, req = self.remote_call('add_pending_inserts',
- [('12', 'tags', '13'), ('12', 'tags', '14')])
- inserts = get_pending_inserts(req)
- self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
- req.remove_pending_operations()
+ with self.remote_calling('add_pending_inserts',
+ [('12', 'tags', '13'), ('12', 'tags', '14')]) as (_, req):
+ inserts = get_pending_inserts(req)
+ self.assertEqual(inserts, ['12:tags:13', '12:tags:14'])
+ req.remove_pending_operations()
# silly tests
def test_external_resource(self):
- self.assertEqual(self.remote_call('external_resource', 'RSS_LOGO')[0],
- json_dumps(self.config.uiprops['RSS_LOGO']))
+ with self.remote_calling('external_resource', 'RSS_LOGO') as (res, _):
+ self.assertEqual(json_dumps(self.config.uiprops['RSS_LOGO']),
+ res)
+
def test_i18n(self):
- self.assertEqual(self.remote_call('i18n', ['bimboom'])[0],
- json_dumps(['bimboom']))
+ with self.remote_calling('i18n', ['bimboom']) as (res, _):
+ self.assertEqual(json_dumps(['bimboom']), res)
def test_format_date(self):
- self.assertEqual(self.remote_call('format_date', '2007-01-01 12:00:00')[0],
- json_dumps('2007/01/01'))
+ with self.remote_calling('format_date', '2007-01-01 12:00:00') as (res, _):
+ self.assertEqual(json_dumps('2007/01/01'), res)
def test_ajaxfunc_noparameter(self):
@ajaxfunc
@@ -826,9 +843,9 @@
self.assertEqual(appobject.__regid__, 'foo')
self.assertEqual(appobject.check_pageid, False)
self.assertEqual(appobject.output_type, None)
- req = self.request()
- f = appobject(req)
- self.assertEqual(f(12, 13), 'hello')
+ with self.admin_access.web_request() as req:
+ f = appobject(req)
+ self.assertEqual(f(12, 13), 'hello')
def test_ajaxfunc_checkpageid(self):
@ajaxfunc(check_pageid=True)
@@ -841,9 +858,9 @@
self.assertEqual(appobject.check_pageid, True)
self.assertEqual(appobject.output_type, None)
# no pageid
- req = self.request()
- f = appobject(req)
- self.assertRaises(RemoteCallFailed, f, 12, 13)
+ with self.admin_access.web_request() as req:
+ f = appobject(req)
+ self.assertRaises(RemoteCallFailed, f, 12, 13)
def test_ajaxfunc_json(self):
@ajaxfunc(output_type='json')
@@ -856,9 +873,9 @@
self.assertEqual(appobject.check_pageid, False)
self.assertEqual(appobject.output_type, 'json')
# no pageid
- req = self.request()
- f = appobject(req)
- self.assertEqual(f(12, 13), '25')
+ with self.admin_access.web_request() as req:
+ f = appobject(req)
+ self.assertEqual(f(12, 13), '25')
class JSonControllerTC(AjaxControllerTC):
@@ -879,38 +896,44 @@
delattr(JSonController, funcname)
def test_monkeypatch_jsoncontroller(self):
- self.assertRaises(RemoteCallFailed, self.remote_call, 'foo')
+ with self.assertRaises(RemoteCallFailed):
+ with self.remote_calling('foo'):
+ pass
@monkeypatch(JSonController)
def js_foo(self):
return u'hello'
- res, req = self.remote_call('foo')
- self.assertEqual(res, u'hello')
+ with self.remote_calling('foo') as (res, _):
+ self.assertEqual(res, u'hello')
def test_monkeypatch_jsoncontroller_xhtmlize(self):
- self.assertRaises(RemoteCallFailed, self.remote_call, 'foo')
+ with self.assertRaises(RemoteCallFailed):
+ with self.remote_calling('foo'):
+ pass
@monkeypatch(JSonController)
@xhtmlize
def js_foo(self):
return u'hello'
- res, req = self.remote_call('foo')
- self.assertEqual(u'<div>hello</div>', res)
+ with self.remote_calling('foo') as (res, _):
+ self.assertEqual(u'<div>hello</div>', res)
def test_monkeypatch_jsoncontroller_jsonize(self):
- self.assertRaises(RemoteCallFailed, self.remote_call, 'foo')
+ with self.assertRaises(RemoteCallFailed):
+ with self.remote_calling('foo'):
+ pass
@monkeypatch(JSonController)
@jsonize
def js_foo(self):
return 12
- res, req = self.remote_call('foo')
- self.assertEqual(res, '12')
+ with self.remote_calling('foo') as (res, _):
+ self.assertEqual(res, '12')
def test_monkeypatch_jsoncontroller_stdfunc(self):
@monkeypatch(JSonController)
@jsonize
def js_reledit_form(self):
return 12
- res, req = self.remote_call('reledit_form')
- self.assertEqual(res, '12')
+ with self.remote_calling('reledit_form') as (res, _):
+ self.assertEqual(res, '12')
class UndoControllerTC(CubicWebTC):
@@ -926,75 +949,76 @@
super(UndoControllerTC, self).tearDown()
cubicweb.server.session.Connection = OldConnection
-
def setup_database(self):
- req = self.request()
- self.toto = self.create_user(req, 'toto', password='toto', groups=('users',),
- commit=False)
- self.txuuid_toto = self.commit()
- self.toto_email = self.session.create_entity('EmailAddress',
- address=u'toto@logilab.org',
- reverse_use_email=self.toto)
- self.txuuid_toto_email = self.commit()
+ with self.admin_access.repo_cnx() as cnx:
+ self.toto = self.create_user(cnx, 'toto',
+ password='toto',
+ groups=('users',),
+ commit=False)
+ self.txuuid_toto = cnx.commit()
+ self.toto_email = cnx.create_entity('EmailAddress',
+ address=u'toto@logilab.org',
+ reverse_use_email=self.toto)
+ self.txuuid_toto_email = cnx.commit()
def test_no_such_transaction(self):
- req = self.request()
- txuuid = u"12345acbd"
- req.form['txuuid'] = txuuid
- controller = self.vreg['controllers'].select('undo', req)
- with self.assertRaises(tx.NoSuchTransaction) as cm:
- result = controller.publish(rset=None)
- self.assertEqual(cm.exception.txuuid, txuuid)
+ with self.admin_access.web_request() as req:
+ txuuid = u"12345acbd"
+ req.form['txuuid'] = txuuid
+ controller = self.vreg['controllers'].select('undo', req)
+ with self.assertRaises(tx.NoSuchTransaction) as cm:
+ result = controller.publish(rset=None)
+ self.assertEqual(cm.exception.txuuid, txuuid)
def assertURLPath(self, url, expected_path, expected_params=None):
""" This assert that the path part of `url` matches expected path
TODO : implement assertion on the expected_params too
"""
- req = self.request()
- scheme, netloc, path, query, fragment = urlsplit(url)
- query_dict = url_parse_query(query)
- expected_url = urljoin(req.base_url(), expected_path)
- self.assertEqual( urlunsplit((scheme, netloc, path, None, None)), expected_url)
+ with self.admin_access.web_request() as req:
+ scheme, netloc, path, query, fragment = urlsplit(url)
+ query_dict = url_parse_query(query)
+ expected_url = urljoin(req.base_url(), expected_path)
+ self.assertEqual( urlunsplit((scheme, netloc, path, None, None)), expected_url)
def test_redirect_redirectpath(self):
"Check that the potential __redirectpath is honored"
- req = self.request()
- txuuid = self.txuuid_toto_email
- req.form['txuuid'] = txuuid
- rpath = "toto"
- req.form['__redirectpath'] = rpath
- controller = self.vreg['controllers'].select('undo', req)
- with self.assertRaises(Redirect) as cm:
- result = controller.publish(rset=None)
- self.assertURLPath(cm.exception.location, rpath)
+ with self.admin_access.web_request() as req:
+ txuuid = self.txuuid_toto_email
+ req.form['txuuid'] = txuuid
+ rpath = "toto"
+ req.form['__redirectpath'] = rpath
+ controller = self.vreg['controllers'].select('undo', req)
+ with self.assertRaises(Redirect) as cm:
+ result = controller.publish(rset=None)
+ self.assertURLPath(cm.exception.location, rpath)
def test_redirect_default(self):
- req = self.request()
- txuuid = self.txuuid_toto_email
- req.form['txuuid'] = txuuid
- req.session.data['breadcrumbs'] = [ urljoin(req.base_url(), path)
- for path in ('tata', 'toto',)]
- controller = self.vreg['controllers'].select('undo', req)
- with self.assertRaises(Redirect) as cm:
- result = controller.publish(rset=None)
- self.assertURLPath(cm.exception.location, 'toto')
+ with self.admin_access.web_request() as req:
+ txuuid = self.txuuid_toto_email
+ req.form['txuuid'] = txuuid
+ req.session.data['breadcrumbs'] = [ urljoin(req.base_url(), path)
+ for path in ('tata', 'toto',)]
+ controller = self.vreg['controllers'].select('undo', req)
+ with self.assertRaises(Redirect) as cm:
+ result = controller.publish(rset=None)
+ self.assertURLPath(cm.exception.location, 'toto')
class LoginControllerTC(CubicWebTC):
def test_login_with_dest(self):
- req = self.request()
- req.form = {'postlogin_path': 'elephants/babar'}
- with self.assertRaises(Redirect) as cm:
- self.ctrl_publish(req, ctrl='login')
- self.assertEqual(req.build_url('elephants/babar'), cm.exception.location)
+ with self.admin_access.web_request() as req:
+ req.form = {'postlogin_path': 'elephants/babar'}
+ with self.assertRaises(Redirect) as cm:
+ self.ctrl_publish(req, ctrl='login')
+ self.assertEqual(req.build_url('elephants/babar'), cm.exception.location)
def test_login_no_dest(self):
- req = self.request()
- with self.assertRaises(Redirect) as cm:
- self.ctrl_publish(req, ctrl='login')
- self.assertEqual(req.base_url(), cm.exception.location)
+ with self.admin_access.web_request() as req:
+ with self.assertRaises(Redirect) as cm:
+ self.ctrl_publish(req, ctrl='login')
+ self.assertEqual(req.base_url(), cm.exception.location)
if __name__ == '__main__':
unittest_main()
--- a/web/test/unittest_views_basetemplates.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_basetemplates.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# 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.
@@ -18,7 +18,6 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.devtools.htmlparser import XMLValidator
-from cubicweb.dbapi import DBAPISession
class LogFormTemplateTC(CubicWebTC):
@@ -39,7 +38,8 @@
class MainNoTopTemplateTC(CubicWebTC):
def test_valid_xhtml(self):
- self.view('index', template='main-no-top')
+ with self.admin_access.web_request() as req:
+ self.view('index', template='main-no-top', req=req)
if __name__ == '__main__':
--- a/web/test/unittest_views_baseviews.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_baseviews.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.
@@ -22,7 +22,6 @@
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.utils import json
from cubicweb.view import StartupView, TRANSITIONAL_DOCTYPE
-from cubicweb.web.htmlwidgets import TableWidget
from cubicweb.web.views import vid_from_rset
def loadjson(value):
@@ -31,90 +30,85 @@
class VidFromRsetTC(CubicWebTC):
def test_no_rset(self):
- req = self.request()
- self.assertEqual(vid_from_rset(req, None, self.schema), 'index')
+ with self.admin_access.web_request() as req:
+ self.assertEqual(vid_from_rset(req, None, self.schema), 'index')
def test_no_entity(self):
- req = self.request()
- rset = self.execute('Any X WHERE X login "blabla"')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'noresult')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X login "blabla"')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'noresult')
def test_one_entity(self):
- req = self.request()
- rset = self.execute('Any X WHERE X login "admin"')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
- rset = self.execute('Any X, L WHERE X login "admin", X login L')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
- req.search_state = ('pasnormal',)
- rset = self.execute('Any X WHERE X login "admin"')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'outofcontext-search')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X login "admin"')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
+ rset = req.execute('Any X, L WHERE X login "admin", X login L')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
+ req.search_state = ('pasnormal',)
+ rset = req.execute('Any X WHERE X login "admin"')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'outofcontext-search')
def test_one_entity_eid(self):
- req = self.request()
- rset = self.execute('Any X WHERE X eid 1')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X eid 1')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'primary')
def test_more_than_one_entity_same_type(self):
- req = self.request()
- rset = self.execute('Any X WHERE X is CWUser')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'sameetypelist')
- rset = self.execute('Any X, L WHERE X login L')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'sameetypelist')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X is CWUser')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'sameetypelist')
+ rset = req.execute('Any X, L WHERE X login L')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'sameetypelist')
def test_more_than_one_entity_diff_type(self):
- req = self.request()
- rset = self.execute('Any X WHERE X is IN (CWUser, CWGroup)')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'list')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X WHERE X is IN (CWUser, CWGroup)')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'list')
def test_more_than_one_entity_by_row(self):
- req = self.request()
- rset = self.execute('Any X, G WHERE X in_group G')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X, G WHERE X in_group G')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
def test_more_than_one_entity_by_row_2(self):
- req = self.request()
- rset = self.execute('Any X, GN WHERE X in_group G, G name GN')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X, GN WHERE X in_group G, G name GN')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
def test_aggregat(self):
- req = self.request()
- rset = self.execute('Any X, COUNT(T) GROUPBY X WHERE X is T')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
- rset = self.execute('Any MAX(X) WHERE X is CWUser')
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X, COUNT(T) GROUPBY X WHERE X is T')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
+ rset = req.execute('Any MAX(X) WHERE X is CWUser')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
def test_subquery(self):
- rset = self.execute(
+ with self.admin_access.web_request() as req:
+ rset = req.execute(
'DISTINCT Any X,N ORDERBY N '
'WITH X,N BEING ('
' (DISTINCT Any P,N WHERE P is CWUser, P login N)'
' UNION'
' (DISTINCT Any W,N WHERE W is CWGroup, W name N))')
- req = self.request()
- self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
+ self.assertEqual(vid_from_rset(req, rset, self.schema), 'table')
class TableViewTC(CubicWebTC):
- def _prepare_entity(self):
- req = self.request()
+ def _prepare_entity(self, req):
e = req.create_entity("State", name=u'<toto>', description=u'loo"ong blabla')
- rset = req.execute('Any X, D, CD, NOW - CD WHERE X is State, X description D, X creation_date CD, X eid %(x)s',
+ rset = req.execute('Any X, D, CD, NOW - CD WHERE X is State, '
+ 'X description D, X creation_date CD, X eid %(x)s',
{'x': e.eid})
view = self.vreg['views'].select('table', req, rset=rset)
return e, rset, view
- def test_headers(self):
- self.skipTest('implement me')
-
def test_sortvalue(self):
- e, _, view = self._prepare_entity()
- colrenderers = view.build_column_renderers()[:3]
- self.assertListEqual([renderer.sortvalue(0) for renderer in colrenderers],
- [u'<toto>', u'loo"ong blabla', e.creation_date])
- # XXX sqlite does not handle Interval correctly
- # value = loadjson(view.sortvalue(0, 3))
- # self.assertAlmostEquals(value, rset.rows[0][3].seconds)
+ with self.admin_access.web_request() as req:
+ e, _, view = self._prepare_entity(req)
+ colrenderers = view.build_column_renderers()[:3]
+ self.assertListEqual([renderer.sortvalue(0) for renderer in colrenderers],
+ [u'<toto>', u'loo"ong blabla', e.creation_date])
class HTMLStreamTests(CubicWebTC):
@@ -129,11 +123,15 @@
def call(self):
self._cw.set_doctype('<!DOCTYPE html>')
- with self.temporary_appobjects(MyView):
- html_source = self.view('my-view').source
- source_lines = [line.strip() for line in html_source.splitlines(False)
- if line.strip()]
- self.assertListEqual(['<!DOCTYPE html>', '<html xmlns:cubicweb="http://www.cubicweb.org" lang="en">'], source_lines[:2])
+ with self.admin_access.web_request() as req:
+ with self.temporary_appobjects(MyView):
+ html_source = self.view('my-view', req=req).source
+ source_lines = [line.strip()
+ for line in html_source.splitlines(False)
+ if line.strip()]
+ self.assertListEqual(['<!DOCTYPE html>',
+ '<html xmlns:cubicweb="http://www.cubicweb.org" lang="en">'],
+ source_lines[:2])
def test_set_doctype_no_reset_xmldecl(self):
"""
@@ -147,12 +145,16 @@
self._cw.set_doctype(html_doctype)
self._cw.main_stream.set_htmlattrs([('lang', 'cz')])
- with self.temporary_appobjects(MyView):
- html_source = self.view('my-view').source
- source_lines = [line.strip() for line in html_source.splitlines(False)
- if line.strip()]
- self.assertListEqual([html_doctype, '<html xmlns:cubicweb="http://www.cubicweb.org" lang="cz">', '<head>'],
- source_lines[:3])
+ with self.admin_access.web_request() as req:
+ with self.temporary_appobjects(MyView):
+ html_source = self.view('my-view', req=req).source
+ source_lines = [line.strip()
+ for line in html_source.splitlines(False)
+ if line.strip()]
+ self.assertListEqual([html_doctype,
+ '<html xmlns:cubicweb="http://www.cubicweb.org" lang="cz">',
+ '<head>'],
+ source_lines[:3])
if __name__ == '__main__':
unittest_main()
--- a/web/test/unittest_views_editforms.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_editforms.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# 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.
@@ -15,9 +15,6 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-"""
from logilab.common.testlib import unittest_main, mock_object
from cubicweb.devtools.testlib import CubicWebTC
@@ -32,154 +29,171 @@
permission = 'update'
else:
permission = 'add'
- return [(rschema.type, x) for rschema, tschemas, x in AFS.relations_by_section(entity, formtype, section, permission)]
+ return [(rschema.type, x)
+ for rschema, tschemas, x in AFS.relations_by_section(entity,
+ formtype,
+ section,
+ permission)]
class AutomaticEntityFormTC(CubicWebTC):
def test_custom_widget(self):
- AFFK.tag_subject_of(('CWUser', 'login', '*'),
- {'widget': AutoCompletionWidget(autocomplete_initfunc='get_logins')})
- form = self.vreg['forms'].select('edition', self.request(),
- entity=self.user())
- field = form.field_by_name('login', 'subject')
- self.assertIsInstance(field.widget, AutoCompletionWidget)
- AFFK.del_rtag('CWUser', 'login', '*', 'subject')
+ with self.admin_access.web_request() as req:
+ AFFK.tag_subject_of(('CWUser', 'login', '*'),
+ {'widget': AutoCompletionWidget(autocomplete_initfunc='get_logins')})
+ form = self.vreg['forms'].select('edition', req, entity=self.user(req))
+ field = form.field_by_name('login', 'subject')
+ self.assertIsInstance(field.widget, AutoCompletionWidget)
+ AFFK.del_rtag('CWUser', 'login', '*', 'subject')
def test_cwuser_relations_by_category(self):
- e = self.vreg['etypes'].etype_class('CWUser')(self.request())
- # see custom configuration in views.cwuser
- self.assertEqual(rbc(e, 'main', 'attributes'),
- [('login', 'subject'),
- ('upassword', 'subject'),
- ('firstname', 'subject'),
- ('surname', 'subject'),
- ('in_group', 'subject'),
- ])
- self.assertListEqual(rbc(e, 'muledit', 'attributes'),
+ with self.admin_access.web_request() as req:
+ e = self.vreg['etypes'].etype_class('CWUser')(req)
+ # see custom configuration in views.cwuser
+ self.assertEqual(rbc(e, 'main', 'attributes'),
[('login', 'subject'),
('upassword', 'subject'),
+ ('firstname', 'subject'),
+ ('surname', 'subject'),
('in_group', 'subject'),
])
- self.assertListEqual(rbc(e, 'main', 'metadata'),
- [('last_login_time', 'subject'),
- ('cw_source', 'subject'),
- ('creation_date', 'subject'),
- ('cwuri', 'subject'),
- ('modification_date', 'subject'),
- ('created_by', 'subject'),
- ('owned_by', 'subject'),
- ('bookmarked_by', 'object'),
- ])
- # XXX skip 'tags' relation here and in the hidden category because
- # of some test interdependancy when pytest is launched on whole cw
- # (appears here while expected in hidden
- self.assertListEqual([x for x in rbc(e, 'main', 'relations')
- if x != ('tags', 'object')],
- [('connait', 'subject'),
- ('custom_workflow', 'subject'),
- ('primary_email', 'subject'),
- ('checked_by', 'object'),
- ])
- self.assertListEqual(rbc(e, 'main', 'inlined'),
- [('use_email', 'subject'),
- ])
- # owned_by is defined both as subject and object relations on CWUser
- self.assertListEqual(sorted(x for x in rbc(e, 'main', 'hidden')
- if x != ('tags', 'object')),
- sorted([('for_user', 'object'),
- ('created_by', 'object'),
- ('wf_info_for', 'object'),
- ('owned_by', 'object'),
- ]))
+ self.assertListEqual(rbc(e, 'muledit', 'attributes'),
+ [('login', 'subject'),
+ ('upassword', 'subject'),
+ ('in_group', 'subject'),
+ ])
+ self.assertListEqual(rbc(e, 'main', 'metadata'),
+ [('last_login_time', 'subject'),
+ ('cw_source', 'subject'),
+ ('creation_date', 'subject'),
+ ('cwuri', 'subject'),
+ ('modification_date', 'subject'),
+ ('created_by', 'subject'),
+ ('owned_by', 'subject'),
+ ('bookmarked_by', 'object'),
+ ])
+ # XXX skip 'tags' relation here and in the hidden category because
+ # of some test interdependancy when pytest is launched on whole cw
+ # (appears here while expected in hidden
+ self.assertListEqual([x for x in rbc(e, 'main', 'relations')
+ if x != ('tags', 'object')],
+ [('connait', 'subject'),
+ ('custom_workflow', 'subject'),
+ ('primary_email', 'subject'),
+ ('checked_by', 'object'),
+ ])
+ self.assertListEqual(rbc(e, 'main', 'inlined'),
+ [('use_email', 'subject'),
+ ])
+ # owned_by is defined both as subject and object relations on CWUser
+ self.assertListEqual(sorted(x for x in rbc(e, 'main', 'hidden')
+ if x != ('tags', 'object')),
+ sorted([('for_user', 'object'),
+ ('created_by', 'object'),
+ ('wf_info_for', 'object'),
+ ('owned_by', 'object'),
+ ]))
def test_inlined_view(self):
- self.assertTrue('main_inlined' in AFS.etype_get('CWUser', 'use_email', 'subject', 'EmailAddress'))
- self.assertFalse('main_inlined' in AFS.etype_get('CWUser', 'primary_email', 'subject', 'EmailAddress'))
- self.assertTrue('main_relations' in AFS.etype_get('CWUser', 'primary_email', 'subject', 'EmailAddress'))
+ self.assertIn('main_inlined',
+ AFS.etype_get('CWUser', 'use_email', 'subject', 'EmailAddress'))
+ self.assertNotIn('main_inlined',
+ AFS.etype_get('CWUser', 'primary_email', 'subject', 'EmailAddress'))
+ self.assertIn('main_relations',
+ AFS.etype_get('CWUser', 'primary_email', 'subject', 'EmailAddress'))
def test_personne_relations_by_category(self):
- e = self.vreg['etypes'].etype_class('Personne')(self.request())
- self.assertListEqual(rbc(e, 'main', 'attributes'),
- [('nom', 'subject'),
- ('prenom', 'subject'),
- ('sexe', 'subject'),
- ('promo', 'subject'),
- ('titre', 'subject'),
- ('ass', 'subject'),
- ('web', 'subject'),
- ('tel', 'subject'),
- ('fax', 'subject'),
- ('datenaiss', 'subject'),
- ('test', 'subject'),
- ('description', 'subject'),
- ('salary', 'subject'),
- ])
- self.assertListEqual(rbc(e, 'muledit', 'attributes'),
- [('nom', 'subject'),
- ])
- self.assertListEqual(rbc(e, 'main', 'metadata'),
- [('cw_source', 'subject'),
- ('creation_date', 'subject'),
- ('cwuri', 'subject'),
- ('modification_date', 'subject'),
- ('created_by', 'subject'),
- ('owned_by', 'subject'),
- ])
- self.assertListEqual(rbc(e, 'main', 'relations'),
- [('travaille', 'subject'),
- ('manager', 'object'),
- ('connait', 'object'),
- ])
- self.assertListEqual(rbc(e, 'main', 'hidden'),
- [])
+ with self.admin_access.web_request() as req:
+ e = self.vreg['etypes'].etype_class('Personne')(req)
+ self.assertListEqual(rbc(e, 'main', 'attributes'),
+ [('nom', 'subject'),
+ ('prenom', 'subject'),
+ ('sexe', 'subject'),
+ ('promo', 'subject'),
+ ('titre', 'subject'),
+ ('ass', 'subject'),
+ ('web', 'subject'),
+ ('tel', 'subject'),
+ ('fax', 'subject'),
+ ('datenaiss', 'subject'),
+ ('test', 'subject'),
+ ('description', 'subject'),
+ ('salary', 'subject'),
+ ])
+ self.assertListEqual(rbc(e, 'muledit', 'attributes'),
+ [('nom', 'subject'),
+ ])
+ self.assertListEqual(rbc(e, 'main', 'metadata'),
+ [('cw_source', 'subject'),
+ ('creation_date', 'subject'),
+ ('cwuri', 'subject'),
+ ('modification_date', 'subject'),
+ ('created_by', 'subject'),
+ ('owned_by', 'subject'),
+ ])
+ self.assertListEqual(rbc(e, 'main', 'relations'),
+ [('travaille', 'subject'),
+ ('manager', 'object'),
+ ('connait', 'object'),
+ ])
+ self.assertListEqual(rbc(e, 'main', 'hidden'),
+ [])
def test_edition_form(self):
- rset = self.execute('CWUser X LIMIT 1')
- form = self.vreg['forms'].select('edition', rset.req, rset=rset,
- row=0, col=0)
- # should be also selectable by specifying entity
- self.vreg['forms'].select('edition', rset.req,
- entity=rset.get_entity(0, 0))
- self.assertFalse(any(f for f in form.fields if f is None))
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X LIMIT 1')
+ form = self.vreg['forms'].select('edition', req, rset=rset, row=0, col=0)
+ # should be also selectable by specifying entity
+ self.vreg['forms'].select('edition', req, entity=rset.get_entity(0, 0))
+ self.assertFalse(any(f for f in form.fields if f is None))
class FormViewsTC(CubicWebTC):
+
def test_delete_conf_formview(self):
- rset = self.execute('CWGroup X')
- self.view('deleteconf', rset, template=None).source
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWGroup X')
+ self.view('deleteconf', rset, template=None, req=req).source
def test_automatic_edition_formview(self):
- rset = self.execute('CWUser X')
- self.view('edition', rset, row=0, template=None).source
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ self.view('edition', rset, row=0, template=None, req=req).source
- def test_automatic_edition_formview(self):
- rset = self.execute('CWUser X')
- self.view('copy', rset, row=0, template=None).source
+ def test_automatic_edition_copyformview(self):
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ self.view('copy', rset, row=0, template=None, req=req).source
def test_automatic_creation_formview(self):
- self.view('creation', None, etype='CWUser', template=None).source
+ with self.admin_access.web_request() as req:
+ self.view('creation', None, etype='CWUser', template=None, req=req).source
def test_automatic_muledit_formview(self):
- rset = self.execute('CWUser X')
- self.view('muledit', rset, template=None).source
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ self.view('muledit', rset, template=None, req=req).source
def test_automatic_reledit_formview(self):
- rset = self.execute('CWUser X')
- self.view('reledit', rset, row=0, rtype='login', template=None).source
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWUser X')
+ self.view('reledit', rset, row=0, rtype='login', template=None, req=req).source
def test_automatic_inline_edit_formview(self):
- geid = self.execute('CWGroup X LIMIT 1')[0][0]
- rset = self.execute('CWUser X LIMIT 1')
- self.view('inline-edition', rset, row=0, col=0, rtype='in_group',
- peid=geid, role='object', i18nctx='', pform=MOCKPFORM,
- template=None).source
+ with self.admin_access.web_request() as req:
+ geid = req.execute('CWGroup X LIMIT 1')[0][0]
+ rset = req.execute('CWUser X LIMIT 1')
+ self.view('inline-edition', rset, row=0, col=0, rtype='in_group',
+ peid=geid, role='object', i18nctx='', pform=MOCKPFORM,
+ template=None, req=req).source
def test_automatic_inline_creation_formview(self):
- geid = self.execute('CWGroup X LIMIT 1')[0][0]
- self.view('inline-creation', None, etype='CWUser', rtype='in_group',
- peid=geid, petype='CWGroup', i18nctx='', role='object', pform=MOCKPFORM,
- template=None)
+ with self.admin_access.web_request() as req:
+ geid = req.execute('CWGroup X LIMIT 1')[0][0]
+ self.view('inline-creation', None, etype='CWUser', rtype='in_group',
+ peid=geid, petype='CWGroup', i18nctx='', role='object', pform=MOCKPFORM,
+ template=None, req=req)
MOCKPFORM = mock_object(form_previous_values={}, form_valerror=None)
--- a/web/test/unittest_views_json.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_json.py Fri Jul 18 17:35:25 2014 +0200
@@ -30,14 +30,14 @@
def test_json_rsetexport(self):
with self.admin_access.web_request() as req:
rset = req.execute('Any GN,COUNT(X) GROUPBY GN ORDERBY GN WHERE X in_group G, G name GN')
- data = self.view('jsonexport', rset)
+ data = self.view('jsonexport', rset, req=req)
self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
self.assertListEqual(data, [["guests", 1], ["managers", 1]])
def test_json_rsetexport_empty_rset(self):
with self.admin_access.web_request() as req:
rset = req.execute('Any X WHERE X is CWUser, X login "foobarbaz"')
- data = self.view('jsonexport', rset)
+ data = self.view('jsonexport', rset, req=req)
self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
self.assertListEqual(data, [])
@@ -65,7 +65,7 @@
def test_json_ersetexport(self):
with self.admin_access.web_request() as req:
rset = req.execute('Any G ORDERBY GN WHERE G is CWGroup, G name GN')
- data = self.view('ejsonexport', rset)
+ data = self.view('ejsonexport', rset, req=req)
self.assertEqual(req.headers_out.getRawHeaders('content-type'), ['application/json'])
self.assertEqual(data[0]['name'], 'guests')
self.assertEqual(data[1]['name'], 'managers')
--- a/web/test/unittest_views_navigation.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_navigation.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# 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.
@@ -17,7 +17,7 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb.web.views.navigation unit tests"""
-from logilab.common.testlib import unittest_main, mock_object
+from logilab.common.testlib import unittest_main
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.web.views.navigation import (PageNavigation, SortedNavigation,
@@ -29,123 +29,94 @@
class NavigationTC(CubicWebTC):
def test_navigation_selection_whatever(self):
- req = self.request()
- rset = self.execute('Any X,N WHERE X name N')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- self.assertIsInstance(navcomp, PageNavigation)
- req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- self.assertIsInstance(navcomp, PageNavigation)
- req.set_search_state('normal')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,N WHERE X name N')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ self.assertIsInstance(navcomp, PageNavigation)
+ req.set_search_state('W:X:Y:Z')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ self.assertIsInstance(navcomp, PageNavigation)
+ req.set_search_state('normal')
def test_navigation_selection_ordered(self):
- req = self.request()
- rset = self.execute('Any X,N ORDERBY N LIMIT 40 WHERE X name N')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
- self.assertIsInstance(navcomp, SortedNavigation)
- req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
- self.assertIsInstance(navcomp, SortedNavigation)
- req.set_search_state('normal')
- html = navcomp.render()
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,N ORDERBY N LIMIT 40 WHERE X name N')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
+ self.assertIsInstance(navcomp, SortedNavigation)
+ req.set_search_state('W:X:Y:Z')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
+ self.assertIsInstance(navcomp, SortedNavigation)
+ req.set_search_state('normal')
+ navcomp.render()
def test_navigation_selection_large_rset(self):
- req = self.request()
- rset = self.execute('Any X,N LIMIT 120 WHERE X name N')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
- self.assertIsInstance(navcomp, PageNavigationSelect)
- rset = self.execute('Any X,N ORDERBY N LIMIT 120 WHERE X name N')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
- self.assertIsInstance(navcomp, PageNavigationSelect)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,N LIMIT 120 WHERE X name N')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
+ self.assertIsInstance(navcomp, PageNavigationSelect)
+ rset = req.execute('Any X,N ORDERBY N LIMIT 120 WHERE X name N')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset, page_size=20)
+ self.assertIsInstance(navcomp, PageNavigationSelect)
def test_navigation_selection_not_enough_1(self):
- req = self.request()
- rset = self.execute('Any X,N LIMIT 10 WHERE X name N')
- navcomp = self.vreg['components'].select_or_none('navigation', req, rset=rset)
- self.assertEqual(navcomp, None)
- req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg['components'].select_or_none('navigation', req, rset=rset)
- self.assertEqual(navcomp, None)
- req.set_search_state('normal')
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,N LIMIT 10 WHERE X name N')
+ navcomp = self.vreg['components'].select_or_none('navigation', req, rset=rset)
+ self.assertEqual(navcomp, None)
+ req.set_search_state('W:X:Y:Z')
+ navcomp = self.vreg['components'].select_or_none('navigation', req, rset=rset)
+ self.assertEqual(navcomp, None)
+ req.set_search_state('normal')
def test_navigation_selection_not_enough_2(self):
- req = self.request()
- rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- self.assertIsInstance(navcomp, SortedNavigation)
- req.set_search_state('W:X:Y:Z')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- self.assertIsInstance(navcomp, SortedNavigation)
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N '
+ 'WHERE RDEF relation_type RT, RT name N')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ self.assertIsInstance(navcomp, SortedNavigation)
+ req.set_search_state('W:X:Y:Z')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ self.assertIsInstance(navcomp, SortedNavigation)
def test_navigation_selection_wrong_boundary(self):
- req = self.request()
- rset = self.execute('Any X,N WHERE X name N')
- req = self.request()
- req.form['__start'] = 1000000
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- html = navcomp.render()
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any X,N WHERE X name N')
+ req.form['__start'] = 1000000
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ html = navcomp.render()
def test_sorted_navigation_1(self):
- req = self.request()
- rset = self.execute('Any RDEF ORDERBY RT WHERE RDEF relation_type RT')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- html = navcomp.render()
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any RDEF ORDERBY RT WHERE RDEF relation_type RT')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ html = navcomp.render()
def test_sorted_navigation_2(self):
- req = self.request()
- rset = self.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- html = navcomp.render()
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any RDEF ORDERBY RDEF WHERE RDEF relation_type RT')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ html = navcomp.render()
def test_sorted_navigation_3(self):
- req = self.request()
- rset = self.execute('CWAttribute RDEF ORDERBY RDEF')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- html = navcomp.render()
+ with self.admin_access.web_request() as req:
+ rset = req.execute('CWAttribute RDEF ORDERBY RDEF')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ html = navcomp.render()
def test_sorted_navigation_4(self):
- req = self.request()
- rset = self.execute('Any RDEF ORDERBY N WHERE RDEF relation_type RT, RT name N')
- navcomp = self.vreg['components'].select('navigation', req, rset=rset)
- html = navcomp.render()
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any RDEF ORDERBY N '
+ 'WHERE RDEF relation_type RT, RT name N')
+ navcomp = self.vreg['components'].select('navigation', req, rset=rset)
+ html = navcomp.render()
def test_sorted_navigation_5(self):
- req = self.request()
- rset = self.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N WHERE RDEF relation_type RT, RT name N')
- navcomp = self.vreg['components'].select('navigation', rset.req, rset=rset)
- html = navcomp.render()
-
+ with self.admin_access.web_request() as req:
+ rset = req.execute('Any N, COUNT(RDEF) GROUPBY N ORDERBY N '
+ 'WHERE RDEF relation_type RT, RT name N')
+ navcomp = self.vreg['components'].select('navigation', rset.req, rset=rset)
+ html = navcomp.render()
-# XXX deactivate, contextual component has been removed
-# class ContentNavigationTC(CubicWebTC):
- # def test_component_context(self):
- # view = mock_object(is_primary=lambda x: True)
- # rset = self.execute('CWUser X LIMIT 1')
- # req = self.request()
- # objs = self.vreg['ctxcomponents'].poss_visible_objects(
- # req, rset=rset, view=view, context='navtop')
- # # breadcrumbs should be in headers by default
- # clsids = set(obj.id for obj in objs)
- # self.assertIn('breadcrumbs', clsids)
- # objs = self.vreg['ctxcomponents'].poss_visible_objects(
- # req, rset=rset, view=view, context='navbottom')
- # # breadcrumbs should _NOT_ be in footers by default
- # clsids = set(obj.id for obj in objs)
- # self.assertNotIn('breadcrumbs', clsids)
- # self.execute('INSERT CWProperty P: P pkey "ctxcomponents.breadcrumbs.context", '
- # 'P value "navbottom"')
- # # breadcrumbs should now be in footers
- # req.cnx.commit()
- # objs = self.vreg['ctxcomponents'].poss_visible_objects(
- # req, rset=rset, view=view, context='navbottom')
-
- # clsids = [obj.id for obj in objs]
- # self.assertIn('breadcrumbs', clsids)
- # objs = self.vreg['ctxcomponents'].poss_visible_objects(
- # req, rset=rset, view=view, context='navtop')
-
- # clsids = [obj.id for obj in objs]
- # self.assertNotIn('breadcrumbs', clsids)
if __name__ == '__main__':
--- a/web/test/unittest_views_xmlrss.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_views_xmlrss.py Fri Jul 18 17:35:25 2014 +0200
@@ -10,7 +10,7 @@
self.assertMultiLineEqual(
req.user.view('xml'),
'''\
-<CWUser eid="6" cwuri="None6" cwsource="system">
+<CWUser eid="6" cwuri="http://testing.fr/cubicweb/6" cwsource="system">
<login>admin</login>
<upassword/>
<firstname/>
@@ -21,10 +21,10 @@
<tags role="object">
</tags>
<in_group role="subject">
- <CWGroup eid="%(group_eid)s" cwuri="None%(group_eid)s"/>
+ <CWGroup eid="%(group_eid)s" cwuri="http://testing.fr/cubicweb/%(group_eid)s"/>
</in_group>
<in_state role="subject">
- <State eid="%(state_eid)s" cwuri="None%(state_eid)s" name="activated"/>
+ <State eid="%(state_eid)s" cwuri="http://testing.fr/cubicweb/%(state_eid)s" name="activated"/>
</in_state>
<use_email role="subject">
</use_email>
--- a/web/test/unittest_web.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/test/unittest_web.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# 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.
@@ -18,6 +18,7 @@
from json import loads
from os.path import join
+import tempfile
try:
import requests
@@ -64,7 +65,8 @@
@property
def _post_url(self):
- return self.request().build_url('ajax', fname='fileupload')
+ with self.admin_access.web_request() as req:
+ return req.build_url('ajax', fname='fileupload')
def _fobject(self, fname):
return open(join(self.datadir, fname), 'rb')
@@ -92,6 +94,7 @@
self.assertEqual(webreq.status_code, 200)
self.assertDictEqual(expect, loads(webreq.content))
+
class LanguageTC(CubicWebServerTC):
def test_language_neg(self):
@@ -115,5 +118,21 @@
self.assertEqual(webreq.status, 200)
+class LogQueriesTC(CubicWebServerTC):
+ @classmethod
+ def init_config(cls, config):
+ super(LogQueriesTC, cls).init_config(config)
+ cls.logfile = tempfile.NamedTemporaryFile()
+ config.global_set_option('query-log-file', cls.logfile.name)
+
+ def test_log_queries(self):
+ self.web_request()
+ self.assertTrue(self.logfile.read())
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.logfile.close()
+
+
if __name__ == '__main__':
unittest_main()
--- a/web/views/ajaxedit.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/views/ajaxedit.py Fri Jul 18 17:35:25 2014 +0200
@@ -53,9 +53,9 @@
self.w(u'<h1>%s</h1>' % self._cw._('relation %(relname)s of %(ent)s')
% {'relname': rschema.display_name(self._cw, role(self)),
'ent': entity.view('incontext')})
- self.w(u'<ul>')
+ self.w(u'<ul class="list-unstyled">')
for boxitem in self.unrelated_boxitems(entity):
- self.w('<li class="invisible">%s</li>' % boxitem)
+ self.w('<li>%s</li>' % boxitem)
self.w(u'</ul></div>')
def unrelated_entities(self, entity):
--- a/web/views/authentication.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/views/authentication.py Fri Jul 18 17:35:25 2014 +0200
@@ -44,7 +44,7 @@
"""
raise NotImplementedError()
- def authenticated(self, retriever, req, cnx, login, authinfo):
+ def authenticated(self, retriever, req, session, login, authinfo):
"""callback when return authentication information have opened a
repository connection successfully. Take care req has no session
attached yet, hence req.execute isn't available.
--- a/web/views/autoform.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/views/autoform.py Fri Jul 18 17:35:25 2014 +0200
@@ -504,15 +504,15 @@
label = rschema.display_name(req, role, context=form.edited_entity.cw_etype)
w(u'<tr><th class="labelCol">%s</th>' % label)
w(u'<td>')
- w(u'<ul>')
+ w(u'<ul class="list-unstyled">')
for viewparams in related:
- w(u'<li class="invisible">%s<span id="span%s" class="%s">%s</span></li>'
+ w(u'<li>%s<span id="span%s" class="%s">%s</span></li>'
% (viewparams[1], viewparams[0], viewparams[2], viewparams[3]))
if not form.force_display and form.maxrelitems < len(related):
- link = (u'<span class="invisible">'
+ link = (u'<span>'
'[<a href="javascript: window.location.href+=\'&__force_display=1\'">%s</a>]'
'</span>' % _('view all'))
- w(u'<li class="invisible">%s</li>' % link)
+ w(u'<li>%s</li>' % link)
w(u'</ul>')
w(u'</td>')
w(u'</tr>')
--- a/web/views/reledit.py Thu Jul 17 11:08:56 2014 +0200
+++ b/web/views/reledit.py Fri Jul 18 17:35:25 2014 +0200
@@ -1,4 +1,4 @@
-# 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.
@@ -329,13 +329,13 @@
w = self.w
w(u'<div id="%(id)s-reledit" onmouseout="%(out)s" onmouseover="%(over)s" class="%(css)s">' %
{'id': divid, 'css': 'releditField',
- 'out': "jQuery('#%s').addClass('hidden')" % divid,
- 'over': "jQuery('#%s').removeClass('hidden')" % divid})
+ 'out': "jQuery('#%s').addClass('invisible')" % divid,
+ 'over': "jQuery('#%s').removeClass('invisible')" % divid})
w(u'<div id="%s-value" class="editableFieldValue">' % divid)
w(value)
w(u'</div>')
form.render(w=w, renderer=renderer)
- w(u'<div id="%s" class="editableField hidden">' % divid)
+ w(u'<div id="%s" class="editableField invisible">' % divid)
def _edit_action(self, divid, args, edit_related, add_related, _delete_related):
# XXX disambiguate wrt edit_related